/// <summary> /// Explicitly creates the matrix Q1, which consists of the first n columns of the orthogonal matrix Q that resulted /// from the factorization: A = Q * R = [Q1, Q2] * [R1; 0] (Matlab notation) = Q1 * R1, /// where A is m-by-n, Q is m-by-m, R is m-by-n, Q1 is m-by-n and R1 is (n-by-n). /// This method is safe to use as the factorization data are copied (if necessary). However, it is inefficient if the /// generated matrix is only used once. /// </summary> public Matrix GetEconomyFactorQ() { if (NumRows < NumColumns) { throw new NotImplementedException("For now, the number of rows must be >= the number of columns"); } int m = NumRows; int n = NumColumns; int k = NumColumns; int ldA = m; var matrixQ = new double[NumRows * NumColumns]; Array.Copy(reflectorsAndR, matrixQ, matrixQ.Length); // Call Lapack int numRowsQ = NumRows; int numColsQ = NumColumns; int numReflectors = NumColumns; int leadingDimQ = numRowsQ; LapackLeastSquares.Dorgqr(numRowsQ, numColsQ, numReflectors, matrixQ, 0, leadingDimQ, reflectorScalars, 0); return(Matrix.CreateFromArray(matrixQ, NumRows, NumColumns, false)); }
/// <summary> /// Explicitly creates the orthogonal matrix Q that resulted from the factorization: A = Q * R, where A is m-by-n, /// Q is m-by-m and R is m-by-n. /// This method is safe to use as the factorization data are copied (if necessary). However, it is inefficient if the /// generated matrix is only used once. /// </summary> public Matrix GetFactorQ() { if (NumRows < NumColumns) { throw new NotImplementedException("For now, the number of rows must be >= the number of columns"); } // We need a larger buffer for Q (m-by-m) > reflectorsAndR (m-by-p) double[] matrixQ = ArrayColMajor.ResizeCols(NumRows, NumColumns, NumRows, reflectorsAndR); // Call Lapack int numRowsQ = NumRows; int numColsQ = numRowsQ; int numReflectors = NumColumns; int leadingDimQ = numRowsQ; LapackLeastSquares.Dorgqr(numRowsQ, numColsQ, numReflectors, matrixQ, 0, leadingDimQ, reflectorScalars, 0); return(Matrix.CreateFromArray(matrixQ, NumRows, NumRows, false)); }