5
Adding Formulas to JClass LiveTable
Introduction com.klg.jclass.util.formulae's Hierarchy Expressions and Results Math Values
Operations Exceptions Using Formulae in JClass LiveTable
5.1 Introduction
The formulae package in
com.klg.
jclass.util
has special capabilities for evaluating mathematical objects. Similar to the way that objects such asjava.lang.Double
wrap a primitive type, those incom.klg.
jclass.util.formulae
encapsulate mathematical expressions (operators) whose operands may be scalars, vectors (in the mathematical sense), and matrices. These objects may then be stored as the generalized values of cells in a JClass LiveTable, or in a JClass PageLayout table, where they may be evaluated at run time to produce results based on the then-current data.In addition, subclasses of
MathValue
, which are wrappers for generalized scalars, vectors, and matrices, provide several methods for converting an expression to a value and to aString
, as well as other methods useful when dealing with these objects.
5.2 com.klg.jclass.util.formulae's Hierarchy
The interfaces, abstract classes, and derived classes, including possible exception classes, are shown in Figure 13.
Figure 13 : The inheritance hierarchy for com.klg.jclass.util.formulae.
The diverse set of mathematical operations permit you to compose complex mathematical formulas and provide references to them. Dynamic updating of the value represented by the expression is made possible through callbacks to the mathematical expression object.
5.3 Expressions and Results
The top-level interface for the
com.klg.
jclass.util.formulae
package isExpression
, whose sole method isevaluate()
. Any object that functions as an expression must have anevaluate()
method that knows how to operate on data that might be a scalar, a vector, or a matrix. Applying theevaluate()
method to anExpression
produces aResult
, which is a marker interface that identifiesExpression
types that are valid return types from the evaluation of otherExpression
s.An
Expression f = new Add(op1, op2);Expression
may be anOperation
, as in:which, after evaluation, returns a
Result
.
5.4 Math Values
The abstract class
MathValue
forms the root for all derived constant-based result/data classes. It satisfies theExpression
interface by defining anevaluate()
method, which simply returns theMathValue
as aResult
. Its concrete subclasses areMathMatrix
,MathScalar
, andMathVector
. BecauseMathValue
has anevaluate()
method it is anExpression
. Thus,MathValue
s may be passed asExpression
objects.MathValue Methods
Note: The subclasses of
MathValue
override all but the first method. Since, for example,matrixValue()
is not appropriate to aMathScalar
, it throws anUnsupportedOperationException
if it is called. Other method-data type mismatches also throwUnsupportedOperationException
s. The method tables for the subclasses indicate which methods are data type mismatches for the given class.
5.4.1 MathScalar
double s1 = 10.0; MathValue ss1 = new MathScalar(s1);
MathScalar
is a scalar constant represented as aMathValue
. By encapsulating it in this fashion it can support integer and real numbers, and it can be extended if necessary to support other types of scalar numbers. Its data field is arealValue
, aNumber
that is output based on the currentdataFormat
kept inMathValue.
MathScalar Constructors
The no-argument constructor
MathScalar()
creates an instance that encapsulates the value 0.0, while the other three constructors take adouble
, anint
, or ajava.lang.Number
argument.MathScalar Methods
5.4.2 MathVector
double[] ed = {2.71828, 3.1415927, 1.6020505};
MathVector
is a representation of the class of vectors in a linear algebra sense. They may also be used as operands in matrix multiplication. AMathVector
encapsulates a list of values which may be integers, doubles, or more generally, objects of typeNumber
. It has methods for retrieval or modification of a value at a particular index, and for outputting the list as a String. The operators discussed in the next section accept these objects as operands.
MathValue mv = new MathVector(ed);MathVector Constructors
The constructors for
MathVector
parallel those forMathScalar
, except they take arrays as parameters rather than single values.MathVector Methods
5.4.3 MathMatrix
double[][] m1 = {{1.1, 1.2, 1.3},
MathMatrix
is a representation of the class of matrices, again in the sense of linear algebra. The package implements the basic addition and multiplication operations in matrix algebra, including multiplying a matrix by a vector. It has methods for retrieval or modification of a value at a particular pair of indices, and for outputting the matrix as a String. The operators discussed in the next section accept these objects as operands.
{2.1, 2.2, 2.3},
{3.1, 3.2, 3.3}};
MathValue mm = new MathMatrix(m1);MathMatrix Constructors
The constructors for
MathMatrix
parallel those forMathScalar
, except they take 2D arrays as parameters rather than single values.MathMatrix Methods
5.5 Operations
The abstract
double[] ed = {2.71828, 3.1415927, 1.6020505};Operation
class defines the basic elements of an operator. Binary operators have a left and right operand, which enables the correct ordering to be applied to matrix operations and any other non-commutative operators. Unary operators have a single operand.
double[] rd = {(Math.sqrt(5.0) + 1.0) / 2.0, 4.0, 32.0};
MathValue e = new MathVector(ed);
MathValue r = new MathVector(rd);
Expression add = new Add(e, r);Operation Constructors
There is a no-argument constructor that creates a generic operator, and there are constructors for every unary and binary permutation of
Expression
s andNumber
s. A sample constructor is:Operation(Expression left, Expression right)
.Operation Methods
The two non-inherited methods in
Operation
areevaluate()
, which returns aResult
containing the evaluation of the expression, andclone()
, which returns a deep-copy clone of the operation and of all operands.
5.5.1 The Defined Mathematical Operations
Unary Operators
Unary operators take one parameter, which is either an
Expression
or aNumber
. Because they areExpression
s they all have anevaluate()
method which returns aResult.
Binary Operators
Binary operators take two parameters, which are
Expression
s,Number
s, or one of each. Because they areExpression
s they all have anevaluate()
method which returns aResult.
5.5.2 Reducing Operations to Values
Since
double edd = 2.0;Operation
s areExpression
s, they all have anevaluate()
method. Evaluation returns aResult
, which may be converted to aString
for printing. Here is an example:
double exp = 8.0;
MathValue eddy = new MathScalar(edd);
MathScalar expy = new MathScalar(exp);
double[] ed = {2.71828, 3.1415927, 1.6020505};
MathValue e = new MathVector(ed);
Expression pow = new Power(eddy, expy);
Expression powr = pow.evaluate();
// Either one of these has a toString() method
System.out.println("Power without evaluate(): " + pow);
System.out.println("Power with evaluate(): " + powr);After which the following is written on the output:
Power without evaluate(): com.klg.jclass.util.formulae.Power@eb4f3b8c
Power with evaluate(): 256.0You see that calling
evaluate()
is necessary to have a value returned by the implicittoString()
call.
5.6 Expression Lists
Expression lists are handy containers that permit you to perform an operation on a group of values.
MathExpressionList
The example shown here uses the binary form of
// Expression ListsAdd
to find the grand total of all the elements in twoExpressionList
s.
Expression[] exprs1 = {null, null, null, null, null, null, null, null, null, null};
for (int i = 0; i < 10; i++){
exprs1[i] = new MathScalar(95 + i);
}
ExpressionList explist1 = new MathExpressionList(exprs1);
Expression[] exprs2 = {null, null, null, null, null, null, null null, null, null};
for (int i = 0; i < 10; i++){
exprs2[i] = new MathScalar(95 + i);
}
ExpressionList explist2 = new MathExpressionList(exprs2);
sss1 = new Sum(explist1, explist2);
ssss1 = sss1.evaluate();
System.out.println(
"Summing ExpressionLists with evaluate(): " + ssss1);
Summing ExpressionLists with evaluate(): 1990QueryExpressionList
A
QueryExpressionList
is designed as a wrapper for a set ofExpression
s stored in a JDBC-typeResultSet
; that is, the result of a database query. Users of JClass DataSource may also use this facility.TableExpressionList
Expression lists may be used to extend data from portions of a JClass LiveTable to produce summary reports. For details, see Section 5.9, Using Formulae in JClass LiveTable.
5.7 Events and Listeners
TableListenerPropagator
The
TableListenerPropagator
listener, which implements theJCTableDataListener
interface, wraps a formula and listens for changes to table cells that are operands for this formula, and propagates the changes so that other interested listeners can re-evaluate themselves. TheTableListenerPropagator
listener automatically updates the whole dependency hierarchy ofcom.klg.
jclass.util.formulae
when a suboperation has been modified.
5.8 Exceptions
OperandMismatchException
Various operations such as adding a number to a vector are not defined, whereas other operations, for example, multiplying a vector by a number, can be interpreted as a scaling operation. At compile time, numbers, vectors, and matrices can be declared as generic
Expression
s, making it impossible to predetermine which operations are not permitted. A run time check of the validity of an operation must be made. If a mathematical construct is evaluated and found to be illegal, the class throws anOperandMismatchException
.ClassCastException
There are cases where a run time class cast exception may occur. While most of these should be avoidable by selecting the correct class (such as using
Product
rather thanMultiply
when multiplying two vectors) the fact that both takeExpression
s as their parameters makes it difficult to avoid the possibility of an end-user passing in an incorrect type if your application permits flexible user input. You may permit substitution of one arithmetic class for another, since they are allOperation
s. This also opens the door to class cast exceptions.If the possibility exists for either of these exceptions, your code should attempt to handle it.
5.9 Using Formulae in JClass LiveTable
5.9.1 Registering a Cell Editor and a Cell Renderer with the JClass Central Registry
If you are planning to allow your end-users to specify mathematical operations, you may make use of the editor/renderer registry in
com.klg.
jclass.cell
. Note that if a cell is placed in a JClass LiveTable, theExpressionCellRenderer
will be used by default.The following code snippet, taken from the SpreadSheet demo, registers a cell editor that takes a value in the form of a
EditorRendererRegistry.getCentralRegistry().addClass(util.formulae.Expression
from a table cell and copies its String equivalent in a text box. In the SpreadSheet demo, formulas are entered by beginning them with an equal sign (=), for example, =SUM(A1:A5). The class calledMyFormulaCellEditor
recognizes this syntax and translates a String of this form to anExpression
, then stores it in a table cell.
"java.lang.String",
null,
"demos.table.spreadsheet.MyFormulaCellEditor",
"com.klg.jclass.cell.renderers.JCStringCellRenderer");See the SpreadSheet demo for a complete code listing.
5.9.2 Performing a Mathematical Operation on a Range of Cells
Expression Lists and Expression References
Expression list objects hold a group of
Expression
s.ExpressionList
is an abstract class whose methods permit the inclusion of additional elements to those already present, a method for removing elements or clearing all elements, for retrieving an element, and for comparing with another list. These operations are common to the concrete classesMathExpressionList
,QueryExpressionList
, andTableExpressionList
.Expression lists may be used as arguments for all mathematical operations. When given an expression list, evaluating a unary operator such as
ABS
returns a list containing the absolute values of its input list. Binary operators may return a single result or a list. Given expression lists, the mathematical operatorsAbs
,Add
,Ceiling
,Divide
,Floor
,Multiply
,Power
,Remainder
,Root
,Round
,Sort
, andSubtract
return lists, whileAverage
,Count
,GeometricMean
,Max
,Median
,Min
,Product
, andSum
all return a single result afterevaluate()
has been called.Use
Expression expression = new TableExpressionList(TableExpressionList
to perform an operation over a range of cells in a table. The following code snippet shows that the required parameters are a table data model and a block of cells.
table.getDataSource(),
new MathScalar(startRow), // first row
new MathScalar(endRow), // last row
new MathScalar(startColumn), // first column
new MathScalar(endColumn) // last column
);
Sum sum = new Sum(expression);The next code fragment places the formula for the sum in the last column, just below the last row. With the proper cell renderer/editor combination, such as the one listed in the previous section, the formula or the numerical value of the sum is shown, depending on whether the cell is selected or not.
((EditableTableDataModel)table.getDataSource()).setTableDataItem(sum, endRow + 1, endColumn);The advantage of using
TableExpressionList
s is that the formulas containing them know to update themselves when a cell's value is altered.