The Basic Linear Algebra Subprograms (BLAS) library provides computational kernels for several of the fundamental linear algebra operations, such as matrix-multiply, the solution of triangular systems, and simple vector operations.
Rather than reproduce the complete BLAS interface here, we describe the translation rules to generate the Java version, based on the Fortran template. See here for the complete Fortran BLAS source code and documentation.
Most of the differences between the interfaces are due to how Java handles native arrays. Like C and C++, Java matrices are stored by rows, without any guarantee that the consecutive rows are actually contiguous in memory. In fact, there is no mechanism to test for this in Java. Furthermore, because there are no capabilties to manipulate pointers directly, one cannot 'alias' subvectors, or reshape vectors into matrices. These considerations are discussed below.
The alternative possibility is to treat a 1-D Java array (vector) as a matrix by performing indexing computations. This allows flexibility to use row-major or column-major conventions, but introduces indexing overhead when accessing matrix elements. Instead, we will focus on using native Java arrays wherever possible.
The JBLAS are designed to work with submatrices. This same mechanism allows one to use 0 or 1-based offset conventions. (To use 1-basd conventions, declare a Java native array to be of size [M+1][N+1] and use the submatrix [1:M][1:N].)
For example, in Fortran, if the function SUM(N, X)
adds N elements from a given vector X, then calling it as
SUM(N, X(I))sums the elements x_i, x_i+1, ..., x_i+N. Because no analogue exists in Java, we must mention subvectors explicitly by describing the original vector (X) and its offset (i) separately, i.e.
sum(N, x, i)
daxpy
on two columns
of matrices A and B:
A(:,J) = A(:,J) + alpha * B(:,J)
.
In Fortran we would have
To perform a daxpy
on two rows of
A and B,
DAXPY(N, ALPHA, A(I,1), LDA, B(I,1), LDB)
BLAS.daxpy(N, alpha, A[i], 0, B[i], 0);
Note that Java row vectors are really 1D arrays and can be used with no argument modifications.
DAXPY(...)
BLAS.daxpy(...)
(N, ..., X(I), ...)
(N, ..., X, i, ... )
(1D array,
X is double[]
)
(N, ..., A, i, j, ...)
(column vector,
A is double[][]
)
(M, N, ..., A(I,J), LDA, ...)
(M, N, ..., A, i, j, ... )
(..., 'NoTranspose', ... )
(..., BLAS.NoTranspose, ... )
Although Java has no support enumerated types, such "constants" can be emulated through a public integers, e.g.
public class BLAS { public final static int Tranpose = 11; public final static int NoTranpose = 12; public final static int UpperTriangular = 13; public final static int LowerTriangular = 14; ... }
DGEMM('No Tranpose', 'No Tranpose', M, N, K,
ALPHA,
A(AI,AJ), LDA, B(BI,BJ), LDB, BETA, C(CI,CJ), LDC)
BLAS.dgemm( BLAS.NoTranpose, BLAS.NoTranspose,
M, N, K, alpha A, ai, aj, B, bi, bj, beta, C, ci, cj);
DTRSM('Left', 'Lower', 'No transpose', 'Unit',
M, N, ALPHA, A(AI,AJ), LDA, B(BI,BJ), LDB)
BLAS.dtsrm(BLAS.Left, BLAS.Lower,
BLAS.NoTranspose, BLAS.UnitTriangular,
M, N, alpha, A, ai, aj, B, bi, bj);