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;
}