// transformations
cern.jet.math.Mult div = cern.jet.math.Mult.div(0);
cern.jet.math.PlusMult minusMult = cern.jet.math.PlusMult.minusMult(0);
cern.colt.list.IntArrayList nonZeroIndexes = new cern.colt.list.IntArrayList(); // sparsity
DoubleMatrix1D Browk = cern.colt.matrix.DoubleFactory1D.dense.make(nx); // blocked row k
// Solve L*Y = B(piv,:)
for (int k = 0; k < n; k++) {
// blocking (make copy of k-th row to localize references)
Browk.assign(Brows[k]);
// sparsity detection
int maxCardinality = nx/CUT_OFF; // == heuristic depending on speedup
Browk.getNonZeros(nonZeroIndexes,null,maxCardinality);
int cardinality = nonZeroIndexes.size();
boolean sparse = (cardinality < maxCardinality);
for (int i = k+1; i < n; i++) {
//for (int j = 0; j < nx; j++) B[i][j] -= B[k][j]*LU[i][k];
//for (int j = 0; j < nx; j++) B.set(i,j, B.get(i,j) - B.get(k,j)*LU.get(i,k));
minusMult.multiplicator = -LU.getQuick(i,k);
if (minusMult.multiplicator != 0) {
if (sparse) {
Brows[i].assign(Browk,minusMult,nonZeroIndexes);
}
else {
Brows[i].assign(Browk,minusMult);
}
}
}
}
// Solve U*B = Y;
for (int k = n-1; k >= 0; k--) {
// for (int j = 0; j < nx; j++) B[k][j] /= LU[k][k];
// for (int j = 0; j < nx; j++) B.set(k,j, B.get(k,j) / LU.get(k,k));
div.multiplicator = 1 / LU.getQuick(k,k);
Brows[k].assign(div);
// blocking
if (Browk==null) Browk = cern.colt.matrix.DoubleFactory1D.dense.make(B.columns());
Browk.assign(Brows[k]);
// sparsity detection
int maxCardinality = nx/CUT_OFF; // == heuristic depending on speedup
Browk.getNonZeros(nonZeroIndexes,null,maxCardinality);
int cardinality = nonZeroIndexes.size();
boolean sparse = (cardinality < maxCardinality);
//Browk.getNonZeros(nonZeroIndexes,null);
//boolean sparse = nonZeroIndexes.size() < nx/10;