Esempio n. 1
0
    private static void idamax_test()

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    IDAMAX_TEST demonstrates IDAMAX.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    23 February 2006
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        int N = 11;

        double[] x = new double[N];

        Console.WriteLine("");
        Console.WriteLine("IDAMAX_TEST");
        Console.WriteLine("  IDAMAX returns the index of maximum magnitude;");

        for (int i = 1; i <= N; i++)
        {
            x[i - 1] = 7 * i % 11 - (double)(N / 2);
        }

        Console.WriteLine("");
        Console.WriteLine("  The vector X:");
        Console.WriteLine("");

        for (int i = 1; i <= N; i++)
        {
            Console.WriteLine("  " + i.ToString(CultureInfo.InvariantCulture).PadLeft(6)
                              + "  " + x[i - 1].ToString(CultureInfo.InvariantCulture).PadLeft(8) + "");
        }

        int incx = 1;

        int i1 = BLAS1D.idamax(N, x, incx);

        Console.WriteLine("");
        Console.WriteLine("  The index of maximum magnitude = " + i1 + "");
    }
Esempio n. 2
0
    public static int dgefa(ref double[] a, int lda, int n, ref int[] ipvt)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    DGEFA factors a real general matrix.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    16 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 intput, the matrix to be factored.
    //    On output, an upper triangular matrix and the multipliers used to obtain
    //    it.  The factorization can be written A=L*U, where L is a product of
    //    permutation and unit lower triangular matrices, and U is upper triangular.
    //
    //    Input, int LDA, the leading dimension of A.
    //
    //    Input, int N, the order of the matrix A.
    //
    //    Output, int IPVT[N], the pivot indices.
    //
    //    Output, int DGEFA, singularity indicator.
    //    0, normal value.
    //    K, if U(K,K) == 0.  This is not an error condition for this subroutine,
    //    but it does indicate that DGESL or DGEDI will divide by zero if called.
    //    Use RCOND in DGECO for a reliable indication of singularity.
    //
    {
        int k;
        //
        //  Gaussian elimination with partial pivoting.
        //
        int info = 0;

        for (k = 1; k <= n - 1; k++)
        {
            //
            //  Find L = pivot index.
            //
            int l = BLAS1D.idamax(n - k + 1, a, 1, index:  +(k - 1) + (k - 1) * lda) + k - 1;
            ipvt[k - 1] = l;
            switch (a[l - 1 + (k - 1) * lda])
            {
            //
            //  Zero pivot implies this column already triangularized.
            //
            case 0.0:
                info = k;
                continue;
            }

            //
            //  Interchange if necessary.
            //
            double t;
            if (l != k)
            {
                t = a[l - 1 + (k - 1) * lda];
                a[l - 1 + (k - 1) * lda] = a[k - 1 + (k - 1) * lda];
                a[k - 1 + (k - 1) * lda] = t;
            }

            //
            //  Compute multipliers.
            //
            t = -1.0 / a[k - 1 + (k - 1) * lda];

            BLAS1D.dscal(n - k, t, ref a, 1, index: +k + (k - 1) * lda);
            //
            //  Row elimination with column indexing.
            //
            int j;
            for (j = k + 1; j <= n; j++)
            {
                t = a[l - 1 + (j - 1) * lda];
                if (l != k)
                {
                    a[l - 1 + (j - 1) * lda] = a[k - 1 + (j - 1) * lda];
                    a[k - 1 + (j - 1) * lda] = t;
                }

                BLAS1D.daxpy(n - k, t, a, 1, ref a, 1, xIndex:  +k + (k - 1) * lda, yIndex:  +k + (j - 1) * lda);
            }
        }

        ipvt[n - 1] = n;

        info = a[n - 1 + (n - 1) * lda] switch
        {
            0.0 => n,
            _ => info
        };

        return(info);
    }
}
Esempio n. 3
0
    public static int dgbfa(ref double[] abd, int lda, int n, int ml, int mu, ref int[] ipvt)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    DGBFA factors a real band matrix by elimination.
    //
    //  Discussion:
    //
    //    DGBFA is usually called by DGBCO, but it can be called
    //    directly with a saving in time if RCOND is not needed.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    23 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 ABD[LDA*N].  On input, the matrix in band
    //    storage.  The columns of the matrix are stored in the columns of ABD
    //    and the diagonals of the matrix are stored in rows ML+1 through
    //    2*ML+MU+1 of ABD.  On output, an upper triangular matrix in band storage
    //    and the multipliers which were used to obtain it.  The factorization
    //    can be written A = L*U where L is a product of permutation and unit lower
    //    triangular matrices and U is upper triangular.
    //
    //    Input, int LDA, the leading dimension of the array ABD.
    //    2*ML + MU + 1 <= LDA is required.
    //
    //    Input, int N, the order of the matrix.
    //
    //    Input, int ML, MU, the number of diagonals below and above the
    //    main diagonal.  0 <= ML < N, 0 <= MU < N.
    //
    //    Output, int IPVT[N], the pivot indices.
    //
    //    Output, integer DGBFA, error flag.
    //    0, normal value.
    //    K, if U(K,K) == 0.0D+00.  This is not an error condition for this
    //      subroutine, but it does indicate that DGBSL will divide by zero if
    //      called.  Use RCOND in DGBCO for a reliable indication of singularity.
    //
    {
        int i;
        int jz;
        int k;

        int m    = ml + mu + 1;
        int info = 0;
        //
        //  Zero initial fill-in columns.
        //
        int j0 = mu + 2;
        int j1 = Math.Min(n, m) - 1;

        for (jz = j0; jz <= j1; jz++)
        {
            int i0 = m + 1 - jz;
            for (i = i0; i <= ml; i++)
            {
                abd[i - 1 + (jz - 1) * lda] = 0.0;
            }
        }

        jz = j1;
        int ju = 0;

        //
        //  Gaussian elimination with partial pivoting.
        //
        for (k = 1; k <= n - 1; k++)
        {
            //
            //  Zero out the next fill-in column.
            //
            jz += 1;
            if (jz <= n)
            {
                for (i = 1; i <= ml; i++)
                {
                    abd[i - 1 + (jz - 1) * lda] = 0.0;
                }
            }

            //
            //  Find L = pivot index.
            //
            int lm = Math.Min(ml, n - k);
            int l  = BLAS1D.idamax(lm + 1, abd, 1, +m - 1 + (k - 1) * lda) + m - 1;
            ipvt[k - 1] = l + k - m;
            switch (abd[l - 1 + (k - 1) * lda])
            {
            //
            //  Zero pivot implies this column already triangularized.
            //
            case 0.0:
                info = k;
                break;

            //
            default:
            {
                double t;
                if (l != m)
                {
                    t = abd[l - 1 + (k - 1) * lda];
                    abd[l - 1 + (k - 1) * lda] = abd[m - 1 + (k - 1) * lda];
                    abd[m - 1 + (k - 1) * lda] = t;
                }

                //
                //  Compute multipliers.
                //
                t = -1.0 / abd[m - 1 + (k - 1) * lda];
                BLAS1D.dscal(lm, t, ref abd, 1, +m + (k - 1) * lda);
                //
                //  Row elimination with column indexing.
                //
                ju = Math.Min(Math.Max(ju, mu + ipvt[k - 1]), n);
                int mm = m;

                int j;
                for (j = k + 1; j <= ju; j++)
                {
                    l  -= 1;
                    mm -= 1;
                    t   = abd[l - 1 + (j - 1) * lda];
                    if (l != mm)
                    {
                        abd[l - 1 + (j - 1) * lda]  = abd[mm - 1 + (j - 1) * lda];
                        abd[mm - 1 + (j - 1) * lda] = t;
                    }

                    BLAS1D.daxpy(lm, t, abd, 1, ref abd, 1, +m + (k - 1) * lda, +mm + (j - 1) * lda);
                }

                break;
            }
            }
        }

        ipvt[n - 1] = n;

        info = abd[m - 1 + (n - 1) * lda] switch
        {
            0.0 => n,
            _ => info
        };

        return(info);
    }
}
Esempio n. 4
0
    public static int dspfa(ref double[] ap, int n, ref int[] kpvt)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    DSPFA factors a real symmetric matrix stored in packed form.
    //
    //  Discussion:
    //
    //    To solve A*X = B, follow DSPFA by DSPSL.
    //
    //    To compute inverse(A)*C, follow DSPFA by DSPSL.
    //
    //    To compute determinant(A), follow DSPFA by DSPDI.
    //
    //    To compute inertia(A), follow DSPFA by DSPDI.
    //
    //    To compute inverse(A), follow DSPFA by DSPDI.
    //
    //  Packed storage:
    //
    //    The following program segment will pack the upper triangle of a
    //    symmetric matrix.
    //
    //      k = 0
    //      do j = 1, n
    //        do i = 1, j
    //          k = k + 1
    //          ap(k) = a(i,j)
    //        end do
    //      end do
    //
    //  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 packed form of a
    //    symmetric matrix A.  The columns of the upper triangle are stored
    //    sequentially in a one-dimensional array.  On output, a block diagonal
    //    matrix and the multipliers which were used to obtain it stored in
    //    packed form.  The factorization can be written A = U*D*U' where U
    //    is a product of permutation and unit upper triangular matrices, U'
    //    is the transpose of U, and D is block diagonal with 1 by 1 and 2
    //    by 2 blocks.
    //
    //    Input, int N, the order of the matrix.
    //
    //    Output, int KPVT[N], the pivot indices.
    //
    //    Output, int DSPFA, error flag.
    //    0, normal value.
    //    K, if the K-th pivot block is singular.  This is not an error
    //    condition for this subroutine, but it does indicate that DSPSL or
    //    DSPDI may divide by zero if called.
    //
    {
        int im = 0;
        //
        //  ALPHA is used in choosing pivot block size.
        //
        double alpha = (1.0 + Math.Sqrt(17.0)) / 8.0;

        int info = 0;
        //
        //  Main loop on K, which goes from N to 1.
        //
        int k  = n;
        int ik = n * (n - 1) / 2;

        for (;;)
        {
            //
            //  Leave the loop if K = 0 or K = 1.
            //
            if (k == 0)
            {
                break;
            }

            if (k == 1)
            {
                kpvt[0] = 1;
                info    = ap[0] switch
                {
                    0.0 => 1,
                    _ => info
                };

                break;
            }

            //
            //  This section of code determines the kind of elimination to be performed.
            //  When it is completed, KSTEP will be set to the size of the pivot block,
            //  and SWAP will be set to .true. if an interchange is required.
            //
            int    km1    = k - 1;
            int    kk     = ik + k;
            double absakk = Math.Abs(ap[kk - 1]);
            //
            //  Determine the largest off-diagonal element in column K.
            //
            int    imax   = BLAS1D.idamax(k - 1, ap, 1, index: +ik);
            int    imk    = ik + imax;
            double colmax = Math.Abs(ap[imk - 1]);

            int  kstep;
            bool swap;
            int  j;
            int  imj;
            if (alpha * colmax <= absakk)
            {
                kstep = 1;
                swap  = false;
            }
            //
            //  Determine the largest off-diagonal element in row IMAX.
            //
            else
            {
                double rowmax = 0.0;
                int    imaxp1 = imax + 1;
                im  = imax * (imax - 1) / 2;
                imj = im + 2 * imax;

                for (j = imaxp1; j <= k; j++)
                {
                    rowmax = Math.Max(rowmax, Math.Abs(ap[imj - 1]));
                    imj   += j;
                }

                if (imax != 1)
                {
                    int jmax = BLAS1D.idamax(imax - 1, ap, 1, index: +im);
                    int jmim = jmax + im;
                    rowmax = Math.Max(rowmax, Math.Abs(ap[jmim - 1]));
                }

                int imim = imax + im;

                if (alpha * rowmax <= Math.Abs(ap[imim - 1]))
                {
                    kstep = 1;
                    swap  = true;
                }
                else if (alpha * colmax * (colmax / rowmax) <= absakk)
                {
                    kstep = 1;
                    swap  = false;
                }
                else
                {
                    kstep = 2;
                    swap  = imax != km1;
                }
            }

            switch (Math.Max(absakk, colmax))
            {
            //
            //  Column K is zero.  Set INFO and iterate the loop.
            //
            case 0.0:
                kpvt[k - 1] = k;
                info        = k;
                break;

            default:
            {
                double mulk;
                int    jk;
                int    jj;
                double t;
                int    ij;
                if (kstep != 2)
                {
                    switch (swap)
                    {
                    //
                    //  1 x 1 pivot block.
                    //
                    case true:
                    {
                        //
                        //  Perform an interchange.
                        //
                        BLAS1D.dswap(imax, ref ap, 1, ref ap, 1, xIndex: +im, yIndex: +ik);
                        imj = ik + imax;

                        for (jj = imax; jj <= k; jj++)
                        {
                            j           = k + imax - jj;
                            jk          = ik + j;
                            t           = ap[jk - 1];
                            ap[jk - 1]  = ap[imj - 1];
                            ap[imj - 1] = t;
                            imj        -= j - 1;
                        }

                        break;
                    }
                    }

                    //
                    //  Perform the elimination.
                    //
                    ij = ik - (k - 1);

                    for (jj = 1; jj <= km1; jj++)
                    {
                        j    = k - jj;
                        jk   = ik + j;
                        mulk = -ap[jk - 1] / ap[kk - 1];
                        t    = mulk;
                        BLAS1D.daxpy(j, t, ap, 1, ref ap, 1, xIndex: +ik, yIndex: +ij);
                        ap[jk - 1] = mulk;
                        ij        -= j - 1;
                    }

                    kpvt[k - 1] = swap switch
                    {
                        //
                        //  Set the pivot array.
                        //
                        true => imax,
                        _ => k
                    };
                }
                else
                {
                    //
                    //  2 x 2 pivot block.
                    //
                    int km1k = ik + k - 1;
                    int ikm1 = ik - (k - 1);
                    int jkm1;
                    switch (swap)
                    {
                    //
                    //  Perform an interchange.
                    //
                    case true:
                    {
                        BLAS1D.dswap(imax, ref ap, 1, ref ap, 1, xIndex: +im, yIndex: +ikm1);
                        imj = ikm1 + imax;

                        for (jj = imax; jj <= km1; jj++)
                        {
                            j            = km1 + imax - jj;
                            jkm1         = ikm1 + j;
                            t            = ap[jkm1 - 1];
                            ap[jkm1 - 1] = ap[imj - 1];
                            ap[imj - 1]  = t;
                            imj         -= j - 1;
                        }

                        t            = ap[km1k - 1];
                        ap[km1k - 1] = ap[imk - 1];
                        ap[imk - 1]  = t;
                        break;
                    }
                    }

                    //
                    //  Perform the elimination.
                    //
                    if (k - 2 != 0)
                    {
                        double ak     = ap[kk - 1] / ap[km1k - 1];
                        int    km1km1 = ikm1 + k - 1;
                        double akm1   = ap[km1km1 - 1] / ap[km1k - 1];
                        double denom  = 1.0 - ak * akm1;
                        ij = ik - (k - 1) - (k - 2);

                        for (jj = 1; jj <= k - 2; jj++)
                        {
                            j  = km1 - jj;
                            jk = ik + j;
                            double bk = ap[jk - 1] / ap[km1k - 1];
                            jkm1 = ikm1 + j;
                            double bkm1 = ap[jkm1 - 1] / ap[km1k - 1];
                            mulk = (akm1 * bk - bkm1) / denom;
                            double mulkm1 = (ak * bkm1 - bk) / denom;
                            t = mulk;
                            BLAS1D.daxpy(j, t, ap, 1, ref ap, 1, xIndex: +ik, yIndex: +ij);
                            t = mulkm1;
                            BLAS1D.daxpy(j, t, ap, 1, ref ap, 1, xIndex: +ikm1, yIndex: +ij);
                            ap[jk - 1]   = mulk;
                            ap[jkm1 - 1] = mulkm1;
                            ij          -= j - 1;
                        }
                    }

                    kpvt[k - 1] = swap switch
                    {
                        //
                        //  Set the pivot array.
                        //
                        true => - imax,
                        _ => 1 - k
                    };

                    kpvt[k - 2] = kpvt[k - 1];
                }

                break;
            }
            }

            ik -= k - 1;
            switch (kstep)
            {
            case 2:
                ik -= k - 2;
                break;
            }

            k -= kstep;
        }

        return(info);
    }
}
Esempio n. 5
0
    public static int dsifa(ref double[] a, int lda, int n, ref int[] kpvt)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    DSIFA factors a real symmetric matrix.
    //
    //  Discussion:
    //
    //    To solve A*X = B, follow DSIFA by DSISL.
    //
    //    To compute inverse(A)*C, follow DSIFA by DSISL.
    //
    //    To compute determinant(A), follow DSIFA by DSIDI.
    //
    //    To compute inertia(A), follow DSIFA by DSIDI.
    //
    //    To compute inverse(A), follow DSIFA by DSIDI.
    //
    //  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 symmetric matrix
    //    to be factored.  Only the diagonal and upper triangle are used.
    //    On output, a block diagonal matrix and the multipliers which
    //    were used to obtain it.  The factorization can be written A = U*D*U'
    //    where U is a product of permutation and unit upper triangular
    //    matrices, U' is the transpose of U, and D is block diagonal
    //    with 1 by 1 and 2 by 2 blocks.
    //
    //    Input, int LDA, the leading dimension of the array A.
    //
    //    Input, int N, the order of the matrix.
    //
    //    Output, int KPVT[N], the pivot indices.
    //
    //    Output, integer DSIFA, error flag.
    //    0, normal value.
    //    K, if the K-th pivot block is singular.  This is not an error
    //    condition for this subroutine, but it does indicate that DSISL
    //    or DSIDI may divide by zero if called.
    //
    {
        //
        //  ALPHA is used in choosing pivot block size.
        //
        double alpha = (1.0 + Math.Sqrt(17.0)) / 8.0;

        int info = 0;
        //
        //  Main loop on K, which goes from N to 1.
        //
        int k = n;

        while (0 < k)
        {
            switch (k)
            {
            case 1:
            {
                kpvt[0] = 1;
                info    = a[0 + 0 * lda] switch
                {
                    0.0 => 1,
                    _ => info
                };

                return(info);
            }
            }

            //
            //  This section of code determines the kind of
            //  elimination to be performed.  When it is completed,
            //  KSTEP will be set to the size of the pivot block, and
            //  SWAP will be set to .true. if an interchange is required.
            //
            double absakk = Math.Abs(a[k - 1 + (k - 1) * lda]);
            //
            //  Determine the largest off-diagonal element in column K.
            //
            int    imax   = BLAS1D.idamax(k - 1, a, 1, index: +0 + (k - 1) * lda);
            double colmax = Math.Abs(a[imax - 1 + (k - 1) * lda]);

            int  j;
            int  kstep;
            bool swap;
            if (alpha * colmax <= absakk)
            {
                kstep = 1;
                swap  = false;
            }
            //
            //  Determine the largest off-diagonal element in row IMAX.
            //
            else
            {
                double rowmax = 0.0;
                int    imaxp1 = imax + 1;
                for (j = imaxp1; j <= k; j++)
                {
                    rowmax = Math.Max(rowmax, Math.Abs(a[imax - 1 + (j - 1) * lda]));
                }

                if (imax != 1)
                {
                    int jmax = BLAS1D.idamax(imax - 1, a, 1, index: +0 + (imax - 1) * lda);
                    rowmax = Math.Max(rowmax, Math.Abs(a[jmax - 1 + (imax - 1) * lda]));
                }

                if (alpha * rowmax <= Math.Abs(a[imax - 1 + (imax - 1) * lda]))
                {
                    kstep = 1;
                    swap  = true;
                }
                else if (alpha * colmax * (colmax / rowmax) <= absakk)
                {
                    kstep = 1;
                    swap  = false;
                }
                else
                {
                    kstep = 2;
                    swap  = imax != k - 1;
                }
            }

            switch (Math.Max(absakk, colmax))
            {
            //
            //  Column K is zero.
            //  Set INFO and iterate the loop.
            //
            case 0.0:
                kpvt[k - 1] = k;
                info        = k;
                break;

            //
            default:
            {
                int    jj;
                double mulk;
                double t;
                if (kstep != 2)
                {
                    switch (swap)
                    {
                    case true:
                    {
                        BLAS1D.dswap(imax, ref a, 1, ref a, 1, xIndex: +0 + (imax - 1) * lda,
                                     yIndex: +0 + (k - 1) * lda);

                        for (jj = imax; jj <= k; jj++)
                        {
                            j = k + imax - jj;
                            t = a[j - 1 + (k - 1) * lda];
                            a[j - 1 + (k - 1) * lda]    = a[imax - 1 + (j - 1) * lda];
                            a[imax - 1 + (j - 1) * lda] = t;
                        }

                        break;
                    }
                    }

                    //
                    //  Perform the elimination.
                    //
                    for (jj = 1; jj <= k - 1; jj++)
                    {
                        j    = k - jj;
                        mulk = -a[j - 1 + (k - 1) * lda] / a[k - 1 + (k - 1) * lda];
                        t    = mulk;
                        BLAS1D.daxpy(j, t, a, 1, ref a, 1, xIndex: +0 + (k - 1) * lda, yIndex: +0 + (j - 1) * lda);
                        a[j - 1 + (k - 1) * lda] = mulk;
                    }

                    kpvt[k - 1] = swap switch
                    {
                        //
                        //  Set the pivot array.
                        //
                        true => imax,
                        _ => k
                    };
                }
                //
                //  2 x 2 pivot block.
                //
                //  Perform an interchange.
                //
                else
                {
                    switch (swap)
                    {
                    case true:
                    {
                        BLAS1D.dswap(imax, ref a, 1, ref a, 1, xIndex: +0 + (imax - 1) * lda,
                                     yIndex: +0 + (k - 2) * lda);

                        for (jj = imax; jj <= k - 1; jj++)
                        {
                            j = k - 1 + imax - jj;
                            t = a[j - 1 + (k - 1) * lda];
                            a[j - 1 + (k - 1) * lda]    = a[imax - 1 + (j - 1) * lda];
                            a[imax - 1 + (j - 1) * lda] = t;
                        }

                        t = a[k - 2 + (k - 1) * lda];
                        a[k - 2 + (k - 1) * lda]    = a[imax - 1 + (k - 1) * lda];
                        a[imax - 1 + (k - 1) * lda] = t;
                        break;
                    }
                    }

                    //
                    //  Perform the elimination.
                    //
                    if (k - 2 != 0)
                    {
                        double ak    = a[k - 1 + (k - 1) * lda] / a[k - 2 + (k - 1) * lda];
                        double akm1  = a[k - 2 + (k - 2) * lda] / a[k - 2 + (k - 1) * lda];
                        double denom = 1.0 - ak * akm1;

                        for (jj = 1; jj <= k - 2; jj++)
                        {
                            j = k - 1 - jj;
                            double bk   = a[j - 1 + (k - 1) * lda] / a[k - 2 + (k - 1) * lda];
                            double bkm1 = a[j - 1 + (k - 2) * lda] / a[k - 2 + (k - 1) * lda];
                            mulk = (akm1 * bk - bkm1) / denom;
                            double mulkm1 = (ak * bkm1 - bk) / denom;
                            t = mulk;
                            BLAS1D.daxpy(j, t, a, 1, ref a, 1, xIndex: +0 + (k - 1) * lda, yIndex: +0 + (j - 1) * lda);
                            t = mulkm1;
                            BLAS1D.daxpy(j, t, a, 1, ref a, 1, xIndex: +0 + (k - 2) * lda, yIndex: +0 + (j - 1) * lda);
                            a[j - 1 + (k - 1) * lda] = mulk;
                            a[j - 1 + (k - 2) * lda] = mulkm1;
                        }
                    }

                    kpvt[k - 1] = swap switch
                    {
                        //
                        //  Set the pivot array.
                        //
                        true => - imax,
                        _ => 1 - k
                    };

                    kpvt[k - 2] = kpvt[k - 1];
                }

                break;
            }
            }

            k -= kstep;
        }

        return(info);
    }
}