There are numerous mathematical libraries available for Java use. In this section, we will provide a quick and high-level overview of several libraries. These libraries do not necessarily automatically support multiple processors. In addition, the intent of this section is to provide some insight into how these libraries can be used. In most cases, they are relatively easy to use.
A list of Java mathematical libraries is found at https://en.wikipedia.org/wiki/List_of_numerical_libraries#Java and https://java-matrix.org/. We will demonstrate the use of the jblas, Apache Commons Math, and the ND4J libraries.
The jblas API (http://jblas.org/) is a math library supporting Java. It is based on Basic Linear Algebra Subprograms (BLAS) (http://www.netlib.org/blas/) and Linear Algebra Package (LAPACK) (http://www.netlib.org/lapack/), which are standard libraries for fast arithmetic calculation. The jblas API provides a wrapper around these libraries.
The following is a demonstration of how matrix multiplication is performed. We start with the matrix definitions:
DoubleMatrix A = new DoubleMatrix(new double[][]{ {0.1950, 0.0311}, {0.3588, 0.2203}, {0.1716, 0.5931}, {0.2105, 0.3242}}); DoubleMatrix B = new DoubleMatrix(new double[][]{ {0.0502, 0.9823, 0.9472}, {0.5732, 0.2694, 0.916}}); DoubleMatrix C;
The actual statement to perform multiplication is quite short, as shown next. The mmul
method is executed against the A
matrix, where the B
array is passed as an argument:
C = A.mmul(B);
The resulting C
matrix is then displayed:
for(int i=0; i<C.getRows(); i++) { out.println(C.getRow(i)); }
The output should be as follows:
[0.027616, 0.199927, 0.213192] [0.144288, 0.411798, 0.541650] [0.348579, 0.328344, 0.705819] [0.196399, 0.294114, 0.496353]
This library is fairly easy to use and supports an extensive set of arithmetic operations.
The Apache Commons math API (http://commons.apache.org/proper/commons-math/) supports a large number of mathematical and statistical operations. The following example illustrates how to perform matrix multiplication.
We start with the declaration and initialization of the A
and B
matrices:
double[][] A = { {0.1950, 0.0311}, {0.3588, 0.2203}, {0.1716, 0.5931}, {0.2105, 0.3242}}; double[][] B = { {0.0502, 0.9823, 0.9472}, {0.5732, 0.2694, 0.916}};
Apache Commons uses the RealMatrix
class to hold a matrix. In the following code sequence, the corresponding matrices for the A
and B
matrices are created using the Array2DRowRealMatrix
constructor:
RealMatrix aRealMatrix = new Array2DRowRealMatrix(A); RealMatrix bRealMatrix = new Array2DRowRealMatrix(B);
The multiplication is straightforward using the multiply method, as shown next:
RealMatrix cRealMatrix = aRealMatrix.multiply(bRealMatrix);
The next for
loop will display the following results:
for (int i = 0; i < cRealMatrix.getRowDimension(); i++) { out.println(cRealMatrix.getRowVector(i)); }
The output should be as follows:
{0.02761552; 0.19992684; 0.2131916} {0.14428772; 0.41179806; 0.54165016} {0.34857924; 0.32834382; 0.70581912} {0.19639854; 0.29411363; 0.4963528}
ND4J (http://nd4j.org/) is the library used by DL4J to perform arithmetic operations. The library is also available for direct use. In this section, we will demonstrate how matrix multiplication is performed using the A
and B
matrices.
Before we can perform the multiplication, we need to flatten the matrices to vectors. The following declares and initializes these vectors:
double[] A = { 0.1950, 0.0311, 0.3588, 0.2203, 0.1716, 0.5931, 0.2105, 0.3242}; double[] B = { 0.0502, 0.9823, 0.9472, 0.5732, 0.2694, 0.916};
The Nd4j
class' create
method creates an INDArray
instance given a vector and dimension information. The first argument of the method is the vector. The second argument specifies the dimensions of the matrix. The last argument specifies the order the rows and columns are laid out. This order is either row-column major as exemplified by c
, or column-row major order as used by FORTRAN. Row-column order means the first row is allocated to the vector, followed by the second row, and so forth.
In the following code sequence 2INDArray
instances are created using the A
and B
vectors. The first is a 4
row, 2
column matrix using row-major order as specified by the third argument, c
. The second INDArray
instance represents the B
matrix. If we wanted to use column-row ordering, we would use an f
instead.
INDArray aINDArray = Nd4j.create(A,new int[]{4,2},'c'); INDArray bINDArray = Nd4j.create(B,new int[]{2,3},'c');
The C
array, represented by cINDArray
, is then declared and assigned the result of the multiplication. The mmul
performs the operation:
INDArray cINDArray; cINDArray = aINDArray.mmul(bINDArray);
The following sequence displays the results using the getRow
method:
for(int i=0; i<cINDArray.rows(); i++) { out.println(cINDArray.getRow(i)); }
The output should be as follows:
[0.03, 0.20, 0.21] [0.14, 0.41, 0.54] [0.35, 0.33, 0.71] [0.20, 0.29, 0.50]
Next, we will provide an overview of the OpenCL API that provide supports for concurrent operations on a number of platforms.