package mikera.matrixx.algo;
import mikera.matrixx.AMatrix;
import mikera.matrixx.Matrix;
import mikera.matrixx.impl.ImmutableMatrix;
import mikera.vectorz.util.DoubleArrays;
import mikera.vectorz.util.ErrorMessages;
public class Multiplications {
private Multiplications(){}
// target number of elements in working set group
// aim for around 200kb => fits comfortably in L2 cache in modern machines
protected static final int WORKING_SET_TARGET=8192;
/**
* General purpose matrix multiplication, with smart selection of algorithm based
* on matrix size and type.
*
* @param a
* @param b
* @return
*/
public static Matrix multiply(AMatrix a, AMatrix b) {
if (a instanceof Matrix) {
return multiply((Matrix)a,b);
} else if (a instanceof ImmutableMatrix) {
return multiply(Matrix.wrap(a.rowCount(),a.columnCount(),((ImmutableMatrix)a).getInternalData()),b);
} else {
return blockedMultiply(a.toMatrix(),b);
}
}
public static Matrix multiply(Matrix a, AMatrix b) {
return blockedMultiply(a,b);
}
/**
* Performs fast matrix multiplication using temporary working storage for the second matrix
* @param a
* @param b
* @return
*/
public static Matrix blockedMultiply(Matrix a, AMatrix b) {
int rc=a.rowCount();
int cc=b.columnCount();
int ic=a.columnCount();
if ((ic!=b.rowCount())) {
throw new IllegalArgumentException(ErrorMessages.incompatibleShapes(a,b));
}
Matrix result=Matrix.create(rc, cc);
if (ic==0) return result;
int block=(WORKING_SET_TARGET/ic)+1;
// working set stores up to number of columns from second matrix
Matrix wsb=Matrix.create(Math.min(block,cc), ic);
for (int bj=0; bj number of columns from each matrix
Matrix wsa=Matrix.create(Math.min(block,rc), ic);
Matrix wsb=Matrix.create(Math.min(block,cc), ic);
for (int bj=0; bj
Ads help maintain this website.