/// <summary> /// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized. /// </summary> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param> public override void Solve(Matrix <Complex> input, Matrix <Complex> result) { // Check for proper arguments. if (input == null) { throw new ArgumentNullException("input"); } if (result == null) { throw new ArgumentNullException("result"); } // The solution X should have the same number of columns as B if (input.ColumnCount != result.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); } // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows if (MatrixQ.RowCount != input.RowCount) { throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); } // The solution X row dimension is equal to the column dimension of A if (MatrixQ.ColumnCount != result.RowCount) { throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); } var inputCopy = input.Clone(); // Compute Y = transpose(Q)*B var column = new Complex[MatrixQ.RowCount]; for (var j = 0; j < input.ColumnCount; j++) { for (var k = 0; k < MatrixQ.RowCount; k++) { column[k] = inputCopy.At(k, j); } for (var i = 0; i < MatrixQ.ColumnCount; i++) { var s = Complex.Zero; for (var k = 0; k < MatrixQ.RowCount; k++) { s += MatrixQ.At(k, i).Conjugate() * column[k]; } inputCopy.At(i, j, s); } } // Solve R*X = Y; for (var k = MatrixQ.ColumnCount - 1; k >= 0; k--) { for (var j = 0; j < input.ColumnCount; j++) { inputCopy.At(k, j, inputCopy.At(k, j) / MatrixR.At(k, k)); } for (var i = 0; i < k; i++) { for (var j = 0; j < input.ColumnCount; j++) { inputCopy.At(i, j, inputCopy.At(i, j) - (inputCopy.At(k, j) * MatrixR.At(i, k))); } } } for (var i = 0; i < MatrixR.ColumnCount; i++) { for (var j = 0; j < input.ColumnCount; j++) { result.At(i, j, inputCopy.At(i, j)); } } }
/// <summary> /// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized. /// </summary> /// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param> public override void Solve(Vector <double> input, Vector <double> result) { if (input == null) { throw new ArgumentNullException("input"); } if (result == null) { throw new ArgumentNullException("result"); } // Ax=b where A is an m x n matrix // Check that b is a column vector with m entries if (MatrixQ.RowCount != input.Count) { throw new ArgumentException(Resources.ArgumentVectorsSameLength); } // Check that x is a column vector with n entries if (MatrixQ.ColumnCount != result.Count) { throw Matrix.DimensionsDontMatch <ArgumentException>(MatrixQ, result); } var inputCopy = input.Clone(); // Compute Y = transpose(Q)*B var column = new double[MatrixQ.RowCount]; for (var k = 0; k < MatrixQ.RowCount; k++) { column[k] = inputCopy[k]; } for (var i = 0; i < MatrixQ.ColumnCount; i++) { double s = 0; for (var k = 0; k < MatrixQ.RowCount; k++) { s += MatrixQ.At(k, i) * column[k]; } inputCopy[i] = s; } // Solve R*X = Y; for (var k = MatrixQ.ColumnCount - 1; k >= 0; k--) { inputCopy[k] /= MatrixR.At(k, k); for (var i = 0; i < k; i++) { inputCopy[i] -= inputCopy[k] * MatrixR.At(i, k); } } for (var i = 0; i < MatrixR.ColumnCount; i++) { result[i] = inputCopy[i]; } }