private void ssor(ISparseRowAccessMatrix A, double[] xdata) { int n = A.RowCount; // 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; } IntDoubleVectorPair Arow = A.GetRow(i); double[] Adat = Arow.data; int[] Aind = Arow.indices; double sum = 0; for (int j = 0; j < Aind.Length && Aind[j] < i; ++j) { sum += Adat[j] * xdata[Aind[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; } IntDoubleVectorPair Arow = A.GetRow(i); double[] Adat = Arow.data; int[] Aind = Arow.indices; double sum = 0; for (int j = diagInd[i] + 1; j < Aind.Length; ++j) { sum += Adat[j] * xdata[Aind[j]]; } xdata[i] = (omega / diag[i]) * (xdata[i] - sum); } }
/// <summary> F is lower-triangular, and it is solved for.</summary> /// <param name="data">Initially the right hand side. Overwritten with solution.</param> /// <param name="diagDiv">True if the diagonal will be divided with.</param> protected internal virtual void solveL(double[] data, bool diagDiv) { for (int i = 0; i < F.RowCount; ++i) { IntDoubleVectorPair cur = F.GetRow(i); int[] curInd = cur.indices; double[] curDat = cur.data; double sum = 0; int j = 0; for (; curInd[j] < i; ++j) { sum += curDat[j] * data[curInd[j]]; } data[i] -= sum; // Divide by diagonal. The factorization guarantees its existence if (diagDiv) { data[i] /= curDat[j]; } } }
private void sor(ISparseRowAccessMatrix A, double[] bdata, double[] xdata) { for (int i = 0; i < A.RowCount; ++i) { IntDoubleVectorPair Arow = A.GetRow(i); double newVal = 0, diagVal = 0.0; for (int j = 0; j < Arow.indices.Length; ++j) { if (Arow.indices[j] != i) { newVal += Arow.data[j] * xdata[Arow.indices[j]]; } else { diagVal = Arow.data[j]; } } newVal = (bdata[i] - newVal) / diagVal; xdata[i] += omega * (newVal - xdata[i]); } }
private void gaussSeidel(ISparseRowAccessMatrix A, double[] bdat, double[] xdat) { for (int i = 0; i < A.RowCount; ++i) { IntDoubleVectorPair Arow = A.GetRow(i); int[] ArowInd = Arow.indices; double[] ArowDat = Arow.data; double newVal = 0, diagVal = 0.0; for (int j = 0; j < ArowInd.Length; ++j) { if (ArowInd[j] != i) { newVal += ArowDat[j] * xdat[ArowInd[j]]; } else { diagVal = ArowDat[j]; } } xdat[i] = (bdat[i] - newVal) / diagVal; } }