/// <summary> /// Solve the system A x = b. /// </summary> /// <param name="rhs">The right-hand-side b.</param> /// <returns>The column vector x for which A x is closest to b.</returns> public ColumnVector Solve(IReadOnlyList <double> rhs) { if (rhs == null) { throw new ArgumentNullException(nameof(rhs)); } if (rhs.Count != rows) { throw new DimensionMismatchException(); } // BLAS requires an array, but doesn't modify it, so if given one, use it directly double[] x = rhs as double[]; if (x == null) { x = new double[rows]; rhs.CopyTo(x, 0); } // Q^T x is a row-length vector, but we only need the first cols entries // so truncate Q^T to cols X rows, so that Q^T x is only of length cols double[] y = new double[cols]; Blas2.dGemv(qtStore, 0, 1, rows, x, 0, 1, y, 0, 1, cols, rows); MatrixAlgorithms.SolveUpperRightTriangular(rStore, rows, cols, y, 0); return(new ColumnVector(y, cols)); }
/// <summary> /// Solve the system A x = b. /// </summary> /// <param name="rhs">The right-hand-side b.</param> /// <returns>The column vector x for which A x is closest to b.</returns> public ColumnVector Solve(IList <double> rhs) { if (rhs == null) { throw new ArgumentNullException(nameof(rhs)); } if (rhs.Count != rows) { throw new DimensionMismatchException(); } // copy rhs into an array, if necessary double[] x; if (rhs is double[]) { x = (double[])rhs; } else { x = new double[rows]; rhs.CopyTo(x, 0); } // Q^T x is a row-length vector, but we only need the first cols entries // so truncate Q^T to cols X rows, so that Q^T x is only of length cols double[] y = new double[cols]; Blas2.dGemv(qtStore, 0, 1, rows, x, 0, 1, y, 0, 1, cols, rows); MatrixAlgorithms.SolveUpperRightTriangular(rStore, rows, cols, y, 0); return(new ColumnVector(y, cols)); }