Example Customizing Equations

From Efficient Java Matrix Library
Jump to: navigation, search

While Equations provides many of the most common functions used in Linear Algebra, there are many it does not provide. The following example demonstrates how to add your own functions to Equations allowing you to extend its capabilities.

External Resources:

Example

/**
 * Demonstration on how to create and use a custom function in Equation.  A custom function must implement
 * ManagerFunctions.Input1 or ManagerFunctions.InputN, depending on the number of inputs it takes.
 *
 * @author Peter Abeles
 */
public class EquationCustomFunction {

    public static void main(String[] args) {
        Random rand = new Random(234);

        Equation eq = new Equation();
        eq.getFunctions().add("multTransA",createMultTransA());

        SimpleMatrix A = new SimpleMatrix(1,1); // will be resized
        SimpleMatrix B = SimpleMatrix.random64(3,4,-1,1,rand);
        SimpleMatrix C = SimpleMatrix.random64(3,4,-1,1,rand);

        eq.alias(A,"A",B,"B",C,"C");

        eq.process("A=multTransA(B,C)");

        System.out.println("Found");
        System.out.println(A);
        System.out.println("Expected");
        B.transpose().mult(C).print();
    }

    /**
     * Create the function.  Be sure to handle all possible input types and combinations correctly and provide
     * meaningful error messages.  The output matrix should be resized to fit the inputs.
     */
    public static ManagerFunctions.InputN createMultTransA() {
        return new ManagerFunctions.InputN() {
            @Override
            public Operation.Info create(List<Variable> inputs, ManagerTempVariables manager ) {
                if( inputs.size() != 2 )
                    throw new RuntimeException("Two inputs required");

                final Variable varA = inputs.get(0);
                final Variable varB = inputs.get(1);

                Operation.Info ret = new Operation.Info();

                if( varA instanceof VariableMatrix && varB instanceof VariableMatrix ) {

                    // The output matrix or scalar variable must be created with the provided manager
                    final VariableMatrix output = manager.createMatrix();
                    ret.output = output;
                    ret.op = new Operation("multTransA-mm") {
                        @Override
                        public void process() {
                            DMatrixRMaj mA = ((VariableMatrix)varA).matrix;
                            DMatrixRMaj mB = ((VariableMatrix)varB).matrix;
                            output.matrix.reshape(mA.numCols,mB.numCols);

                            CommonOps_DDRM.multTransA(mA,mB,output.matrix);
                        }
                    };
                } else {
                    throw new IllegalArgumentException("Expected both inputs to be a matrix");
                }

                return ret;
            }
        };
    }
}