The most important classes in HartMath are the following from package com.hartmath.expression:
HDouble - floating-point numbers
HDoubleComplex - complex floating-point numbers
HInteger - integer numbers
HFraction - rational numbers
HComplex - complex numbers
HString - strings
HSymbol - mathematical symbols, i.e. constants, variables, function names
HPattern - a place-holder in pattern-matching rules
HFunction - a function which consists of a header (HSymbol) and a body of (HObject) arguments
The most important interfaces for these classes are the following:
HObject - implemented by HDouble, HDoubleComplex, HInteger, HFraction HComplex, HString, HSymbol, HPattern, HFunction
HNumber - implemented by HDouble, HDoubleComplex, HInteger, HFraction HComplex
HSignedNumber - implemented by HDouble, HInteger, HFraction
HRational - implemented by HInteger, HFraction
The HartMath input on the left is internally represented by the class on
the right:
Input | class for internal representation: |
0.5 | HDouble |
0.25+I*2.0 | HDoubleComplex |
1 | HInteger |
1/3 | HFraction |
2+3*I | HComplex |
"TestString" | HString |
symbol | HSymbol |
x_ | HPattern |
g(x,10) | HFunction with the header-symbol "g" and the 1st HSymbol argument "x" and the 2nd HInteger argument "10" |
The construction of the above class-objects is implemented in the class com.hartmath.lib.Scanner. The constructor of class Scanner gets a HartMath input string
public Scanner(String s)
and returns a parsed HartMath HObject with the method
public start() throws SyntaxError
All kernel function-header symbols and some often used constants are
defined as static Java variables in the class com.hartmath.lib.C.
For example the constant 1
is represented by the HInteger
C.C1
;
the constant -1/3
is represented by the HFraction C.CN1D3
;
the header symbol "Sin
" is represented by the
HSymbol C.Sin
So the function Sin(1)
can be constructed in Java by the
following syntax:
new HFunction(C.Sin, C.C1);
To define a function in a more "intuitive way" the class
HSymbol contains the
public f(HObject obj0, ... , HObject obj3)
methods which construct a HFunction for a given HSymbol:
C.Sin.f(C.C1);
Every implementation of a built-in function is a class which extends the interface com.hartmath.mapping.FunctionEvaluator; FunctionEvaluator defines the method
public abstract evaluate(HFunction fun)
The method evaluate() should compute the result of the given function
and return this result as a new HObject. If the function cannot be
evaluated the evaluate() method returns the Java null
value.
The following classes implement the FunctionEvaluator interface and some
additional evaluation methods for special types of arguments:
class-name |
description |
E1Arg |
a unary-function with 1 argument |
E2Arg |
a binary-function with 2 arguments |
EB1Arg |
a unary-predicate with 1 argument which returns C.True or C.False |
EB2Arg |
a binary-predicate with 2 arguments which returns C.True or C.False |
To extend the HartMath kernel with new functions you can use the
following example template [in this case the unary function MyUnaryFunction
with attribute Listable
]:
In file C.java
define: the functions header
symbol:
final static public HSymbol MyUnaryFunction = new HSymbol("MyUnaryFunction", C.loadClass, HSymbol.LISTABLE);
add the symbol to the symbol-hash-table in the init() method:
static public void init() {
// ...
MyUnaryFunction.putSymbol();
// ...
}
In the package com.hartmath.loadable add the evaluation class for the new header symbol:
public class EMyUnaryFunction extends E1Arg {
public HObject e1ObjArg(HObject o) {
// for example test the instance of the argument:
// if (o instanceof HInteger ) {
// HObject result;
// now the implementation of the MyUnaryFunction computes the result-value
// ...
// return result;
// }
// if the evaluation fails, return the null-value
return null;
}
}
in the init() method assign the new evaluation class to the header symbol:
C.MyUnaryFunction.setEval(new EMyUnaryFunction());