Delay math registry initialization

This commit is contained in:
Sergey Solovyev
2017-05-25 16:50:25 +02:00
parent b6945f17e7
commit fd0dc88c64
13 changed files with 275 additions and 239 deletions

View File

@@ -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> numberFormatter = new ThreadLocal<NumberFormatter>() {
@Override
protected NumberFormatter initialValue() {
@@ -104,17 +101,17 @@ public class JsclMathEngine implements MathEngine {
@Nonnull
public MathRegistry<Function> getFunctionsRegistry() {
return FunctionsRegistry.getInstance();
return FunctionsRegistry.lazyInstance();
}
@Nonnull
public MathRegistry<Operator> getOperatorsRegistry() {
return OperatorsRegistry.getInstance();
return OperatorsRegistry.lazyInstance();
}
@Nonnull
public MathRegistry<Operator> getPostfixFunctionsRegistry() {
return PostfixFunctionsRegistry.getInstance();
return PostfixFunctionsRegistry.lazyInstance();
}
@Nonnull
@@ -137,7 +134,7 @@ public class JsclMathEngine implements MathEngine {
@Nonnull
public MathRegistry<IConstant> 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<IConstant> 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) {

View File

@@ -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<NumericWrapper> {
@Nonnull
@@ -48,7 +53,7 @@ public final class NumericWrapper extends Generic implements INumeric<NumericWra
}
public NumericWrapper(@Nonnull Constant constant) {
final IConstant constantFromRegistry = JsclMathEngine.getInstance().getConstantsRegistry().get(constant.getName());
final IConstant constantFromRegistry = ConstantsRegistry.getInstance().get(constant.getName());
if (constantFromRegistry != null) {
if (constantFromRegistry.getName().equals(Constants.I.getName())) {

View File

@@ -1,15 +1,19 @@
package jscl.math.function;
import jscl.JsclMathEngine;
import jscl.math.*;
import jscl.mathml.MathML;
import jscl.util.ArrayComparator;
import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
import jscl.math.Generic;
import jscl.math.JsclInteger;
import jscl.math.NotIntegrableException;
import jscl.math.NumericWrapper;
import jscl.math.Variable;
import jscl.mathml.MathML;
import jscl.util.ArrayComparator;
public class Constant extends Variable {
public static final int PRIME_CHARS = 3;
@@ -182,7 +186,7 @@ public class Constant extends Variable {
}
public String toJava() {
final IConstant constantFromRegistry = JsclMathEngine.getInstance().getConstantsRegistry().get(getName());
final IConstant constantFromRegistry = ConstantsRegistry.getInstance().get(getName());
if (constantFromRegistry != null) {
return constantFromRegistry.toJava();

View File

@@ -1,8 +1,10 @@
package jscl.math.function;
import org.solovyev.common.math.AbstractMathRegistry;
import org.solovyev.common.math.MathRegistry;
public class ConstantsRegistry extends AbstractMathRegistry<IConstant> {
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<IConstant> {
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<IConstant> getInstance() {
INSTANCE.init();
return INSTANCE;
}
public static MathRegistry<IConstant> lazyInstance() {
return INSTANCE;
}
}

View File

@@ -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<Function> {
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<Function> {
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));
}
}
}

View File

@@ -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<Operator> {
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<Operator> {
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));
}
}

View File

@@ -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<Operator> {
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<Operator> {
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));
}
}

View File

@@ -52,10 +52,27 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
@GuardedBy("this")
@Nonnull
protected final SortedList<T> systemEntities = SortedList.newInstance(new ArrayList<T>(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;

View File

@@ -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<T extends MathEntity> {
@@ -48,4 +49,6 @@ public interface MathRegistry<T extends MathEntity> {
@Nullable
T getById(@Nonnull Integer id);
void init();
}