/// <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 Double[,] Solve(Double[,] b) { var k = Restart; var x = default(Double[, ]); var converged = false; var c = new Double[k - 1]; var s = new Double[k - 1]; var gamma = new Double[k + 1]; var iter = 0; if (Guess == null) { Guess = new Double[b.GetLength(0), b.GetLength(1)]; } if (Guess.GetLength(0) != b.GetLength(0) || Guess.GetLength(1) != b.GetLength(1)) { throw new InvalidOperationException(ErrorMessages.DimensionMismatch); } var H = new Double[k + 1, k]; var V = new Double[Guess.GetLength(0), k]; do { var j = 0; x = (Double[, ])Guess.Clone(); var r0 = Helpers.Subtract(b, Helpers.Multiply(Matrix, x)); var beta = Helpers.Norm(r0); H.Initialize(); V.Initialize(); gamma.Initialize(); c.Initialize(); s.Initialize(); gamma[0] = beta; Helpers.SetColumnVector(V, 1, Helpers.Multiply(r0, 1.0 / beta)); if (beta < Tolerance) { break; } do { iter++; var Avj = Helpers.Multiply(Matrix, Helpers.GetColumnVector(V, j)); var sum = new Double[Avj.GetLength(0), Avj.GetLength(1)]; for (var m = 0; m <= j; m++) { var w = Helpers.GetColumnVector(V, m); H[m, j] = Helpers.Reduce(w, Avj); sum = Helpers.AddScaled(sum, H[m, j], w); } var wj = Helpers.Subtract(Avj, sum); H[j + 1, j] = Helpers.Reduce(wj, wj); Rotate(j, H, c, s, gamma); if (Math.Abs(H[j + 1, j]) == 0.0) { j++; converged = true; break; } Helpers.SetColumnVector(V, j + 1, Helpers.Multiply(wj, 1.0 / H[j + 1, j])); beta = Math.Abs(gamma[j]); if (beta < Tolerance) { j++; converged = true; break; } j++; }while (j < k); var y = new Double[j]; for (var l = j; l >= 1; l--) { var sum = 0.0; 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 = 0; l < j; l++) { x = Helpers.AddScaled(x, y[l], Helpers.GetColumnVector(V, l)); } if (converged) { break; } Guess = x; }while (iter < MaxIterations); return(x); }