final int maxInt = 100000;
final double omega = 1.0;
final double[] invD = new double[_nNodesX];
for (int ii = 0; ii < _nNodesX; ii++) {
if (d[ii] == 0.0) {
throw new MathException("Cannot solve by PSOR - zero on diagonal");
}
invD[ii] = 1.0 / d[ii];
}
final int n = b.length;
double maxErr = 1.0;
int count = 0;
double temp;
for (int ii = 0; ii < n; ii++) {
x[ii] = Math.max(minVal[ii], x[ii]);
}
final double small = 1e-15;
while (count < maxInt && maxErr > 1e-8) {
temp = Math.max(minVal[0], (1 - omega) * x[0] + omega * invD[0] * (b[0] - u[0] * x[1]));
// errSqr = (temp - x[0]) * (temp - x[0]);
maxErr = Math.abs(temp - x[0]) / (Math.abs(x[0]) + small);
x[0] = temp;
for (int ii = 1; ii < n - 1; ii++) {
temp = Math.max(minVal[ii], (1 - omega) * x[ii] + omega * invD[ii] * (b[ii] - l[ii - 1] * x[ii - 1] - u[ii] * x[ii + 1]));
// errSqr += (temp - x[ii]) * (temp - x[ii]);
maxErr = Math.max(Math.abs(temp - x[ii]) / (Math.abs(x[ii]) + small), maxErr);
x[ii] = temp;
}
temp = Math.max(minVal[n - 1], (1 - omega) * x[n - 1] + omega * invD[n - 1] * (b[n - 1] - l[n - 2] * x[n - 2]));
maxErr = Math.max(Math.abs(temp - x[n - 1]) / (Math.abs(x[n - 1]) + small), maxErr);
//errSqr += (temp - x[n - 1]) * (temp - x[n - 1]);
x[n - 1] = temp;
// errSqr = Math.sqrt(errSqr);
count++;
}
if (count == maxInt) {
throw new MathException("PSOR failed to converge");
}
return x;
}