Esempio n. 1
0
    private static void dcopy_test()

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    DCOPY_TEST demonstrates DCOPY.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    15 May 2006
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        double[] a = new double[5 * 5];
        double[] x = new double[10];
        double[] y = new double[10];

        Console.WriteLine("");
        Console.WriteLine("DCOPY_TEST");
        Console.WriteLine("  DCOPY copies one vector into another.");
        Console.WriteLine("");

        for (int i = 0; i < 10; i++)
        {
            x[i] = i + 1;
        }

        for (int i = 0; i < 10; i++)
        {
            y[i] = 10 * (i + 1);
        }

        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                a[i + j * 5] = 10 * (i + 1) + j + 1;
            }
        }

        Console.WriteLine("");
        Console.WriteLine("  X =");
        Console.WriteLine("");
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("  "
                              + (i + 1).ToString(CultureInfo.InvariantCulture).PadLeft(6) + "  "
                              + x[i].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }

        Console.WriteLine("");
        Console.WriteLine("  Y =");
        Console.WriteLine("");
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("  "
                              + (i + 1).ToString(CultureInfo.InvariantCulture).PadLeft(6) + "  "
                              + y[i].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }

        Console.WriteLine("");
        Console.WriteLine("  A =");
        Console.WriteLine("");
        for (int i = 0; i < 5; i++)
        {
            string cout = "";
            for (int j = 0; j < 5; j++)
            {
                cout += "  " + a[i + j * 5].ToString(CultureInfo.InvariantCulture).PadLeft(14);
            }

            Console.WriteLine(cout);
        }

        BLAS1D.dcopy(5, x, 1, ref y, 1);
        Console.WriteLine("");
        Console.WriteLine("  DCOPY ( 5, X, 1, Y, 1 )");
        Console.WriteLine("");
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("  "
                              + (i + 1).ToString(CultureInfo.InvariantCulture).PadLeft(6) + "  "
                              + y[i].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }

        for (int i = 0; i < 10; i++)
        {
            y[i] = 10 * (i + 1);
        }

        BLAS1D.dcopy(3, x, 2, ref y, 3);
        Console.WriteLine("");
        Console.WriteLine("  DCOPY ( 3, X, 2, Y, 3 )");
        Console.WriteLine("");
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("  "
                              + (i + 1).ToString(CultureInfo.InvariantCulture).PadLeft(6) + "  "
                              + y[i].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }

        BLAS1D.dcopy(5, x, 1, ref a, 1);
        Console.WriteLine("");
        Console.WriteLine("  DCOPY ( 5, X, 1, A, 1 )");
        Console.WriteLine("");
        Console.WriteLine("  A =");
        Console.WriteLine("");
        for (int i = 0; i < 5; i++)
        {
            string cout = "";
            for (int j = 0; j < 5; j++)
            {
                cout += "  " + a[i + j * 5].ToString(CultureInfo.InvariantCulture).PadLeft(14);
            }

            Console.WriteLine(cout);
        }

        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                a[i + j * 5] = 10 * (i + 1) + j + 1;
            }
        }

        BLAS1D.dcopy(5, x, 2, ref a, 5);
        Console.WriteLine("");
        Console.WriteLine("  DCOPY ( 5, X, 2, A, 5 )");
        Console.WriteLine("");
        Console.WriteLine("  A =");
        Console.WriteLine("");
        for (int i = 0; i < 5; i++)
        {
            string cout = "";
            for (int j = 0; j < 5; j++)
            {
                cout += "  " + a[i + j * 5].ToString(CultureInfo.InvariantCulture).PadLeft(14);
            }

            Console.WriteLine(cout);
        }
    }
