Пример #1
0
        public static void gaussj(MatDoub a)
        {
            // Overloaded version with no right-hand sides. Replaces a by its
            // inverse.
            MatDoub b = new MatDoub(a.nrows(), 0); // Dummy vector with zero columns.

            gaussj(a, b);
        }
Пример #2
0
 public static void printmatrix(MatDoub a)
 {
     for (int i = 0; i < a.nrows(); i++)
     {
         for (int j = 0; j < a.ncols(); j++)
         {
             System.Console.Write(a[i][j] + ",");
         }
         System.Console.WriteLine();
     }
     System.Console.WriteLine();
 }
Пример #3
0
        public static void fillMat(MatDoub a, Double[,] b)
        {
            int rows = a.nrows();

            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < rows; j++)
                {
                    a[i][j] = b[i, j];
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Constructor.  The single argument is A.  The SVD computation is done by
        /// decompose(), and the results are sorted by reorder().
        /// </summary>
        /// <param name="a">The matrix to decompose.</param>

        public SVD(MatDoub a)
        {
            m   = (a.nrows());
            n   = (a.ncols());
            u   = new MatDoub(a);
            v   = new MatDoub(n, n);
            w   = new VecDoub(n);
            eps = double.Epsilon;
            decompose();
            reorder();
            tsh = 0.5 * Math.Sqrt(m + n + 1.0) * w[0] * eps; // Default threshold for nonzero singular values;
        }
Пример #5
0
        /// <summary>
        /// Give an orthonormal basis for the nullspace of A as the columns of a returned matrix,
        /// after zeroing any singular values smaller than thresh.
        /// If thresh is negative, a default value based on estimated roundoff is used.
        /// </summary>
        /// <param name="thresh"></param>
        /// <returns></returns>

        //MatDoub nullspace(double thresh);
        public MatDoub nullspace(double thresh)
        {
            int     j, jj, nn = 0;
            MatDoub nullsp = new MatDoub(n, nullity(thresh));

            for (j = 0; j < n; j++)
            {
                if (w[j] <= tsh)
                {
                    for (jj = 0; jj < n; jj++)
                    {
                        nullsp[jj][nn] = v[jj][j];
                    }
                    nn++;
                }
            }
            return(nullsp);
        }
Пример #6
0
        /// <summary>
        /// Give an orthonormal basis for the range of A as the columns of a returned matrix,
        /// after zeroing any singular values smaller than thresh.
        /// If thresh is negative, a default value based on estimated roundoff is used.
        /// </summary>
        /// <param name="thresh"></param>
        /// <returns></returns>

        //MatDoub range(double thresh);
        public MatDoub range(double thresh)
        {
            int     i, j, nr = 0;
            MatDoub rnge = new MatDoub(m, rank(thresh));

            for (j = 0; j < n; j++)
            {
                if (w[j] > tsh)
                {
                    for (i = 0; i < m; i++)
                    {
                        rnge[i][nr] = u[i][j];
                    }
                    nr++;
                }
            }
            return(rnge);
        }
Пример #7
0
        public Sprsin(MatDoub a)//TODO: make a VecULong type to further save on space.
        {
            /************************************
            *  Converts a square matrix a[1..n][1..n] into row-indexed sparse storage mode.
            *  Only elements of a with magnitude ≥thresh are retained. Output is in two linear arrays
            *  with dimension nmax (an input parameter): sa[1..] contains array values, indexed by ija[1..].
            *  The number of elements filled of sa and ija on output are both ija[ija[1]-1]-1
            ************************************/
            sa  = new VecDoub(new double[nmax]);
            ija = new VecLong(18, new long[nmax], 0);
            n   = a.nrows();

            int i, j, k;

            for (j = 0; j < n; j++)
            {
                sa[j] = a[j][j]; //Store the diagonal elements.
            }
            ija[0] = n + 1;      //Index to the first off diagonal element if any.
            k      = n;

            for (i = 0; i < n; i++)
            {
                for (j = 0; j < n; j++)
                {
                    if (Math.Abs(a[i][j]) >= thresh && i != j)
                    {
                        if (++k > (int)nmax)
                        {
                            throw new Exception("sprsin: nmax too small");
                        }
                        sa[k]  = a[i][j]; //Store off diagonal elements.
                        ija[k] = j;       //And their column indices.
                    }
                }
                ija[i + 1] = k + 1; //As each row is completed, store index to next
            }
            this.numelements = k + 1;
        }
Пример #8
0
        /// <summary>
        /// Solve m sets of n equations AX=B using the pseudoinverse of A.
        /// The right-hand sides are input as b[0..n-1][0..m-1], while
        /// x[0..n-1][0..m-1] return the solutions.
        /// If positive, thresh is the threshold value below which singular values
        /// as considered to be zero.  If thresh is negative, a default based on rounodd error is used.
        /// </summary>
        /// <param name="b"></param>
        /// <param name="x"></param>
        /// <param name="thresh"></param>

        //void solve(MatDoub_I &b, MatDoub_O &x, double thresh);
        public void solve(MatDoub b, MatDoub x, double thresh)
        {
            int i, j, m = b.ncols();

            if (b.nrows() != n || x.nrows() != n || b.ncols() != x.ncols())
            {
                throw new Exception("SVD::solve bad sizes");
            }
            VecDoub xx = new VecDoub(n);

            for (j = 0; j < m; j++)
            {
                for (i = 0; i < n; i++)
                {
                    xx[i] = b[i][j];
                }
                solve(xx, xx, thresh);
                for (i = 0; i < n; i++)
                {
                    x[i][j] = xx[i];
                }
            }
        }
Пример #9
0
 public void solve(MatDoub b, MatDoub x)
 {
     solve(b, x, -1.0);
 }
Пример #10
0
        private bool sing;        // Indicates whether A is singular.

        public QRdcmp(MatDoub a)
        {
            n = a.nrows();
            MatDoub qt = new MatDoub(n, n);
            MatDoub r  = new MatDoub(a);

            sing = (false);
            int     i, j, k;
            VecDoub c = new VecDoub(n);
            VecDoub d = new VecDoub(n);
            double  scale, sigma, sum, tau;

            for (k = 0; k < n - 1; k++)
            {
                scale = 0.0;
                for (i = k; i < n; i++)
                {
                    scale = Math.Max(scale, Math.Abs(r[i][k]));
                }
                if (scale == 0.0)
                { // Singular case.
                    sing = true;
                    c[k] = d[k] = 0.0;
                }
                else
                { // Form Qk and Qk A.
                    for (i = k; i < n; i++)
                    {
                        r[i][k] /= scale;
                    }

                    for (sum = 0.0, i = k; i < n; i++)
                    {
                        sum += r[i][k] * r[i][k];
                    }

                    sigma    = NR.SIGN(Math.Sqrt(sum), r[k][k]);
                    r[k][k] += sigma;
                    c[k]     = sigma * r[k][k];
                    d[k]     = -scale * sigma;

                    for (j = k + 1; j < n; j++)
                    {
                        for (sum = 0.0, i = k; i < n; i++)
                        {
                            sum += r[i][k] * r[i][j];
                        }
                        tau = sum / c[k];
                        for (i = k; i < n; i++)
                        {
                            r[i][j] -= tau * r[i][k];
                        }
                    }
                }
            }
            d[n - 1] = r[n - 1][n - 1];
            if (d[n - 1] == 0.0)
            {
                sing = true;
            }

            ///////////////////////////
            for (i = 0; i < n; i++)
            { // Form QT explicitly.
                for (j = 0; j < n; j++)
                {
                    qt[i][j] = 0.0;
                }
                qt[i][i] = 1.0;
            }
            for (k = 0; k < n - 1; k++)
            {
                if (c[k] != 0.0)
                {
                    for (j = 0; j < n; j++)
                    {
                        sum = 0.0;
                        for (i = k; i < n; i++)
                        {
                            sum += r[i][k] * qt[i][j];
                        }
                        sum /= c[k];
                        for (i = k; i < n; i++)
                        {
                            qt[i][j] -= sum * r[i][k];
                        }
                    }
                }
            }
            for (i = 0; i < n; i++)
            { // Form R explicitly.
                r[i][i] = d[i];
                for (j = 0; j < i; j++)
                {
                    r[i][j] = 0.0;
                }
            }
        }
Пример #11
0
        public static void _Main(String[] args)
        {
            var array2D = new Double[, ]
            {
                { 3.0, 0.0, 1.0, 0.0, 0.0 },
                { 0.0, 4.0, 0.0, 0.0, 0.0 },
                { 0.0, 7.0, 5.0, 9.0, 0.0 },
                { 0.0, 0.0, 0.0, 0.0, 2.0 },
                { 0.0, 0.0, 0.0, 6.0, 5.0 }
            };

            MatDoub a = new MatDoub(5, 5);

            MatUtils.fillMat(a, array2D);
            MatUtils.printmatrix(a);

            MatDoub b = new MatDoub(5, 5);

            MatUtils.fillMat(b, array2D);
            MatUtils.fillMat(a, array2D);

            GaussJordan.gaussj(a, b);
            MatUtils.printmatrix(a);

            LUdcmp lu = new LUdcmp(a);

            MatDoub aInv = new MatDoub(5, 5);//A container for the inverse of a.

            lu.inverse(aInv);
            MatUtils.printmatrix(aInv);

            MatUtils.fillMat(a, array2D);
            Sprsin sprs = new Sprsin(a);

            System.Console.Write("\n###################\n Sparse matrix \n###################\n");
            for (int i = 0; i < sprs.numelements; i++)
            {
                System.Console.Write(sprs.sa[i] + (i + 1 < sprs.numelements ? "," : "\n"));
            }

            for (int i = 0; i < sprs.numelements; i++)
            {
                System.Console.Write(sprs.ija[i] + (i + 1 < sprs.numelements ? "," : "\n"));
            }

            //////////////////////////
            /// Now lets solve the system of linear equations.
            /////////////////////////
            VecDoub b1   = new VecDoub(new double[] { 1, 1, 1, 1, 1 });
            VecDoub x1   = new VecDoub(new double[] { 0.14, 0.3, 0.5, -0.25, 0.7 });
            int     iter = 0;
            double  err  = 0;

            System.Console.Write("\n###################\n Solution of sparse system \n###################\n");
            sprs.linbcg(b1, x1, 1, 1e-4d, 30, ref iter, ref err);

            for (int i = 0; i < 5; i++)
            {
                System.Console.Write(x1[i] + (i + 1 < 5 ? "," : "\n"));
            }

            //////////////////////////
            /// Vandermonde matrices.
            /////////////////////////
            System.Console.Write("\n###################\n Vandermonde matrices \n###################\n");
            VecDoub x_v = new VecDoub(new double[] { 2, 3, 5 });

            double[] w = new double[] { 1, 1, 1 };
            double[] q = new double[] { 1, 1, 1 };

            Vander va = new Vander(x_v, w, q);

            for (int i = 0; i < w.Length; i++)
            {
                System.Console.Write(w[i] + (i + 1 < w.Length?",":"\n"));
            }

            //////////////////////////
            /// Toeplitz matrices.
            /////////////////////////
            System.Console.Write("\n###################\n Toeplitz matrices \n###################\n");
            VecDoub x_t = new VecDoub(new double[] { 1.3, 2, 3.7, 4, 5.2 });

            Toeplitz to = new Toeplitz(x_t, w, q);

            for (int i = 0; i < w.Length; i++)
            {
                System.Console.Write(w[i] + (i + 1 < w.Length ? "," : "\n"));
            }

            System.Console.WriteLine("End");
            System.Console.Read();
        }
Пример #12
0
        public static void gaussj(MatDoub a, MatDoub b)
        {
            // Linear equation solution by Gauss-Jordan elimination,
            // equation (2.1.1) above. The input matrix is a[0..n-1][0..n-1].
            // b[0..n-1][0..m-1] is input containing the m right-hand side vectors.
            // On output, a is replaced by its matrix inverse, and b is replaced by
            // the corresponding set of solution vectors.
            int    i, icol = 0, irow = 0, j, k, l, ll, n = a.nrows(), m = a.ncols();
            double big, dum, pivinv;
            VecInt indxc = new VecInt(n);
            VecInt indxr = new VecInt(n);
            VecInt ipiv  = new VecInt(n); // These integer arrays are used

            // for bookkeeping on the pivoting.
            for (j = 0; j < n; j++)
            {
                ipiv[j] = 0;
            }
            for (i = 0; i < n; i++) // This is the main loop over the columns to
                                    // be
            {
                big = 0.0;          // reduced.
                for (j = 0; j < n; j++)
                {
                    // This is the outer loop of the search for a pivot over the entire matrix!
                    if (ipiv[j] != 1) // element.
                    {
                        for (k = 0; k < n; k++)
                        {
                            if (ipiv[k] == 0)
                            {
                                if (Math.Abs(a[j][k]) >= big)
                                {
                                    big  = Math.Abs(a[j][k]);
                                    irow = j;
                                    icol = k;
                                }
                            }
                        }
                    }
                }
                ++(ipiv[icol]);
                // We now have the pivot element, so we interchange rows, if needed,
                // to put the pivot element on the diagonal. The columns are not
                // physically interchanged, only relabeled: indxc[i], the column of the .iC1/th
                // pivot element, is the .iC1/th column that is reduced, while indxr[i] is
                // the row in which that pivot element was originally located.
                // If indxr[i] indxc[i], there is an implied column interchange.
                // With this form of bookkeeping, the solution bs will end up in the
                // correct order, and the inverse matrix will be scrambled by columns.
                if (irow != icol)
                {
                    for (l = 0; l < n; l++)
                    {
                        NR.SWAP(a, irow, l, icol, l);
                    }
                    for (l = 0; l < m; l++)
                    {
                        NR.SWAP(b, irow, l, icol, l);
                    }
                }
                indxr[i] = irow; // We are now ready to divide the pivot row by the
                // pivot element, located at irow and icol.
                indxc[i] = icol;
                if (a[icol][icol] == 0.0)
                {
                    throw new Exception("gaussj: Singular Matrix");
                }
                pivinv        = 1.0 / a[icol][icol];
                a[icol][icol] = 1.0;
                for (l = 0; l < n; l++)
                {
                    a[icol][l] *= pivinv;
                }
                for (l = 0; l < m; l++)
                {
                    b[icol][l] *= pivinv;
                }
                for (ll = 0; ll < n; ll++)
                {
                    // Next, we reduce the rows...
                    if (ll != icol)
                    { // ...except for the pivot one, of course.
                        dum         = a[ll][icol];
                        a[ll][icol] = 0.0;
                        for (l = 0; l < n; l++)
                        {
                            a[ll][l] -= a[icol][l] * dum;
                        }
                        for (l = 0; l < m; l++)
                        {
                            b[ll][l] -= b[icol][l] * dum;
                        }
                    }
                }
            }
            // This is the end of the main loop over columns of the reduction. It
            // only remains to unscramble the solution in view of the column
            // interchanges. We do this by interchanging pairs of columns in the
            // reverse order that the permutation was built up.
            for (l = n - 1; l >= 0; l--)
            {
                if (indxr[l] != indxc[l])
                {
                    for (k = 0; k < n; k++)
                    {
                        NR.SWAP(a, k, indxr[l], k, indxc[l]);
                    }
                }
            }
        }