Exemple #1
0
        private double snrm(int n, VecDoub sx, int itol)
        {
            /*****************************
             * Compute one of two norms for a vector sx[1..n] as signaled by itol. Used by linbcg.
             ****************************/
            int    isamax;
            int    i;
            double ans;

            if (itol <= 3)
            {
                ans = 0.0;
                for (i = 0; i < n; i++)
                {
                    ans += sx[i] * sx[i]; //Vector magnitude norm.
                }
                return(Math.Sqrt(ans));
            }
            else
            {
                isamax = 1;
                for (i = 0; i < n; i++)
                { //Largest component norm
                    if (Math.Abs(sx[i]) > Math.Abs(sx[isamax]))
                    {
                        isamax = i;
                    }
                }
                return(Math.Abs(sx[isamax]));
            }
        }
Exemple #2
0
        /// <summary>
        /// Solve Ax = b for a vector x using the psudoinverse of A as obtained by SVD.
        /// If positive, thresh is the threshold value below which singular values
        /// as considered to be zero.  If thresh is negative, a default based on roundoff error is used.
        /// </summary>
        /// <param name="b"></param>
        /// <param name="x"></param>
        /// <param name="thresh"></param>

        //void solve(VecDoub_I &b, VecDoub_O &x, double thresh);
        public void solve(VecDoub b, VecDoub x, double thresh)
        {
            int    i, j, jj;
            double s;

            if (b.size() != m || x.size() != n)
            {
                throw new Exception("SVD::solve bad sizes");
            }
            VecDoub tmp = new VecDoub(n);

            tsh = (thresh >= 0.0 ? thresh : 0.5 * Math.Sqrt(m + n + 1.0) * w[0] * eps);
            for (j = 0; j < n; j++)
            {
                s = 0.0;
                if (w[j] > tsh)
                {
                    for (i = 0; i < m; i++)
                    {
                        s += u[i][j] * b[i];
                    }
                    s /= w[j];
                }
                tmp[j] = s;
            }
            for (j = 0; j < n; j++)
            {
                s = 0.0;
                for (jj = 0; jj < n; jj++)
                {
                    s += v[j][jj] * tmp[jj];
                }
                x[j] = s;
            }
        }
Exemple #3
0
        private void asolve(int n, VecDoub b, VecDoub x, int itrnsp)
        {
            int i;

            for (i = 0; i < n; i++)
            {
                x[i] = (sa[i] != 0.0 ? b[i] / sa[i] : b[i]); //The matrix A is the diagonal part of A,
            }
            //stored in the first n elements of sa. Since the transpose matrix has the same diagonal, the flag itrnsp is not used.
        }
Exemple #4
0
 private void atimes(int n, VecDoub x, VecDoub r, int itrnsp)
 {
     if (itrnsp > 0)
     {
         sprstx(sa, ija, x, r, n);
     }
     else
     {
         sprsax(sa, ija, x, r, n);
     }
 }
Exemple #5
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;
        }
Exemple #6
0
        //For theory see 31st Jan notes
        public Vander(VecDoub x, double[] w, double[] q)
        {
            // Solves the Vandermonde linear system PN1
            // iD0 xk i wi D qk .k D 0; : : : ; N  1/. Input consists
            // of the vectors x[0..n-1] and q[0..n-1]; the vector w[0..n-1] is output.
            int     i, j, k, n = q.Length;
            double  b, s, t, xx;
            VecDoub c = new VecDoub(n);

            if (n == 1)
            {
                w[0] = q[0];
            }
            else
            {
                for (i = 0; i < n; i++)
                {
                    c[i] = 0.0;   // Initialize array.
                }
                c[n - 1] = -x[0]; // Coefficients of the master polynomial are found.
                for (i = 1; i < n; i++)
                {                 // by recursion.
                    xx = -x[i];
                    for (j = (n - 1 - i); j < (n - 1); j++)
                    {
                        c[j] += xx * c[j + 1];
                    }
                    c[n - 1] += xx;
                }
                for (i = 0; i < n; i++)
                { // Each subfactor in turn
                    xx = x[i];
                    t  = b = 1.0;
                    s  = q[n - 1];
                    for (k = n - 1; k > 0; k--)
                    {                       // Is synthetically divided.
                        b  = c[k] + xx * b; //This is just the synthetic division formula.
                        s += q[k - 1] * b;  // Matrix-multiplied by the right-hand side.
                        t  = xx * t + b;
                    }
                    w[i] = s / t; // and supplied with a denominator.
                }
            }
        }
