From fd0dc88c64e18517047d6ca044290a5f17563ac6 Mon Sep 17 00:00:00 2001 From: Sergey Solovyev Date: Thu, 25 May 2017 16:50:25 +0200 Subject: [PATCH] Delay math registry initialization --- .../android/calculator/EntitiesRegistry.java | 2 - .../android/calculator/VariablesRegistry.java | 35 +++--- .../entities/BaseEntitiesRegistry.java | 29 +++-- .../functions/FunctionsRegistry.java | 54 +++++---- jscl/src/main/java/jscl/JsclMathEngine.java | 46 ++++--- .../main/java/jscl/math/NumericWrapper.java | 23 ++-- .../java/jscl/math/function/Constant.java | 18 +-- .../jscl/math/function/ConstantsRegistry.java | 35 ++++-- .../jscl/math/function/FunctionsRegistry.java | 111 ++++++++++------- .../function/PostfixFunctionsRegistry.java | 27 +++-- .../operator/matrix/OperatorsRegistry.java | 112 ++++-------------- .../common/math/AbstractMathRegistry.java | 17 +++ .../solovyev/common/math/MathRegistry.java | 5 +- 13 files changed, 275 insertions(+), 239 deletions(-) diff --git a/app/src/main/java/org/solovyev/android/calculator/EntitiesRegistry.java b/app/src/main/java/org/solovyev/android/calculator/EntitiesRegistry.java index 65187065..7f1c1e78 100644 --- a/app/src/main/java/org/solovyev/android/calculator/EntitiesRegistry.java +++ b/app/src/main/java/org/solovyev/android/calculator/EntitiesRegistry.java @@ -37,7 +37,5 @@ public interface EntitiesRegistry extends MathRegistry @Nullable Category getCategory(@Nonnull E entity); - void init(); - void save(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/VariablesRegistry.java b/app/src/main/java/org/solovyev/android/calculator/VariablesRegistry.java index 125d0cfd..382a2f53 100644 --- a/app/src/main/java/org/solovyev/android/calculator/VariablesRegistry.java +++ b/app/src/main/java/org/solovyev/android/calculator/VariablesRegistry.java @@ -23,9 +23,9 @@ package org.solovyev.android.calculator; import android.support.annotation.NonNull; + import com.google.common.base.Strings; -import jscl.JsclMathEngine; -import jscl.math.function.IConstant; + import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; import org.solovyev.android.Check; @@ -39,12 +39,16 @@ import org.solovyev.android.calculator.variables.OldVars; import org.solovyev.android.calculator.variables.VariableCategory; import org.solovyev.android.io.FileSaver; +import java.io.File; +import java.util.List; + import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; -import java.io.File; -import java.util.List; + +import jscl.JsclMathEngine; +import jscl.math.function.IConstant; @Singleton public class VariablesRegistry extends BaseEntitiesRegistry { @@ -82,23 +86,20 @@ public class VariablesRegistry extends BaseEntitiesRegistry { bus.post(new RemovedEvent(variable)); } - public void init() { + @Override + protected void onInit() { Check.isNotMainThread(); - try { - migrateOldVariables(); + migrateOldVariables(); - for (CppVariable variable : loadEntities(CppVariable.JSON_CREATOR)) { - addSafely(variable.toJsclConstant()); - } - - addSafely("x"); - addSafely("y"); - addSafely("t"); - addSafely("j"); - } finally { - setInitialized(); + for (CppVariable variable : loadEntities(CppVariable.JSON_CREATOR)) { + addSafely(variable.toJsclConstant()); } + + addSafely("x"); + addSafely("y"); + addSafely("t"); + addSafely("j"); } private void migrateOldVariables() { diff --git a/app/src/main/java/org/solovyev/android/calculator/entities/BaseEntitiesRegistry.java b/app/src/main/java/org/solovyev/android/calculator/entities/BaseEntitiesRegistry.java index ea8798b2..fdbaeb1d 100644 --- a/app/src/main/java/org/solovyev/android/calculator/entities/BaseEntitiesRegistry.java +++ b/app/src/main/java/org/solovyev/android/calculator/entities/BaseEntitiesRegistry.java @@ -27,7 +27,9 @@ import android.content.SharedPreferences; import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.StringRes; + import com.squareup.otto.Bus; + import org.json.JSONArray; import org.json.JSONException; import org.solovyev.android.Check; @@ -41,14 +43,19 @@ import org.solovyev.android.io.FileSystem; import org.solovyev.common.math.MathEntity; import org.solovyev.common.math.MathRegistry; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Named; -import java.io.File; -import java.io.IOException; -import java.util.*; -import java.util.concurrent.Executor; public abstract class BaseEntitiesRegistry implements EntitiesRegistry { @@ -103,8 +110,16 @@ public abstract class BaseEntitiesRegistry implements Enti } @Override - public void init() { - setInitialized(); + public final void init() { + try { + mathRegistry.init(); + onInit(); + } finally { + setInitialized(); + } + } + + protected void onInit() { } @NonNull @@ -121,7 +136,7 @@ public abstract class BaseEntitiesRegistry implements Enti return Collections.emptyList(); } - protected final void setInitialized() { + private final void setInitialized() { synchronized (lock) { Check.isTrue(!initialized); initialized = true; diff --git a/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsRegistry.java b/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsRegistry.java index a0e451af..46ae2d95 100644 --- a/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsRegistry.java +++ b/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsRegistry.java @@ -22,11 +22,10 @@ package org.solovyev.android.calculator.functions; +import static android.text.TextUtils.isEmpty; + import android.support.annotation.NonNull; -import jscl.JsclMathEngine; -import jscl.math.function.CustomFunction; -import jscl.math.function.Function; -import jscl.math.function.IFunction; + import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; import org.solovyev.android.Check; @@ -39,14 +38,22 @@ import org.solovyev.android.calculator.json.Jsonable; import org.solovyev.android.io.FileSaver; import org.solovyev.common.text.Strings; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; -import java.io.File; -import java.util.*; -import static android.text.TextUtils.isEmpty; +import jscl.JsclMathEngine; +import jscl.math.function.CustomFunction; +import jscl.math.function.Function; +import jscl.math.function.IFunction; @Singleton public class FunctionsRegistry extends BaseEntitiesRegistry { @@ -95,26 +102,27 @@ public class FunctionsRegistry extends BaseEntitiesRegistry { } @Override - public void init() { + protected void onInit() { Check.isNotMainThread(); - try { - migrateOldFunctions(); + migrateOldFunctions(); - final List functions = new ArrayList<>(); - functions.add(new CustomFunction.Builder(true, "log", Arrays.asList("base", "x"), "ln(x)/ln(base)")); - functions.add(new CustomFunction.Builder(true, "√3", Collections.singletonList("x"), "x^(1/3)")); - functions.add(new CustomFunction.Builder(true, "√4", Collections.singletonList("x"), "x^(1/4)")); - functions.add(new CustomFunction.Builder(true, "√n", Arrays.asList("x", "n"), "x^(1/n)")); - functions.add(new CustomFunction.Builder(true, "re", Collections.singletonList("x"), "(x+conjugate(x))/2")); - functions.add(new CustomFunction.Builder(true, "im", Collections.singletonList("x"), "(x-conjugate(x))/(2*i)")); + final List functions = new ArrayList<>(); + functions.add(new CustomFunction.Builder(true, "log", Arrays.asList("base", "x"), + "ln(x)/ln(base)")); + functions.add(new CustomFunction.Builder(true, "√3", Collections.singletonList("x"), + "x^(1/3)")); + functions.add(new CustomFunction.Builder(true, "√4", Collections.singletonList("x"), + "x^(1/4)")); + functions.add(new CustomFunction.Builder(true, "√n", Arrays.asList("x", "n"), "x^(1/n)")); + functions.add(new CustomFunction.Builder(true, "re", Collections.singletonList("x"), + "(x+conjugate(x))/2")); + functions.add(new CustomFunction.Builder(true, "im", Collections.singletonList("x"), + "(x-conjugate(x))/(2*i)")); - for (CppFunction function : loadEntities(CppFunction.JSON_CREATOR)) { - functions.add(function.toJsclBuilder()); - } - addSafely(functions); - } finally { - setInitialized(); + for (CppFunction function : loadEntities(CppFunction.JSON_CREATOR)) { + functions.add(function.toJsclBuilder()); } + addSafely(functions); } /** diff --git a/jscl/src/main/java/jscl/JsclMathEngine.java b/jscl/src/main/java/jscl/JsclMathEngine.java index 1ed2adc6..1bd99744 100644 --- a/jscl/src/main/java/jscl/JsclMathEngine.java +++ b/jscl/src/main/java/jscl/JsclMathEngine.java @@ -1,34 +1,33 @@ package jscl; +import static midpcalc.Real.NumberFormat.FSE_ENG; +import static midpcalc.Real.NumberFormat.FSE_NONE; +import static midpcalc.Real.NumberFormat.FSE_SCI; + +import org.solovyev.common.NumberFormatter; +import org.solovyev.common.math.MathRegistry; +import org.solovyev.common.msg.MessageRegistry; +import org.solovyev.common.msg.Messages; + +import java.math.BigInteger; +import java.util.List; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + import jscl.math.Expression; import jscl.math.Generic; -import jscl.math.NotIntegerException; import jscl.math.function.Constants; import jscl.math.function.ConstantsRegistry; import jscl.math.function.Function; import jscl.math.function.FunctionsRegistry; import jscl.math.function.IConstant; import jscl.math.function.PostfixFunctionsRegistry; -import jscl.math.function.*; import jscl.math.operator.Operator; import jscl.math.operator.Percent; import jscl.math.operator.Rand; import jscl.math.operator.matrix.OperatorsRegistry; import jscl.text.ParseException; -import org.solovyev.common.NumberFormatter; -import org.solovyev.common.math.MathRegistry; -import org.solovyev.common.msg.MessageRegistry; -import org.solovyev.common.msg.Messages; - -import static midpcalc.Real.NumberFormat.FSE_ENG; -import static midpcalc.Real.NumberFormat.FSE_NONE; -import static midpcalc.Real.NumberFormat.FSE_SCI; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.math.BigInteger; -import java.util.List; - -import static midpcalc.Real.NumberFormat.*; public class JsclMathEngine implements MathEngine { @@ -38,8 +37,6 @@ public class JsclMathEngine implements MathEngine { @Nonnull private static JsclMathEngine instance = new JsclMathEngine(); @Nonnull - private final ConstantsRegistry constantsRegistry = new ConstantsRegistry(); - @Nonnull private final ThreadLocal numberFormatter = new ThreadLocal() { @Override protected NumberFormatter initialValue() { @@ -104,17 +101,17 @@ public class JsclMathEngine implements MathEngine { @Nonnull public MathRegistry getFunctionsRegistry() { - return FunctionsRegistry.getInstance(); + return FunctionsRegistry.lazyInstance(); } @Nonnull public MathRegistry getOperatorsRegistry() { - return OperatorsRegistry.getInstance(); + return OperatorsRegistry.lazyInstance(); } @Nonnull public MathRegistry getPostfixFunctionsRegistry() { - return PostfixFunctionsRegistry.getInstance(); + return PostfixFunctionsRegistry.lazyInstance(); } @Nonnull @@ -137,7 +134,7 @@ public class JsclMathEngine implements MathEngine { @Nonnull public MathRegistry getConstantsRegistry() { - return constantsRegistry; + return ConstantsRegistry.lazyInstance(); } @Nonnull @@ -202,11 +199,12 @@ public class JsclMathEngine implements MathEngine { @Nullable private IConstant findConstant(double value) { - final IConstant constant = findConstant(constantsRegistry.getSystemEntities(), value); + final MathRegistry constants = ConstantsRegistry.getInstance(); + final IConstant constant = findConstant(constants.getSystemEntities(), value); if (constant != null) { return constant; } - final IConstant piInv = constantsRegistry.get(Constants.PI_INV.getName()); + final IConstant piInv = constants.get(Constants.PI_INV.getName()); if (piInv != null) { final Double piInvValue = piInv.getDoubleValue(); if (piInvValue != null && piInvValue == value) { diff --git a/jscl/src/main/java/jscl/math/NumericWrapper.java b/jscl/src/main/java/jscl/math/NumericWrapper.java index 03a3c426..9576e2d5 100644 --- a/jscl/src/main/java/jscl/math/NumericWrapper.java +++ b/jscl/src/main/java/jscl/math/NumericWrapper.java @@ -1,17 +1,22 @@ package jscl.math; -import jscl.JsclMathEngine; -import jscl.math.function.Constant; -import jscl.math.function.Constants; -import jscl.math.function.IConstant; -import jscl.math.numeric.*; -import jscl.mathml.MathML; - -import javax.annotation.Nonnull; import java.math.BigInteger; import java.util.Collections; import java.util.Set; +import javax.annotation.Nonnull; + +import jscl.math.function.Constant; +import jscl.math.function.Constants; +import jscl.math.function.ConstantsRegistry; +import jscl.math.function.IConstant; +import jscl.math.numeric.Complex; +import jscl.math.numeric.INumeric; +import jscl.math.numeric.Numeric; +import jscl.math.numeric.Real; +import jscl.math.numeric.Vector; +import jscl.mathml.MathML; + public final class NumericWrapper extends Generic implements INumeric { @Nonnull @@ -48,7 +53,7 @@ public final class NumericWrapper extends Generic implements INumeric { + private static final ConstantsRegistry INSTANCE = new ConstantsRegistry(); public static final String E = "e"; public static final String C = "c"; @@ -14,15 +16,28 @@ public class ConstantsRegistry extends AbstractMathRegistry { public final static String NAN = "NaN"; public ConstantsRegistry() { - this.add(new PiConstant()); - this.add(new ExtendedConstant(Constants.PI_INV, Math.PI, null)); - this.add(new ExtendedConstant(Constants.INF, Double.POSITIVE_INFINITY, "JsclDouble.valueOf(Double.POSITIVE_INFINITY)")); - this.add(new ExtendedConstant(Constants.INF_2, Double.POSITIVE_INFINITY, "JsclDouble.valueOf(Double.POSITIVE_INFINITY)")); - this.add(new ExtendedConstant(Constants.I, "√(-1)", null)); - this.add(new ExtendedConstant(new Constant(E), Math.E, null)); - this.add(new ExtendedConstant(new Constant(C), C_VALUE, null)); - this.add(new ExtendedConstant(new Constant(G), G_VALUE, null)); - this.add(new ExtendedConstant(new Constant(H_REDUCED), H_REDUCED_VALUE, null)); - this.add(new ExtendedConstant(new Constant(NAN), Double.NaN, null)); + } + + @Override + public void onInit() { + add(new PiConstant()); + add(new ExtendedConstant(Constants.PI_INV, Math.PI, null)); + add(new ExtendedConstant(Constants.INF, Double.POSITIVE_INFINITY, "JsclDouble.valueOf(Double.POSITIVE_INFINITY)")); + add(new ExtendedConstant(Constants.INF_2, Double.POSITIVE_INFINITY, "JsclDouble.valueOf(Double.POSITIVE_INFINITY)")); + add(new ExtendedConstant(Constants.I, "√(-1)", null)); + add(new ExtendedConstant(new Constant(E), Math.E, null)); + add(new ExtendedConstant(new Constant(C), C_VALUE, null)); + add(new ExtendedConstant(new Constant(G), G_VALUE, null)); + add(new ExtendedConstant(new Constant(H_REDUCED), H_REDUCED_VALUE, null)); + add(new ExtendedConstant(new Constant(NAN), Double.NaN, null)); + } + + public static MathRegistry getInstance() { + INSTANCE.init(); + return INSTANCE; + } + + public static MathRegistry lazyInstance() { + return INSTANCE; } } diff --git a/jscl/src/main/java/jscl/math/function/FunctionsRegistry.java b/jscl/src/main/java/jscl/math/function/FunctionsRegistry.java index 0d721b32..9078e3cd 100644 --- a/jscl/src/main/java/jscl/math/function/FunctionsRegistry.java +++ b/jscl/src/main/java/jscl/math/function/FunctionsRegistry.java @@ -1,12 +1,27 @@ package jscl.math.function; -import jscl.math.Variable; -import jscl.math.function.hyperbolic.*; -import jscl.math.function.trigonometric.*; import org.solovyev.common.math.AbstractMathRegistry; import javax.annotation.Nonnull; +import jscl.math.Variable; +import jscl.math.function.hyperbolic.Acosh; +import jscl.math.function.hyperbolic.Acoth; +import jscl.math.function.hyperbolic.Asinh; +import jscl.math.function.hyperbolic.Atanh; +import jscl.math.function.hyperbolic.Cosh; +import jscl.math.function.hyperbolic.Coth; +import jscl.math.function.hyperbolic.Sinh; +import jscl.math.function.hyperbolic.Tanh; +import jscl.math.function.trigonometric.Acos; +import jscl.math.function.trigonometric.Acot; +import jscl.math.function.trigonometric.Asin; +import jscl.math.function.trigonometric.Atan; +import jscl.math.function.trigonometric.Cos; +import jscl.math.function.trigonometric.Cot; +import jscl.math.function.trigonometric.Sin; +import jscl.math.function.trigonometric.Tan; + /** * User: serso * Date: 10/29/11 @@ -16,50 +31,14 @@ public class FunctionsRegistry extends AbstractMathRegistry { private final static FunctionsRegistry instance = new FunctionsRegistry(); - static { - instance.add(new Deg(null)); - instance.add(new Rad(null, null, null)); - instance.add(new Dms(null, null, null)); - - instance.add(new Sin(null)); - instance.add(new Cos(null)); - instance.add(new Tan(null)); - instance.add(new Cot(null)); - - instance.add(new Asin(null)); - instance.add(new Acos(null)); - instance.add(new Atan(null)); - instance.add(new Acot(null)); - - instance.add(new Ln(null)); - instance.add(new Lg(null)); - instance.add(new Exp(null)); - instance.add(new Sqrt(null)); - instance.add(new Cubic(null)); - - instance.add(new Sinh(null)); - instance.add(new Cosh(null)); - instance.add(new Tanh(null)); - instance.add(new Coth(null)); - - instance.add(new Asinh(null)); - instance.add(new Acosh(null)); - instance.add(new Atanh(null)); - instance.add(new Acoth(null)); - - instance.add(new Abs(null)); - instance.add(new Sgn(null)); - - instance.add(new Conjugate(null)); - - for (String name : Comparison.names) { - instance.add(new Comparison(name, null, null)); - } - } - - @Nonnull public static FunctionsRegistry getInstance() { + instance.init(); + return instance; + } + + @Nonnull + public static FunctionsRegistry lazyInstance() { return instance; } @@ -78,4 +57,46 @@ public class FunctionsRegistry extends AbstractMathRegistry { final Function function = super.get(name); return function == null ? null : copy(function); } + + @Override + public void onInit() { + add(new Deg(null)); + add(new Rad(null, null, null)); + add(new Dms(null, null, null)); + + add(new Sin(null)); + add(new Cos(null)); + add(new Tan(null)); + add(new Cot(null)); + + add(new Asin(null)); + add(new Acos(null)); + add(new Atan(null)); + add(new Acot(null)); + + add(new Ln(null)); + add(new Lg(null)); + add(new Exp(null)); + add(new Sqrt(null)); + add(new Cubic(null)); + + add(new Sinh(null)); + add(new Cosh(null)); + add(new Tanh(null)); + add(new Coth(null)); + + add(new Asinh(null)); + add(new Acosh(null)); + add(new Atanh(null)); + add(new Acoth(null)); + + add(new Abs(null)); + add(new Sgn(null)); + + add(new Conjugate(null)); + + for (String name : Comparison.names) { + add(new Comparison(name, null, null)); + } + } } diff --git a/jscl/src/main/java/jscl/math/function/PostfixFunctionsRegistry.java b/jscl/src/main/java/jscl/math/function/PostfixFunctionsRegistry.java index 7439e7f5..9dd6973d 100644 --- a/jscl/src/main/java/jscl/math/function/PostfixFunctionsRegistry.java +++ b/jscl/src/main/java/jscl/math/function/PostfixFunctionsRegistry.java @@ -1,12 +1,17 @@ package jscl.math.function; -import jscl.math.Generic; -import jscl.math.operator.*; import org.solovyev.common.math.AbstractMathRegistry; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import jscl.math.Generic; +import jscl.math.operator.Degree; +import jscl.math.operator.DoubleFactorial; +import jscl.math.operator.Factorial; +import jscl.math.operator.Operator; +import jscl.math.operator.Percent; + /** * User: serso * Date: 10/31/11 @@ -16,15 +21,14 @@ public class PostfixFunctionsRegistry extends AbstractMathRegistry { private final static PostfixFunctionsRegistry instance = new PostfixFunctionsRegistry(); - static { - instance.add(new DoubleFactorial(null)); - instance.add(new Factorial(null)); - instance.add(new Degree(null)); - instance.add(new Percent(null, null)); + @Nonnull + public static PostfixFunctionsRegistry getInstance() { + instance.init(); + return instance; } @Nonnull - public static PostfixFunctionsRegistry getInstance() { + public static PostfixFunctionsRegistry lazyInstance() { return instance; } @@ -40,4 +44,11 @@ public class PostfixFunctionsRegistry extends AbstractMathRegistry { return operator == null ? null : FunctionsRegistry.copy(operator); } + @Override + public void onInit() { + add(new DoubleFactorial(null)); + add(new Factorial(null)); + add(new Degree(null)); + add(new Percent(null, null)); + } } diff --git a/jscl/src/main/java/jscl/math/operator/matrix/OperatorsRegistry.java b/jscl/src/main/java/jscl/math/operator/matrix/OperatorsRegistry.java index 6d1ea731..6c845b00 100644 --- a/jscl/src/main/java/jscl/math/operator/matrix/OperatorsRegistry.java +++ b/jscl/src/main/java/jscl/math/operator/matrix/OperatorsRegistry.java @@ -1,13 +1,20 @@ package jscl.math.operator.matrix; -import jscl.math.Generic; -import jscl.math.function.FunctionsRegistry; -import jscl.math.operator.*; import org.solovyev.common.math.AbstractMathRegistry; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import jscl.math.Generic; +import jscl.math.function.FunctionsRegistry; +import jscl.math.operator.Derivative; +import jscl.math.operator.IndefiniteIntegral; +import jscl.math.operator.Integral; +import jscl.math.operator.Modulo; +import jscl.math.operator.Operator; +import jscl.math.operator.Product; +import jscl.math.operator.Sum; + /** * User: serso * Date: 11/17/11 @@ -17,91 +24,14 @@ public class OperatorsRegistry extends AbstractMathRegistry { private final static OperatorsRegistry instance = new OperatorsRegistry(); - static { - instance.add(new Derivative(null, null, null, null)); - //instance.add(new Grad(null, null)); - //instance.add(new Divergence(null, null)); - //instance.add(new Curl(null, null)); - //instance.add(new Jacobian(null, null)); - //instance.add(new Laplacian(null, null)); - //instance.add(new Dalembertian(null, null)); - //instance.add(new Del(null, null, null)); - //instance.add(new VectorProduct(null, null)); - //instance.add(new ComplexProduct(null, null)); - //instance.add(new QuaternionProduct(null, null)); - //instance.add(new GeometricProduct(null, null, null)); - //instance.add(new MatrixProduct(null, null)); - //instance.add(new TensorProduct(null, null)); - //instance.add(new Transpose(null)); - //instance.add(new Trace(null)); - //instance.add(new Determinant(null)); - //instance.add(new Coefficient(null, null)); - //instance.add(new Solve(null, null, null)); - //instance.add(new Substitute(null, null, null)); - //instance.add(new Limit(null, null, null, null)); - instance.add(new Sum(null, null, null, null)); - instance.add(new Product(null, null, null, null)); - //instance.add(new Groebner(null, null, null, null)); - //instance.add(new Division(null, null)); - instance.add(new Modulo(null, null)); - //instance.add(new ModPow(null, null, null)); - //instance.add(new ModInverse(null, null)); - //instance.add(new EulerPhi(null)); - instance.add(new Integral(null, null, null, null)); - instance.add(new IndefiniteIntegral(null, null)); - //instance.add(new Rand()); - //instance.add(new Mean(null)); - //instance.add(new Min(null)); - //instance.add(new Max(null)); - //instance.add(new MeanSquareDeviation(null)); - //instance.add(new StandardDeviation(null)); - //instance.add(new PrimitiveRoots(null)); - } - - /* if (operatorName.compareTo("d") == 0) - v = new Derivative(parameters[0], parameters[1], parameters.length > 2 ? parameters[2] : parameters[1], parameters.length > 3 ? parameters[3] : JsclInteger.valueOf(1)); - else if (operatorName.compareTo("grad") == 0) v = new Grad(parameters[0], parameters[1]); - else if (operatorName.compareTo("diverg") == 0) v = new Divergence(parameters[0], parameters[1]); - else if (operatorName.compareTo("curl") == 0) v = new Curl(parameters[0], parameters[1]); - else if (operatorName.compareTo("jacobian") == 0) v = new Jacobian(parameters[0], parameters[1]); - else if (operatorName.compareTo("laplacian") == 0) v = new Laplacian(parameters[0], parameters[1]); - else if (operatorName.compareTo("dalembertian") == 0) v = new Dalembertian(parameters[0], parameters[1]); - else if (operatorName.compareTo("del") == 0) - v = new Del(parameters[0], parameters[1], parameters.length > 2 ? parameters[2] : JsclInteger.valueOf(0)); - else if (operatorName.compareTo("vector") == 0) v = new VectorProduct(parameters[0], parameters[1]); - else if (operatorName.compareTo("complex") == 0) v = new ComplexProduct(parameters[0], parameters[1]); - else if (operatorName.compareTo("quaternion") == 0) v = new QuaternionProduct(parameters[0], parameters[1]); - else if (operatorName.compareTo("geometric") == 0) - v = new GeometricProduct(parameters[0], parameters[1], parameters.length > 2 ? parameters[2] : JsclInteger.valueOf(0)); - else if (operatorName.compareTo("matrix") == 0) v = new MatrixProduct(parameters[0], parameters[1]); - else if (operatorName.compareTo("tensor") == 0) v = new TensorProduct(parameters[0], parameters[1]); - else if (operatorName.compareTo("tran") == 0) v = new Transpose(parameters[0]); - else if (operatorName.compareTo("trace") == 0) v = new Trace(parameters[0]); - else if (operatorName.compareTo("det") == 0) v = new Determinant(parameters[0]); - else if (operatorName.compareTo("coef") == 0) v = new Coefficient(parameters[0], parameters[1]); - else if (operatorName.compareTo("solve") == 0) - v = new Solve(parameters[0], parameters[1], parameters.length > 2 ? parameters[2] : JsclInteger.valueOf(0)); - else if (operatorName.compareTo("subst") == 0) - v = new Substitute(parameters[0], parameters[1], parameters[2]).transmute(); - else if (operatorName.compareTo("lim") == 0) - v = new Limit(parameters[0], parameters[1], parameters[2], parameters.length > 3 && (parameters[2].compareTo(Constant.infinity) != 0 && parameters[2].compareTo(Constant.infinity.negate()) != 0) ? JsclInteger.valueOf(parameters[3].signum()) : JsclInteger.valueOf(0)); - else if (operatorName.compareTo("sum") == 0) - v = new Sum(parameters[0], parameters[1], parameters[2], parameters[3]); - else if (operatorName.compareTo("prod") == 0) - v = new Product(parameters[0], parameters[1], parameters[2], parameters[3]); - else if (operatorName.compareTo("integral") == 0) - v = parameters.length > 2 ? new Integral(parameters[0], parameters[1], parameters[2], parameters[3]) : new IndefiniteIntegral(parameters[0], parameters[1]); - else if (operatorName.compareTo("groebner") == 0) - v = new Groebner(parameters[0], parameters[1], parameters.length > 2 ? parameters[2] : Expression.valueOf("lex"), parameters.length > 3 ? parameters[3] : JsclInteger.valueOf(0)).transmute(); - else if (operatorName.compareTo("div") == 0) v = new Division(parameters[0], parameters[1]); - else if (operatorName.compareTo("mod") == 0) v = new Modulo(parameters[0], parameters[1]); - else if (operatorName.compareTo("modpow") == 0) v = new ModPow(parameters[0], parameters[1], parameters[2]); - else if (operatorName.compareTo("modinv") == 0) v = new ModInverse(parameters[0], parameters[1]); - else if (operatorName.compareTo("eulerphi") == 0) v = new EulerPhi(parameters[0]); - else if (operatorName.compareTo("primitiveroots") == 0) v = new PrimitiveRoots(parameters[0]);*/ - @Nonnull public static OperatorsRegistry getInstance() { + instance.init(); + return instance; + } + + @Nonnull + public static OperatorsRegistry lazyInstance() { return instance; } @@ -124,4 +54,14 @@ public class OperatorsRegistry extends AbstractMathRegistry { final Operator operator = super.get(name); return operator == null ? null : FunctionsRegistry.copy(operator); } + + @Override + public void onInit() { + add(new Derivative(null, null, null, null)); + add(new Sum(null, null, null, null)); + add(new Product(null, null, null, null)); + add(new Modulo(null, null)); + add(new Integral(null, null, null, null)); + add(new IndefiniteIntegral(null, null)); + } } diff --git a/jscl/src/main/java/org/solovyev/common/math/AbstractMathRegistry.java b/jscl/src/main/java/org/solovyev/common/math/AbstractMathRegistry.java index 15484de4..2a80c703 100644 --- a/jscl/src/main/java/org/solovyev/common/math/AbstractMathRegistry.java +++ b/jscl/src/main/java/org/solovyev/common/math/AbstractMathRegistry.java @@ -52,10 +52,27 @@ public abstract class AbstractMathRegistry implements Math @GuardedBy("this") @Nonnull protected final SortedList systemEntities = SortedList.newInstance(new ArrayList(30), MATH_ENTITY_COMPARATOR); + private volatile boolean initialized; protected AbstractMathRegistry() { } + @Override + public final void init() { + if (initialized) { + return; + } + synchronized (this) { + if (initialized) { + return; + } + onInit(); + initialized = true; + } + } + + protected abstract void onInit(); + @Nonnull private static synchronized Integer count() { final Integer result = counter; diff --git a/jscl/src/main/java/org/solovyev/common/math/MathRegistry.java b/jscl/src/main/java/org/solovyev/common/math/MathRegistry.java index 440c004b..ae50461f 100644 --- a/jscl/src/main/java/org/solovyev/common/math/MathRegistry.java +++ b/jscl/src/main/java/org/solovyev/common/math/MathRegistry.java @@ -22,9 +22,10 @@ package org.solovyev.common.math; +import java.util.List; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.List; public interface MathRegistry { @@ -48,4 +49,6 @@ public interface MathRegistry { @Nullable T getById(@Nonnull Integer id); + + void init(); }