org.ejml.alg.dense.linsol.lu.LinearSolverLuBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ejml Show documentation
Show all versions of ejml Show documentation
A fast and easy to use dense matrix linear algebra library written in Java.
/*
* Copyright (c) 2009-2012, Peter Abeles. All Rights Reserved.
*
* This file is part of Efficient Java Matrix Library (EJML).
*
* EJML is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* EJML is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EJML. If not, see .
*/
package org.ejml.alg.dense.linsol.lu;
import org.ejml.alg.dense.decomposition.lu.LUDecompositionBase;
import org.ejml.alg.dense.linsol.LinearSolverAbstract;
import org.ejml.data.DenseMatrix64F;
/**
* @author Peter Abeles
*/
public abstract class LinearSolverLuBase extends LinearSolverAbstract {
protected LUDecompositionBase decomp;
public LinearSolverLuBase( LUDecompositionBase decomp ) {
this.decomp = decomp;
}
@Override
public boolean setA(DenseMatrix64F A) {
_setA(A);
return decomp.decompose(A);
}
@Override
public double quality() {
return decomp.quality();
}
@Override
public void invert(DenseMatrix64F A_inv) {
double []vv = decomp._getVV();
DenseMatrix64F LU = decomp.getLU();
if( A_inv.numCols != LU.numCols || A_inv.numRows != LU.numRows )
throw new IllegalArgumentException("Unexpected matrix dimension");
int n = A.numCols;
double dataInv[] = A_inv.data;
for( int j = 0; j < n; j++ ) {
// don't need to change inv into an identity matrix before hand
for( int i = 0; i < n; i++ ) vv[i] = i == j ? 1 : 0;
decomp._solveVectorInternal(vv);
// for( int i = 0; i < n; i++ ) dataInv[i* n +j] = vv[i];
int index = j;
for( int i = 0; i < n; i++ , index += n) dataInv[ index ] = vv[i];
}
}
/**
* This attempts to improve upon the solution generated by account
* for numerical imprecisions. See numerical recipes for more information. It
* is assumed that solve has already been run on 'b' and 'x' at least once.
*
* @param b A matrix. Not modified.
* @param x A matrix. Modified.
*/
public void improveSol( DenseMatrix64F b , DenseMatrix64F x )
{
if( b.numCols != x.numCols ) {
throw new IllegalArgumentException("bad shapes");
}
double dataA[] = A.data;
double dataB[] = b.data;
double dataX[] = x.data;
final int nc = b.numCols;
final int n = b.numCols;
double []vv = decomp._getVV();
DenseMatrix64F LU = decomp.getLU();
// BigDecimal sdp = new BigDecimal(0);
for( int k = 0; k < nc; k++ ) {
for( int i = 0; i < n; i++ ) {
// *NOTE* in the book this is a long double. extra precision might be required
double sdp = -dataB[ i * nc + k];
// BigDecimal sdp = new BigDecimal(-dataB[ i * nc + k]);
for( int j = 0; j < n; j++ ) {
sdp += dataA[i* n +j] * dataX[ j * nc + k];
// sdp = sdp.add( BigDecimal.valueOf(dataA[i* n +j] * dataX[ j * nc + k]));
}
vv[i] = sdp;
// vv[i] = sdp.doubleValue();
}
decomp._solveVectorInternal(vv);
for( int i = 0; i < n; i++ ) {
dataX[i*nc + k] -= vv[i];
}
}
}
@Override
public boolean modifiesA() {
return false;
}
@Override
public boolean modifiesB() {
return false;
}
}