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.


Copyright 2005 - 2010 by Heaton Research, Inc.. Heaton Research™ and Encog™ are trademarks of Heaton Research. Click here for copyright and trademark information.