Exemple #7
0
        private void sprsax(VecDoub sa, VecLong ija, VecDoub x, VecDoub b, int n)
        {
            if (ija[1] != n + 2)
            {
                new Exception("sprsax: mismatched vector and matrix");
            }
            int  i;
            long k;

            for (i = 0; i < n; i++)
            {
                b[i] = sa[i] * x[i];                          //Diagonal entries
                for (k = ija[i]; k <= ija[i + 1] - 1; k++)    //TODO: Verify this.
                {
                    b[i] += sa[(int)k] * x[(int)ija[(int)k]]; //Off diagonal entries. Multiply the entry of the matrix by the x of the corresponding column.
                }
                //TODO: Find out how to reference arrays in C# with some thing that could be > 2 billion (max value of integer).
            }
        }
Exemple #8
0
        private void sprstx(VecDoub sa, VecLong ija, VecDoub x, VecDoub b, int n)
        {
            int  i, j;
            long k;

            if (ija[1] != n + 2)
            {
                new Exception("mismatched vector and matrix in sprstx");
            }
            for (i = 0; i < n; i++)
            {
                b[i] = sa[i] * x[i]; //First come the diagonal terms
            }
            for (i = 0; i < n; i++)
            {//Now loop over the off diagonal terms.
                for (k = ija[i]; k <= ija[i + 1] - 1; k++)
                {
                    j     = (int)ija[(int)k];
                    b[j] += sa[(int)k] * x[i]; //Because this is multiplication by the transpose, the indices of b and x interchange.
                }
            }
        }
Exemple #9
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;
        }
Exemple #10
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];
                }
            }
        }
Exemple #11
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;
                }
            }
        }
Exemple #12
0
        /// <summary>
        /// Solve with (apply the pseudoinverse to) one or more right-hand sides.
        /// </summary>
        /// <param name="b">The RHS to solve.</param>
        /// <param name="x">The result.</param>

        public void solve(VecDoub b, VecDoub x)
        {
            solve(b, x, -1.0);
        }
Exemple #13
0
        //void reorder();
        private void reorder()
        {
            int     i, j, k, s, inc = 1;
            double  sw;
            VecDoub su = new VecDoub(m), sv = new VecDoub(n);

            do
            {
                inc *= 3; inc++;
            } while (inc <= n);
            do
            {
                inc /= 3;
                for (i = inc; i < n; i++)
                {
                    sw = w[i];
                    for (k = 0; k < m; k++)
                    {
                        su[k] = u[k][i];
                    }
                    for (k = 0; k < n; k++)
                    {
                        sv[k] = v[k][i];
                    }
                    j = i;
                    while (w[j - inc] < sw)
                    {
                        w[j] = w[j - inc];
                        for (k = 0; k < m; k++)
                        {
                            u[k][j] = u[k][j - inc];
                        }
                        for (k = 0; k < n; k++)
                        {
                            v[k][j] = v[k][j - inc];
                        }
                        j -= inc;
                        if (j < inc)
                        {
                            break;
                        }
                    }
                    w[j] = sw;
                    for (k = 0; k < m; k++)
                    {
                        u[k][j] = su[k];
                    }
                    for (k = 0; k < n; k++)
                    {
                        v[k][j] = sv[k];
                    }
                }
            } while (inc > 1);
            for (k = 0; k < n; k++)
            {
                s = 0;
                for (i = 0; i < m; i++)
                {
                    if (u[i][k] < 0.0)
                    {
                        s++;
                    }
                }
                for (j = 0; j < n; j++)
                {
                    if (v[j][k] < 0.0)
                    {
                        s++;
                    }
                }
                if (s > (m + n) / 2)
                {
                    for (i = 0; i < m; i++)
                    {
                        u[i][k] = -u[i][k];
                    }
                    for (j = 0; j < n; j++)
                    {
                        v[j][k] = -v[j][k];
                    }
                }
            }
        }
