private void ssor(ISparseRowColumnAccessMatrix A, double[] xdata) { int n = A.RowCount; IntIntDoubleVectorTriple 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.minor[i]; j < Amat.minor[i + 1] && Amat.major[j] < i; ++j) { sum += Amat.data[j] * xdata[Amat.major[j]]; } 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; j < Amat.minor[i + 1]; ++j) { sum += Amat.data[j] * xdata[Amat.major[j]]; } xdata[i] = (omega / diag[i]) * (xdata[i] - sum); } }
private void sor(ISparseRowColumnAccessMatrix A, double[] bdata, double[] xdata) { IntIntDoubleVectorTriple Amat = A.Matrix; for (int i = 0; i < A.RowCount; ++i) { double newVal = 0, diagVal = 0.0; for (int j = Amat.minor[i]; j < Amat.minor[i + 1]; ++j) { if (Amat.major[j] != i) { newVal += Amat.data[j] * xdata[Amat.major[j]]; } else { diagVal = Amat.data[j]; } } newVal = (bdata[i] - newVal) / diagVal; xdata[i] += omega * (newVal - xdata[i]); } }
private void gaussSeidel(ISparseRowColumnAccessMatrix A, double[] bdat, double[] xdat) { IntIntDoubleVectorTriple Amat = A.Matrix; for (int i = 0; i < A.RowCount; ++i) { double newVal = 0, diagVal = 0.0; for (int j = Amat.minor[i]; j < Amat.minor[i + 1]; ++j) { if (Amat.major[j] != i) { newVal += Amat.data[j] * xdat[Amat.major[j]]; } else { diagVal = Amat.data[j]; } } xdat[i] = (bdat[i] - newVal) / diagVal; } }