예제 #1
0
 public void zupmtr(int m, int n, Complex[] ap, Complex[] tau, Complex[] c, Complex[] work, LAPACK.Side side = LAPACK.Side.Left, BLAS.MatrixTransposeState transposeState = BLAS.MatrixTransposeState.NoTranspose, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
 {
     throw new NotImplementedException();
 }
예제 #2
0
 public void zunmtr(int m, int n, Complex[] a, Complex[] tau, Complex[] c, Complex[] work, LAPACK.Side side, BLAS.MatrixTransposeState transposeState, BLAS.TriangularMatrixType triangularMatrixType)
 {
     throw new NotImplementedException();
 }
예제 #3
0
 public int zunmtrQuery(int m, int n, LAPACK.Side side = LAPACK.Side.Left, BLAS.MatrixTransposeState transposeState = BLAS.MatrixTransposeState.NoTranspose, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
 {
     throw new NotImplementedException();
 }
예제 #4
0
 public void zunmhr(LAPACK.Side side, BLAS.MatrixTransposeState transposeState, int m, int n, int ilo, int ihi, Complex[] a, Complex[] tau, Complex[] c, Complex[] work)
 {
     throw new NotImplementedException();
 }
예제 #5
0
 public int zunmhrQuery(LAPACK.Side side, BLAS.MatrixTransposeState transposeState, int m, int n, int ilo, int ihi)
 {
     throw new NotImplementedException();
 }
예제 #6
0
 public void zunmbr(LapackEigenvalues.SVDxormbrJob job, int m, int n, int k, Complex[] a, Complex[] tau, Complex[] c, Complex[] work, LAPACK.Side side = LAPACK.Side.Left, BLAS.MatrixTransposeState transposeState = BLAS.MatrixTransposeState.NoTranspose)
 {
     throw new NotImplementedException();
 }
예제 #7
0
 public int zunmbrQuery(LapackEigenvalues.SVDxormbrJob job, int m, int n, int k, LAPACK.Side side = LAPACK.Side.Left, BLAS.MatrixTransposeState transposeState = BLAS.MatrixTransposeState.NoTranspose)
 {
     throw new NotImplementedException();
 }
예제 #8
0
 public int driver_zgelsQuery(int m, int n, int nrhs, BLAS.MatrixTransposeState transposeState = BLAS.MatrixTransposeState.NoTranspose)
 {
     throw new NotImplementedException();
 }
예제 #9
0
 public void ztrsyl(BLAS.MatrixTransposeState transposeStateA, BLAS.MatrixTransposeState transposeStateB, int sign, int m, int n, Complex[] a, Complex[] b, Complex[] c, out double scale)
 {
     throw new NotImplementedException();
 }
예제 #10
0
        /// <summary>Solves a triangular matrix equation, i.e. op(A) * X = \alpha * B or X * op(A) = \alpha *B, where A is a unit or non-unit upper or lower triangular matrix.
        /// </summary>
        /// <param name="m">The number of rows of matrix B.</param>
        /// <param name="n">The number of column of matrix B.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="a">The triangular matrix A supplied column-by-column of dimension (<paramref name="lda"/>, k), where k is <paramref name="m"/> if to calculate op(A) * X = \alpha * B; <paramref name="n"/> otherwise.</param>
        /// <param name="b">The matrix B supplied column-by-column of dimension (<paramref name="ldb"/>, <paramref name="n"/>).</param>
        /// <param name="lda">The leading dimension of <paramref name="a"/>, must be at least max(1,<paramref name="m"/>) if to calculate op(A) * X = \alpha * B; max(1,<paramref name="n"/>) otherwise.</param>
        /// <param name="ldb">The leading dimension of <paramref name="b"/>, must be at least max(1,<paramref name="m"/>).</param>
        /// <param name="isUnitTriangular">A value indicating whether the matrix A is unit triangular.</param>
        /// <param name="side">A value indicating whether to calculate op(A) * X = \alpha * B or X * op(A) = \alpha *B.</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="transpose">A value indicating whether 'op(A)=A' or 'op(A)=A^t'.</param>
        public void dtrsm(int m, int n, double alpha, double[] a, double[] b, int lda, int ldb, bool isUnitTriangular = true, BLAS.Side side = BLAS.Side.Left, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, BLAS.MatrixTransposeState transpose = BLAS.MatrixTransposeState.NoTranspose)
        {
            if (n == 0)
            {
                return; // nothing to do
            }

            if (side == BLAS.Side.Left)
            {
                if (transpose == BLAS.MatrixTransposeState.NoTranspose)  // A * X = \alpha * B, i.e. X [=:B] = \alpha * Inv(A) * B
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                b[i + j * ldb] = alpha * b[i + j * ldb];
                            }

                            for (int k = m - 1; k >= 0; k--)
                            {
                                if (b[k + j * ldb] != 0.0)
                                {
                                    if (isUnitTriangular == false)
                                    {
                                        b[k + j * ldb] /= a[k + k * lda];
                                    }
                                    for (int i = 0; i <= k - 1; i++)
                                    {
                                        b[i + j * ldb] -= b[k + j * ldb] * a[i + k * lda];
                                    }
                                }
                            }
                        }
                    }
                    else  // lower triangular matrix
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                b[i + j * ldb] = alpha * b[i + j * ldb];
                            }

                            for (int k = 0; k < m; k++)
                            {
                                if (isUnitTriangular == false)
                                {
                                    b[k + j * ldb] /= a[k + k * lda];
                                }
                                for (int i = k + 1; i < m; i++)
                                {
                                    b[i + j * ldb] -= b[k + j * ldb] * a[i + k * lda];
                                }
                            }
                        }
                    }
                }
                else  // A' * X = \alpha * B, i.e. X [=: B] = \alpha * inv(A') * B
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                double temp = alpha * b[i + j * ldb];
                                for (int k = 0; k <= i - 1; k++)
                                {
                                    temp -= a[k + i * lda] * b[k + j * ldb];
                                }
                                if (isUnitTriangular == false)
                                {
                                    temp /= a[i + i * lda];
                                }
                                b[i + j * ldb] = temp;
                            }
                        }
                    }
                    else  // lower triangular matrix
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = m - 1; i >= 0; i--)
                            {
                                double temp = alpha * b[i + j * ldb];
                                for (int k = i + 1; k < m; k++)
                                {
                                    temp -= a[k + i * lda] * b[k + j * ldb];
                                }
                                if (isUnitTriangular == false)
                                {
                                    temp /= a[i + i * lda];
                                }
                                b[i + j * ldb] = temp;
                            }
                        }
                    }
                }
            }
            else  // side == BLAS.Side.Right
            {
                if (transpose == BLAS.MatrixTransposeState.NoTranspose)  // X  * A = \alpha * B, i.e. X [=:B] = \alpha * B * Inv(A)
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                b[i + j * ldb] = alpha * b[i + j * ldb];
                            }

                            for (int k = 0; k <= j - 1; k++)
                            {
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] -= a[k + j * lda] * b[i + k * ldb];
                                }
                            }
                            if (isUnitTriangular == false)
                            {
                                double temp = 1.0 / a[j + j * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] = temp * b[i + j * ldb];
                                }
                            }
                        }
                    }
                    else  // lower triangular matrix
                    {
                        for (int j = n - 1; j >= 0; j--)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                b[i + j * ldb] = alpha * b[i + j * ldb];
                            }
                            for (int k = j + 1; k < n; k++)
                            {
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] -= a[k + j * lda] * b[i + k * ldb];
                                }
                            }

                            if (isUnitTriangular == false)
                            {
                                double temp = 1.0 / a[j + j * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] = temp * b[i + j * ldb];
                                }
                            }
                        }
                    }
                }
                else  // X  * A' = \alpha * B, i.e. X [=:B] = \alpha * B * Inv(A')
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        for (int k = n - 1; k >= 0; k--)
                        {
                            if (isUnitTriangular == false)
                            {
                                double temp = 1.0 / a[k + k * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + k * ldb] = temp * b[i + k * ldb];
                                }
                            }
                            for (int j = 0; j <= k - 1; j++)
                            {
                                double temp = a[j + k * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] -= temp * b[i + k * ldb];
                                }
                            }

                            for (int i = 0; i < m; i++)
                            {
                                b[i + k * ldb] = alpha * b[i + k * ldb];
                            }
                        }
                    }
                    else  // lower triangular matrix
                    {
                        for (int k = 0; k < n; k++)
                        {
                            if (isUnitTriangular == false)
                            {
                                double temp = 1.0 / a[k + k * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + k * ldb] = temp * b[i + k * ldb];
                                }
                            }
                            for (int j = k + 1; j < n; j++)
                            {
                                double temp = a[j + k * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] -= temp * b[i + k * ldb];
                                }
                            }

                            for (int i = 0; i < m; i++)
                            {
                                b[i + k * ldb] = alpha * b[i + k * ldb];
                            }
                        }
                    }
                }
            }
        }