Exemple #14
0
        /***************************************
        *  View these equations in a latex editor. They are referenced in the comments. These are the bi-conjugate gradient with pre-conditioning matrix equations.
        \[\alpha_k = \frac{\vec rr_k^T \vec z_k}{\vec pp_k^T.A. \vec p_k} \tag{1}\]
        \[\vec r_{k+1} = \vec r_k - \alpha_k . A . \vec p_k \tag{2}\]
        \[\vec rr_k = \vec rr_k - \alpha_kA^T \vec pp_k \tag{3}\]
        \[\vec z_k = \widetilde{A}^{-1}. \vec r_k \tag{4}\]
        \[\vec zz_k = \widetilde{A}^{-T} \vec rr_k \tag{5}\]
        \[\beta_k = \frac{\vec rr_k^T.\vec z_{k+1}}{\vec rr_k ^T \vec z_k} \tag{6}\]
        \[\vec p_{k+1} = \vec z_{k+a} + \beta_k \vec p_k \tag{7}\]
        \[\vec pp_{k+1} = \vec zz_{k+1} + \beta_k. \vec pp_k \tag{8}\]
        \[\vec x_{k+a} = \vec x_k + \alpha_k. \vec p_k \tag{9}\]
        ***************************************/

        public void linbcg(VecDoub b, VecDoub x, int itol, double tol, int itmax, ref int iter, ref double err)
        {
            VecDoub p  = new VecDoub(n);
            VecDoub pp = new VecDoub(n);
            VecDoub r  = new VecDoub(n);
            VecDoub rr = new VecDoub(n);
            VecDoub z  = new VecDoub(n);
            VecDoub zz = new VecDoub(n);

            iter = 0;
            atimes(n, x, r, 0);

            double ak, akden, bk, bkden = 0, bknum = 0, bnrm, dxnrm, xnrm, zm1nrm, znrm = 0;
            int    j;

            for (j = 0; j < n; j++)
            {   //Initialize r and rr. The vectors corresponding to A and A^T.
                r[j]  = b[j] - r[j];
                rr[j] = r[j];
            }
            /*atimes(n, r, rr, 0); */
            //Uncomment this line to get maximum residual variant of the algorithm.
            if (itol == 1)
            {
                bnrm = snrm(n, b, itol);
                //Equation (4)
                asolve(n, r, z, 0); //Input is r[1..n], output is z[1..n]; the final 0 indicates that A and not its transpose is used.
            }
            else if (itol == 2)
            {
                asolve(n, b, z, 0);
                bnrm = snrm(n, z, itol);
                asolve(n, r, z, 0);
            }
            else if (itol == 3 || itol == 4)
            {
                asolve(n, b, z, 0);
                bnrm = snrm(n, z, itol);
                asolve(n, r, z, 0);
                znrm = snrm(n, z, itol);
            }
            else
            {
                throw new Exception("illegal itol in linbcg");
            }

            while (iter <= itmax) //Main loop.
            {
                ++iter;
                //Equation (5)
                asolve(n, rr, zz, 1);   //Final 1 indicates use of transpose matrix AT

                for (bknum = 0.0, j = 0; j < n; j++)
                {
                    bknum += z[j] * rr[j]; //Numerator of equation (6)
                }
                if (iter == 1)
                {
                    for (j = 0; j < n; j++)
                    {
                        p[j]  = z[j];
                        pp[j] = zz[j];
                    }
                }
                else
                {
                    bk = bknum / bkden; //beta
                    for (j = 0; j < n; j++)
                    {
                        p[j]  = bk * p[j] + z[j];   //Equation (7)
                        pp[j] = bk * pp[j] + zz[j]; //Equation (8)
                    }
                }
                bkden = bknum;                       //Denominator of equation (6)

                atimes(n, p, z, 0);                  //Since z has been used, we change its definition to save space.

                for (akden = 0.0, j = 0; j < n; j++) //Denominator of equation (1)
                {
                    akden += z[j] * pp[j];
                }

                ak = bknum / akden;   //Equation (1)

                atimes(n, pp, zz, 1); //Since zz has been used, we can changte the definition to save space.

                for (j = 0; j < n; j++)
                {
                    x[j]  += ak * p[j];  //Equation (9)
                    r[j]  -= ak * z[j];  //Equation (2)
                    rr[j] -= ak * zz[j]; //Equation (3)
                }
                asolve(n, r, z, 0);      //Equation (4)

                if (itol == 1)
                {
                    err = snrm(n, r, itol) / bnrm;
                }
                else if (itol == 2)
                {
                    err = snrm(n, z, itol) / bnrm;
                }
                else if (itol == 3 || itol == 4)
                {
                    zm1nrm = znrm;
                    znrm   = snrm(n, z, itol);
                    if (Math.Abs(zm1nrm - znrm) > EPS * znrm)
                    {
                        dxnrm = Math.Abs(ak) * snrm(n, p, itol);
                        err   = znrm / Math.Abs(zm1nrm - znrm) * dxnrm;
                    }
                    else
                    {
                        err = znrm / bnrm;      //Error may not be accurate, so loop again.
                        continue;
                    }
                    xnrm = snrm(n, x, itol);
                    if (err <= 0.5 * xnrm)
                    {
                        err /= xnrm;
                    }
                    else
                    {
                        err = znrm / bnrm;      //Error may not be accurate, so loop again.
                        continue;
                    }
                }
                System.Console.WriteLine("iteration : " + iter + " ;error : " + err);
                if (err <= tol)
                {
                    break;
                }
            }
        }