Esempio n. 2
0
    public static void dspdi(ref double[] ap, int n, int[] kpvt, ref double[] det, ref int[] inert,
                             double[] work, int job)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    DSPDI computes the determinant, inertia and inverse of a real symmetric matrix.
    //
    //  Discussion:
    //
    //    DSPDI uses the factors from DSPFA, where the matrix is stored in
    //    packed form.
    //
    //    A division by zero will occur if the inverse is requested
    //    and DSPCO has set RCOND == 0.0D+00 or DSPFA has set INFO /= 0.
    //
    //    Variables not requested by JOB are not used.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    25 May 2005
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Jack Dongarra, Cleve Moler, Jim Bunch,
    //    Pete Stewart.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart,
    //    LINPACK User's Guide,
    //    SIAM, (Society for Industrial and Applied Mathematics),
    //    3600 University City Science Center,
    //    Philadelphia, PA, 19104-2688.
    //    ISBN 0-89871-172-X
    //
    //  Parameters:
    //
    //    Input/output, double AP[(N*(N+1))/2].  On input, the output from
    //    DSPFA.  On output, the upper triangle of the inverse of the original
    //    matrix, stored in packed form, if requested.  The columns of the upper
    //    triangle are stored sequentially in a one-dimensional array.
    //
    //    Input, int N, the order of the matrix.
    //
    //    Input, int KPVT[N], the pivot vector from DSPFA.
    //
    //    Output, double DET[2], the determinant of the original matrix,
    //    if requested.
    //      determinant = DET[0] * 10.0**DET[1]
    //    with 1.0D+00 <= abs ( DET[0] ) < 10.0D+00 or DET[0] = 0.0.
    //
    //    Output, int INERT[3], the inertia of the original matrix, if requested.
    //    INERT(1) = number of positive eigenvalues.
    //    INERT(2) = number of negative eigenvalues.
    //    INERT(3) = number of zero eigenvalues.
    //
    //    Workspace, double WORK[N].
    //
    //    Input, int JOB, has the decimal expansion ABC where:
    //      if A /= 0, the inertia is computed,
    //      if B /= 0, the determinant is computed,
    //      if C /= 0, the inverse is computed.
    //    For example, JOB = 111  gives all three.
    //
    {
        double d;
        int    ik;
        int    ikp1;
        int    k;
        int    kk;
        int    kkp1;
        double t;

        bool doinv = job % 10 != 0;
        bool dodet = job % 100 / 10 != 0;
        bool doert = job % 1000 / 100 != 0;

        if (dodet || doert)
        {
            switch (doert)
            {
            case true:
                inert[0] = 0;
                inert[1] = 0;
                inert[2] = 0;
                break;
            }

            switch (dodet)
            {
            case true:
                det[0] = 1.0;
                det[1] = 0.0;
                break;
            }

            t  = 0.0;
            ik = 0;

            for (k = 1; k <= n; k++)
            {
                kk = ik + k;
                d  = ap[kk - 1];
                switch (kpvt[k - 1])
                {
                //
                //  2 by 2 block
                //  use det (d  s)  =  (d/t * c - t) * t,  t = abs ( s )
                //          (s  c)
                //  to avoid underflow/overflow troubles.
                //
                //  Take two passes through scaling.  Use T for flag.
                //
                case <= 0 when t == 0.0:
                    ikp1 = ik + k;
                    kkp1 = ikp1 + k;
                    t    = Math.Abs(ap[kkp1 - 1]);
                    d    = d / t * ap[kkp1] - t;
                    break;

                case <= 0:
                    d = t;
                    t = 0.0;
                    break;
                }

                switch (doert)
                {
                case true:
                    switch (d)
                    {
                    case > 0.0:
                        inert[0] += 1;
                        break;

                    case < 0.0:
                        inert[1] += 1;
                        break;

                    case 0.0:
                        inert[2] += 1;
                        break;
                    }

                    break;
                }

                switch (dodet)
                {
                case true:
                {
                    det[0] *= d;

                    if (det[0] != 0.0)
                    {
                        while (Math.Abs(det[0]) < 1.0)
                        {
                            det[0] *= 10.0;
                            det[1] -= 1.0;
                        }

                        while (10.0 <= Math.Abs(det[0]))
                        {
                            det[0] /= 10.0;
                            det[1] += 1.0;
                        }
                    }

                    break;
                }
                }

                ik += k;
            }
        }

        switch (doinv)
        {
        //
        //  Compute inverse(A).
        //
        case true:
        {
            k  = 1;
            ik = 0;

            while (k <= n)
            {
                int km1 = k - 1;
                kk   = ik + k;
                ikp1 = ik + k;
                kkp1 = ikp1 + k;

                int kstep;
                int jk;
                int j;
                int ij;
                switch (kpvt[k - 1])
                {
                case >= 0:
                {
                    //
                    //  1 by 1.
                    //
                    ap[kk - 1] = 1.0 / ap[kk - 1];

                    switch (k)
                    {
                    case >= 2:
                    {
                        BLAS1D.dcopy(k - 1, ap, 1, ref work, 1, xIndex: +ik);
                        ij = 0;

                        for (j = 1; j <= k - 1; j++)
                        {
                            jk         = ik + j;
                            ap[jk - 1] = BLAS1D.ddot(j, ap, 1, work, 1, xIndex: +ij);
                            BLAS1D.daxpy(j - 1, work[j - 1], ap, 1, ref ap, 1, xIndex: +ij, yIndex: +ik);
                            ij += j;
                        }

                        ap[kk - 1] += BLAS1D.ddot(k - 1, work, 1, ap, 1, yIndex: +ik);
                        break;
                    }
                    }

                    kstep = 1;
                    break;
                }

                default:
                {
                    //
                    //  2 by 2.
                    //
                    t = Math.Abs(ap[kkp1 - 1]);
                    double ak    = ap[kk - 1] / t;
                    double akp1  = ap[kkp1] / t;
                    double akkp1 = ap[kkp1 - 1] / t;
                    d            = t * (ak * akp1 - 1.0);
                    ap[kk - 1]   = akp1 / d;
                    ap[kkp1]     = ak / d;
                    ap[kkp1 - 1] = -akkp1 / d;

                    switch (km1)
                    {
                    case >= 1:
                    {
                        BLAS1D.dcopy(km1, ap, 1, ref work, 1, xIndex: +ikp1);
                        ij = 0;

                        for (j = 1; j <= km1; j++)
                        {
                            int jkp1 = ikp1 + j;
                            ap[jkp1 - 1] = BLAS1D.ddot(j, ap, 1, work, 1, xIndex: +ij);
                            BLAS1D.daxpy(j - 1, work[j - 1], ap, 1, ref ap, 1, xIndex: +ij, yIndex: +ikp1);
                            ij += j;
                        }

                        ap[kkp1]     += BLAS1D.ddot(km1, work, 1, ap, 1, yIndex: +ikp1);
                        ap[kkp1 - 1] += BLAS1D.ddot(km1, ap, 1, ap, 1, xIndex: +ik, yIndex: +ikp1);
                        BLAS1D.dcopy(km1, ap, 1, ref work, 1, xIndex: +ik);
                        ij = 0;

                        for (j = 1; j <= km1; j++)
                        {
                            jk         = ik + j;
                            ap[jk - 1] = BLAS1D.ddot(j, ap, 1, work, 1, xIndex: +ij);
                            BLAS1D.daxpy(j - 1, work[j - 1], ap, 1, ref ap, 1, xIndex: +ij, yIndex: +ik);
                            ij += j;
                        }

                        ap[kk - 1] += BLAS1D.ddot(km1, work, 1, ap, 1, yIndex: +ik);
                        break;
                    }
                    }

                    kstep = 2;
                    break;
                }
                }

                //
                //  Swap.
                //
                int ks = Math.Abs(kpvt[k - 1]);

                if (ks != k)
                {
                    int iks = ks * (ks - 1) / 2;
                    BLAS1D.dswap(ks, ref ap, 1, ref ap, 1, xIndex: +iks, yIndex: +ik);
                    int ksj = ik + ks;

                    double temp;
                    int    jb;
                    for (jb = ks; jb <= k; jb++)
                    {
                        j           = k + ks - jb;
                        jk          = ik + j;
                        temp        = ap[jk - 1];
                        ap[jk - 1]  = ap[ksj - 1];
                        ap[ksj - 1] = temp;
                        ksj        -= j - 1;
                    }

                    if (kstep != 1)
                    {
                        int kskp1 = ikp1 + ks;
                        temp          = ap[kskp1 - 1];
                        ap[kskp1 - 1] = ap[kkp1 - 1];
                        ap[kkp1 - 1]  = temp;
                    }
                }

                ik += k;
                ik  = kstep switch
                {
                    2 => ik + k + 1,
                    _ => ik
                };

                k += kstep;
            }

            break;
        }
        }
    }
}
Esempio n. 3
0
    public static void dsidi(ref double[] a, int lda, int n, int[] kpvt, ref double[] det,
                             ref int[] inert, double[] work, int job)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    DSIDI computes the determinant, inertia and inverse of a real symmetric matrix.
    //
    //  Discussion:
    //
    //    DSIDI uses the factors from DSIFA.
    //
    //    A division by zero may occur if the inverse is requested
    //    and DSICO has set RCOND == 0.0D+00 or DSIFA has set INFO /= 0.
    //
    //    Variables not requested by JOB are not used.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    25 May 2005
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Jack Dongarra, Cleve Moler, Jim Bunch,
    //    Pete Stewart.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart,
    //    LINPACK User's Guide,
    //    SIAM, (Society for Industrial and Applied Mathematics),
    //    3600 University City Science Center,
    //    Philadelphia, PA, 19104-2688.
    //    ISBN 0-89871-172-X
    //
    //  Parameters:
    //
    //    Input/output, double A(LDA,N).  On input, the output from DSIFA.
    //    On output, the upper triangle of the inverse of the original matrix,
    //    if requested.  The strict lower triangle is never referenced.
    //
    //    Input, int LDA, the leading dimension of the array A.
    //
    //    Input, int N, the order of the matrix.
    //
    //    Input, int KPVT[N], the pivot vector from DSIFA.
    //
    //    Output, double DET[2], the determinant of the original matrix,
    //    if requested.
    //      determinant = DET[0] * 10.0**DET[1]
    //    with 1.0D+00 <= abs ( DET[0] ) < 10.0D+00 or DET[0] = 0.0.
    //
    //    Output, int INERT(3), the inertia of the original matrix,
    //    if requested.
    //    INERT(1) = number of positive eigenvalues.
    //    INERT(2) = number of negative eigenvalues.
    //    INERT(3) = number of zero eigenvalues.
    //
    //    Workspace, double WORK[N].
    //
    //    Input, int JOB, specifies the tasks.
    //    JOB has the decimal expansion ABC where
    //    If C /= 0, the inverse is computed,
    //    If B /= 0, the determinant is computed,
    //    If A /= 0, the inertia is computed.
    //    For example, JOB = 111 gives all three.
    //
    {
        double d;
        int    k;
        double t;

        bool doinv = job % 10 != 0;
        bool dodet = job % 100 / 10 != 0;
        bool doert = job % 1000 / 100 != 0;

        if (dodet || doert)
        {
            switch (doert)
            {
            case true:
                inert[0] = 0;
                inert[1] = 0;
                inert[2] = 0;
                break;
            }

            switch (dodet)
            {
            case true:
                det[0] = 1.0;
                det[1] = 0.0;
                break;
            }

            t = 0.0;

            for (k = 1; k <= n; k++)
            {
                d = a[k - 1 + (k - 1) * lda];
                switch (kpvt[k - 1])
                {
                //
                //  2 by 2 block.
                //
                //  use det (d  s)  =  (d/t * c - t) * t,  t = abs ( s )
                //          (s  c)
                //  to avoid underflow/overflow troubles.
                //
                //  Take two passes through scaling.  Use T for flag.
                //
                case <= 0 when t == 0.0:
                    t = Math.Abs(a[k - 1 + k * lda]);
                    d = d / t * a[k + k * lda] - t;
                    break;

                case <= 0:
                    d = t;
                    t = 0.0;
                    break;
                }

                switch (doert)
                {
                case true:
                    switch (d)
                    {
                    case > 0.0:
                        inert[0] += 1;
                        break;

                    case < 0.0:
                        inert[1] += 1;
                        break;

                    case 0.0:
                        inert[2] += 1;
                        break;
                    }

                    break;
                }

                switch (dodet)
                {
                case true:
                {
                    det[0] *= d;

                    if (det[0] != 0.0)
                    {
                        while (Math.Abs(det[0]) < 1.0)
                        {
                            det[0] *= 10.0;
                            det[1] -= 1.0;
                        }

                        while (10.0 <= Math.Abs(det[0]))
                        {
                            det[0] /= 10.0;
                            det[1] += 1.0;
                        }
                    }

                    break;
                }
                }
            }
        }

        switch (doinv)
        {
        //
        //  Compute inverse(A).
        //
        case true:
        {
            k = 1;

            while (k <= n)
            {
                int j;
                int kstep;
                switch (kpvt[k - 1])
                {
                case >= 0:
                {
                    //
                    //  1 by 1.
                    //
                    a[k - 1 + (k - 1) * lda] = 1.0 / a[k - 1 + (k - 1) * lda];

                    switch (k)
                    {
                    case >= 2:
                    {
                        BLAS1D.dcopy(k - 1, a, 1, ref work, 1, xIndex: +0 + (k - 1) * lda);

                        for (j = 1; j <= k - 1; j++)
                        {
                            a[j - 1 + (k - 1) * lda] = BLAS1D.ddot(j, a, 1, work, 1, xIndex: +0 + (j - 1) * lda);
                            BLAS1D.daxpy(j - 1, work[j - 1], a, 1, ref a, 1, xIndex: +0 + (j - 1) * lda,
                                         yIndex: +0 + (k - 1) * lda);
                        }

                        a[k - 1 + (k - 1) * lda] += BLAS1D.ddot(k - 1, work, 1, a, 1, yIndex: +0 + (k - 1) * lda);
                        break;
                    }
                    }

                    kstep = 1;
                    break;
                }

                //
                default:
                {
                    t = Math.Abs(a[k - 1 + k * lda]);
                    double ak    = a[k - 1 + (k - 1) * lda] / t;
                    double akp1  = a[k + k * lda] / t;
                    double akkp1 = a[k - 1 + k * lda] / t;
                    d = t * (ak * akp1 - 1.0);
                    a[k - 1 + (k - 1) * lda] = akp1 / d;
                    a[k + k * lda]           = ak / d;
                    a[k - 1 + k * lda]       = -akkp1 / d;

                    switch (k)
                    {
                    case >= 2:
                    {
                        BLAS1D.dcopy(k - 1, a, 1, ref work, 1, xIndex: +0 + k * lda);

                        for (j = 1; j <= k - 1; j++)
                        {
                            a[j - 1 + k * lda] = BLAS1D.ddot(j, a, 1, work, 1, xIndex: +0 + (j - 1) * lda);
                            BLAS1D.daxpy(j - 1, work[j - 1], a, 1, ref a, 1, xIndex: +0 + (j - 1) * lda,
                                         yIndex: +0 + k * lda);
                        }

                        a[k + k * lda]     += BLAS1D.ddot(k - 1, work, 1, a, 1, yIndex: +0 + k * lda);
                        a[k - 1 + k * lda] += BLAS1D.ddot(k - 1, a, 1, a, 1, xIndex: +0 + (k - 1) * lda,
                                                          yIndex: +0 + k * lda);
                        BLAS1D.dcopy(k - 1, a, 1, ref work, 1, xIndex: +0 + (k - 1) * lda);

                        for (j = 1; j <= k - 1; j++)
                        {
                            a[j - 1 + (k - 1) * lda] = BLAS1D.ddot(j, a, 1, work, 1, xIndex: +0 + (j - 1) * lda);
                            BLAS1D.daxpy(j - 1, work[j - 1], a, 1, ref a, 1, xIndex: +0 + (j - 1) * lda,
                                         yIndex: +0 + (k - 1) * lda);
                        }

                        a[k - 1 + (k - 1) * lda] += BLAS1D.ddot(k - 1, work, 1, a, 1, yIndex: +0 + (k - 1) * lda);
                        break;
                    }
                    }

                    kstep = 2;
                    break;
                }
                }

                //
                //  Swap.
                //
                int ks = Math.Abs(kpvt[k - 1]);

                if (ks != k)
                {
                    BLAS1D.dswap(ks, ref a, 1, ref a, 1, xIndex: +0 + (ks - 1) * lda, yIndex: +0 + (k - 1) * lda);

                    int    jb;
                    double temp;
                    for (jb = ks; jb <= k; jb++)
                    {
                        j    = k + ks - jb;
                        temp = a[j - 1 + (k - 1) * lda];
                        a[j - 1 + (k - 1) * lda]  = a[ks - 1 + (j - 1) * lda];
                        a[ks - 1 + (j - 1) * lda] = temp;
                    }

                    if (kstep != 1)
                    {
                        temp = a[ks - 1 + k * lda];
                        a[ks - 1 + k * lda] = a[k - 1 + k * lda];
                        a[k - 1 + k * lda]  = temp;
                    }
                }

                k += kstep;
            }

            break;
        }
        }
    }