Class MrpEval
- java.lang.Object
-
- com.singularsys.extensions.fastreal.AbstractEval
-
- com.singularsys.extensions.fastmatrix.MrpEval
-
- All Implemented Interfaces:
JepComponent
,ParserVisitor
,java.io.Serializable
public final class MrpEval extends AbstractEval
A fast evaluation algorithm for equations using Vectors and Matrix over the Doubles. This is based around reverse polish notation (hence the name M Rp Eval) and is optimised for speed at every opportunity.To use do
Jep jep = new Jep(); MRpEval rpe = new MRpEval(j); DimensionVisitor dimV = new DimensionVisitor(jep); Node node = jep.parse(...); dimV.visit(node); MRpCommandList list = rpe.compile(node); MRpRes rpRes = rpe.evaluate(list); System.out.println(rpRes.toString()); MatrixI mat = rpRes.toVecMat(); rpe.cleanUp();
The real use of this class is when an equation (or set of equations) need to be repeatedly evaluated with different values for the variables. MRpEval use an internal store for variable values different from those used in the main Jep classes. Changes in the Jep variable values, say by calling
Jep.setVarValue
, are reflected in changes in MRpEval variables, (the converse does not hold). A more efficient way is to useint ref=getVarRef(var)
to return an index number of the variable and then callingsetVarVal(ref,value)
to set its value. For exampleMRpCommandList list = rpe.compile(node); int ref = rpe.getVarRef(j.getVar("x")); for(double x=-1.;x<1.001;x+=0.1) { rpe.setVarVal(ref,x); rpe.evaluate(list); }
Combining mrpe with Differentiation requires special techniques to cope with that fact that internal equations are used
The compile methods converts the expression represented by node into a string of commands. For example the expression "1+2*3" will be converted into the sequence of commands
Constant no 1 (pushes constant onto stack) Constant no 2 Constant no 3 Multiply scalers (multiplies last two entries on stack) Add scalers (adds last two entries on stack)
The evaluate method executes these methods sequentially using a stack (actually a set of stacks) and returns the last object on the stack.A few cautionary notes: the values returned by evaluate are references to internal variables, their values will change at the next call to compile or evaluate. Its very unlikely to be thread safe. It only works over doubles; expressions with complex numbers or strings will cause problems. It is tuned to work best for expressions involving scalers and 2, 3 and 4 dimensional vectors and matricies, larger vectors and matrices will be noticeably slower. The cleanUp function should be used when you no longer need the evaluator, this stops the evaluator listening to Variable through the java.util.Observer interface.
Implementation notes A lot of things have been done to make it as fast as possible:
- Everything is final which maximises the possibility for in-lining.
- All object creation happens during compile.
- All calculations done using double values.
- Vectors and Matrices are instances of VnObj and MatObj optimised for speed.
- The values of variables are kept on local arrays for fast access.
Scalers, Vectors and matrices used during evaluation are kept in three store classes. Each Store class contains a stack, a heap and a array of variable values. During evaluation objects are pushed and popped from the stack when a new object is needed it is taken from the heap.
LimitationsThere is a limit to the number of function calls to non-inbuilt functions. A maximum of 65536 calls to external unary functions,
- See Also:
- Serialized Form
-
-
Field Summary
-
Fields inherited from class com.singularsys.extensions.fastreal.AbstractEval
customFunctionCommands, functionHash, jep, ls, opSet
-
-
Constructor Summary
Constructors Constructor Description MrpEval(Jep mjep)
Constructor using the MatrixFactory from the jep instanceMrpEval(Jep mjep, MatrixFactoryI mfac)
Constructor using a supplied MatrixFactoryMrpEval(Jep mjep, MatrixFactoryI mfac, int indexShift)
Constructor using a supplied function table
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description MrpCommandList
compile(Node node)
Compile the expressions to produce a set of commands in reverse Polish notation.MrpCommandList
compile(Variable var, Node node)
compile an expression of the type var = node.java.lang.Object
convertResult(MrpRes res)
Converts the results from the evaluate method into a more useful Double, VectorI or MatrixI type.MatrixI
convertToMatrix(MrpRes res)
Converts the results from the evaluate method into a MatrixI type.VectorI
convertToVector(MrpRes res)
Converts the results from the evaluate method into a VectorI type.MrpRes
evaluate(MrpCommandList comList)
Evaluate the expression.protected java.lang.Object
getConstantValue(short ref)
JepComponent
getLightWeightInstance()
Returns a new instance which can be safely used in a separate thread.MrpEval
getLightWeightInstance(Jep newjep)
Create a new instance using the supplied Jep context.Variable
getVariable(MrpVarRef ref)
Gets the Jep Variable associated with a particular referenceMrpVarRef
getVarRef(Variable uVar)
Finds the reference used for this variable.MrpVarRef
getVarRef(java.lang.String name)
Finds the reference used for this variable.MrpRes
getVarValue(MrpVarRef ref)
Return the value of a variable.void
init(Jep j)
CallsJepComponent.init(Jep)
for any custom function which implementsJepComponent
.void
reset()
Clear all internal data.void
setVarValue(MrpVarRef ref, double d)
Sets the value of a variablevoid
setVarValue(MrpVarRef varRef, double... vals)
Sets the value of a scaler or vector variable.void
setVarValue(MrpVarRef varRef, double[][] vals)
Sets the value of a matrix variablevoid
setVarValue(MrpVarRef varRef, MatrixI val)
Sets the value of a matrix variablevoid
setVarValue(MrpVarRef varRef, VectorI val)
Sets the value of a vector variablejava.lang.String
toString()
java.lang.String
toString(MrpCommandList.MrpCommand com)
void
updateFromJepVariables()
If the variables used by Jep has a valid value set the corresponding mrpe valuevoid
updateToJepVariables()
java.lang.Object
visit(ASTConstant node, java.lang.Object data)
java.lang.Object
visit(ASTFunNode node, java.lang.Object data)
java.lang.Object
visit(ASTOpNode node, java.lang.Object data)
java.lang.Object
visit(ASTVarNode node, java.lang.Object data)
java.lang.Object
visitAssign(ASTOpNode node)
java.lang.Object
visitSetEle(ASTOpNode node)
Givens a expression like ele(var,index) = value Produce sequence of commands-
Methods inherited from class com.singularsys.extensions.fastreal.AbstractEval
chargeFunctionName, duplicateCustomFunctions, getFunction, getUserFunction, staticGetFunction
-
-
-
-
Constructor Detail
-
MrpEval
public MrpEval(Jep mjep)
Constructor using the MatrixFactory from the jep instance- Parameters:
mjep
- jep instance
-
MrpEval
public MrpEval(Jep mjep, MatrixFactoryI mfac)
Constructor using a supplied MatrixFactory- Parameters:
mjep
- jep instancemfac
- matrix factory instance
-
MrpEval
public MrpEval(Jep mjep, MatrixFactoryI mfac, int indexShift)
Constructor using a supplied function table- Parameters:
mjep
- jep instancemfac
- matrix factory instanceindexShift
- base for array access, either 0 for zero based indexing, or 1 for 1 based indexing
-
-
Method Detail
-
compile
public final MrpCommandList compile(Variable var, Node node) throws ParseException
compile an expression of the type var = node.- Throws:
ParseException
-
compile
public final MrpCommandList compile(Node node) throws ParseException
Compile the expressions to produce a set of commands in reverse Polish notation.- Throws:
ParseException
-
visit
public final java.lang.Object visit(ASTConstant node, java.lang.Object data) throws ParseException
- Throws:
ParseException
-
visit
public final java.lang.Object visit(ASTVarNode node, java.lang.Object data) throws ParseException
- Throws:
ParseException
-
visitAssign
public java.lang.Object visitAssign(ASTOpNode node) throws JepException, ParseException
- Throws:
JepException
ParseException
-
visitSetEle
public java.lang.Object visitSetEle(ASTOpNode node) throws JepException, ParseException
Givens a expression like ele(var,index) = value Produce sequence of commands... value = pop() index = pop() addCommand(VAR,dimType,vRef); // pops the var value addCommand(SETELE,dimType,index) // sets top of stacks the index's element addCommand(ASSIGN,dt,vRef);
- Parameters:
node
-- Returns:
- Throws:
JepException
ParseException
-
visit
public final java.lang.Object visit(ASTOpNode node, java.lang.Object data) throws JepException
- Throws:
JepException
-
visit
public final java.lang.Object visit(ASTFunNode node, java.lang.Object data) throws JepException
- Throws:
JepException
-
evaluate
public final MrpRes evaluate(MrpCommandList comList) throws EvaluationException
Evaluate the expression.- Parameters:
comList
- list of commands to evaluate- Returns:
- the value after evaluation
- Throws:
EvaluationException
- if an exception occurs in a user function
-
getConstantValue
protected java.lang.Object getConstantValue(short ref)
- Specified by:
getConstantValue
in classAbstractEval
-
getVarRef
public MrpVarRef getVarRef(Variable uVar) throws ParseException
Finds the reference used for this variable. The variable should have a known dimensions. This can be set either by using theDimensionVisitor
by setting it to a explicit value or by setting the dimensions explicitly usingvar.setHook(DimensionVisitor.DIM_KEY,Dimensions.SCALER)
.- Parameters:
uVar
- the variable- Returns:
- an index used to refer to the variable
- Throws:
ParseException
- if the dimensions for the variable cannot be found.
-
getVarRef
public MrpVarRef getVarRef(java.lang.String name) throws ParseException
Finds the reference used for this variable. This method requires an associate Jep reference so cannot be used with instances created usinggetLightWeightInstance()
- Parameters:
name
- variable name- Returns:
- the reference
- Throws:
ParseException
- if the dimensions for the variable cannot be found, or there is no jep instance
-
setVarValue
public void setVarValue(MrpVarRef ref, double d) throws EvaluationException
Sets the value of a variable- Parameters:
ref
- reference to the variabled
- value- Throws:
EvaluationException
- if the reference is not a scaler variable
-
setVarValue
public void setVarValue(MrpVarRef varRef, double... vals) throws EvaluationException
Sets the value of a scaler or vector variable. Scaler variables can be set to arrays of length 1.- Parameters:
varRef
- reference to the variablevals
- either an array of doubles, or a set of values- Throws:
EvaluationException
-
setVarValue
public void setVarValue(MrpVarRef varRef, double[][] vals) throws EvaluationException
Sets the value of a matrix variable- Parameters:
varRef
- reference to the variablevals
- two dimensional array of values- Throws:
EvaluationException
- if the variable is not a matrix variable or has the wrong dimensions- Since:
- Jep 4.0/Extensions 2.1
-
setVarValue
public void setVarValue(MrpVarRef varRef, VectorI val) throws EvaluationException
Sets the value of a vector variable- Parameters:
varRef
- reference to the variableval
- vector value- Throws:
EvaluationException
- if the dimensions do not match
-
setVarValue
public void setVarValue(MrpVarRef varRef, MatrixI val) throws EvaluationException
Sets the value of a matrix variable- Parameters:
varRef
- reference to the variableval
- a matrix vlaue- Throws:
EvaluationException
- if the dimensions do not match
-
getVarValue
public MrpRes getVarValue(MrpVarRef ref)
Return the value of a variable. It returns a subtype ofMrpRes
which can be converted usingconvertResult(MrpRes)
.- Parameters:
ref
- a reference to the variable- Returns:
- the value of that variable or null if the reference is no longer current (happens when the dimensions of the variable changes)
-
getVariable
public Variable getVariable(MrpVarRef ref) throws ParseException
Gets the Jep Variable associated with a particular reference- Parameters:
ref
- reference to variable- Returns:
- the Jep Variable
- Throws:
ParseException
-
updateFromJepVariables
public void updateFromJepVariables() throws EvaluationException
If the variables used by Jep has a valid value set the corresponding mrpe value- Throws:
EvaluationException
- if the jep variable has different dimensions to the mrpe variable
-
updateToJepVariables
public void updateToJepVariables() throws EvaluationException
- Throws:
EvaluationException
-
convertResult
public java.lang.Object convertResult(MrpRes res) throws EvaluationException
Converts the results from the evaluate method into a more useful Double, VectorI or MatrixI type. Conversion to vectors or matrices will not work if aMatrixFactoryI
is not defined, i.e. if this instance is created usinggetLightWeightInstance()
.- Parameters:
res
- the value returned byevaluate(MrpCommandList)
- Returns:
- a Double, VectorI or MatrixI type.
- Throws:
EvaluationException
- if noMatrixFactoryI
is defined
-
convertToMatrix
public MatrixI convertToMatrix(MrpRes res) throws EvaluationException
Converts the results from the evaluate method into a MatrixI type. Will fail if aMatrixFactoryI
is not defined, i.e. if this instance is created usinggetLightWeightInstance()
.- Parameters:
res
- the value returned byevaluate(MrpCommandList)
- Returns:
- a MatrixI type, uses the MatrixFactory suppled to MatrixFunctionTable
- Throws:
EvaluationException
- if the res is a scalar or vector or noMatrixFactoryI
is defined
-
convertToVector
public VectorI convertToVector(MrpRes res) throws EvaluationException
Converts the results from the evaluate method into a VectorI type. Will fail if aMatrixFactoryI
is not defined,- Parameters:
res
- the value returned byevaluate(MrpCommandList)
- Returns:
- a VectorI type,
- Throws:
EvaluationException
- if the res is a scalar or matrix or noMatrixFactoryI
is defined
-
reset
public void reset()
Clear all internal data. This removes all variables, so variable references previously found fromgetVarRef(String)
,getVarRef(Variable)
will no longer be valid.
-
toString
public java.lang.String toString()
- Overrides:
toString
in classjava.lang.Object
-
toString
public java.lang.String toString(MrpCommandList.MrpCommand com)
-
getLightWeightInstance
public JepComponent getLightWeightInstance()
Returns a new instance which can be safely used in a separate thread. SeeAbstractEval.duplicateCustomFunctions(AbstractEval, Jep)
for handling of custom functions.- Returns:
- a new instance
- Since:
- Jep 4.0/Extensions 2.1
-
getLightWeightInstance
public MrpEval getLightWeightInstance(Jep newjep)
Create a new instance using the supplied Jep context. Will duplicate all variables and other data so the evaluator can be safely used in a new thread. SeeAbstractEval.duplicateCustomFunctions(AbstractEval, Jep)
for handling of custom functions.- Parameters:
newjep
- new jep instance for context- Returns:
- a new instance
- Since:
- Jep 4.0/Extensions 2.1
-
init
public void init(Jep j)
Description copied from class:AbstractEval
CallsJepComponent.init(Jep)
for any custom function which implementsJepComponent
.- Specified by:
init
in interfaceJepComponent
- Overrides:
init
in classAbstractEval
- Parameters:
j
- the current Jep instance
-
-