/*
Copyright (C) 2008 Richard Gomes

This source code is release under the BSD License.

This file is part of JQuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://jquantlib.org/

JQuantLib is free software: you can redistribute it and/or modify it
under the terms of the JQuantLib license.  You should have received a
copy of the license along with this program; if not, please email
. The license is also available online at
.

This program 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 license for more details.

JQuantLib is based on QuantLib. http://quantlib.org/
When applicable, the original copyright notice follows this notice.
 */

/*
 Copyright (C) 2008 Klaus Spanderen

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 . The license is also available online at
 .

 This program 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 license for more details.
*/

package org.jquantlib.math.matrixutilities;

import java.util.Arrays;

import org.jquantlib.QL;
import org.jquantlib.math.optimization.Minpack;


/**
 * QR decompoisition
 * 

* This implementation is based on MINPACK/J *

* This subroutine uses householder transformations with optional column pivoting to compute a QR factorization of * the {@latex$ m} by {@latex$ n} matrix {@latex$ A}. *

* That is, Minpack_f77#qrfac determines an orthogonal matrix {@latex$ Q}, a permutation matrix {@latex$ P}, and * an upper trapezoidal matrix {@latex$ R} with diagonal elements of nonincreasing magnitude, such that {@latex$ A*P = Q*R}. *

* Return value ipvt is an integer array of length {@latex$ n}, which defines the permutation matrix {@latex$ P} * such that {@latex$ A*P = Q*R}. *

* Column {@latex$ j} of {@latex$ P} is column ipvt[j] of the identity matrix. *

* See lmdiff.cpp for further details. * * @see MathWorld * @see Wikipedia * @see MINPACK/J * @see MINPACK * * @author Richard Gomes */ public class QRDecomposition { private final int m; private final int n; private final Matrix A; private final Matrix Q; private final Matrix R; private final Matrix P; private final int ipvt[]; private final boolean isNonSingular; /** * Calculates the QR-decomposition of the given matrix. * @param A The matrix to decompose. */ public QRDecomposition(final Matrix matrix) { this(matrix, false); } /** * Calculates the QR-decomposition of the given matrix. * @param M The matrix to decompose. */ public QRDecomposition(final Matrix A, final boolean pivot) { this.A = A; this.m = A.rows(); this.n = A.cols(); this.ipvt = new int[n]; final Matrix mT = A.clone().toJava().transpose(); final Array rdiag = new Array(n); final Array wa = new Array(n); System.out.println("mT (BEFORE) = " + mT); Minpack.qrfac( m, n, mT, // input/output parameter (sorry for that :~ ) pivot, ipvt, rdiag, rdiag, wa // output parameters (sorry for that :~ ) ); System.out.println("mT (AFTER) = " + mT); System.out.println("Array ipvt = " + Arrays.toString(ipvt)); System.out.println("Array rdiag = " + rdiag); System.out.println("Array wa = " + wa); // obtain R final double[][] r = new double[n][n]; for (int i=0; i < n; i++) { // r[i][i] = rdiag[i]; r[i][i] = rdiag.get(i); if (i < m) { // std::copy(mT.column_begin(i)+i+1, mT.column_end(i), r.row_begin(i)+i+1); for (int k = i + 1; k < n; k++) { // r[i][k] = mT[k][i]; r[i][k] = mT.get(k, i); } } } // obtain Q final double[][] q = new double[m][n]; final double w[] = new double[m]; for (int k=0; k < m; k++) { Arrays.fill(w, 0.0); w[k] = 1.0; for (int j=0; j < Math.min(n, m); j++) { final double t3 = mT.get(j, j); if (t3 != 0.0) { // final double t = std::inner_product(mT.row_begin(j)+j, mT.row_end(j), w.begin()+j, 0.0)/t3; double t = 0.0; for (int p = j; p < m; p++) { t += mT.get(j, p) * w[p]; } t /= t3; for (int i=j; i

Ads help maintain this website.