To handle definitions in mathExpr
there is the class
DefinitionModel
.
This model holds all defined Variables
and Functions
and provides methods to define new variables or functions.
Usually a DefinitionModel
is used by any
ExpressionConfiguration
object, which
methods defineVariable(...)
and defineFunction(...)
delegates the appropriate methods of the DefinitionModel
.
Problem:
You want to work with more than one expression and all of these
expressions must be able to use the same definitions.
Solution:
Create only one DefinitionModel
and pass it to any
ExpressionConfiguration
. (Remember: One
ExpressionConfiguration
holds exactly
one Expression
).
Example:
DefinitionModel defModel=new DefinitionModel(); ExpressionConfiguration[] ec=new ExpressionConfiguration[5]; for(int i=0; i<ec.length; i++) ec[i]=new ExpressionConfiguration(ComplexType.TYPE, defModel); Complex a=new Complex(0, 0); Complex b=new Complex(2); ec[0].defineVariable("a", a, ComplexType.TYPE); ec[0].defineVariable("b", b, ComplexType.TYPE); ec[0].defineFunction("f", new String[] {"x"}, "x^2"); Complex[] result=new Complex[ec.length]; for(int i=0; i<ec.length; i++) { ec[i].setExpression("f(a*b)"+i); result[i]=(Complex)ec[i].evaluateExpression(); }
There is a big difference between defining a variable and a function. A function has to be defined already before it can be used within an expression. But a variable can be also defined after that. For example:
ExpressionConfiguration config=new ExpressionConfiguration(); //define a Variable before setting the expression using it config.defineVariable("a", new Real(1), RealType.TYPE); config.setExpression(2a); //define a Variable after setting the expression using it defModel.setExpression(2b); defModel.defineVariable("b", new Real(1), RealType.TYPE); //define a Function before setting the expression using it config.defineFunction("f", new String[] {"x"}, "x^2"); config.setExpression("f(5)"); //to define a Function after setting the expression using it is //not possible config.setExpression("g(5)"); config.defineFunction("g", new String[] {"x"}, "x^2"); //"g" would be handled as a variable ("g*5") and an evaluation //would fail because "g" isn't defined as a variable
That is because every identifier within an expression will be handled as a variable by the parser if it's not explicitly defined as a function.
More precisely: The Parser
uses an ExpressionFactory
to create all necessary sub-expressions for the hole expression.
This ExpresssionFactory
knows the
DefinitionModel
. There it looks for functions, if an identifier
comes from the expression-stack. If this identifier is defined as a function,
a FunctionCall
will be created. If it is not defined as a function, a
Symbol
will be created (even if there is no variable defined for the identifier).
UML-Diagramm