예제 #11
0
 public void driver_zgels(int m, int n, int nrhs, Complex[] a, Complex[] b, Complex[] work, BLAS.MatrixTransposeState transposeState = BLAS.MatrixTransposeState.NoTranspose)
 {
     throw new NotImplementedException();
 }
        /// <summary>Solves a system of linear equations whose coefficients are in a triangular matrix, i.e. op(A) * x = b, where op(A) = A, op(A) = A ^t or op(A) = A^h.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="a">The triangular matrix A with dimension (<paramref name="lda" />, <paramref name="n" />).</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" /> - 1) * | <paramref name="incX" /> | elements.</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1, <paramref name="n" />).</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="isUnitTriangular">A value indicating whether the matrix A is unit triangular.</param>
        /// <param name="transpose">A value indicating whether 'op(A)=A', 'op(A)=A^t' or 'op(A)=A^h'.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        public void ztrsv(int n, Complex[] a, Complex[] x, int lda, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, bool isUnitTriangular = true, BLAS.MatrixTransposeState transpose = BLAS.MatrixTransposeState.NoTranspose, int incX = 1)
        {
            if (n == 0)
            {
                return;
            }
            int kx = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }
            else if (incX != 1)
            {
                kx = 1;
            }

            if (transpose == BLAS.MatrixTransposeState.NoTranspose) // x := Inv( A ) *x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int jx = kx + (n - 1) * incX;
                    for (int j = n; j >= 1; j--)
                    {
                        if (isUnitTriangular == false)
                        {
                            x[jx - 1] /= a[j - 1 + (j - 1) * lda];
                        }
                        Complex temp = x[jx - 1];
                        int     ix   = jx;
                        for (int i = j - 1; i >= 1; i--)
                        {
                            ix        -= incX;
                            x[ix - 1] -= temp * a[i - 1 + (j - 1) * lda];
                        }
                        jx -= incX;
                    }
                }
                else
                {
                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        if (isUnitTriangular == false)
                        {
                            x[jx - 1] /= a[j - 1 + (j - 1) * lda];
                        }
                        Complex temp = x[jx - 1];
                        int     ix   = jx;
                        for (int i = j + 1; i <= n; i++)
                        {
                            ix        += incX;
                            x[ix - 1] -= temp * a[i - 1 + (j - 1) * lda];
                        }
                        jx += incX;
                    }
                }
            }
            else if (transpose == BLAS.MatrixTransposeState.Transpose) // x := Inv( A' ) * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        for (int i = 1; i <= j - 1; i++)
                        {
                            temp -= a[i - 1 + (j - 1) * lda] * x[ix - 1];
                            ix   += incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= a[j - 1 + (j - 1) * lda];
                        }
                        x[jx - 1] = temp;
                        jx       += incX;
                    }
                }
                else
                {
                    kx += (n - 1) * incX;
                    int jx = kx;
                    for (int j = n; j >= 1; j--)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        for (int i = n; i >= j + 1; i--)
                        {
                            temp -= a[i - 1 + (j - 1) * lda] * x[ix - 1];
                            ix   -= incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= a[j - 1 + (j - 1) * lda];
                        }
                        x[jx - 1] = temp;
                        jx       -= incX;
                    }
                }
            }
            else // x := Inv( Conj(A)' ) * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        for (int i = 1; i <= j - 1; i++)
                        {
                            temp -= Complex.Conjugate(a[i - 1 + (j - 1) * lda]) * x[ix - 1];
                            ix   += incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= Complex.Conjugate(a[j - 1 + (j - 1) * lda]);
                        }
                        x[jx - 1] = temp;
                        jx       += incX;
                    }
                }
                else
                {
                    kx += (n - 1) * incX;
                    int jx = kx;
                    for (int j = n; j >= 1; j--)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        for (int i = n; i >= j + 1; i--)
                        {
                            temp -= Complex.Conjugate(a[i - 1 + (j - 1) * lda]) * x[ix - 1];
                            ix   -= incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= Complex.Conjugate(a[j - 1 + (j - 1) * lda]);
                        }
                        x[jx - 1] = temp;
                        jx       -= incX;
                    }
                }
            }
        }
        /// <summary>Computes a matrix-vector product for a general matrix, i.e. y = \alpha * op(A)*x + \beta*y, where op(A) = A, op(A) = A^t or op(A) = A^h.
        /// </summary>
        /// <param name="m">The number of rows of matrix A.</param>
        /// <param name="n">The number of columns of matrix A.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="a">The matrix A of dimension (<paramref name="lda" />, <paramref name="n" />) supplied column-by-column.</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" />-1) * |<paramref name="incX" />| elements if 'op(A)=A'; 1 + (<paramref name="m" />-1) * |<paramref name="incY" />| elements otherwise.</param>
        /// <param name="beta">The scalar \beta.</param>
        /// <param name="y">The vector y with at least 1 + (<paramref name="m" />-1) * |<paramref name="incY" />| elements if 'op(A)=A'; 1 + (<paramref name="n" />-1) * | <paramref name="incX" />| otherwise (input/output).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1,<paramref name="m" />).</param>
        /// <param name="transpose">A value indicating whether 'op(A)=A' or 'op(A)=A^t'.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        /// <param name="incY">The increment for the elements of <paramref name="y" />.</param>
        public void zgemv(int m, int n, Complex alpha, Complex[] a, Complex[] x, Complex beta, Complex[] y, int lda, BLAS.MatrixTransposeState transpose = BLAS.MatrixTransposeState.NoTranspose, int incX = 1, int incY = 1)
        {
            if (m == 0 || n == 0 || alpha == 0.0 && beta == 1.0)
            {
                return;
            }

            int lenx, leny;

            if (transpose == BLAS.MatrixTransposeState.NoTranspose)
            {
                lenx = n;
                leny = m;
            }
            else
            {
                lenx = m;
                leny = n;
            }
            int kx = 1;
            int ky = 1;

            if (incX <= 0)
            {
                kx = 1 - (lenx - 1) * incX;
            }
            if (incY <= 0)
            {
                ky = 1 - (leny - 1) * incY;
            }


            // y := \beta * y
            int iy = ky;

            for (int i = 1; i <= leny; i++)
            {
                y[iy - 1] *= beta;
                iy        += incY;
            }

            if (transpose == BLAS.MatrixTransposeState.NoTranspose)  // y := \alpha * A * x + y
            {
                int jx = kx;
                for (int j = 1; j <= n; ++j)
                {
                    Complex temp = alpha * x[jx - 1];
                    iy = ky;

                    for (int i = 1; i <= m; ++i)
                    {
                        y[iy - 1] += temp * a[i - 1 + (j - 1) * lda];
                        iy        += incY;
                    }
                    jx += incX;
                }
            }
            else if (transpose == BLAS.MatrixTransposeState.Transpose) // y := \alpha * A' *x + y
            {
                int jy = ky;
                for (int j = 1; j <= n; j++)
                {
                    Complex temp = 0.0;
                    int     ix   = kx;
                    for (int i = 1; i <= m; i++)
                    {
                        temp += a[i - 1 + (j - 1) * lda] * x[ix - 1];
                        ix   += incX;
                    }
                    y[jy - 1] += alpha * temp;
                    jy        += incY;
                }
            }
            else // y := \alpha *conj(A)' * x + y
            {
                int jy = ky;
                for (int j = 1; j <= n; j++)
                {
                    Complex temp = 0.0;
                    int     ix   = kx;
                    for (int i = 1; i <= m; i++)
                    {
                        temp += Complex.Conjugate(a[i - 1 + (j - 1) * lda]) * x[ix - 1];
                        ix   += incX;
                    }
                    y[jy - 1] += alpha * temp;
                    jy        += incY;
                }
            }
        }
        /// <summary>Computes a matrix-vector product using a triangular packed matrix, i.e. x := op(A) * x, where op(A) = A, op(A) = A ^t or op(A) = A^h.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="aPacked">The triangular packed matrix A with dimension at least (<paramref name="n" /> * (<paramref name="n" /> + 1) ) / 2.</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" /> - 1) * | <paramref name="incX" /> | elements.</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="isUnitTriangular">A value indicating whether the matrix A is unit triangular.</param>
        /// <param name="transpose">A value indicating whether 'op(A)=A', 'op(A)=A^t' or 'op(A)=A^h'.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        public void ztpmv(int n, Complex[] aPacked, Complex[] x, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, bool isUnitTriangular = true, BLAS.MatrixTransposeState transpose = BLAS.MatrixTransposeState.NoTranspose, int incX = 1)
        {
            if (n == 0)
            {
                return;
            }

            int kx = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }
            else if (incX != 1)
            {
                kx = 1;
            }

            if (transpose == BLAS.MatrixTransposeState.NoTranspose)  // x := A * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int kk = 1;

                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        for (int k = kk; k <= kk + j - 2; k++)
                        {
                            x[ix - 1] += temp * aPacked[k - 1];
                            ix        += incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            x[jx - 1] *= aPacked[kk + j - 2];
                        }
                        jx += incX;
                        kk += j;
                    }
                }
                else
                {
                    int kk = n * (n + 1) / 2;

                    kx += (n - 1) * incX;
                    int jx = kx;
                    for (int j = n; j >= 1; j--)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        for (int k = kk; k >= kk - (n - (j + 1)); k--)
                        {
                            x[ix - 1] += temp * aPacked[k - 1];
                            ix        -= incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            x[jx - 1] *= aPacked[kk - n + j - 1];
                        }
                        jx -= incX;
                        kk -= n - j + 1;
                    }
                }
            }
            else if (transpose == BLAS.MatrixTransposeState.Transpose)  // x := A' * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int kk = n * (n + 1) / 2;

                    int jx = kx + (n - 1) * incX;
                    for (int j = n; j >= 1; j--)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = jx;
                        if (isUnitTriangular == false)
                        {
                            temp *= aPacked[kk - 1];
                        }
                        for (int k = kk - 1; k >= kk - j + 1; k--)
                        {
                            ix   -= incX;
                            temp += aPacked[k - 1] * x[ix - 1];
                        }
                        x[jx - 1] = temp;
                        jx       -= incX;
                        kk       -= j;
                    }
                }
                else
                {
                    int kk = 1;

                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = jx;
                        if (isUnitTriangular == false)
                        {
                            temp *= aPacked[kk - 1];
                        }
                        for (int k = kk + 1; k <= kk + n - j; k++)
                        {
                            ix   += incX;
                            temp += aPacked[k - 1] * x[ix - 1];
                        }
                        x[jx - 1] = temp;
                        jx       += incX;
                        kk       += n - j + 1;
                    }
                }
            }
            else  // x := conj(A)' * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int kk = n * (n + 1) / 2;

                    int jx = kx + (n - 1) * incX;
                    for (int j = n; j >= 1; j--)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = jx;
                        if (isUnitTriangular == false)
                        {
                            temp *= Complex.Conjugate(aPacked[kk - 1]);
                        }
                        for (int k = kk - 1; k >= kk - j + 1; k--)
                        {
                            ix   -= incX;
                            temp += Complex.Conjugate(aPacked[k - 1]) * x[ix - 1];
                        }
                        x[jx - 1] = temp;
                        jx       -= incX;
                        kk       -= j;
                    }
                }
                else
                {
                    int kk = 1;

                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = jx;
                        if (isUnitTriangular == false)
                        {
                            temp *= Complex.Conjugate(aPacked[kk - 1]);
                        }
                        for (int k = kk + 1; k <= kk + n - j; k++)
                        {
                            ix   += incX;
                            temp += Complex.Conjugate(aPacked[k - 1]) * x[ix - 1];
                        }
                        x[jx - 1] = temp;
                        jx       += incX;
                        kk       += n - j + 1;
                    }
                }
            }
        }
