Пример #1
0
        public override void Setup(IMatrix A)
        {
            int n = A.RowCount;

            diag    = new double[n];
            diagInd = new int[n];

            // Get the diagonal and its indices
            if (A is ISparseRowAccessMatrix)
            {
                for (int i = 0; i < n; ++i)
                {
                    IntDoubleVectorPair Arow = ((ISparseRowAccessMatrix)A).GetRow(i);
                    int ind = Array.BinarySearch(Arow.indices, i);
                    if (ind < 0)
                    {
                        throw new ArgumentException("Diagonal not present");
                    }
                    diag[i]    = Arow.data[ind];
                    diagInd[i] = ind;
                }
            }
            else if (A is ISparseRowColumnAccessMatrix)
            {
                IntIntDoubleVectorTriple Amat = ((ISparseRowColumnAccessMatrix)A).Matrix;
                for (int i = 0; i < n; ++i)
                {
                    int ind = Arrays.binarySearch(Amat.major, i, Amat.minor[i], Amat.minor[i + 1]);
                    if (ind < 0)
                    {
                        throw new ArgumentException("Diagonal not present");
                    }
                    diag[i]    = Amat.data[ind];
                    diagInd[i] = ind;
                }
            }
            else if (A is IDenseRowColumnAccessMatrix)
            {
                IntDoubleVectorPair Amat = ((IDenseRowColumnAccessMatrix)A).Matrix;
                for (int i = 0; i < n; ++i)
                {
                    diagInd[i] = Amat.indices[i] + i;
                    diag[i]    = Amat.data[diagInd[i]];
                }
            }
            else if (A is IDenseRowAccessMatrix)
            {
                for (int i = 0; i < n; ++i)
                {
                    double[] Arow = ((IDenseRowAccessMatrix)A).GetRow(i);
                    diagInd[i] = i;
                    diag[i]    = Arow[i];
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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;
            }
        }