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];
                }
            }
        }
示例#3
0
        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;
            }
        }