예제 #15
0
        /// <summary>Solves a triangular matrix equation, i.e. op(A) * X = \alpha * B or X * op(A) = \alpha *B, where A is a unit or non-unit upper or lower triangular matrix.
        /// </summary>
        /// <param name="m">The number of rows of matrix B.</param>
        /// <param name="n">The number of column of matrix B.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="a">The triangular matrix A supplied column-by-column of dimension (<paramref name="lda" />, k), where k is <paramref name="m" /> if to calculate op(A) * X = \alpha * B; <paramref name="n" /> otherwise.</param>
        /// <param name="b">The matrix B supplied column-by-column of dimension (<paramref name="ldb" />, <paramref name="n" />).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1,<paramref name="m" />) if to calculate op(A) * X = \alpha * B; max(1,<paramref name="n" />) otherwise.</param>
        /// <param name="ldb">The leading dimension of <paramref name="b" />, must be at least max(1,<paramref name="m" />).</param>
        /// <param name="isUnitTriangular">A value indicating whether the matrix A is unit triangular.</param>
        /// <param name="side">A value indicating whether to calculate op(A) * X = \alpha * B or X * op(A) = \alpha *B.</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="transpose">A value indicating whether 'op(A)=A' or 'op(A)=A^t'.</param>
        public void ztrsm(int m, int n, Complex alpha, Complex[] a, Complex[] b, int lda, int ldb, bool isUnitTriangular = true, BLAS.Side side = BLAS.Side.Left, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, BLAS.MatrixTransposeState transpose = BLAS.MatrixTransposeState.NoTranspose)
        {
            if (side == BLAS.Side.Left)
            {
                if (transpose == BLAS.MatrixTransposeState.NoTranspose)  // B := \alpha * Inv(A) * B
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                b[i + j * ldb] *= alpha;
                            }
                            for (int k = m - 1; k >= 0; k--)
                            {
                                if (isUnitTriangular == false)
                                {
                                    b[k + j * ldb] = b[k + j * ldb] / a[k + k * lda];
                                }
                                for (int i = 0; i <= k - 1; i++)
                                {
                                    b[i + j * ldb] += -b[k + j * ldb] * a[i + k * lda];
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                b[i + j * ldb] *= alpha;
                            }
                            for (int k = 0; k < m; k++)
                            {
                                if (isUnitTriangular == false)
                                {
                                    b[k + j * ldb] = b[k + j * ldb] / a[k + k * lda];
                                }
                                for (int i = k + 1; i < m; i++)
                                {
                                    b[i + j * ldb] += -b[k + j * ldb] * a[i + k * lda];
                                }
                            }
                        }
                    }
                }
                else  // B:= \alpha * Inv(A') * B or B := \alpha * Inv( Conj(A') ) * B
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        Complex temp = 0.0;

                        for (int j = 0; j < n; j++)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                temp = alpha * b[i + j * ldb];
                                if (transpose == BLAS.MatrixTransposeState.Transpose)
                                {
                                    for (int k = 0; k <= i - 1; k++)
                                    {
                                        temp += -a[k + i * lda] * b[k + j * ldb];
                                    }
                                    if (isUnitTriangular == false)
                                    {
                                        temp = temp / a[i + i * lda];
                                    }
                                }
                                else
                                {
                                    for (int k = 0; k <= i - 1; k++)
                                    {
                                        temp += -Complex.Conjugate(a[k + i * lda]) * b[k + j * ldb];
                                    }
                                    if (isUnitTriangular == false)
                                    {
                                        temp = temp / Complex.Conjugate(a[i + i * lda]);
                                    }
                                }
                                b[i + j * ldb] = temp;
                            }
                        }
                    }
                    else
                    {
                        Complex temp = 0.0;
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = m - 1; i >= 0; i--)
                            {
                                temp = alpha * b[i + j * ldb];
                                if (transpose == BLAS.MatrixTransposeState.Transpose)
                                {
                                    for (int k = i + 1; k < m; k++)
                                    {
                                        temp += -a[k + i * lda] * b[k + j * ldb];
                                    }
                                    if (isUnitTriangular == false)
                                    {
                                        temp = temp / a[i + i * lda];
                                    }
                                }
                                else
                                {
                                    for (int k = i + 1; k < m; k++)
                                    {
                                        temp = temp - Complex.Conjugate(a[k + i * lda]) * b[k + j * ldb];
                                    }
                                    if (isUnitTriangular == false)
                                    {
                                        temp = temp / Complex.Conjugate(a[i + i * lda]);
                                    }
                                }
                                b[i + j * ldb] = temp;
                            }
                        }
                    }
                }
            }
            else
            {
                if (transpose == BLAS.MatrixTransposeState.NoTranspose)  // B := \alpha * B * Inv(A)
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                b[i + j * ldb] = alpha * b[i + j * ldb];
                            }
                            for (int k = 0; k <= j - 1; k++)
                            {
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] = b[i + j * ldb] - a[k + j * lda] * b[i + k * ldb];
                                }
                            }
                            if (isUnitTriangular == false)
                            {
                                Complex temp = 1.0 / a[j + j * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] = temp * b[i + j * ldb];
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int j = n - 1; j >= 0; j--)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                b[i + j * ldb] = alpha * b[i + j * ldb];
                            }
                            for (int k = j + 1; k < n; k++)
                            {
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] = b[i + j * ldb] - a[k + j * lda] * b[i + k * ldb];
                                }
                            }

                            if (isUnitTriangular == false)
                            {
                                Complex temp = 1.0 / a[j + j * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] = temp * b[i + j * ldb];
                                }
                            }
                        }
                    }
                }
                else  // B := \alpha * B * Inv(A') or B:=\alpha * B *Inv( Conj(A') )
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        Complex temp = 0.0;

                        for (int k = n - 1; k >= 0; k--)
                        {
                            if (isUnitTriangular == false)
                            {
                                if (transpose == BLAS.MatrixTransposeState.Hermite)
                                {
                                    temp = 1.0 / Complex.Conjugate(a[k + k * lda]);
                                }
                                else
                                {
                                    temp = 1.0 / a[k + k * lda];
                                }
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + k * ldb] = temp * b[i + k * ldb];
                                }
                            }
                            for (int j = 0; j <= k - 1; j++)
                            {
                                if (transpose == BLAS.MatrixTransposeState.Hermite)
                                {
                                    temp = Complex.Conjugate(a[j + k * lda]);
                                }
                                else
                                {
                                    temp = a[j + k * lda];
                                }
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] = b[i + j * ldb] - temp * b[i + k * ldb];
                                }
                            }
                            for (int i = 0; i < m; i++)
                            {
                                b[i + k * ldb] = alpha * b[i + k * ldb];
                            }
                        }
                    }
                    else
                    {
                        Complex temp = 0.0;

                        for (int k = 0; k < n; k++)
                        {
                            if (isUnitTriangular == false)
                            {
                                if (transpose == BLAS.MatrixTransposeState.Hermite)
                                {
                                    temp = 1.0 / Complex.Conjugate(a[k + k * lda]);
                                }
                                else
                                {
                                    temp = 1.0 / a[k + k * lda];
                                }
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + k * ldb] = temp * b[i + k * ldb];
                                }
                            }
                            for (int j = k + 1; j < n; j++)
                            {
                                if (transpose == BLAS.MatrixTransposeState.Hermite)
                                {
                                    temp = Complex.Conjugate(a[j + k * lda]);
                                }
                                else
                                {
                                    temp = a[j + k * lda];
                                }
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] = b[i + j * ldb] - temp * b[i + k * ldb];
                                }
                            }

                            for (int i = 0; i < m; i++)
                            {
                                b[i + k * ldb] = alpha * b[i + k * ldb];
                            }
                        }
                    }
                }
            }
        }
        /// <summary>Computes a matrix-matrix product with a general matrix, i.e. C := \alpha * op(A)*op(B) + \beta * C, where where op(.) is the identity or the transpose operation.
        /// </summary>
        /// <param name="m">The number of rows of the matrix op(A) and of the matrix C.</param>
        /// <param name="n">The number of columns of the matrix op(B) and of the matrix C.</param>
        /// <param name="k">The number of columns of the matrix op(A) and the number of rows of the matrix op(B).</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="a">The matrix A supplied column-by-column of dimension (<paramref name="lda"/>, ka), where ka is <paramref name="k"/> if op(A) = A; <paramref name="m"/> otherwise.</param>
        /// <param name="b">The matrix B supplied column-by-column of dimension (<paramref name="ldb"/>, kb), where kb is <paramref name="n"/> if op(B) = B; <paramref name="k"/> otherwise.</param>
        /// <param name="beta">The scalar \beta.</param>
        /// <param name="c">The matrix C supplied column-by-column of dimension (<paramref name="ldc"/>, <paramref name="n"/>).</param>
        /// <param name="lda">The leading dimension of <paramref name="a"/>, must be at least max(1,<paramref name="m"/>) if op(A) = A; max(1, <paramref name="k"/>) otherwise.</param>
        /// <param name="ldb">The leading dimension of <paramref name="b"/>, must be at least max(1,<paramref name="k"/>) if op(B) = B; max(1, <paramref name="n"/>) otherwise.</param>
        /// <param name="ldc">The leading dimension of <paramref name="c"/>, must be at least max(1, <paramref name="m"/>).</param>
        /// <param name="transposeA">A value indicating whether 'op(A)=A' or 'op(A)=A^t'.</param>
        /// <param name="transposeB">A value indicating whether 'op(B)=B' or 'op(B)=B^t'.</param>
        public void dgemm(int m, int n, int k, double alpha, double[] a, double[] b, double beta, double[] c, int lda, int ldb, int ldc, BLAS.MatrixTransposeState transposeA = BLAS.MatrixTransposeState.NoTranspose, BLAS.MatrixTransposeState transposeB = BLAS.MatrixTransposeState.NoTranspose)
        {
            if (m == 0 || n == 0 || ((alpha == 0.0 || k == 0) && beta == 1.0))
            {
                return; // nothing to do
            }

            if (a.Length < lda * ((transposeA == BLAS.MatrixTransposeState.NoTranspose) ? k : m))
            {
                throw new ArgumentException("a");
            }
            if (b.Length < ldb * ((transposeB == BLAS.MatrixTransposeState.NoTranspose) ? n : k))
            {
                throw new ArgumentException("b");
            }
            if (c.Length < ldc * n)
            {
                throw new ArgumentException("c");
            }

            if (transposeA == BLAS.MatrixTransposeState.NoTranspose)
            {
                if (transposeB == BLAS.MatrixTransposeState.NoTranspose) // C = \alpha * A * B + \beta * C
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = 0; i < m; i++)
                        {
                            double temp = 0.0;  // = (A*B)_{i,j}
                            for (int r = 0; r < k; r++)
                            {
                                temp += a[i + r * lda] * b[r + j * ldb];
                            }
                            c[i + j * ldc] = alpha * temp + c[i + j * ldc] * beta;
                        }
                    }
                }
                else  // C = \alpha * A * B' + \beta * C
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = 0; i < m; i++)
                        {
                            double temp = 0.0;  // =(A*B')_{i,j}

                            for (int r = 0; r < k; r++)
                            {
                                temp += a[i + r * lda] * b[j + r * ldb];
                            }
                            c[i + j * ldc] = alpha * temp + c[i + j * ldc] * beta;
                        }
                    }
                }
            }
            else
            {
                if (transposeB == BLAS.MatrixTransposeState.NoTranspose)  // C = \alpha * A' * B + \beta * C
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = 0; i < m; i++)
                        {
                            double temp = 0.0;  // = (A'*B)_{i,j}
                            for (int r = 0; r < k; r++)
                            {
                                temp += a[r + i * lda] * b[r + j * ldb];
                            }
                            c[i + j * ldc] = alpha * temp + c[i + j * ldc] * beta;
                        }
                    }
                }
                else  // C = \alpha * A' * B' + \beta * C
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = 0; i < m; i++)
                        {
                            double temp = 0.0;  // = (A'*B')_{i,j}
                            for (int r = 0; r < k; r++)
                            {
                                temp += a[r + i * lda] * b[j + r * ldb];
                            }
                            c[i + j * ldc] = alpha * temp + c[i + j * ldc] * beta;
                        }
                    }
                }
            }
        }