Package eas.math.matrix.bigDecimal.jama

Source Code of eas.math.matrix.bigDecimal.jama.QRDecomposition

package eas.math.matrix.bigDecimal.jama;
import java.math.BigDecimal;
import java.math.MathContext;

import eas.math.matrix.bigDecimal.MatrixBigDecimal;

/** QR Decomposition.
<P>
   For an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n
   orthogonal matrix Q and an n-by-n upper triangular matrix R so that
   A = Q*R.
<P>
   The QR decompostion always exists, even if the matrix does not have
   full rank, so the constructor will never fail.  The primary use of the
   QR decomposition is in the least squares solution of nonsquare systems
   of simultaneous linear equations.  This will fail if isFullRank()
   returns false.
*/

public class QRDecomposition implements java.io.Serializable {

/* ------------------------
   Class variables
* ------------------------ */

   /** Array for internal storage of decomposition.
   @serial internal array storage.
   */
   private BigDecimal[][] QR;

   /** Row and column dimensions.
   @serial column dimension.
   @serial row dimension.
   */
   private int m, n;

   /** Array for internal storage of diagonal of R.
   @serial diagonal of R.
   */
   private BigDecimal[] Rdiag;

/* ------------------------
   Constructor
* ------------------------ */

   /** QR Decomposition, computed by Householder reflections.
       Structure to access R and the Householder vectors and compute Q.
   @param A    Rectangular matrix
   */

   public QRDecomposition (JamaMatrixBigDecimal A, int roundingMode) {
      // Initialize.
      QR = A.getArrayCopy();
      m = A.getRowDimension();
      n = A.getColumnDimension();
      Rdiag = new BigDecimal[n];

      // Main loop.
      for (int k = 0; k < n; k++) {
         // Compute 2-norm of k-th column without under/overflow.
         BigDecimal nrm = BigDecimal.ZERO;
         for (int i = k; i < m; i++) {
            nrm = Maths.hypot(nrm,QR[i][k], roundingMode);
         }

         if (nrm.compareTo(BigDecimal.ZERO) != 0.0) {
            // Form k-th Householder vector.
            if (QR[k][k].compareTo(BigDecimal.ZERO) < 0) {
               nrm = nrm.negate();
            }
            for (int i = k; i < m; i++) {
                int scale = MatrixBigDecimal.GLOBAL_SCALE;
               QR[i][k] = QR[i][k].divide(nrm, scale, roundingMode);
            }
            QR[k][k] = QR[k][k].add(BigDecimal.ONE);

            // Apply transformation to remaining columns.
            for (int j = k+1; j < n; j++) {
               BigDecimal s = BigDecimal.ZERO;
               for (int i = k; i < m; i++) {
                   int scale = MatrixBigDecimal.GLOBAL_SCALE;
                   s = s.add(QR[i][k].multiply(QR[i][j], new MathContext(scale)));
               }
               int scale = MatrixBigDecimal.GLOBAL_SCALE;
               s = s.negate().divide(QR[k][k], scale, roundingMode);
               for (int i = k; i < m; i++) {
                   int scale2 = MatrixBigDecimal.GLOBAL_SCALE;
                   QR[i][j] = QR[i][j].add(s.multiply(QR[i][k], new MathContext(scale2)));
               }
            }
         }
         Rdiag[k] = nrm.negate();
      }
   }

/* ------------------------
   Public Methods
* ------------------------ */

   /** Is the matrix full rank?
   @return     true if R, and hence A, has full rank.
   */

   public boolean isFullRank () {
      for (int j = 0; j < n; j++) {
         if (Rdiag[j].compareTo(BigDecimal.ZERO) == 0)
            return false;
      }
      return true;
   }

   /** Least squares solution of A*X = B
   @param B    A Matrix with as many rows as A and any number of columns.
   @return     X that minimizes the two norm of Q*R*X-B.
   @exception  IllegalArgumentException  Matrix row dimensions must agree.
   @exception  RuntimeException  Matrix is rank deficient.
   */

   public JamaMatrixBigDecimal solve (JamaMatrixBigDecimal B, int roundingMode) {
      if (B.getRowDimension() != m) {
         throw new IllegalArgumentException("Matrix row dimensions must agree.");
      }
      if (!this.isFullRank()) {
         throw new RuntimeException("Matrix is rank deficient.");
      }
     
      // Copy right hand side
      int nx = B.getColumnDimension();
      BigDecimal[][] X = B.getArrayCopy();

      // Compute Y = transpose(Q)*B
      for (int k = 0; k < n; k++) {
         for (int j = 0; j < nx; j++) {
            BigDecimal s = BigDecimal.ZERO;
            for (int i = k; i < m; i++) {
                int scale = MatrixBigDecimal.GLOBAL_SCALE;
                s = s.add(QR[i][k].multiply(X[i][j]), new MathContext(scale));
            }
            int scale = Math.max(s.scale(), QR[k][k].scale());
            s = s.negate().divide(QR[k][k], scale, roundingMode);
            for (int i = k; i < m; i++) {
                int scale2 = MatrixBigDecimal.GLOBAL_SCALE;
                X[i][j] = X[i][j].add(s.multiply(QR[i][k], new MathContext(scale2)));
            }
         }
      }
      // Solve R*X = Y;
      for (int k = n-1; k >= 0; k--) {
         for (int j = 0; j < nx; j++) {
             int scale = MatrixBigDecimal.GLOBAL_SCALE;
             X[k][j] = X[k][j].divide(Rdiag[k], scale, roundingMode);
         }
         for (int i = 0; i < k; i++) {
            for (int j = 0; j < nx; j++) {
                int scale = MatrixBigDecimal.GLOBAL_SCALE;
                X[i][j] = X[i][j].subtract(X[k][j].multiply(QR[i][k], new MathContext(scale)));
            }
         }
      }
      return (new JamaMatrixBigDecimal(X,n,nx).getMatrix(0,n-1,0,nx-1));
   }
  private static final long serialVersionUID = 1;
}
TOP

Related Classes of eas.math.matrix.bigDecimal.jama.QRDecomposition

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.