edu.mines.jtk.lapack.DMatrixLud Maven / Gradle / Ivy
Show all versions of edu-mines-jtk Show documentation
/****************************************************************************
Copyright 2005, Colorado School of Mines and others.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
****************************************************************************/
package edu.mines.jtk.lapack;
import static java.lang.Math.min;
import org.netlib.lapack.LAPACK;
import static edu.mines.jtk.util.ArrayMath.*;
import edu.mines.jtk.util.Check;
/**
* LU decomposition of a matrix A.
* For an m-by-n matrix A, the LU decomposition is A = P*L*U or A(p,:) =
* L*U, where P is an m-by-m row permutation matrix, p is a corresponding
* array of m row permutation indices, L is an m-by-min(m,n) lower
* triangular or trapezoidal matrix with unit diagonal elements, and
* U is a min(m,n)-by-n upper triangular or trapezoidal matrix.
*
* The LU decomposition with pivoting never fails, even if the matrix
* A is singular. However, the primary use of LU decomposition is in the
* solution of square systems of linear equations, which will fail if A
* is singular (or not square).
* @author Dave Hale, Colorado School of Mines
* @version 2005.12.12
*/
public class DMatrixLud {
/**
* Constructs an LU decomposition of the specified matrix A.
* @param a the matrix.
*/
public DMatrixLud(DMatrix a) {
_m = a.getM();
_n = a.getN();
_lu = a.getPackedColumns();
_npiv = min(_m,_n);
_ipiv = new int[_npiv];
LapackInfo li = new LapackInfo();
_lapack.dgetrf(_m,_n,_lu,_m,_ipiv,li);
int info = li.get("dgetrf");
_p = new int[_m];
for (int i=0; i<_m; ++i)
_p[i] = i;
_det = 1.0;
for (int i=0; i<_m; ++i) {
if (i<_npiv) {
int j = _ipiv[i]-1;
_det *= _lu[i+i*_m];
if (j!=i) {
int pi = _p[i];
_p[i] = _p[j];
_p[j] = pi;
_det = -_det;
}
}
}
_singular = info>0;
}
/**
* Determines whether the matrix A is singular. If singular, then this
* decomposition cannot be used to solve systems of linear equations.
* @return true, if singular; false, otherwise.
*/
public boolean isSingular() {
return _singular;
}
/**
* Gets the lower triangular (or lower trapezoidal) factor L.
* The matrix L has dimensions m-by-min(m,n) and unit diagonal elements.
* @return the factor L.
*/
public DMatrix getL() {
int m = _m;
int n = min(_m,_n);
double[] l = new double[m*n];
for (int j=0; j