/// <summary> /// Solves a system of linear equations, <b>AX = B</b>, with A SVD 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) { // 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 (EigenValues.Count != input.RowCount) { throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); } // The solution X row dimension is equal to the column dimension of A if (EigenValues.Count != result.RowCount) { throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); } if (IsSymmetric) { var order = EigenValues.Count; var tmp = new Complex[order]; for (var k = 0; k < order; k++) { for (var j = 0; j < order; j++) { Complex value = 0.0; if (j < order) { for (var i = 0; i < order; i++) { value += EigenVectors.At(i, j).Conjugate() * input.At(i, k); } value /= EigenValues[j].Real; } tmp[j] = value; } for (var j = 0; j < order; j++) { Complex value = 0.0; for (var i = 0; i < order; i++) { value += EigenVectors.At(j, i) * tmp[i]; } result.At(j, k, value); } } } else { throw new ArgumentException(Resources.ArgumentMatrixSymmetric); } }
/// <summary> /// Solves a system of linear equations, <b>AX = B</b>, with A SVD 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 <float> input, Matrix <float> result) { // The solution X should have the same number of columns as B if (input.ColumnCount != result.ColumnCount) { throw new ArgumentException("Matrix column dimensions must agree."); } // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows if (EigenValues.Count != input.RowCount) { throw new ArgumentException("Matrix row dimensions must agree."); } // The solution X row dimension is equal to the column dimension of A if (EigenValues.Count != result.RowCount) { throw new ArgumentException("Matrix column dimensions must agree."); } if (IsSymmetric) { var order = EigenValues.Count; var tmp = new float[order]; for (var k = 0; k < order; k++) { for (var j = 0; j < order; j++) { float value = 0; if (j < order) { for (var i = 0; i < order; i++) { value += EigenVectors.At(i, j) * input.At(i, k); } value /= (float)EigenValues[j].Real; } tmp[j] = value; } for (var j = 0; j < order; j++) { float value = 0; for (var i = 0; i < order; i++) { value += EigenVectors.At(j, i) * tmp[i]; } result.At(j, k, value); } } } else { throw new ArgumentException("Matrix must be symmetric."); } }
/// <summary> /// Solves a system of linear equations, <b>Ax = b</b>, with A EVD 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 <Complex> input, Vector <Complex> result) { // Ax=b where A is an m x m matrix // Check that b is a column vector with m entries if (EigenValues.Count != input.Count) { throw new ArgumentException(Resources.ArgumentVectorsSameLength); } // Check that x is a column vector with n entries if (EigenValues.Count != result.Count) { throw Matrix.DimensionsDontMatch <ArgumentException>(EigenValues, result); } if (IsSymmetric) { // Symmetric case -> x = V * inv(λ) * VH * b; var order = EigenValues.Count; var tmp = new Complex[order]; Complex value; for (var j = 0; j < order; j++) { value = 0; if (j < order) { for (var i = 0; i < order; i++) { value += EigenVectors.At(i, j).Conjugate() * input[i]; } value /= EigenValues[j].Real; } tmp[j] = value; } for (var j = 0; j < order; j++) { value = 0; for (int i = 0; i < order; i++) { value += EigenVectors.At(j, i) * tmp[i]; } result[j] = value; } } else { throw new ArgumentException(Resources.ArgumentMatrixSymmetric); } }
/// <summary> /// Solves a system of linear equations, <b>Ax = b</b>, with A EVD 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 <float> input, Vector <float> result) { // Ax=b where A is an m x m matrix // Check that b is a column vector with m entries if (EigenValues.Count != input.Count) { throw new ArgumentException("All vectors must have the same dimensionality."); } // Check that x is a column vector with n entries if (EigenValues.Count != result.Count) { throw new ArgumentException("Matrix dimensions must agree."); } if (IsSymmetric) { // Symmetric case -> x = V * inv(λ) * VT * b; var order = EigenValues.Count; var tmp = new float[order]; float value; for (var j = 0; j < order; j++) { value = 0; if (j < order) { for (var i = 0; i < order; i++) { value += EigenVectors.At(i, j) * input[i]; } value /= (float)EigenValues[j].Real; } tmp[j] = value; } for (var j = 0; j < order; j++) { value = 0; for (int i = 0; i < order; i++) { value += EigenVectors.At(j, i) * tmp[i]; } result[j] = value; } } else { throw new ArgumentException("Matrix must be symmetric."); } }