Exemple #15
0
        //void decompose();
        private void decompose()
        {
            bool    flag;
            int     i, its, j, jj, k, nm = int.MinValue;
            int     l = int.MinValue;
            double  anorm, c, f, g, h, s, scale, x, y, z;
            VecDoub rv1 = new VecDoub(n);

            g = scale = anorm = 0.0;
            for (i = 0; i < n; i++)
            {
                l      = i + 2;
                rv1[i] = scale * g;
                g      = s = scale = 0.0;
                if (i < m)
                {
                    for (k = i; k < m; k++)
                    {
                        scale += Math.Abs(u[k][i]);
                    }
                    if (scale != 0.0)
                    {
                        for (k = i; k < m; k++)
                        {
                            u[k][i] /= scale;
                            s       += u[k][i] * u[k][i];
                        }
                        f       = u[i][i];
                        g       = -NR.SIGN(Math.Sqrt(s), f);
                        h       = f * g - s;
                        u[i][i] = f - g;
                        for (j = l - 1; j < n; j++)
                        {
                            for (s = 0.0, k = i; k < m; k++)
                            {
                                s += u[k][i] * u[k][j];
                            }
                            f = s / h;
                            for (k = i; k < m; k++)
                            {
                                u[k][j] += f * u[k][i];
                            }
                        }
                        for (k = i; k < m; k++)
                        {
                            u[k][i] *= scale;
                        }
                    }
                }
                w[i] = scale * g;
                g    = s = scale = 0.0;
                if (i + 1 <= m && i + 1 != n)
                {
                    for (k = l - 1; k < n; k++)
                    {
                        scale += Math.Abs(u[i][k]);
                    }
                    if (scale != 0.0)
                    {
                        for (k = l - 1; k < n; k++)
                        {
                            u[i][k] /= scale;
                            s       += u[i][k] * u[i][k];
                        }
                        f           = u[i][l - 1];
                        g           = -NR.SIGN(Math.Sqrt(s), f);
                        h           = f * g - s;
                        u[i][l - 1] = f - g;
                        for (k = l - 1; k < n; k++)
                        {
                            rv1[k] = u[i][k] / h;
                        }
                        for (j = l - 1; j < m; j++)
                        {
                            for (s = 0.0, k = l - 1; k < n; k++)
                            {
                                s += u[j][k] * u[i][k];
                            }
                            for (k = l - 1; k < n; k++)
                            {
                                u[j][k] += s * rv1[k];
                            }
                        }
                        for (k = l - 1; k < n; k++)
                        {
                            u[i][k] *= scale;
                        }
                    }
                }
                anorm = Math.Max(anorm, (Math.Abs(w[i]) + Math.Abs(rv1[i])));
            }
            for (i = n - 1; i >= 0; i--)
            {
                if (i < n - 1)
                {
                    if (g != 0.0)
                    {
                        for (j = l; j < n; j++)
                        {
                            v[j][i] = (u[i][j] / u[i][l]) / g;
                        }
                        for (j = l; j < n; j++)
                        {
                            for (s = 0.0, k = l; k < n; k++)
                            {
                                s += u[i][k] * v[k][j];
                            }
                            for (k = l; k < n; k++)
                            {
                                v[k][j] += s * v[k][i];
                            }
                        }
                    }
                    for (j = l; j < n; j++)
                    {
                        v[i][j] = v[j][i] = 0.0;
                    }
                }
                v[i][i] = 1.0;
                g       = rv1[i];
                l       = i;
            }
            for (i = Math.Min(m, n) - 1; i >= 0; i--)
            {
                l = i + 1;
                g = w[i];
                for (j = l; j < n; j++)
                {
                    u[i][j] = 0.0;
                }
                if (g != 0.0)
                {
                    g = 1.0 / g;
                    for (j = l; j < n; j++)
                    {
                        for (s = 0.0, k = l; k < m; k++)
                        {
                            s += u[k][i] * u[k][j];
                        }
                        f = (s / u[i][i]) * g;
                        for (k = i; k < m; k++)
                        {
                            u[k][j] += f * u[k][i];
                        }
                    }
                    for (j = i; j < m; j++)
                    {
                        u[j][i] *= g;
                    }
                }
                else
                {
                    for (j = i; j < m; j++)
                    {
                        u[j][i] = 0.0;
                    }
                }
                ++u[i][i];
            }
            for (k = n - 1; k >= 0; k--)
            {
                for (its = 0; its < 30; its++)
                {
                    flag = true;
                    for (l = k; l >= 0; l--)
                    {
                        nm = l - 1;
                        if (l == 0 || Math.Abs(rv1[l]) <= eps * anorm)
                        {
                            flag = false;
                            break;
                        }
                        if (Math.Abs(w[nm]) <= eps * anorm)
                        {
                            break;
                        }
                    }
                    if (flag)
                    {
                        c = 0.0;
                        s = 1.0;
                        for (i = l; i < k + 1; i++)
                        {
                            f      = s * rv1[i];
                            rv1[i] = c * rv1[i];
                            if (Math.Abs(f) <= eps * anorm)
                            {
                                break;
                            }
                            g    = w[i];
                            h    = pythag(f, g);
                            w[i] = h;
                            h    = 1.0 / h;
                            c    = g * h;
                            s    = -f * h;
                            for (j = 0; j < m; j++)
                            {
                                y        = u[j][nm];
                                z        = u[j][i];
                                u[j][nm] = y * c + z * s;
                                u[j][i]  = z * c - y * s;
                            }
                        }
                    }
                    z = w[k];
                    if (l == k)
                    {
                        if (z < 0.0)
                        {
                            w[k] = -z;
                            for (j = 0; j < n; j++)
                            {
                                v[j][k] = -v[j][k];
                            }
                        }
                        break;
                    }
                    if (its == 29)
                    {
                        throw new Exception("no convergence in 30 svdcmp iterations");
                    }
                    x  = w[l];
                    nm = k - 1;
                    y  = w[nm];
                    g  = rv1[nm];
                    h  = rv1[k];
                    f  = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
                    g  = pythag(f, 1.0);
                    f  = ((x - z) * (x + z) + h * ((y / (f + NR.SIGN(g, f))) - h)) / x;
                    c  = s = 1.0;
                    for (j = l; j <= nm; j++)
                    {
                        i      = j + 1;
                        g      = rv1[i];
                        y      = w[i];
                        h      = s * g;
                        g      = c * g;
                        z      = pythag(f, h);
                        rv1[j] = z;
                        c      = f / z;
                        s      = h / z;
                        f      = x * c + g * s;
                        g      = g * c - x * s;
                        h      = y * s;
                        y     *= c;
                        for (jj = 0; jj < n; jj++)
                        {
                            x        = v[jj][j];
                            z        = v[jj][i];
                            v[jj][j] = x * c + z * s;
                            v[jj][i] = z * c - x * s;
                        }
                        z    = pythag(f, h);
                        w[j] = z;
                        if (z != 0.0)
                        {
                            z = 1.0 / z;
                            c = f * z;
                            s = h * z;
                        }
                        f = c * g + s * y;
                        x = c * y - s * g;
                        for (jj = 0; jj < m; jj++)
                        {
                            y        = u[jj][j];
                            z        = u[jj][i];
                            u[jj][j] = y * c + z * s;
                            u[jj][i] = z * c - y * s;
                        }
                    }
                    rv1[l] = 0.0;
                    rv1[k] = f;
                    w[k]   = x;
                }
            }
        }
