HartMath Programming Guide (Build 276)

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

Examples:

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"

Parser

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

Predefined header symbols and constants

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);

Extending the built-in functions

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());