/// <summary> /// Solves the system of linear equations. /// </summary> /// <param name="b">The vector b in A * x = b.</param> /// <returns>The solution vector x.</returns> public override MatrixValue Solve(MatrixValue b) { var k = Restart; MatrixValue x; if (X0 == null) { X0 = new MatrixValue(b.DimensionY, b.DimensionX); } else if (X0.DimensionX != b.DimensionX || X0.DimensionY != b.DimensionY) { throw new YAMPDifferentDimensionsException(X0, b); } H = new MatrixValue(k + 1, k); V = new MatrixValue(X0.DimensionY, k); c = new MatrixValue(k - 1, 1); s = new MatrixValue(k - 1, 1); gamma = new MatrixValue(k + 1, 1); var converged = false; do { var j = 0; x = X0.Clone(); var r0 = b - A * x; var beta = r0.Abs().Re; H.Clear(); V.Clear(); gamma.Clear(); gamma[1] = new ScalarValue(beta); c.Clear(); s.Clear(); V.SetColumnVector(1, r0 / gamma[1]); if (beta < Tolerance) { break; } do { j++; i++; var Avj = A * V.GetColumnVector(j); var sum = new MatrixValue(Avj.DimensionY, Avj.DimensionX); for (var m = 1; m <= j; m++) { var w = V.GetColumnVector(m); H[m, j] = w.ComplexDot(Avj); sum += H[m, j] * w; } var wj = Avj - sum; H[j + 1, j] = wj.Abs(); Rotate(j); if (H[j + 1, j].AbsSquare() == 0.0) { converged = true; break; } V.SetColumnVector(j + 1, wj / H[j + 1, j]); beta = gamma[j + 1].Abs(); if (beta < Tolerance) { converged = true; break; } }while (j < k); var y = new MatrixValue(j, 1); for (int l = j; l >= 1; l--) { var sum = ScalarValue.Zero; for (var m = l + 1; m <= j; m++) { sum += H[l, m] * y[m]; } y[l] = (gamma[l] - sum) / H[l, l]; } for (var l = 1; l <= j; l++) { x += y[l] * V.GetColumnVector(l); } if (converged) { break; } X0 = x; }while (i < MaxIterations); return(x); }
/// <summary> /// Solves the system of linear equations. /// </summary> /// <param name="b">The vector b in A * x = b.</param> /// <returns>The solution vector x.</returns> public override MatrixValue Solve(MatrixValue b) { var k = Restart; MatrixValue x; if (X0 == null) { X0 = new MatrixValue(b.DimensionY, b.DimensionX); } else if (X0.DimensionX != b.DimensionX || X0.DimensionY != b.DimensionY) { throw new YAMPDifferentDimensionsException(X0, b); } H = new MatrixValue(k + 1, k); V = new MatrixValue(X0.DimensionY, k); c = new MatrixValue(k - 1, 1); s = new MatrixValue(k - 1, 1); gamma = new MatrixValue(k + 1, 1); var converged = false; do { var j = 0; x = X0.Clone(); var r0 = b - A * x; var beta = r0.Abs().Re; H.Clear(); V.Clear(); gamma.Clear(); gamma[1] = new ScalarValue(beta); c.Clear(); s.Clear(); V.SetColumnVector(1, r0 / gamma[1]); if (beta < Tolerance) { break; } do { j++; i++; var Avj = A * V.GetColumnVector(j); var sum = new MatrixValue(Avj.DimensionY, Avj.DimensionX); for (var m = 1; m <= j; m++) { var w = V.GetColumnVector(m); H[m, j] = w.ComplexDot(Avj); sum += H[m, j] * w; } var wj = Avj - sum; H[j + 1, j] = wj.Abs(); Rotate(j); if (H[j + 1, j].AbsSquare() == 0.0) { converged = true; break; } V.SetColumnVector(j + 1, wj / H[j + 1, j]); beta = gamma[j + 1].Abs(); if (beta < Tolerance) { converged = true; break; } } while (j < k); var y = new MatrixValue(j, 1); for (int l = j; l >= 1; l--) { var sum = ScalarValue.Zero; for (var m = l + 1; m <= j; m++) { sum += H[l, m] * y[m]; } y[l] = (gamma[l] - sum) / H[l, l]; } for (var l = 1; l <= j; l++) { x += y[l] * V.GetColumnVector(l); } if (converged) { break; } X0 = x; } while (i < MaxIterations); return x; }