public static float Compute(ComplexFloat a, ComplexFloat b) { ComplexFloat temp = a * ComplexMath.Conjugate(a); temp += (b * ComplexMath.Conjugate(b)); float ret = ComplexMath.Absolute(temp); return (float)System.Math.Sqrt(ret); }
internal static int Compute( int m, int n, int k, ComplexFloat[] A, int lda, ComplexFloat[] tau ){ ArgumentCheck(m, n, k, A, lda, tau); if (tau.Length < System.Math.Max(1, k) ){ throw new ArgumentException("tau must be at least max(1,k)."); } return dna_lapack_cungqr(Configuration.BlockSize, m, n, k, A, lda, tau); }
internal static int Compute( int m, int n, ComplexFloat[] A, int lda, out float[] d, out float[] e, out ComplexFloat[] tauq, out ComplexFloat[] taup ){ ArgumentCheck(m, n, A, lda); d = new float[System.Math.Max(1, System.Math.Min(m,n))]; e = new float[System.Math.Max(1, System.Math.Min(m,n))]; tauq = new ComplexFloat[System.Math.Max(1, System.Math.Min(m,n))]; taup = new ComplexFloat[System.Math.Max(1, System.Math.Min(m,n))]; return dna_lapack_cgebrd(Configuration.BlockSize, m, n, A, lda, d, e, tauq, taup); }
///<summary>Constructor for <c>ComplexFloatVector</c> with components set to a value</summary> ///<param name="length">Length of vector.</param> ///<param name="value"><c>ComplexFloat</c> value to set all components.</param> ///<exception cref="ArgumentException">Exception thrown if length parameter isn't positive</exception> public ComplexFloatVector(int length, ComplexFloat value) { if (length < 1) { throw new ArgumentException("length must be positive.", "length"); } data = new ComplexFloat[length]; for (int i = 0; i < data.Length; ++i) { data[i] = value; } }
///<summary>Constructor for <c>ComplexFloatVector</c> from <c>ComplexFloat</c> array</summary> ///<param name="values">Array of <c>ComplexFloat</c> to convert into <c>ComplexFloatVector</c>.</param> ///<exception cref="ArgumentNullException">Exception thrown if null passed as 'value' parameter.</exception> public ComplexFloatVector(ComplexFloat[] values) { if (values == null) { throw new ArgumentNullException("Array cannot be null"); } data = new ComplexFloat[values.Length]; for (int i = 0; i < values.Length; ++i) { data[i] = values[i]; } }
internal static int Compute( Vector vect, Side side, Transpose trans, int m, int n, int k, ComplexFloat[] A, int lda, ComplexFloat[] tau, ComplexFloat[] C, int ldc ){ ArgumentCheck(vect,side, m, n, k, A, lda, tau, C, ldc); if( side == Side.Left){ if (tau.Length < System.Math.Max(1, System.Math.Min(m,k))){ throw new ArgumentException("tau must be at least max(1,k)."); } }else{ if (tau.Length < System.Math.Max(1, System.Math.Min(n,k))){ throw new ArgumentException("tau must be at least max(1,k)."); } } return dna_lapack_cunmbr(Configuration.BlockSize, vect, side, trans, m, n, k, A, lda, tau, C, ldc); }
///<summary>Compute the function of this class</summary> internal static ComplexFloat Compute( int n, ComplexFloat[] X, int incx, ComplexFloat[] Y, int incy ) { if ( n < 0) { return ComplexFloat.Zero; } ArgumentCheck(n, X, X.Length, ref incx, Y, Y.Length, ref incy); ComplexFloat ret = new ComplexFloat(0); #if MANAGED int ix = 0; int iy = 0; for ( int i = 0; i < n; ++i ) { ret += (ComplexMath.Conjugate(X[ix]) * Y[iy]); ix += incx; iy += incy; } #else dna_blas_cdotc(n, X, incx, Y, incy, ref ret); #endif return ret; }
private static ComplexFloat csign(ComplexFloat z1, ComplexFloat z2) { ComplexFloat ret = ComplexMath.Absolute(z1) * (z2 / ComplexMath.Absolute(z2)); return(ret); }
internal static int Compute( int m, int n, ComplexFloat[] A, int lda, int[] jpvt, out ComplexFloat[] tau ){ ArgumentCheck(m, n, A, lda, jpvt); tau = new ComplexFloat[System.Math.Max(1, System.Math.Min(m,n))]; return dna_lapack_cgeqp3(m,n,A,lda,jpvt,tau); }
/// <summary> /// Solve a symmetric square Toeplitz system with a right-side matrix. /// </summary> /// <param name="Y">The right-hand side of the system.</param> /// <returns>The solution matrix.</returns> /// <exception cref="ArgumentNullException"> /// Parameter <B>Y</B> is a null reference. /// </exception> /// <exception cref="RankException"> /// The number of rows in <B>Y</B> is not equal to the number of rows in the Toeplitz matrix. /// </exception> /// <exception cref="SingularMatrixException"> /// The Toeplitz matrix or one of the the leading sub-matrices is singular. /// </exception> /// <remarks> /// This member solves the linear system <B>TX</B> = <B>Y</B>, where <B>T</B> is /// a symmetric square Toeplitz matrix, <B>X</B> is the unknown solution matrix /// and <B>Y</B> is a known matrix. /// <para> /// The class implicitly decomposes the inverse Toeplitz matrix into a <b>UDL</b> factorisation /// using the Levinson algorithm, and then calculates the solution matrix. /// </para> /// </remarks> public ComplexFloatMatrix Solve(IROComplexFloatMatrix Y) { ComplexFloatMatrix X; // check parameters if (Y == null) { throw new System.ArgumentNullException("Y"); } else if (m_Order != Y.Columns) { throw new RankException("The numer of rows in Y is not equal to the number of rows in the Toeplitz matrix."); } Compute(); if (m_IsSingular == true) { throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular."); } int M = Y.Rows; int i, j, l, m; // index/loop variables ComplexFloat[] Inner; // inner product ComplexFloat[] G; // scaling constant ComplexFloat[] A; // reference to current order coefficients ComplexFloat scalar; // allocate memory for solution X = new ComplexFloatMatrix(m_Order, M); Inner = new ComplexFloat[M]; G = new ComplexFloat[M]; // setup zero order solution scalar = ComplexFloat.One / m_LeftColumn[0]; for (m = 0; m < M; m++) { #if MANAGED X.data[0][m] = scalar * Y[0,m]; #else X.data[m*m_Order] = scalar * Y[0,m]; #endif } // solve systems of increasing order for (i = 1; i < m_Order; i++) { // calculate inner product for (m = 0; m < M; m++) { #if MANAGED Inner[m] = Y[i,m]; #else Inner[m] = Y[i,m]; #endif } for (j = 0, l = i; j < i; j++, l--) { scalar = m_LeftColumn[l]; for (m = 0; m < M; m++) { #if MANAGED Inner[m] -= scalar * X.data[j][m]; #else Inner[m] -= scalar * X.data[m*m_Order+j]; #endif } } // get the current predictor coefficients row A = m_LowerTriangle[i]; // update the solution matrix for (m = 0; m < M; m++) { G[m] = m_Diagonal[i] * Inner[m]; } for (j = 0; j <= i; j++) { scalar = A[j]; for (m = 0; m < M; m++) { #if MANAGED X.data[j][m] += scalar * G[m]; #else X.data[m*m_Order+j] += scalar * G[m]; #endif } } } return X; }
/// <overloads> /// There are two permuations of the constructor, both require a parameter corresponding /// to the left-most column of a Toeplitz matrix. /// </overloads> /// <summary> /// Constructor with <c>ComplexFloatVector</c> parameter. /// </summary> /// <param name="T">The left-most column of the Toeplitz matrix.</param> /// <exception cref="ArgumentNullException"> /// <B>T</B> is a null reference. /// </exception> /// <exception cref="RankException"> /// The length of <B>T</B> is zero. /// </exception> public ComplexFloatSymmetricLevinson(IROComplexFloatVector T) { // check parameter if (T == null) { throw new System.ArgumentNullException("T"); } else if (T.Length == 0) { throw new RankException("The length of T is zero."); } // save the vector m_LeftColumn = new ComplexFloatVector(T); m_Order = m_LeftColumn.Length; // allocate memory for lower triangular matrix m_LowerTriangle = new ComplexFloat[m_Order][]; for (int i = 0; i < m_Order; i++) { m_LowerTriangle[i] = new ComplexFloat[i+1]; } // allocate memory for diagonal m_Diagonal = new ComplexFloat[m_Order]; }
private static extern void dna_blas_cgerc( Order order, int M, int N, ref ComplexFloat alpha, [In]ComplexFloat[] X, int incX, [In]ComplexFloat[] Y, int incY, [In,Out]ComplexFloat[] A, int lda);
internal static int Compute( int n, ComplexFloat[] X, int incx ) { if( n < 0 ) { return 0; } if ( X == null ) { throw new ArgumentNullException( "X", "X cannot be null."); } if( incx == 0 ) { throw new ArgumentException("incx cannot be zero.", "incx"); } incx = System.Math.Abs(incx); if( X.Length < ( 1 + (n-1) * incx) ) { throw new ArgumentException("The dimension of X must be a least 1 + (n-1) * incx."); } int index = 0; float min = System.Single.MaxValue; for ( int i = 0, ix = 0; i < n; ++i, ix += incx ) { float test = System.Math.Abs(X[ix].Real) + System.Math.Abs(X[ix].Imag); if( test < min ) { index = i; min = test; } } return index; }
private static extern void dna_blas_ctrsm(Order order, Side side, UpLo uplo, Transpose transA, Diag diag, int m, int n, ref ComplexFloat alpha, [In] ComplexFloat[] A, int lda, [In, Out] ComplexFloat[] B, int ldb);
///<summary>Computes the algorithm.</summary> protected override void InternalCompute() { rows = matrix.RowLength; cols = matrix.ColumnLength; int mm = System.Math.Min(rows + 1, cols); s = new ComplexFloatVector(mm); // singular values #if MANAGED // Derived from LINPACK code. // Initialize. u = new ComplexFloatMatrix(rows, rows); // left vectors v = new ComplexFloatMatrix(cols, cols); // right vectors ComplexFloatVector e = new ComplexFloatVector(cols); ComplexFloatVector work = new ComplexFloatVector(rows); int i, iter, j, k, kase, l, lp1, ls = 0, lu, m, nct, nctp1, ncu, nrt, nrtp1; float b, c, cs = 0.0f, el, emm1, f, g, scale, shift, sl, sm, sn = 0.0f, smm1, t1, test, ztest, xnorm, enorm; ComplexFloat t, r; ncu = rows; // reduce matrix to bidiagonal form, storing the diagonal elements // in s and the super-diagonal elements in e. int info = 0; nct = System.Math.Min(rows - 1, cols); nrt = System.Math.Max(0, System.Math.Min(cols - 2, rows)); lu = System.Math.Max(nct, nrt); for (l = 0; l < lu; l++) { lp1 = l + 1; if (l < nct) { // compute the transformation for the l-th column and // place the l-th diagonal in s[l]. xnorm = dznrm2Column(matrix, l, l); s[l] = new ComplexFloat(xnorm, 0.0f); if (dcabs1(s[l]) != 0.0f) { if (dcabs1(matrix[l, l]) != 0.0f) { s[l] = csign(s[l], matrix[l, l]); } zscalColumn(matrix, l, l, 1.0f / s[l]); matrix[l, l] = ComplexFloat.One + matrix[l, l]; } s[l] = -s[l]; } for (j = lp1; j < cols; j++) { if (l < nct) { if (dcabs1(s[l]) != 0.0f) { // apply the transformation. t = -zdotc(matrix, l, j, l) / matrix[l, l]; for (int ii = l; ii < matrix.RowLength; ii++) { matrix[ii, j] += t * matrix[ii, l]; } } } //place the l-th row of matrix into e for the //subsequent calculation of the row transformation. e[j] = ComplexMath.Conjugate(matrix[l, j]); } if (computeVectors && l < nct) { // place the transformation in u for subsequent back multiplication. for (i = l; i < rows; i++) { u[i, l] = matrix[i, l]; } } if (l < nrt) { // compute the l-th row transformation and place the l-th super-diagonal in e(l). enorm = dznrm2Vector(e, lp1); e[l] = new ComplexFloat(enorm, 0.0f); if (dcabs1(e[l]) != 0.0f) { if (dcabs1(e[lp1]) != 0.0f) { e[l] = csign(e[l], e[lp1]); } zscalVector(e, lp1, 1.0f / e[l]); e[lp1] = ComplexFloat.One + e[lp1]; } e[l] = ComplexMath.Conjugate(-e[l]); if (lp1 < rows && dcabs1(e[l]) != 0.0f) { // apply the transformation. for (i = lp1; i < rows; i++) { work[i] = ComplexFloat.Zero; } for (j = lp1; j < cols; j++) { for (int ii = lp1; ii < matrix.RowLength; ii++) { work[ii] += e[j] * matrix[ii, j]; } } for (j = lp1; j < cols; j++) { ComplexFloat ww = ComplexMath.Conjugate(-e[j] / e[lp1]); for (int ii = lp1; ii < matrix.RowLength; ii++) { matrix[ii, j] += ww * work[ii]; } } } if (computeVectors) { // place the transformation in v for subsequent back multiplication. for (i = lp1; i < cols; i++) { v[i, l] = e[i]; } } } } // set up the final bidiagonal matrix or order m. m = System.Math.Min(cols, rows + 1); nctp1 = nct + 1; nrtp1 = nrt + 1; if (nct < cols) { s[nctp1 - 1] = matrix[nctp1 - 1, nctp1 - 1]; } if (rows < m) { s[m - 1] = ComplexFloat.Zero; } if (nrtp1 < m) { e[nrtp1 - 1] = matrix[nrtp1 - 1, m - 1]; } e[m - 1] = ComplexFloat.Zero; // if required, generate u. if (computeVectors) { for (j = nctp1 - 1; j < ncu; j++) { for (i = 0; i < rows; i++) { u[i, j] = ComplexFloat.Zero; } u[j, j] = ComplexFloat.One; } for (l = nct - 1; l >= 0; l--) { if (dcabs1(s[l]) != 0.0) { for (j = l + 1; j < ncu; j++) { t = -zdotc(u, l, j, l) / u[l, l]; for (int ii = l; ii < u.RowLength; ii++) { u[ii, j] += t * u[ii, l]; } } zscalColumn(u, l, l, -ComplexFloat.One); u[l, l] = ComplexFloat.One + u[l, l]; for (i = 0; i < l; i++) { u[i, l] = ComplexFloat.Zero; } } else { for (i = 0; i < rows; i++) { u[i, l] = ComplexFloat.Zero; } u[l, l] = ComplexFloat.One; } } } // if it is required, generate v. if (computeVectors) { for (l = cols - 1; l >= 0; l--) { lp1 = l + 1; if (l < nrt) { if (dcabs1(e[l]) != 0.0) { for (j = lp1; j < cols; j++) { t = -zdotc(v, l, j, lp1) / v[lp1, l]; for (int ii = l; ii < v.RowLength; ii++) { v[ii, j] += t * v[ii, l]; } } } } for (i = 0; i < cols; i++) { v[i, l] = ComplexFloat.Zero; } v[l, l] = ComplexFloat.One; } } // transform s and e so that they are float . for (i = 0; i < m; i++) { if (dcabs1(s[i]) != 0.0) { t = new ComplexFloat(ComplexMath.Absolute(s[i]), 0.0f); r = s[i] / t; s[i] = t; if (i < m - 1) { e[i] = e[i] / r; } if (computeVectors) { zscalColumn(u, i, 0, r); } } // ...exit if (i == m - 1) { break; } if (dcabs1(e[i]) != 0.0) { t = new ComplexFloat(ComplexMath.Absolute(e[i]), 0.0f); r = t / e[i]; e[i] = t; s[i + 1] = s[i + 1] * r; if (computeVectors) { zscalColumn(v, i + 1, 0, r); } } } // main iteration loop for the singular values. mm = m; iter = 0; while (m > 0) { // quit if all the singular values have been found. // if too many iterations have been performed, set // flag and return. if (iter >= MAXITER) { info = m; // ......exit break; } // this section of the program inspects for // negligible elements in the s and e arrays. on // completion the variables kase and l are set as follows. // kase = 1 if s[m] and e[l-1] are negligible and l < m // kase = 2 if s[l] is negligible and l < m // kase = 3 if e[l-1] is negligible, l < m, and // s[l, ..., s[m] are not negligible (qr step). // kase = 4 if e[m-1] is negligible (convergence). for (l = m - 2; l >= 0; l--) { test = ComplexMath.Absolute(s[l]) + ComplexMath.Absolute(s[l + 1]); ztest = test + ComplexMath.Absolute(e[l]); if (ztest == test) { e[l] = ComplexFloat.Zero; break; } } if (l == m - 2) { kase = 4; } else { for (ls = m - 1; ls > l; ls--) { test = 0.0f; if (ls != m - 1) { test = test + ComplexMath.Absolute(e[ls]); } if (ls != l + 1) { test = test + ComplexMath.Absolute(e[ls - 1]); } ztest = test + ComplexMath.Absolute(s[ls]); if (ztest == test) { s[ls] = ComplexFloat.Zero; break; } } if (ls == l) { kase = 3; } else if (ls == m - 1) { kase = 1; } else { kase = 2; l = ls; } } l = l + 1; // perform the task indicated by kase. switch (kase) { // deflate negligible s[m]. case 1: f = e[m - 2].Real; e[m - 2] = ComplexFloat.Zero; for (k = m - 2; k >= 0; k--) { t1 = s[k].Real; drotg(ref t1, ref f, ref cs, ref sn); s[k] = new ComplexFloat(t1, 0.0f); if (k != l) { f = -sn * e[k - 1].Real; e[k - 1] = cs * e[k - 1]; } if (computeVectors) { zdrot(v, k, m - 1, cs, sn); } } break; // split at negligible s[l]. case 2: f = e[l - 1].Real; e[l - 1] = ComplexFloat.Zero; for (k = l; k < m; k++) { t1 = s[k].Real; drotg(ref t1, ref f, ref cs, ref sn); s[k] = new ComplexFloat(t1, 0.0f); f = -sn * e[k].Real; e[k] = cs * e[k]; if (computeVectors) { zdrot(u, k, l - 1, cs, sn); } } break; // perform one qr step. case 3: // calculate the shift. scale = 0.0f; scale = System.Math.Max(scale, ComplexMath.Absolute(s[m - 1])); scale = System.Math.Max(scale, ComplexMath.Absolute(s[m - 2])); scale = System.Math.Max(scale, ComplexMath.Absolute(e[m - 2])); scale = System.Math.Max(scale, ComplexMath.Absolute(s[l])); scale = System.Math.Max(scale, ComplexMath.Absolute(e[l])); sm = s[m - 1].Real / scale; smm1 = s[m - 2].Real / scale; emm1 = e[m - 2].Real / scale; sl = s[l].Real / scale; el = e[l].Real / scale; b = ((smm1 + sm) * (smm1 - sm) + emm1 * emm1) / 2.0f; c = (sm * emm1) * (sm * emm1); shift = 0.0f; if (b != 0.0f || c != 0.0f) { shift = (float)System.Math.Sqrt(b * b + c); if (b < 0.0f) { shift = -shift; } shift = c / (b + shift); } f = (sl + sm) * (sl - sm) + shift; g = sl * el; // chase zeros. for (k = l; k < m - 1; k++) { drotg(ref f, ref g, ref cs, ref sn); if (k != l) { e[k - 1] = new ComplexFloat(f, 0.0f); } f = cs * s[k].Real + sn * e[k].Real; e[k] = cs * e[k] - sn * s[k]; g = sn * s[k + 1].Real; s[k + 1] = cs * s[k + 1]; if (computeVectors) { zdrot(v, k, k + 1, cs, sn); } drotg(ref f, ref g, ref cs, ref sn); s[k] = new ComplexFloat(f, 0.0f); f = cs * e[k].Real + sn * s[k + 1].Real; s[k + 1] = -sn * e[k] + cs * s[k + 1]; g = sn * e[k + 1].Real; e[k + 1] = cs * e[k + 1]; if (computeVectors && k < rows) { zdrot(u, k, k + 1, cs, sn); } } e[m - 2] = new ComplexFloat(f, 0.0f); iter = iter + 1; break; // convergence. case 4: // make the singular value positive if (s[l].Real < 0.0) { s[l] = -s[l]; if (computeVectors) { zscalColumn(v, l, 0, -ComplexFloat.One); } } // order the singular value. while (l != mm - 1) { if (s[l].Real >= s[l + 1].Real) { break; } t = s[l]; s[l] = s[l + 1]; s[l + 1] = t; if (computeVectors && l < cols) { zswap(v, l, l + 1); } if (computeVectors && l < rows) { zswap(u, l, l + 1); } l = l + 1; } iter = 0; m = m - 1; break; } } // make matrix w from vector s // there is no constructor, creating diagonal matrix from vector // doing it ourselves mm = System.Math.Min(matrix.RowLength, matrix.ColumnLength); #else float[] d = new float[mm]; u = new ComplexFloatMatrix(rows); v = new ComplexFloatMatrix(cols); ComplexFloat[] a = new ComplexFloat[matrix.data.Length]; Array.Copy(matrix.data, a, matrix.data.Length); Lapack.Gesvd.Compute(rows, cols, a, d, u.data, v.data); v.ConjugateTranspose(); for (int i = 0; i < d.Length; i++) { s[i] = d[i]; } #endif w = new FloatMatrix(matrix.RowLength, matrix.ColumnLength); for (int ii = 0; ii < matrix.RowLength; ii++) { for (int jj = 0; jj < matrix.ColumnLength; jj++) { if (ii == jj) { w[ii, ii] = s[ii]; } } } float eps = (float)System.Math.Pow(2.0, -52.0); float tol = System.Math.Max(matrix.RowLength, matrix.ColumnLength) * s[0].Real * eps; rank = 0; for (int h = 0; h < mm; h++) { if (s[h].Real > tol) { rank++; } } if (!computeVectors) { u = null; v = null; } matrix = null; }
private static extern void dna_blas_cscal(int N, ref ComplexFloat alpha, [In, Out] ComplexFloat[] X, int incX);
internal static void Compute(Order order, Side side, UpLo uplo, Transpose transA, Diag diag, int m, int n, ComplexFloat alpha, ComplexFloat[] A, int lda, ComplexFloat[] B, int ldb) { ArgumentCheck(side, m, n, A, lda, B, ldb); dna_blas_ctrsm(order, side, uplo, transA, diag, m, n, ref alpha, A, lda, B, ldb); }
private static extern void dna_blas_cgbmv(Order order, Transpose TransA, int M, int N, int KL, int KU, ref ComplexFloat alpha, [In] ComplexFloat[] A, int lda, [In] ComplexFloat[] X, int incX, ref ComplexFloat beta, [In, Out] ComplexFloat[] Y, int incY);
internal static void Compute(Order order, Transpose transA, int m, int n, int kl, int ku, ComplexFloat alpha, ComplexFloat[] A, int lda, ComplexFloat[] X, int incx, ComplexFloat beta, ComplexFloat[] Y, int incy) { ArgumentCheck(order, transA, ku + kl + 1, m, n, A, A.Length, lda, X, X.Length, ref incx, Y, Y.Length, ref incy); if (alpha == ComplexFloat.Zero && beta == ComplexFloat.One) { return; } #if MANAGED if ((order == Order.RowMajor && transA == Transpose.NoTrans) || (order == Order.ColumnMajor && transA != Transpose.NoTrans)) { for (int i = 0; i < m; ++i) { Y[i * incy] *= beta; for (int j = 0; j < ku + kl + 1; ++j) { Y[i * incy] += alpha * A[j + i * lda] * X[(System.Math.Max(i - kl, 0) + j) * incx]; } } } else if (order == Order.RowMajor && transA == Transpose.ConjTrans) { for (int i = 0; i < m; ++i) { Y[i * incy] *= beta; for (int j = 0; j < ku + kl + 1; ++j) { Y[i * incy] += alpha * ComplexMath.Conjugate(A[j + i * lda]) * X[(System.Math.Max(i - kl, 0) + j) * incx]; } } } else if (order == Order.ColumnMajor && transA == Transpose.ConjTrans) { for (int i = 0; i < System.Math.Min(m, n); ++i) { int ti = i * incy; Y[ti] *= beta; for (int k = -System.Math.Min(i, kl); k <= System.Math.Min(m - 1 - i, ku); ++k) { Y[ti] += alpha * ComplexMath.Conjugate(A[(i + k) * lda + ku - k]) * X[incx * (i + k)]; } } } else { // corresponds to the case ( (colMajor && noTranspose) || (rowMajor && transpose)) - no conjugates here for (int i = 0; i < System.Math.Min(m, n); ++i) { int ti = i * incy; Y[ti] *= beta; for (int k = -System.Math.Min(i, kl); k <= System.Math.Min(m - 1 - i, ku); ++k) { Y[ti] += alpha * A[(i + k) * lda + ku - k] * X[incx * (i + k)]; } } } #else dna_blas_cgbmv(order, transA, m, n, kl, ku, ref alpha, A, lda, X, incx, ref beta, Y, incy); #endif }
private static extern void dna_blas_caxpy(int N, ref ComplexFloat alpha, [In] ComplexFloat[] X, int incX, [In, Out] ComplexFloat[] Y, int incY);
internal static void Compute(Order order, Transpose transA, Transpose transB, int m, int n, int k, ComplexFloat alpha, ComplexFloat[] A, int lda, ComplexFloat[] B, int ldb, ComplexFloat beta, ComplexFloat[] C, int ldc) { ArgumentCheck(order, transA, transB, m, n, k, A, A.Length, lda, B, B.Length, ldb, C, C.Length, ldc); if (alpha == ComplexFloat.Zero && beta == ComplexFloat.One) { return; } dna_blas_cgemm(order, transA, transB, m, n, k, ref alpha, A, lda, B, ldb, ref beta, C, ldc); }
/// <summary>Performs the LU factorization.</summary> protected override void InternalCompute() { #if MANAGED factor = new ComplexFloatMatrix(matrix).data; int m = matrix.RowLength; int n = matrix.ColumnLength; pivots = new int[m]; for (int i = 0; i < m; i++) { pivots[i] = i; } sign = 1; ComplexFloat[] LUrowi; ComplexFloat[] LUcolj = new ComplexFloat[m]; // Outer loop. for (int j = 0; j < n; j++) { // Make a copy of the j-th column to localize references. for (int i = 0; i < m; i++) { LUcolj[i] = factor[i][j]; } // Apply previous transformations. for (int i = 0; i < m; i++) { LUrowi = factor[i]; // Most of the time is spent in the following dot product. int kmax = System.Math.Min(i, j); ComplexFloat s = ComplexFloat.Zero; for (int k = 0; k < kmax; k++) { s += LUrowi[k] * LUcolj[k]; } LUrowi[j] = LUcolj[i] -= s; } // Find pivot and exchange if necessary. int p = j; for (int i = j + 1; i < m; i++) { if (ComplexMath.Absolute(LUcolj[i]) > ComplexMath.Absolute(LUcolj[p])) { p = i; } } if (p != j) { for (int k = 0; k < n; k++) { ComplexFloat t = factor[p][k]; factor[p][k] = factor[j][k]; factor[j][k] = t; } int r = pivots[p]; pivots[p] = pivots[j]; pivots[j] = r; sign = -sign; } // Compute multipliers. if (j < m & factor[j][j] != ComplexFloat.Zero) { for (int i = j + 1; i < m; i++) { factor[i][j] /= factor[j][j]; } } } #else factor = new ComplexFloat[matrix.data.Length]; Array.Copy(matrix.data, factor, matrix.data.Length); Lapack.Getrf.Compute(order, order, factor, order, out pivots); GetSign(); #endif SetLU(); this.singular = false; for (int j = 0; j < u.RowLength; j++) { if (u[j, j] == 0) { this.singular = true; break; } } }
private static extern void dna_blas_cdotc(int N, [In]ComplexFloat[] X, int incX, [In]ComplexFloat[] Y, int incY, ref ComplexFloat dotc);
internal static void Compute(Order order, Transpose transA, int m, int n, ComplexFloat alpha, ComplexFloat[] A, int lda, ComplexFloat[] X, int incx, ComplexFloat beta, ComplexFloat[] Y, int incy) { ArgumentCheck(order, transA, m, n, A, A.Length, lda, X, X.Length, ref incx, Y, Y.Length, ref incy); #if MANAGED int lenX = m; int lenY = n; if (transA == Transpose.NoTrans) { lenX = n; lenY = m; } if (beta == ComplexFloat.Zero) { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { Y[iy] = 0; } } else if (beta != ComplexFloat.One) { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { Y[iy] *= beta; } } if (alpha == ComplexFloat.Zero) { return; } var add_val = new ComplexFloat(0); if ((order == Order.RowMajor && transA == Transpose.NoTrans) || (order == Order.ColumnMajor && transA == Transpose.Trans)) { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { add_val = 0; for (int j = 0, jx = 0; j < lenX; ++j, jx += incx) { add_val += X[jx] * A[i * lda + j]; } Y[iy] += alpha * add_val; } } else if ((order == Order.RowMajor && transA == Transpose.Trans) || (order == Order.ColumnMajor && transA == Transpose.NoTrans)) { for (int j = 0, jx = 0; j < lenX; ++j, jx += incx) { add_val = alpha * X[jx]; if (add_val != ComplexFloat.Zero) { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { Y[iy] += add_val * A[j * lda + i]; } } } } else if (order == Order.RowMajor && transA == Transpose.ConjTrans) { for (int j = 0, jx = 0; j < lenX; ++j, jx += incx) { add_val = alpha * X[jx]; if (add_val != ComplexFloat.Zero) { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { Y[iy] += add_val * ComplexMath.Conjugate(A[j * lda + i]); } } } } else { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { add_val = 0; for (int j = 0, jx = 0; j < lenX; ++j, jx += incx) { add_val += X[jx] * ComplexMath.Conjugate(A[i * lda + j]); } Y[iy] += alpha * add_val; } } #else dna_blas_cgemv(order, transA, m, n, ref alpha, A, lda, X, incx, ref beta, Y, incy); #endif }
internal static int Compute( int n, int ncvt, int nru, int ncc, float[] d, float[] e, ComplexFloat[] vt, int ldvt, ComplexFloat[] u, int ldu, ComplexFloat[] c, int ldc ){ ArgumentCheck(n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc); if( d.Length < 1 ){ throw new ArgumentException("The length of d must be at least 1.", "d"); } if( e.Length < 1 ){ throw new ArgumentException("The length of e must be at least 1.", "e"); } if( ncvt !=0 && vt != null && vt.Length < ldvt*ncvt ){ throw new ArgumentException("The length of vt must be at least ldvt*ncvt.", "vt"); } if( nru !=0 && u != null && u.Length < ldu*n ){ throw new ArgumentException("The length of nru must be at least lut*n.", "nru"); } if( ncc !=0 && c != null && c.Length < ldc*ncc ){ throw new ArgumentException("The length of c must be at least ldc*ncc.", "c"); } return dna_lapack_cbdsqr(UpLo.Upper, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc); }
private static extern void dna_blas_cgemm(Order order, Transpose transA, Transpose transB, int M, int N, int K, ref ComplexFloat alpha, [In] ComplexFloat[] A, int lda, [In] ComplexFloat[] B, int ldb, ref ComplexFloat beta, [In, Out] ComplexFloat[] C, int ldc);
///<summary>Compute the function of this class</summary> internal static void Compute( Order order, int m, int n, ComplexFloat alpha, ComplexFloat[] X, int incx, ComplexFloat[] Y, int incy, ComplexFloat[] A, int lda ) { ArgumentCheck(order, m, n, X, X.Length, ref incx, Y, Y.Length, ref incy, A, A.Length, lda); #if MANAGED ComplexFloat temp; if( order == Order.RowMajor ) { for( int i = 0, ix = 0; i < m; ++i, ix += incx ) { temp = alpha * X[ix]; for( int j=0, jy =0; j < n; ++j, jy += incy ) { A[i * lda + j] += temp * ComplexMath.Conjugate(Y[jy]); } } } else { for( int j=0, jy=0; j < n; ++j, jy+=incy) { temp = alpha * ComplexMath.Conjugate( Y[jy]); for(int i=0, ix=0; i < m ; ++i, ix+=incx) { A[lda * j + i] += temp*X[ix]; } } } #else dna_blas_cgerc(order, m, n, ref alpha, X, incx, Y, incy, A, lda); #endif }
internal static void Compute(int n, ComplexFloat[] X, int incx, ComplexFloat[] Y, int incy) { if (n < 0) { return; } ArgumentCheck(n, X, X.Length, ref incx, Y, Y.Length, ref incy); #if MANAGED int ix = 0; int iy = 0; for (int i = 0; i < n; ++i) { Y[iy] = X[ix]; ix += incx; iy += incy; } #else dna_blas_ccopy(n, X, incx, Y, incy); #endif }
internal static float Compute(int n, ComplexFloat[] X, int incx) { ArgumentCheck(n, X, X.Length, ref incx); float ret = 0; #if MANAGED ComplexFloat temp = new ComplexFloat(0); int ix = 0; for (int i = 0; i < n; ++i) { temp += (X[ix] * ComplexMath.Conjugate(X[ix])); ix += incx; } ret = (float)System.Math.Sqrt(ComplexMath.Absolute(temp)); #else ret = dna_blas_scnrm2(n, X, incx); #endif return ret; }
public static int Compute( int n, int ilo, int ihi, ComplexFloat[] A, int lda, ComplexFloat[] tau ){ ArgumentCheck(n, ilo, ihi, A, lda, tau); return dna_lapack_cgehrd(Configuration.BlockSize, n, ilo, ihi, A, lda, tau); }
/// <summary> /// Get a copy of the Toeplitz matrix. /// </summary> public ComplexFloatMatrix GetMatrix() { int i, j; // allocate memory for the matrix ComplexFloatMatrix tm = new ComplexFloatMatrix(m_Order); #if MANAGED // fill top row ComplexFloat[] top = tm.data[0]; Array.Copy(m_LeftColumn.data, 0, top, 0, m_Order); if (m_Order > 1) { // fill bottom row (reverse order) ComplexFloat[] bottom = tm.data[m_Order - 1]; for (i = 0, j = m_Order - 1; i < m_Order; i++, j--) { bottom[i] = m_LeftColumn[j]; } // fill rows in-between for (i = 1, j = m_Order - 1 ; j > 1; i++) { Array.Copy(top, 0, tm.data[i], i, j--); Array.Copy(bottom, j, tm.data[i], 0, i); } } #else if (m_Order > 1) { ComplexFloat[] top = new ComplexFloat[m_Order]; Array.Copy(m_LeftColumn.data, 0, top, 0, m_Order); tm.SetRow(0, top); // fill bottom row (reverse order) ComplexFloat[] bottom = new ComplexFloat[m_Order]; for (i = 0, j = m_Order - 1; i < m_Order; i++, j--) { bottom[i] = m_LeftColumn[j]; } // fill rows in-between for (i = 1, j = m_Order - 1 ; j > 0; i++) { ComplexFloat[] temp = new ComplexFloat[m_Order]; Array.Copy(top, 0, temp, i, j--); Array.Copy(bottom, j, temp, 0, i); tm.SetRow(i, temp); } } else { Array.Copy(m_LeftColumn.data, 0, tm.data, 0, m_Order); } #endif return tm; }
private static extern void dna_blas_ctrsm( Order order, Side side, UpLo uplo, Transpose transA, Diag diag, int m,int n, ref ComplexFloat alpha, [In]ComplexFloat[] A, int lda, [In,Out]ComplexFloat[] B, int ldb );
internal static int Compute( int n, ComplexFloat[] A, int lda, int[] ipiv ){ ArgumentCheck(n,A,lda,ipiv); return dna_lapack_cgetri(Configuration.BlockSize, n,A,lda,ipiv); }
internal static int Compute( int m, int n, ComplexFloat[] a, float[] s, ComplexFloat[] u, ComplexFloat[] v ){ if( a == null ){ throw new ArgumentNullException("a", "a cannot be null."); } return dna_lapack_cgesvd(m, n, a, m, s, u, m, v, n); }
internal static float Compute(int n, ComplexFloat[] X, int incx) { if( n < 1 ) { return 0; } if ( incx <= 0 ) { return 0; } ArgumentCheck(n, X, incx, X.Length); float ret = 0; #if MANAGED int ix = 0; double temp = 0; for ( int i = 0; i < n; ++i ) { temp += System.Math.Abs(X[ix].Real) + System.Math.Abs(X[ix].Imag); ix += incx; } ret = (float)temp; #else ret = dna_blas_scasum(n, X, incx); #endif return ret; }
private static float dcabs1(ComplexFloat z) { float s = System.Math.Abs(z.Real) + System.Math.Abs(z.Imag); return(s); }
internal static int Compute( int m, int n, ComplexFloat[] A, int lda, out int[] ipiv ){ ArgumentCheck(m,n,A,lda); ipiv = new int[System.Math.Max(1, System.Math.Min(m,n))]; return dna_lapack_cgetrf(m,n,A,lda,ipiv); }
/// <summary> /// Invert a square Toeplitz matrix. /// </summary> /// <param name="col">The left-most column of the Toeplitz matrix.</param> /// <param name="row">The top-most row of the Toeplitz matrix.</param> /// <returns>The inverse matrix.</returns> /// <exception cref="ArgumentNullException"> /// <B>col</B> is a null reference. /// <para>or</para> /// <para><B>row</B> is a null reference.</para> /// </exception> /// <exception cref="RankException"> /// The length of <B>col</B> is 0, /// <para>or</para> /// <para>the lengths of <B>col</B> and <B>row</B> are not equal.</para> /// </exception> /// <exception cref="SingularMatrixException"> /// The Toeplitz matrix or one of the the leading sub-matrices is singular. /// </exception> /// <exception cref="ArithmeticException"> /// The values of the first element of <B>col</B> and <B>row</B> are not equal. /// </exception> /// <remarks> /// This static member combines the <b>UDL</b> decomposition and Trench's algorithm into a /// single algorithm. It requires minimal data storage, compared to the non-static member /// and suffers from no speed penalty in comparision. /// <para> /// Trench's algorithm requires <b>N</b> squared FLOPS, compared to <b>N</b> cubed FLOPS /// if we simply solved a linear Toeplitz system with a right-side identity matrix (<b>N</b> is the matrix order). /// </para> /// </remarks> public static ComplexFloatMatrix Inverse(IROComplexFloatVector col, IROComplexFloatVector row) { // check parameters if (col == null) { throw new System.ArgumentNullException("col"); } else if (col.Length == 0) { throw new RankException("The length of col is zero."); } else if (row == null) { throw new System.ArgumentNullException("row"); } else if (col.Length != row.Length) { throw new RankException("The lengths of col and row are not equal."); } else if (col[0] != row[0]) { throw new ArithmeticException("The values of the first element of col and row are not equal."); } // check if leading diagonal is zero if (col[0] == ComplexFloat.Zero) { throw new SingularMatrixException("One of the leading sub-matrices is singular."); } // decompose matrix int order = col.Length; ComplexFloat[] A = new ComplexFloat[order]; ComplexFloat[] B = new ComplexFloat[order]; ComplexFloat[] Z = new ComplexFloat[order]; ComplexFloat Q, S, Ke, Kr, e; int i, j, k, l; // setup the zero order solution A[0] = ComplexFloat.One; B[0] = ComplexFloat.One; e = ComplexFloat.One / col[0]; for (i = 1; i < order; i++) { // calculate inner products Q = ComplexFloat.Zero; for (j = 0, l = 1; j < i; j++, l++) { Q += col[l] * A[j]; } S = ComplexFloat.Zero; for (j = 0, l = 1; j < i; j++, l++) { S += row[l] * B[j]; } // reflection coefficients Kr = -S * e; Ke = -Q * e; // update lower triangle (in temporary storage) Z[0] = ComplexFloat.Zero; Array.Copy(A, 0, Z, 1, i); for (j = 0, l = i - 1; j < i; j++, l--) { Z[j] += Ke * B[l]; } // update upper triangle for (j = i; j > 0; j--) { B[j] = B[j - 1]; } B[0] = ComplexFloat.Zero; for (j = 0, l = i - 1; j < i; j++, l--) { B[j] += Kr * A[l]; } // copy from temporary storage to lower triangle Array.Copy(Z, 0, A, 0, i + 1); // check for singular sub-matrix) if (Ke * Kr == ComplexFloat.One) { throw new SingularMatrixException("One of the leading sub-matrices is singular."); } // update diagonal e = e / (ComplexFloat.One - Ke * Kr); } // calculate the inverse ComplexFloatMatrix I = new ComplexFloatMatrix(order); // the solution matrix ComplexFloat A1, B1; #if MANAGED ComplexFloat[] current, previous; // references to rows in the solution // setup the first row in wedge current = I.data[0]; for (i = 0, j = order - 1; i < order; i++, j--) { current[i] = e * B[j]; } // calculate values in the rest of the wedge for (i = 1; i < order; i++) { previous = current; current = I.data[i]; A1 = e * A[order - i - 1]; B1 = e * B[i - 1]; current[0] = A1; for (j = 1, k = 0, l = order - 2; j < order - i; j++, k++, l--) { current[j] = previous[k] + A1 * B[l] - B1 * A[k]; } } #else // setup the first row in wedge for (i = 0, j = order - 1; i < order; i++, j--) { I[0, i] = e * B[j]; } // calculate values in the rest of the wedge for (i = 1; i < order; i++) { A1 = e * A[order - i - 1]; B1 = e * B[i - 1]; I[i, 0] = A1; for (j = 1, k = 0, l = order - 2; j < order - i; j++, k++, l--) { I[i, j] = I[i - 1, k] + A1 * B[l] - B1 * A[k]; } } #endif // inverse is a persymmetric matrix. for (i = 0, j = order - 1; i < order; i++, j--) { for (k = 0, l = order - 1; k < j; k++, l--) { I[l, j] = I[i, k]; } } return I; }
private static extern int dna_lapack_cgehrd(int block_size, int n, int ilo, int ihi, ComplexFloat[] A, int lda, ComplexFloat[] tau);
internal static void Compute(Order order, Transpose transA, int m, int n, ComplexFloat alpha, ComplexFloat[] A, int lda, ComplexFloat[] X, int incx, ComplexFloat beta, ComplexFloat[] Y, int incy) { ArgumentCheck(order, transA, m, n, A, A.Length, lda, X, X.Length, ref incx, Y, Y.Length, ref incy); #if MANAGED int lenX = m; int lenY = n; if (transA == Transpose.NoTrans) { lenX = n; lenY = m; } if (beta == ComplexFloat.Zero) { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { Y[iy] = 0; } } else if (beta != ComplexFloat.One) { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { Y[iy] *= beta; } } if (alpha == ComplexFloat.Zero) { return; } ComplexFloat add_val = new ComplexFloat(0); if ((order == Order.RowMajor && transA == Transpose.NoTrans) || (order == Order.ColumnMajor && transA == Transpose.Trans)) { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { add_val = 0; for (int j = 0, jx = 0; j < lenX; ++j, jx += incx) { add_val += X[jx] * A[i * lda + j]; } Y[iy] += alpha * add_val; } } else if ((order == Order.RowMajor && transA == Transpose.Trans) || (order == Order.ColumnMajor && transA == Transpose.NoTrans)) { for (int j = 0, jx = 0; j < lenX; ++j, jx += incx) { add_val = alpha * X[jx]; if (add_val != ComplexFloat.Zero) { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { Y[iy] += add_val * A[j * lda + i]; } } } } else if (order == Order.RowMajor && transA == Transpose.ConjTrans) { for (int j = 0, jx = 0; j < lenX; ++j, jx += incx) { add_val = alpha * X[jx]; if (add_val != ComplexFloat.Zero) { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { Y[iy] += add_val * ComplexMath.Conjugate(A[j * lda + i]); } } } } else { for (int i = 0, iy = 0; i < lenY; ++i, iy += incy) { add_val = 0; for (int j = 0, jx = 0; j < lenX; ++j, jx += incx) { add_val += X[jx] * ComplexMath.Conjugate(A[i * lda + j]); } Y[iy] += alpha * add_val; } } #else dna_blas_cgemv(order, transA, m, n, ref alpha, A, lda, X, incx, ref beta, Y, incy); #endif }
internal static void Compute( Order order, Side side, UpLo uplo, Transpose transA, Diag diag, int m,int n, ComplexFloat alpha, ComplexFloat[] A, int lda, ComplexFloat[] B, int ldb ){ ArgumentCheck(side, m, n, A, lda, B, ldb); dna_blas_ctrsm(order, side, uplo, transA, diag, m, n, ref alpha, A, lda, B, ldb); }
private static extern void dna_blas_cgemv( Order order, Transpose TransA, int M, int N, ref ComplexFloat alpha, [In]ComplexFloat[] A, int lda, [In]ComplexFloat[] X, int incX, ref ComplexFloat beta, [In,Out]ComplexFloat[] Y, int incY);
internal static int Compute( Side side, Transpose trans, int m, int n, int k, int ilo, int ihi, ComplexFloat[] A, int lda, ComplexFloat[] tau, ComplexFloat[] C, int ldc ){ ArgumentCheck(side, m, n, k, ilo, ihi, A, lda, tau, C, ldc); if (tau.Length < System.Math.Max(1, k) ){ throw new ArgumentException("tau must be at least max(1,k)."); } return dna_lapack_cunmhr(Configuration.BlockSize, side, trans, m, n, k, ilo, ihi, A, lda, tau, C, ldc); }
/// <summary>Finds the least squares solution of <c>A*X = B</c>, where <c>m >= n</c></summary> /// <param name="B">A matrix with as many rows as A and any number of columns.</param> /// <returns>X that minimizes the two norm of <c>Q*R*X-B</c>.</returns> /// <exception cref="ArgumentException">Matrix row dimensions must agree.</exception> /// <exception cref="InvalidOperationException">Matrix is rank deficient or <c>m < n</c>.</exception> public ComplexFloatMatrix Solve(IROComplexFloatMatrix B) { if (B.Rows != matrix.Rows) { throw new ArgumentException("Matrix row dimensions must agree."); } if (matrix.Rows < matrix.Columns) { throw new System.InvalidOperationException("A must have at lest as a many rows as columns."); } Compute(); if (!this.isFullRank) { throw new System.InvalidOperationException("Matrix is rank deficient."); } // Copy right hand side int m = matrix.Rows; int n = matrix.Columns; int nx = B.Columns; ComplexFloatMatrix ret = new ComplexFloatMatrix(n, nx); #if MANAGED ComplexFloatMatrix X = new ComplexFloatMatrix(B); // Compute Y = transpose(Q)*B ComplexFloat[] column = new ComplexFloat[q_.RowLength]; for (int j = 0; j < nx; j++) { for (int k = 0; k < m; k++) { column[k] = X.data[k][j]; } for (int i = 0; i < m; i++) { ComplexFloat s = ComplexFloat.Zero; for (int k = 0; k < m; k++) { s += ComplexMath.Conjugate(q_.data[k][i]) * column[k]; } X.data[i][j] = s; } } // Solve R*X = Y; for (int k = n - 1; k >= 0; k--) { for (int j = 0; j < nx; j++) { X.data[k][j] /= r_.data[k][k]; } for (int i = 0; i < k; i++) { for (int j = 0; j < nx; j++) { X.data[i][j] -= X.data[k][j] * r_.data[i][k]; } } } for (int i = 0; i < n; i++) { for (int j = 0; j < nx; j++) { ret.data[i][j] = X.data[i][j]; } } #else ComplexFloat[] c = ComplexFloatMatrix.ToLinearComplexArray(B); Lapack.Unmqr.Compute(Lapack.Side.Left, Lapack.Transpose.ConjTrans, m, nx, n, qr, m, tau, c, m); Blas.Trsm.Compute(Blas.Order.ColumnMajor, Blas.Side.Left, Blas.UpLo.Upper, Blas.Transpose.NoTrans, Blas.Diag.NonUnit, n, nx, 1, qr, m, c, m); for (int i = 0; i < n; i++) { for (int j = 0; j < nx; j++) { ret.data[j * n + i] = c[j * m + (jpvt[i] - 1)]; } } #endif return(ret); }