Matrix Classes
This chapter presents several classes that can be used to create and manipulate matrixes. These matrix classes will be used throughout this book. These classes are summarized in Table 2.1.
Table 2.1: Matrix Classes
| Class | Purpose |
| BiPolarUtil | A utility class to convert between Boolean and bipolar numbers. |
| Matrix | Holds a matrix. |
| MatrixMath | Performs mathematical operations on a matrix. |
The next three sections will examine each of these classes.
The BiPolarUtil Class
The BiPolarUtil class is used to switch between a bipolar number and a boolean value. A boolean value is either true or false. A bipolar number is either 1 or -1. Using this class, the boolean value of false is expressed as a -1 bipolar value and the boolean value of true is expressed as a 1 bipolar value. The BiPolarUtil class is a collection of static methods. The signatures for these methods are shown here.
public static double bipolar2double(final boolean b) public static double[] bipolar2double(final boolean b[]) public static double[][] bipolar2double(final boolean b[][]) public static boolean double2bipolar(final double d) public static boolean[] double2bipolar(final double d[]) public static boolean[][] double2bipolar(final double d[][])
Table 2.2 summarizes the functions provided by the BiPolarUtil class.
Table 2.2: The BiPolarUtil Class
| Method | Purpose |
| bipolar2double | Converts a Boolean bipolar to a double. For example, true is converted to 1. |
| double2bipolar | Converts a double value to a bipolar Boolean. For example, -1 is converted to false. |
The above two methods are overloaded, so you can convert a single value, a single dimensional array, or a two dimensional array. Bipolar values are particularly useful for Hopfield neural networks. Hopfield neural networks will be discussed in the next chapter.
The Matrix Class
The Matrix class is used to construct two dimensional matrixes. The values contained in the matrixes are stored as Java double variables. The Matrix class provides the fundamental operations of numerical linear algebra. For operations involving two or more matrixes, the MatrixMath class is used. The MatrixMath class is discussed in the next section.
The signatures for the Matrix class members are shown here.
public static Matrix createColumnMatrix(final double input[]) public static Matrix createRowMatrix(final double input[]) public void add(final int row, final int col, final double value) public void clear() public Matrix clone() public boolean equals(final Matrix matrix) public boolean equals(final Matrix matrix, int precision) public double get(final int row, final int col) public Matrix getCol(final int col) public int getCols() public Matrix getRow(final int row) public int getRows() public boolean isVector() public boolean isZero() public void set(final int row, final int col, final double value) public double sum() public double[] toPackedArray()
The methods provided by the Matrix class are summarized in Table 2.3.
Table 2.3: The Matrix Class
| Method | Purpose |
| createColumnMatrix | Static method which creates a matrix with a single column. |
| createRowMatrix | Static method which creates a matrix with a single row. |
| add | Adds the specified value to every cell in the matrix. |
| clear | Sets every cell in a matrix to zero. |
| clone | Creates an exact copy of a matrix. |
| equals | Determines if two matrixes are equal to each other. |
| get | Gets the value for a cell. |
| getCol | Gets one column of a matrix object as a new matrix object. |
| getCols | Determines the number of columns in a matrix object. |
| getRow | Gets one row of a matrix object as a new matrix object. |
| getRows | Determines the number of rows in a matrix object. |
| isVector | Determines if a matrix is a vector. A vector matrix has either a single row or a single column. |
| isZero | Determines if every cell in a matrix object is zero. |
| set | Sets the value of a cell. |
| sum | Returns the sum of every cell in a matrix object. |
| toPackedArray | Converts a two dimensional matrix array into a one dimensional array of Java double variables. |
The Matrix class will be used to construct the weight matrixes for all neural networks presented in this book.
The MatrixMath Class
Most mathematical operations on a Matrix class are accomplished using the MatrixMath class. All methods in the MatrixMath class are static. Further, they always return a new matrix and do not modify the matrixes passed to them. The signatures for the MatrixMath methods are shown here.
public static Matrix add(final Matrix a, final Matrix b) public static Matrix divide(final Matrix a, final double b) public static double dotProduct(final Matrix a, final Matrix b) public static Matrix identity(final int size) public static Matrix multiply(final Matrix a, final double b) public static Matrix multiply(final Matrix a, final Matrix b) public static Matrix subtract(final Matrix a, final Matrix b) public static Matrix transpose(final Matrix input) public static double vectorLength(final Matrix input)
These methods are summarized in Table 2.4.
Table 2.4: The MatrixMath Class
| Method | Purpose |
| add | Adds two matrixes and produces a third matrix. |
| divide | Divides one matrix by a scalar and produces a second matrix. |
| dotProduct | Calculates the dot product of a matrix. |
| identity | Creates an identity matrix of a specified size. |
| multiply | Multiplies one matrix by another and produces a third matrix. |
| subtract | Subtracts one matrix from another and produces a third matrix. |
| transpose | Transposes a matrix and produces a new matrix. |
| vectorLength | Calculates the squared length of a vector. |
These are the primary mathematical operations that neural networks need to perform. Each of these operations will be discussed at length later in this chapter.
Many Java neural network implementations build matrix operations directly into their neural network classes. The result being many nested for loops inside the neural network class. For example, the following code allows a neural network to learn.
public void learn(double learnRate, double momentum) {
if (layer.hasMatrix() ) {
for (int i1 = 0; i1 < layer.getNeuronCount(); i1++) {
for (int i2 = 0; i2 < layer.getNext().getNeuronCount(); i2++) {
matrixDelta[i1][i2] = (learnRate * accMatrixDelta[i1][i2])
+ (momentum * matrixDelta[i1][i2]);
layer.getMatrix().setMatrix(i1,i2,layer.getMatrix().getMatrix(i1,i2) + matrixDelta[i1][i2]);
accMatrixDelta[i1][i2] = 0;
}
}
}
}The above code performs several matrix operations; however, it is not completely obvious which matrix operations are being performed. By encapsulating the matrix operations inside several matrix classes, the above code can be simplified. Further, you will be able to tell, at a glance, which matrix operations are being performed. The following code accomplishes the same as the code above; however, it uses matrix classes.
public void learn(final double learnRate, final double momentum)
{
if (this.layer.hasMatrix()) {
Matrix m1 = MatrixMath.multiply( accMatrixDelta, learnRate );
Matrix m2 = MatrixMath.multiply( matrixDelta, momentum);
matrixDelta = MatrixMath.add(m1, m2);
layer.setMatrix(MatrixMath.add(layer.getMatrix(),matrixDelta));
accMatrixDelta.clear();
}
}As you can see, several matrixes are constructed and then the MatrixMath class is used to perform operations upon them.
