/// <summary> /// Explicitly creates the orthogonal matrix Q that resulted from the factorization: A = L * Q, where A is m-by-n, /// L is m-by-n and Q 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 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 (n-by-n) > reflectorsAndL (p-by-n) double[] matrixQ = ArrayColMajor.IncreaseRows(NumRows, NumColumns, NumColumns, reflectorsAndL); // Call LAPACK int numColsQ = NumColumns; int numRowsQ = numColsQ; int numReflectors = NumRows; int leadingDimQ = numRowsQ; LapackLeastSquares.Dorglq(numRowsQ, numColsQ, numReflectors, matrixQ, 0, leadingDimQ, reflectorScalars, 0); return(Matrix.CreateFromArray(matrixQ, NumColumns, 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)); }