@Test(dataProvider = "styles") public void testPseudoInverse(DataFrameAlgebra.Lib lib, boolean parallel) { DataFrameAlgebra.LIBRARY.set(lib); final DataFrame<Integer,String> source = DataFrame.read().csv("./src/test/resources/pca/svd/poppet-svd-eigenvectors.csv"); Array.of(20, 77, 95, 135, 233, 245).forEach(count -> { final DataFrame<Integer,String> frame = source.cols().select(col -> col.ordinal() < count); final DataFrame<Integer,Integer> inverse = frame.inverse(); final RealMatrix matrix = new QRDecomposition(toMatrix(frame)).getSolver().getInverse(); assertEquals(inverse, matrix); }); }
@Override public double[] smooth(double[] sourceX, double[] noisyY, double[] estimateX, double parameter) { int numDivisions = (int)Math.round(parameter); SmoothingHelper.SmoothingInput filteredInput = SmoothingHelper.filterInvalidValues(sourceX, noisyY); sourceX = filteredInput.getSourceX(); noisyY = filteredInput.getSourceY(); if(numDivisions >= sourceX.length) { throw new IllegalArgumentException("Cannot fit with " + numDivisions + " knots as the input data (after removing NAs) has < " + (numDivisions + 1) + " data points."); } double[][] sourceBasis = createBasis(numDivisions, splineDegree, sourceX); RealMatrix matrix = new Array2DRowRealMatrix(sourceBasis); QRDecomposition decomposition = new QRDecomposition(matrix); RealVector coefficients = decomposition.getSolver().solve(new ArrayRealVector(noisyY)); double[][] estimateBasis = createBasis((int)parameter, splineDegree, estimateX); RealMatrix estimateBasisMatrix = new Array2DRowRealMatrix(estimateBasis); double[] result = estimateBasisMatrix.transpose().preMultiply(coefficients).toArray(); return result; }
/** * Calculates the QR-decomposition of a matrix. The QR-decomposition of a * matrix A consists of two matrices Q and R that satisfy: A = QR, Q is * orthogonal (QTQ = I), and R is upper triangular. If A is m×n, Q is m×m * and R m×n. * * @param a Given matrix. * @return Result Q/R arrays. */ public static Array[] qr(Array a) { int m = a.getShape()[0]; int n = a.getShape()[1]; Array Qa = Array.factory(DataType.DOUBLE, new int[]{m, m}); Array Ra = Array.factory(DataType.DOUBLE, a.getShape()); double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray(a); RealMatrix matrix = new Array2DRowRealMatrix(aa, false); QRDecomposition decomposition = new QRDecomposition(matrix); RealMatrix Q = decomposition.getQ(); RealMatrix R = decomposition.getR(); for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { Qa.setDouble(i * m + j, Q.getEntry(i, j)); } } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { Ra.setDouble(i * n + j, R.getEntry(i, j)); } } return new Array[]{Qa, Ra}; }
/** * Function to solve a given system of equations. * * @param in1 matrix object 1 * @param in2 matrix object 2 * @return matrix block * @throws DMLRuntimeException if DMLRuntimeException occurs */ private static MatrixBlock computeSolve(MatrixObject in1, MatrixObject in2) throws DMLRuntimeException { Array2DRowRealMatrix matrixInput = DataConverter.convertToArray2DRowRealMatrix(in1); Array2DRowRealMatrix vectorInput = DataConverter.convertToArray2DRowRealMatrix(in2); /*LUDecompositionImpl ludecompose = new LUDecompositionImpl(matrixInput); DecompositionSolver lusolver = ludecompose.getSolver(); RealMatrix solutionMatrix = lusolver.solve(vectorInput);*/ // Setup a solver based on QR Decomposition QRDecomposition qrdecompose = new QRDecomposition(matrixInput); DecompositionSolver solver = qrdecompose.getSolver(); // Invoke solve RealMatrix solutionMatrix = solver.solve(vectorInput); return DataConverter.convertToMatrixBlock(solutionMatrix.getData()); }
/** * Function to perform QR decomposition on a given matrix. * * @param in matrix object * @return array of matrix blocks * @throws DMLRuntimeException if DMLRuntimeException occurs */ private static MatrixBlock[] computeQR(MatrixObject in) throws DMLRuntimeException { Array2DRowRealMatrix matrixInput = DataConverter.convertToArray2DRowRealMatrix(in); // Perform QR decomposition QRDecomposition qrdecompose = new QRDecomposition(matrixInput); RealMatrix H = qrdecompose.getH(); RealMatrix R = qrdecompose.getR(); // Read the results into native format MatrixBlock mbH = DataConverter.convertToMatrixBlock(H.getData()); MatrixBlock mbR = DataConverter.convertToMatrixBlock(R.getData()); return new MatrixBlock[] { mbH, mbR }; }
/** * Get the covariance matrix of the optimized parameters. * <br/> * Note that this operation involves the inversion of the * <code>J<sup>T</sup>J</code> matrix, where {@code J} is the * Jacobian matrix. * The {@code threshold} parameter is a way for the caller to specify * that the result of this computation should be considered meaningless, * and thus trigger an exception. * * @param threshold Singularity threshold. * @return the covariance matrix. * @throws org.apache.commons.math3.linear.SingularMatrixException * if the covariance matrix cannot be computed (singular problem). */ public double[][] getCovariances(double threshold) { // Set up the jacobian. updateJacobian(); // Compute transpose(J)J, without building intermediate matrices. double[][] jTj = new double[cols][cols]; for (int i = 0; i < cols; ++i) { for (int j = i; j < cols; ++j) { double sum = 0; for (int k = 0; k < rows; ++k) { sum += weightedResidualJacobian[k][i] * weightedResidualJacobian[k][j]; } jTj[i][j] = sum; jTj[j][i] = sum; } } // Compute the covariances matrix. final DecompositionSolver solver = new QRDecomposition(MatrixUtils.createRealMatrix(jTj), threshold).getSolver(); return solver.getInverse().getData(); }
/** * Computes model parameters and parameter variance using a QR decomposition of the X matrix * @param y the response vector * @param x the design matrix */ private RealMatrix computeBetaQR(RealVector y, RealMatrix x) { final int n = x.getRowDimension(); final int p = x.getColumnDimension(); final int offset = hasIntercept() ? 1 : 0; final QRDecomposition decomposition = new QRDecomposition(x, threshold); final RealVector betaVector = decomposition.getSolver().solve(y); final RealVector residuals = y.subtract(x.operate(betaVector)); this.rss = residuals.dotProduct(residuals); this.errorVariance = rss / (n - p); this.stdError = Math.sqrt(errorVariance); this.residuals = createResidualsFrame(residuals); final RealMatrix rAug = decomposition.getR().getSubMatrix(0, p - 1, 0, p - 1); final RealMatrix rInv = new LUDecomposition(rAug).getSolver().getInverse(); final RealMatrix covMatrix = rInv.multiply(rInv.transpose()).scalarMultiply(errorVariance); final RealMatrix result = new Array2DRowRealMatrix(p, 2); if (hasIntercept()) { result.setEntry(0, 0, betaVector.getEntry(0)); //Intercept coefficient result.setEntry(0, 1, covMatrix.getEntry(0, 0)); //Intercept variance } for (int i = 0; i < getRegressors().size(); i++) { final int index = i + offset; final double variance = covMatrix.getEntry(index, index); result.setEntry(index, 1, variance); result.setEntry(index, 0, betaVector.getEntry(index)); } return result; }
/** {@inheritDoc} */ public RealMatrix getCovariances(double threshold) { // Set up the Jacobian. final RealMatrix j = this.getJacobian(); // Compute transpose(J)J. final RealMatrix jTj = j.transpose().multiply(j); // Compute the covariances matrix. final DecompositionSolver solver = new QRDecomposition(jTj, threshold).getSolver(); return solver.getInverse(); }
/** Guess a start line using the last four results. * @param n number of cached results available * @param target target ground point * @return guessed start line */ private double guessStartLine(final int n, final Vector3D target) { try { // assume a linear model of the form: l = ax + by + cz + d final RealMatrix m = new Array2DRowRealMatrix(n, 4); final RealVector v = new ArrayRealVector(n); for (int i = 0; i < n; ++i) { m.setEntry(i, 0, cachedResults[i].getTarget().getX()); m.setEntry(i, 1, cachedResults[i].getTarget().getY()); m.setEntry(i, 2, cachedResults[i].getTarget().getZ()); m.setEntry(i, 3, 1.0); v.setEntry(i, cachedResults[i].getLine()); } final DecompositionSolver solver = new QRDecomposition(m, Precision.SAFE_MIN).getSolver(); final RealVector coefficients = solver.solve(v); // apply the linear model return target.getX() * coefficients.getEntry(0) + target.getY() * coefficients.getEntry(1) + target.getZ() * coefficients.getEntry(2) + coefficients.getEntry(3); } catch (SingularMatrixException sme) { // the points are not independent return Double.NaN; } }
/** * Function to compute matrix inverse via matrix decomposition. * * @param in commons-math3 Array2DRowRealMatrix * @return matrix block * @throws DMLRuntimeException if DMLRuntimeException occurs */ private static MatrixBlock computeMatrixInverse(Array2DRowRealMatrix in) throws DMLRuntimeException { if ( !in.isSquare() ) throw new DMLRuntimeException("Input to inv() must be square matrix -- given: a " + in.getRowDimension() + "x" + in.getColumnDimension() + " matrix."); QRDecomposition qrdecompose = new QRDecomposition(in); DecompositionSolver solver = qrdecompose.getSolver(); RealMatrix inverseMatrix = solver.getInverse(); return DataConverter.convertToMatrixBlock(inverseMatrix.getData()); }
/** * Assert that the given matrix is unitary. * @param m */ public static void assertUnitaryMatrix(final RealMatrix m){ final RealMatrix mInv = new QRDecomposition(m).getSolver().getInverse(); final RealMatrix mT = m.transpose(); for (int i = 0; i < mInv.getRowDimension(); i ++) { for (int j = 0; j < mInv.getColumnDimension(); j ++) { Assert.assertEquals(mInv.getEntry(i, j), mT.getEntry(i, j), 1e-7); } } }
/** * Check that the given matrix is unitary. */ public static boolean isUnitaryMatrix(final RealMatrix m){ //Note can't use MatrixUtils.inverse because m may not be square final RealMatrix mInv = new QRDecomposition(m).getSolver().getInverse(); final RealMatrix mT = m.transpose(); for (int i = 0; i < mInv.getRowDimension(); i ++) { for (int j = 0; j < mInv.getColumnDimension(); j ++) { if (Math.abs(mInv.getEntry(i, j) - mT.getEntry(i, j)) > 1.0e-7){ return false; } } } return true; }
/** * Creates an instance. * * @param qr The result of the QR decomposition, not null */ public QRDecompositionCommonsResult(QRDecomposition qr) { ArgChecker.notNull(qr, "qr"); _q = CommonsMathWrapper.unwrap(qr.getQ()); _r = CommonsMathWrapper.unwrap(qr.getR()); _qTranspose = _q.transpose(); _solver = qr.getSolver(); }
@Override public QRDecompositionResult apply(DoubleMatrix x) { ArgChecker.notNull(x, "x"); RealMatrix temp = CommonsMathWrapper.wrap(x); QRDecomposition qr = new QRDecomposition(temp); return new QRDecompositionCommonsResult(qr); }
public PacioliTuple qrZeroSub() throws MVMException { // Collect the non-zero numbers NonZeroSubMatrix sub = new NonZeroSubMatrix(numbers); // Do the QR decomposition on the non-zero numbers. QRDecomposition decomposition = new QRDecomposition(sub.numbers); RealMatrix numbersQ = decomposition.getQ(); RealMatrix numbersR = decomposition.getR(); Pacioli.logln("mat=%s", sub.numbers.toString()); // Create the full result matrices Matrix matrixQ = new Matrix(shape.leftIdentity()); Matrix matrixR = new Matrix(shape); // Fill the result matrices from the decomposition result for (int i = 0; i < sub.numbers.getRowDimension(); i++) { for (int j = 0; j < sub.numbers.getRowDimension(); j++) { matrixQ.numbers.setEntry(sub.originalRow(i), sub.originalRow(j), numbersQ.getEntry(i, j)); } } for (int i = 0; i < sub.numbers.getRowDimension(); i++) { for (int j = 0; j < sub.numbers.getColumnDimension(); j++) { matrixR.numbers.setEntry(sub.originalRow(i), sub.originalColumn(j), numbersR.getEntry(i, j)); } } // Return a tuple with the result matrices List<PacioliValue> items = new ArrayList<PacioliValue>(); items.add(matrixQ); items.add(matrixR); return new PacioliTuple(items); }
/** * Find a solution of the linear equation A x = b where * <ul> * <li>A is an n x m - matrix given as double[n][m]</li> * <li>b is an m - vector given as double[m],</li> * <li>x is an n - vector given as double[n],</li> * </ul> * * @param A The matrix (left hand side of the linear equation). * @param b The vector (right hand of the linear equation). * @return A solution x to A x = b. */ public static double[] solveLinearEquation(double[][] A, double[] b) { if(isSolverUseApacheCommonsMath) { Array2DRowRealMatrix matrix = new Array2DRowRealMatrix(A); DecompositionSolver solver; if(matrix.getColumnDimension() == matrix.getRowDimension()) { solver = new LUDecomposition(matrix).getSolver(); } else { solver = new QRDecomposition(new Array2DRowRealMatrix(A)).getSolver(); } // Using SVD - very slow // solver = new SingularValueDecomposition(new Array2DRowRealMatrix(A)).getSolver(); return solver.solve(new Array2DRowRealMatrix(b)).getColumn(0); } else { return org.jblas.Solve.solve(new org.jblas.DoubleMatrix(A), new org.jblas.DoubleMatrix(b)).data; // For use of colt: // cern.colt.matrix.linalg.Algebra linearAlgebra = new cern.colt.matrix.linalg.Algebra(); // return linearAlgebra.solve(new DenseDoubleMatrix2D(A), linearAlgebra.transpose(new DenseDoubleMatrix2D(new double[][] { b }))).viewColumn(0).toArray(); // For use of parallel colt: // return new cern.colt.matrix.tdouble.algo.decomposition.DenseDoubleLUDecomposition(new cern.colt.matrix.tdouble.impl.DenseDoubleMatrix2D(A)).solve(new cern.colt.matrix.tdouble.impl.DenseDoubleMatrix1D(b)).toArray(); } }
/** * Constructor * @param matrix the input matrix */ XQRD(RealMatrix matrix) { this.qrd = new QRDecomposition(matrix); this.q = LazyValue.of(() -> toDataFrame(qrd.getQ())); this.r = LazyValue.of(() -> toDataFrame(qrd.getR())); }
/** Initialize the high order scaled derivatives at step start. * @param h step size to use for scaling * @param t first steps times * @param y first steps states * @param yDot first steps derivatives * @return Nordieck vector at start of first step (h<sup>2</sup>/2 y''<sub>n</sub>, * h<sup>3</sup>/6 y'''<sub>n</sub> ... h<sup>k</sup>/k! y<sup>(k)</sup><sub>n</sub>) */ public Array2DRowRealMatrix initializeHighOrderDerivatives(final double h, final double[] t, final double[][] y, final double[][] yDot) { // using Taylor series with di = ti - t0, we get: // y(ti) - y(t0) - di y'(t0) = di^2 / h^2 s2 + ... + di^k / h^k sk + O(h^k) // y'(ti) - y'(t0) = 2 di / h^2 s2 + ... + k di^(k-1) / h^k sk + O(h^(k-1)) // we write these relations for i = 1 to i= 1+n/2 as a set of n + 2 linear // equations depending on the Nordsieck vector [s2 ... sk rk], so s2 to sk correspond // to the appropriately truncated Taylor expansion, and rk is the Taylor remainder. // The goal is to have s2 to sk as accurate as possible considering the fact the sum is // truncated and we don't want the error terms to be included in s2 ... sk, so we need // to solve also for the remainder final double[][] a = new double[c1.length + 1][c1.length + 1]; final double[][] b = new double[c1.length + 1][y[0].length]; final double[] y0 = y[0]; final double[] yDot0 = yDot[0]; for (int i = 1; i < y.length; ++i) { final double di = t[i] - t[0]; final double ratio = di / h; double dikM1Ohk = 1 / h; // linear coefficients of equations // y(ti) - y(t0) - di y'(t0) and y'(ti) - y'(t0) final double[] aI = a[2 * i - 2]; final double[] aDotI = (2 * i - 1) < a.length ? a[2 * i - 1] : null; for (int j = 0; j < aI.length; ++j) { dikM1Ohk *= ratio; aI[j] = di * dikM1Ohk; if (aDotI != null) { aDotI[j] = (j + 2) * dikM1Ohk; } } // expected value of the previous equations final double[] yI = y[i]; final double[] yDotI = yDot[i]; final double[] bI = b[2 * i - 2]; final double[] bDotI = (2 * i - 1) < b.length ? b[2 * i - 1] : null; for (int j = 0; j < yI.length; ++j) { bI[j] = yI[j] - y0[j] - di * yDot0[j]; if (bDotI != null) { bDotI[j] = yDotI[j] - yDot0[j]; } } } // solve the linear system to get the best estimate of the Nordsieck vector [s2 ... sk], // with the additional terms s(k+1) and c grabbing the parts after the truncated Taylor expansion final QRDecomposition decomposition = new QRDecomposition(new Array2DRowRealMatrix(a, false)); final RealMatrix x = decomposition.getSolver().solve(new Array2DRowRealMatrix(b, false)); // extract just the Nordsieck vector [s2 ... sk] final Array2DRowRealMatrix truncatedX = new Array2DRowRealMatrix(x.getRowDimension() - 1, x.getColumnDimension()); for (int i = 0; i < truncatedX.getRowDimension(); ++i) { for (int j = 0; j < truncatedX.getColumnDimension(); ++j) { truncatedX.setEntry(i, j, x.getEntry(i, j)); } } return truncatedX; }
/** * {@inheritDoc} * <p>This implementation computes and caches the QR decomposition of the X matrix.</p> */ @Override public void newSampleData(double[] data, int nobs, int nvars) { super.newSampleData(data, nobs, nvars); qr = new QRDecomposition(getX(), threshold); }
/** * {@inheritDoc} * <p>This implementation computes and caches the QR decomposition of the X matrix * once it is successfully loaded.</p> */ @Override protected void newXSampleData(double[][] x) { super.newXSampleData(x); qr = new QRDecomposition(getX(), threshold); }
/** * {@inheritDoc} * <p>This implementation computes and caches the QR decomposition of the X matrix.</p> */ @Override public void newSampleData(double[] data, int nobs, int nvars) { super.newSampleData(data, nobs, nvars); qr = new QRDecomposition(getX()); }
/** * {@inheritDoc} * <p>This implementation computes and caches the QR decomposition of the X matrix * once it is successfully loaded.</p> */ @Override protected void newXSampleData(double[][] x) { super.newXSampleData(x); qr = new QRDecomposition(getX()); }
public PacioliTuple qr() throws MVMException { Matrix matrixQ = new Matrix(shape.leftIdentity()); Matrix matrixR = new Matrix(shape); QRDecomposition decomposition = new QRDecomposition(numbers); matrixQ.numbers = decomposition.getQ(); matrixR.numbers = decomposition.getR(); List<PacioliValue> items = new ArrayList<PacioliValue>(); items.add(matrixQ); items.add(matrixR); return new PacioliTuple(items); }