User Defined Classes

MyFractionAlgebra.java (apidocs, source on folder JxnPortable/docs/programmer_examples) is an example of a user defined algebra and the integration of user classes.

Class files of user defined classes including classes implementing a user defined algebra must be found on the path defined in the classpath variable. The predefined classpath for JxnPortable includes among others the current folder (location of the jxn file) and the JxnPortable/user folder. The classpath variable is defined in JxnPortable/JxnStart.bat (see there for details). All public constructors, methods and fields of the class files found on the classpath can be called from JXN. Note for developers: Each time you recompile your java classes you must restart JXN to load the new version!!

User Defined Algebra

The integration of a user defined algebra is based on a predefined mapping of the arithmetic operators to method signatures. The following table shows this mapping. The preference of the operators is from high to low and the signatures are searched in the given order. The big number of matching signatures often allows to use third party classes without modifications (otherwise the class has to be adapted via an additional wrapper class, see e.g. BigIntegerAlgebra).

A complete user defined algebra however only needs to implement a small subset of the signatures. For MyFractionAlgebra it is sufficient to implement methods  a.add(b), a.mul(b), a.div(b) or a.inv(), a.pow(int) and constructors  MyFractionAlgebra(int,int), MyFractionAlgebra(int), MyFractionAlgebra(double) to cover all possible arithmetic operations including mixed operations with integer and double (see the unit tests on the next page).

The following table shows the mapping for variables a and b of class A and class B (a and b may also be instances of the same class). The methods must return the result of the operation. If operator methods modify the left-side operand (object a) the algebra class must implement the interface JxnCloneableAlgebra to avoid an unintended modification of the operand.

operatormaps to the method signatures:
@A(...)new A(...)     calls a constructor of class A
a[b]a.get(b)
a^b ≡ a**b a.pow(b)   A.pow(a,b)   a.pow( new A(b) )   new B(a).pow(b)     Note:  operator ^ for pow differs from java
−a a.neg()   a.negate()   a.mulL(−1)   new A(−1).mul(a)     Note:  −a^b  ≡  −(a^b)   but   −a * b  ≡  (−a) * b
a * b ≡ a b a.mul(b)   A.mul(a,b)   a.mul( new A(b) )   b.mulL(a)   new B(a).mul(b)   a.multiply(b)   A.multiply(a,b)   a.multiply( new A(b) )   new B(a).multiply(b)
a / b a.div(b)   A.div(a,b)   a.div( new A(b) )   new B(a).div(b)   a.divide(b)   A.divide(a,b)   a.divide( new A(b) )   new B(a).divide(b)
c = new A(b).inv()   c = new A(b).reciprocal()   c = b.inv()   c = b.reciprocal()   followed by
a.mul(c)   A.mul(a,c)   a.mul( new A(c) )   c.mulL(a)   new B(a).mul(c)   a.multiply(c)   A.multiply(a,c)   a.multiply( new A(c) )   new B(a).multiply(c)
a % b a.remainder(b)   A.remainder(a,b)   a.remainder( new A(b) )   new B(a).remainder(b)
a + b a.add(b)   A.add(a,b)   a.add( new A(b) )   new B(a).add(b)
a − b a.sub(b)   A.sub(a,b)   a.sub( new A(b) )   new B(a).sub(b)   a.subtract(b)   A.subtract(a,b)   a.subtract( new A(b) )   new B(a).subtract(b)
c = new A(b).neg()   c = new A(b).negate()   c = b.neg()   c = b.negate()   followed by  a.add(c)   A.add(a,c)   a.add( new A(c) )   new B(a).add(c)