-
- Notifications
You must be signed in to change notification settings - Fork 102
Functions preprocessor
- Extend keywords in AST2Expr
- Generate files
- Implementing new functions
- Integrating your own Java library with the WXF format
- Example evaluating partial derivative function
- Integrating your own Java library with the WXF format
To add new predefined constants or function symbols you have to extend the following String arrays in org.matheclipse.core.convert.AST2Expr
-
UPPERCASE_SYMBOL_STRINGS- symbols which are exactly one uppercase constant or function -
DOLLAR_STRINGS- symbols starting with a '$' character -
SYMBOL_STRINGS- constant identifiers, which are not used as a function identifier -
FUNCTION_STRINGS- function identifiers
We can for example add a new user function MyFunction to the FUNCTION_STRINGS array.
If the AST2Expr definitions have changed these two programs can generate new sources in the Eclipse console output:
- the FunctionIDGenerator.java program is used to generate the file org.matheclipse.core.expression.ID
- the BuiltinGenerator.java program is used to generate the predefined
IBuiltInSymbol's in file org.matheclipse.core.expression.F
The built-in Symja constants are implemented in the file:
The built-in Symja functions are implemented in the packages:
System built-in functions must implement the interface IFunctionEvaluator and are evaluated according to the assigned function symbol attributes defined in the IFunctionEvaluator#setUp() method (only very special built-in functions must implement the interface ICoreFunctionEvaluator and evaluate their arguments in a non standard way).
A lot of the system functions have associated pattern matching rule files in the folders:
These rules are converted by the class org.matheclipse.core.preprocessor.RulePreprocessor into the package org.matheclipse.core.reflection.system.rules
A new built-in Symja function name should be added to org.matheclipse.core.convert.AST2Expr#FUNCTION_STRINGS String[] array, with a leading upper case character in its name.
A typical "template" for an example built-in function MyFunction is implemented like this. The evaluation of MyFunction({a,b,c}) should return the first argument {a,b,c} if the first argument is a list.
package org.matheclipse.core.builtin; import org.matheclipse.core.eval.EvalEngine; import org.matheclipse.core.eval.exception.Validate; import org.matheclipse.core.eval.interfaces.AbstractEvaluator; import org.matheclipse.core.expression.F; import org.matheclipse.core.interfaces.IAST; import org.matheclipse.core.interfaces.IExpr; public class UserFunctions { static { F.MyFunction.setEvaluator(new MyFunction()); } private static class MyFunction extends AbstractEvaluator { @Override public IExpr evaluate(final IAST ast, EvalEngine engine) { // test if only 1 argument is allowed: Validate.checkRange(ast, 2); if (ast.arg1().isList()) { return ast.arg1(); } return F.NIL; } } private final static UserFunctions CONST = new UserFunctions(); public static UserFunctions initialize() { return CONST; } private UserFunctions() { } }It must be initialized in the F.class static block:
... static { Thread INIT_THREAD = null; ... VectorAnalysisFunctions.initialize(); QuantityFunctions.initialize(); FinancialFunctions.initialize(); WXFFunctions.initialize(); WindowFunctions.initialize(); UserFunctions.initialize(); ... } ...Now the evaluation of MyFunction({a,b,c}) returns the first argument {a,b,c}. And the evaluation of MyFunction(test) returns unevaluated as MyFunction(test).
In the following section the evaluation and implementation of the partial derivative function is described.
Example usage:
>> D(sin(x)^3 + x, x) 1+3*Sin(x)^2*Cos(x)To see the intermediate evaluation steps you can use the Trace( ) function
>> Trace(D(sin(x)^3 + x, x)) Internally the D(<expression>, x) function uses the Derivative( ) function. Both function names are defined in
Both of these built-in functions are defined in the org.matheclipse.core.reflection.system package:
The Derivative( ) rules are converted by the class org.matheclipse.core.preprocessor.RulePreprocessor into the rules java file org.matheclipse.core.reflection.system.rules.DerivativeRules.
To use these functions (or other built-in constants and functions) from within other java sources you can import org.matheclipse.core.expression.F
For D and Derivative there are two static methods defined:
public static IAST D(final IExpr a0, final IExpr a1) public static IAST Derivative(final IExpr... a)For creating a quick prototype which can use Symja functions to call your own library, you should consider implementing functions similar to the BinarySerialize, BinaryDeserialize functions with the WXF format:
The implementation which is used in Symja can be found here:
- https://github.com/axkr/symja_android_library/blob/master/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/WL.java
- https://github.com/axkr/symja_android_library/blob/master/symja_android_library/matheclipse-io/src/test/java/org/matheclipse/io/system/WXFTestCase.java