public Vector SOR(Vector rhs, double tol)
{
if (rhs.Count != size()) throw new ApplicationException("rhs has the wrong size");
// initial guess
Vector result = (Vector)rhs.Clone();
// solve tridiagonal system with SOR technique
double omega = 1.5;
double err = 2.0 * tol;
double temp;
int i;
for (int sorIteration = 0; err > tol; sorIteration++) {
if (!(sorIteration < 100000))
throw new ApplicationException("tolerance (" + tol + ") not reached in " + sorIteration + " iterations. "
+ "The error still is " + err);
temp = omega * (rhs[0] -
upperDiagonal_[0] * result[1] -
diagonal_[0] * result[0]) / diagonal_[0];
err = temp * temp;
result[0] += temp;
for (i = 1; i < size() - 1; i++) {
temp = omega * (rhs[i] -
upperDiagonal_[i] * result[i + 1] -
diagonal_[i] * result[i] -
lowerDiagonal_[i - 1] * result[i - 1]) / diagonal_[i];
err += temp * temp;
result[i] += temp;
}
temp = omega * (rhs[i] -
diagonal_[i] * result[i] -
lowerDiagonal_[i - 1] * result[i - 1]) / diagonal_[i];
err += temp * temp;
result[i] += temp;
}
return result;
}