private void ssor(IDenseRowColumnAccessMatrix A, double[] xdata) { int n = A.RowCount; IntDoubleVectorPair Amat = A.Matrix; // M = (D+L) D^{-1} (D+L)^T // Solves (1/omega)*(D+L) y = b for (int i = 0; i < n; ++i) { // Do nothing if we get a divide by zero if (Math.Abs(diag[i]) == 0.0) { continue; } double sum = 0; for (int j = Amat.indices[i], k = 0; j < diagInd[i]; ++j, ++k) { sum += Amat.data[j] * xdata[k]; } xdata[i] = (omega / diag[i]) * (xdata[i] - sum); } // Solves (omega/(2-omega))*D^{-1} z = y for (int i = 0; i < n; ++i) { // No need to do anything if (Math.Abs(diag[i]) == 0.0) { continue; } xdata[i] = (2 - omega) / omega * diag[i] * xdata[i]; } // Solves (1/omega)*(D+L)^T x = z for (int i = n - 1; i >= 0; --i) { // Do nothing if we get a divide by zero if (Math.Abs(diag[i]) == 0.0) { continue; } double sum = 0; for (int j = diagInd[i] + 1, k = i + 1; j < n; ++j, ++k) { sum += Amat.data[j] * xdata[k]; } xdata[i] = (omega / diag[i]) * (xdata[i] - sum); } }
private void sor(IDenseRowColumnAccessMatrix A, double[] bdata, double[] xdata) { IntDoubleVectorPair Amat = A.Matrix; for (int i = 0; i < A.RowCount; ++i) { double newVal = 0, diagVal = 0.0; for (int j = Amat.indices[i], k = 0; j < Amat.indices[i + 1]; ++j, ++k) { if (k != i) { newVal += Amat.data[j] * xdata[k]; } else { diagVal = Amat.data[j]; } } newVal = (bdata[i] - newVal) / diagVal; xdata[i] += omega * (newVal - xdata[i]); } }