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(); }
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(); }
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(); }
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(); }
public int zunmhrQuery(LAPACK.Side side, BLAS.MatrixTransposeState transposeState, int m, int n, int ilo, int ihi) { throw new NotImplementedException(); }
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(); }
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(); }
public int driver_zgelsQuery(int m, int n, int nrhs, BLAS.MatrixTransposeState transposeState = BLAS.MatrixTransposeState.NoTranspose) { throw new NotImplementedException(); }
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(); }
/// <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]; } } } } } }
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; } } } }
/// <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; } } } } }