6.8 Adding User-Defined Functions

The functions provided by default for use with algebraic expressions, while powerful, may not provide all the operations you need. For this reason, it is possible to write your own extensions to the expression language. In this way you can specify abritrarily complicated functions. Note however that this will only allow you to define new columns or subsets where each cell is a function only of the other cells in the same row - it will not allow values in one row to be functions of values in another.

In order to do this, you have to write and compile a (probably short) program in the Java language. A full discussion of how to go about this is beyond the scope of this document, so if you are new to Java and/or programming you may need to find a friendly local programmer to assist (or mail the author). The following explanation is aimed at Java programmers, but may not be incomprehensible to non-specialists.

The steps you need to follow are:

  1. Write and compile a class containing one or more static public methods representing the function(s) required
  2. Make this class available on the application's classpath at runtime as described in Section 7.2.1
  3. Specify the class's name to the application, either as the value of the jel.classes or jel.classes.activation system properties (colon-separated if there are several) as described in Section 7.2.3 or during a run using the Available Function Window's Add Class () button

Any public static methods defined in the classes thus specified will be available for use in the Synthetic Column, Algebraic Subset or (in the case of activation functions only) Activation Window windows. They should be defined to take and return the relevant primitive or Object types for the function required (in the case of activation functions the return value should normally be a short log string). For instance a class written as follows would define a three-value average:

    public class AuxFuncs {
        public static double average3( double x, double y, double z ) {
            return ( x + y + z ) / 3.0;
        }
    }
and the expression "average3($1,$2,$3)" could then be used to define a new synthetic column, giving the average of the first three existing columns. Exactly how you would build this is dependent on your system, but it might involve doing something like the following:
  1. Writing a file named "AuxFuncs.java" containing the above code
  2. Compiling it using a command like "javac AuxFuncs.java"
  3. Starting up TOPCAT with the flags: "topcat -Djel.classes=AuxFuncs -classpath ."