Exemple #16
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();
        }
Exemple #17
0
        //Toeplitz matrices tend to occur in deconvolution and signal processing.
        public Toeplitz(VecDoub r, double[] x, double[] y)
        {
            // Solves the Toeplitz system
            // PN1
            // jD0 R.N1Cij/xj D yi .i D 0; : : : ; N  1/. The Toeplitz
            // matrix need not be symmetric. y[0..n-1] and r[0..2*n-2] are input
            // arrays; x[0..n-1] is the output array.

            int    j, k, m, m1, m2, n1, n = y.Length;
            double pp, pt1, pt2, qq, qt1, qt2, sd, sgd, sgn, shn, sxn;

            n1 = n - 1;
            if (r[n1] == 0.0)
            {
                throw new Exception("toeplz-1 singular principal minor");
            }

            ////<Initialize x, g and h>
            x[0] = y[0] / r[n1];
            if (n1 == 0)
            {
                return;
            }
            VecDoub g = new VecDoub(n1), h = new VecDoub(n1);

            g[0] = r[n1 - 1] / r[n1];
            h[0] = r[n1 + 1] / r[n1];
            ////</Initialize x, g and h>

            ////<Main loop of the recursion>
            for (m = 0; m < n; m++)
            {
                m1 = m + 1;
                ////<Compute numerator and denominator for x_{m+1} 2.8.19>
                sxn = -y[m1];
                sd  = -r[n1];
                for (j = 0; j < m + 1; j++)
                {
                    sxn += r[n1 + m1 - j] * x[j];
                    sd  += r[n1 + m1 - j] * g[m - j];
                }
                if (sd == 0.0)
                {
                    throw new Exception("toeplz-2 singular principal minor");
                }
                x[m1] = sxn / sd;
                ////</Compute numerator and denominator for x_{m+1} 2.8.19>

                ////<Compute x_{j} 2.8.15>
                for (j = 0; j < m + 1; j++)
                {
                    // Eq. (2.8.16).
                    x[j] -= x[m1] * g[m - j];
                }
                ////</Compute x_{j} 2.8.15>

                if (m1 == n1)
                {
                    return;
                }
                ////<Compute numerator and denominator for G and H, Equations 2.8.23 and 2.8.24>
                sgn = -r[n1 - m1 - 1];
                shn = -r[n1 + m1 + 1];
                sgd = -r[n1];
                for (j = 0; j < m + 1; j++)
                {
                    sgn += r[n1 + j - m1] * g[j];
                    shn += r[n1 + m1 - j] * h[j];
                    sgd += r[n1 + j - m1] * h[m - j];
                }
                if (sgd == 0.0)
                {
                    throw new Exception("toeplz-3 singular principal minor");
                }
                g[m1] = sgn / sgd; // whence G and H.
                h[m1] = shn / sd;
                ////</Compute numerator and denominator for G and H, Equations 2.8.23 and 2.8.24>

                ////<Compute G_j and H_j for j = 1 to m Equation 2.8.25>
                k  = m;
                m2 = (m + 2) >> 1;
                pp = g[m1];
                qq = h[m1];
                for (j = 0; j < m2; j++)
                {//We split the two equations in 2.8.25 into 4 equations by replacing j by M+1-j. Double the equations mean half the iterations.
                    pt1    = g[j];
                    pt2    = g[k];
                    qt1    = h[j];
                    qt2    = h[k];
                    g[j]   = pt1 - pp * qt2;
                    g[k]   = pt2 - pp * qt1;
                    h[j]   = qt1 - qq * pt2;
                    h[k--] = qt2 - qq * pt1;
                }
                ////<Compute G_j and H_j for j = 1 to m Equation 2.8.25>
            } // Back for another recurrence.
            throw new Exception("toeplz - should not arrive here!");
        }