public void GetInverseSingularTest() { ComplexDoubleMatrix a = new ComplexDoubleMatrix(3, 3); ComplexDoubleLUDecomp dlu = new ComplexDoubleLUDecomp(a); dlu.GetInverse(); }
public void NonSymmFactorTest() { ComplexDoubleMatrix b = new ComplexDoubleMatrix(3); b[0, 0] = 2; b[0, 1] = 1; b[0, 2] = 1; b[1, 0] = 1; b[1, 1] = 2; b[1, 2] = 0; b[2, 0] = 0; b[2, 1] = 0; b[2, 2] = 3; ComplexDoubleCholeskyDecomp dcd = new ComplexDoubleCholeskyDecomp(b); Assert.AreEqual(dcd.Factor[0, 0].Real, 1.414, TOLERENCE); Assert.AreEqual(dcd.Factor[0, 1].Real, 0.000, TOLERENCE); Assert.AreEqual(dcd.Factor[0, 2].Real, 0.000, TOLERENCE); Assert.AreEqual(dcd.Factor[1, 0].Real, 0.707, TOLERENCE); Assert.AreEqual(dcd.Factor[1, 1].Real, 1.225, TOLERENCE); Assert.AreEqual(dcd.Factor[1, 2].Real, 0.000, TOLERENCE); Assert.AreEqual(dcd.Factor[2, 0].Real, 0.000, TOLERENCE); Assert.AreEqual(dcd.Factor[2, 1].Real, 0.000, TOLERENCE); Assert.AreEqual(dcd.Factor[2, 2].Real, 1.732, TOLERENCE); }
public void Current() { var test = new ComplexDoubleMatrix(new Complex[2, 2] { { 1, 2 }, { 3, 4 } }); IEnumerator enumerator = test.GetEnumerator(); bool movenextresult; movenextresult = enumerator.MoveNext(); Assert.IsTrue(movenextresult); Assert.AreEqual(enumerator.Current, test[0, 0]); movenextresult = enumerator.MoveNext(); Assert.IsTrue(movenextresult); Assert.AreEqual(enumerator.Current, test[1, 0]); movenextresult = enumerator.MoveNext(); Assert.IsTrue(movenextresult); Assert.AreEqual(enumerator.Current, test[0, 1]); movenextresult = enumerator.MoveNext(); Assert.IsTrue(movenextresult); Assert.AreEqual(enumerator.Current, test[1, 1]); movenextresult = enumerator.MoveNext(); Assert.IsFalse(movenextresult); }
///<summary>Calculates the inverse of the matrix.</summary> ///<returns>the inverse of the matrix.</returns> ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception> public ComplexDoubleMatrix GetInverse() { Compute(); if (!ispd) { throw new NotPositiveDefiniteException(); } else { #if MANAGED var ret = ComplexDoubleMatrix.CreateIdentity(order); ret = Solve(ret); return(ret); #else Complex[] inverse = new Complex[l.data.Length]; Array.Copy(l.data, inverse, l.data.Length); Lapack.Potri.Compute(Lapack.UpLo.Lower, order, inverse, order); ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order, order); ret.data = inverse; for (int i = 0; i < order; i++) { for (int j = 0; j < order; j++) { if (j > i) { ret.data[j * order + i] = ComplexMath.Conjugate(ret.data[i * order + j]); } } } return(ret); #endif } }
public void GetInverseNotPositiveDefiniteTest() { ComplexDoubleMatrix a = new ComplexDoubleMatrix(3); ComplexDoubleCholeskyDecomp dcd = new ComplexDoubleCholeskyDecomp(a); dcd.GetInverse(); }
public void Current() { ComplexDoubleMatrix test = new ComplexDoubleMatrix(new Complex[2, 2] { { 1, 2 }, { 3, 4 } }); IEnumerator enumerator = test.GetEnumerator(); bool movenextresult; movenextresult = enumerator.MoveNext(); Assert.IsTrue(movenextresult); Assert.AreEqual(enumerator.Current, test[0, 0]); movenextresult = enumerator.MoveNext(); Assert.IsTrue(movenextresult); Assert.AreEqual(enumerator.Current, test[1, 0]); movenextresult = enumerator.MoveNext(); Assert.IsTrue(movenextresult); Assert.AreEqual(enumerator.Current, test[0, 1]); movenextresult = enumerator.MoveNext(); Assert.IsTrue(movenextresult); Assert.AreEqual(enumerator.Current, test[1, 1]); movenextresult = enumerator.MoveNext(); Assert.IsFalse(movenextresult); }
/// <summary> /// Solve a square Toeplitz system with a right-side matrix. /// </summary> /// <param name="Y">The right-side matrix</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 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, before calculating the solution vector. /// </para> /// </remarks> public ComplexDoubleMatrix Solve(IROComplexDoubleMatrix Y) { ComplexDoubleMatrix X; Complex Inner; Complex[] a, b, x, y; int i, j, l; // 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("One of the leading sub-matrices is singular."); } // allocate memory for solution X = new ComplexDoubleMatrix(m_Order, Y.Rows); x = new Complex[m_Order]; for (l = 0; l < Y.Rows; l++) { // get right-side column y = ComplexDoubleVector.GetColumnAsArray(Y, l); // solve left-side column for (i = 0; i < m_Order; i++) { a = m_LowerTriangle[i]; b = m_UpperTriangle[i]; Inner = y[i]; for (j = 0; j < i; j++) { Inner += a[j] * y[j]; } Inner *= m_Diagonal[i]; x[i] = Inner; for (j = 0; j < i; j++) { x[j] += Inner * b[j]; } } // insert left-side column into the matrix X.SetColumn(l, x); } return(X); }
public void IsSingularTest() { Assert.IsFalse(lu.IsSingular); ComplexDoubleMatrix b = new ComplexDoubleMatrix(3); ComplexDoubleLUDecomp dlu = new ComplexDoubleLUDecomp(b); Assert.IsTrue(dlu.IsSingular); }
///<summary>Constructor for SVD decomposition class.</summary> ///<param name="matrix">The matrix to decompose.</param> ///<exception cref="ArgumentNullException">matrix is null.</exception> public ComplexDoubleSVDDecomp(IROComplexDoubleMatrix matrix) { if (matrix == null) { throw new System.ArgumentNullException("matrix cannot be null."); } this.matrix = new ComplexDoubleMatrix(matrix); }
private static void zscalColumn(ComplexDoubleMatrix A, int Col, int Start, Complex z) { // A part of column Col of matrix A from row Start to end multiply by z for (int i = Start; i < A.RowLength; i++) { A[i, Col] = A[i, Col] * z; } }
public void CurrentException() { ComplexDoubleMatrix test = new ComplexDoubleMatrix(new Complex[2, 2] { { 1, 2 }, { 3, 4 } }); IEnumerator enumerator = test.GetEnumerator(); object value = enumerator.Current; }
///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary> ///<param name="B">RHS side of the system.</param> ///<returns>the solution matrix, X.</returns> ///<exception cref="ArgumentNullException">B is null.</exception> ///<exception cref="SingularMatrixException">Ais singular.</exception> ///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception> public ComplexDoubleMatrix Solve(IROComplexDoubleMatrix B) { if (B == null) { throw new System.ArgumentNullException("B cannot be null."); } Compute(); if (singular) { throw new SingularMatrixException(); } else { if (B.Rows != order) { throw new System.ArgumentException("Matrix row dimensions must agree."); } #if MANAGED // Copy right hand side with pivoting int nx = B.Columns; ComplexDoubleMatrix X = Pivot(B); // Solve L*Y = B(piv,:) for (int k = 0; k < order; k++) { for (int i = k + 1; i < order; i++) { for (int j = 0; j < nx; j++) { X.data[i][j] -= X.data[k][j] * factor[i][k]; } } } // Solve U*X = Y; for (int k = order - 1; k >= 0; k--) { for (int j = 0; j < nx; j++) { X.data[k][j] /= factor[k][k]; } for (int i = 0; i < k; i++) { for (int j = 0; j < nx; j++) { X.data[i][j] -= X.data[k][j] * factor[i][k]; } } } return(X); #else Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B); Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, B.Columns, factor, order, pivots, rhs, B.Rows); ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order, B.Columns); ret.data = rhs; return(ret); #endif } }
/// <summary>Performs the QR factorization.</summary> protected override void InternalCompute() { int m = matrix.Rows; int n = matrix.Columns; #if MANAGED int minmn = m < n ? m : n; r_ = new ComplexDoubleMatrix(matrix); // create a copy ComplexDoubleVector[] u = new ComplexDoubleVector[minmn]; for (int i = 0; i < minmn; i++) { u[i] = Householder.GenerateColumn(r_, i, m - 1, i); Householder.UA(u[i], r_, i, m - 1, i + 1, n - 1); } q_ = ComplexDoubleMatrix.CreateIdentity(m); for (int i = minmn - 1; i >= 0; i--) { Householder.UA(u[i], q_, i, m - 1, i, m - 1); } #else qr = ComplexDoubleMatrix.ToLinearComplexArray(matrix); jpvt = new int[n]; jpvt[0] = 1; Lapack.Geqp3.Compute(m, n, qr, m, jpvt, out tau); r_ = new ComplexDoubleMatrix(m, n); // Populate R for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i <= j) { r_.data[j * m + i] = qr[(jpvt[j]-1) * m + i]; } else { r_.data[j * m + i] = Complex.Zero; } } } q_ = new ComplexDoubleMatrix(m, m); for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { if (j < n) q_.data[j * m + i] = qr[j * m + i]; else q_.data[j * m + i] = Complex.Zero; } } if( m < n ){ Lapack.Ungqr.Compute(m, m, m, q_.data, m, tau); } else{ Lapack.Ungqr.Compute(m, m, n, q_.data, m, tau); } #endif for (int i = 0; i < m; i++) { if (q_[i, i] == 0) isFullRank = false; } }
///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary> ///<param name="B">RHS side of the system.</param> ///<returns>the solution matrix, X.</returns> ///<exception cref="ArgumentNullException">B is null.</exception> ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception> ///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception> public ComplexDoubleMatrix Solve(IROComplexDoubleMatrix B) { if (B == null) { throw new System.ArgumentNullException("B cannot be null."); } Compute(); if (!ispd) { throw new NotPositiveDefiniteException(); } else { if (B.Rows != order) { throw new System.ArgumentException("Matrix row dimensions must agree."); } #if MANAGED // Copy right hand side. int cols = B.Columns; var X = new ComplexDoubleMatrix(B); for (int c = 0; c < cols; c++) { // Solve L*Y = B; for (int i = 0; i < order; i++) { Complex sum = B[i, c]; for (int k = i - 1; k >= 0; k--) { sum -= l.data[i][k] * X.data[k][c]; } X.data[i][c] = sum / l.data[i][i]; } // Solve L'*X = Y; for (int i = order - 1; i >= 0; i--) { Complex sum = X.data[i][c]; for (int k = i + 1; k < order; k++) { sum -= ComplexMath.Conjugate(l.data[k][i]) * X.data[k][c]; } X.data[i][c] = sum / ComplexMath.Conjugate(l.data[i][i]); } } return(X); #else Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B); Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, B.Columns, l.data, order, rhs, B.Rows); ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order, B.Columns); ret.data = rhs; return(ret); #endif } }
private static Complex zdotc(ComplexDoubleMatrix A, int Col1, int Col2, int Start) { Complex z = Complex.Zero; for (int i = Start; i < A.RowLength; i++) { z += A[i, Col2] * ComplexMath.Conjugate(A[i, Col1]); } return(z); }
public void CurrentException() { Assert.Throws(typeof(InvalidOperationException), () => { var test = new ComplexDoubleMatrix(new Complex[2, 2] { { 1, 2 }, { 3, 4 } }); IEnumerator enumerator = test.GetEnumerator(); object value = enumerator.Current; }); }
public void ForEach() { var test = new ComplexDoubleMatrix(new Complex[2, 2] { { 1, 2 }, { 3, 4 } }); foreach (Complex f in test) { Assert.IsTrue(test.Contains(f)); } }
public void CtorDimensions() { ComplexDoubleMatrix test = new ComplexDoubleMatrix(2, 2); Assert.AreEqual(test.RowLength, 2); Assert.AreEqual(test.ColumnLength, 2); Assert.AreEqual(test[0, 0], Complex.Zero); Assert.AreEqual(test[0, 1], Complex.Zero); Assert.AreEqual(test[1, 0], Complex.Zero); Assert.AreEqual(test[1, 1], Complex.Zero); }
private static void zswap(ComplexDoubleMatrix A, int Col1, int Col2) { // swap columns Col1,Col2 Complex z; for (int i = 0; i < A.RowLength; i++) { z = A[i, Col1]; A[i, Col1] = A[i, Col2]; A[i, Col2] = z; } }
public void CtorInitialValues() { ComplexDoubleMatrix test = new ComplexDoubleMatrix(2, 2, new Complex(1, 1)); Assert.AreEqual(test.RowLength, 2); Assert.AreEqual(test.ColumnLength, 2); Complex value = new Complex(1, 1); Assert.AreEqual(test[0, 0], value); Assert.AreEqual(test[0, 1], value); Assert.AreEqual(test[1, 0], value); Assert.AreEqual(test[1, 1], value); }
///<summary>Computes the algorithm.</summary> protected override void InternalCompute() { #if MANAGED l = new ComplexDoubleMatrix(matrix); for (int j = 0; j < order; j++) { Complex[] rowj = l.data[j]; double d = 0.0; for (int k = 0; k < j; k++) { Complex[] rowk = l.data[k]; Complex s = Complex.Zero; for (int i = 0; i < k; i++) { s += rowk[i] * rowj[i]; } rowj[k] = s = (matrix.data[j][k] - s) / l.data[k][k]; d = d + (s * ComplexMath.Conjugate(s)).Real; } d = matrix.data[j][j].Real - d; if (d <= 0.0) { ispd = false; return; } l.data[j][j] = new Complex(System.Math.Sqrt(d)); for (int k = j + 1; k < order; k++) { l.data[j][k] = Complex.Zero; } } #else Complex[] factor = new Complex[matrix.data.Length]; Array.Copy(matrix.data, factor, matrix.data.Length); int status = Lapack.Potrf.Compute(Lapack.UpLo.Lower, order, factor, order); if (status != 0) { ispd = false; } l = new ComplexDoubleMatrix(order); l.data = factor; for (int i = 0; i < order; i++) { for (int j = 0; j < order; j++) { if (j > i) { l.data[j * order + i] = 0; } } } #endif }
private static double dznrm2Column(ComplexDoubleMatrix A, int Col, int Start) { // dznrm2Column returns the euclidean norm of a vector, // which is a part of column Col in matrix A, beginning from Start to end of column // so that dznrm2Column := sqrt( conjg( matrix' )*matrix ) double s = 0; for (int i = Start; i < A.RowLength; i++) { s += (A[i, Col] * ComplexMath.Conjugate(A[i, Col])).Real; } return(System.Math.Sqrt(s)); }
///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary> ///<param name="B">RHS side of the system.</param> ///<returns>the solution vector, X.</returns> ///<exception cref="ArgumentNullException">B is null.</exception> ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception> ///<exception cref="ArgumentException">The number of rows of A and the length of B must be the same.</exception> public ComplexDoubleVector Solve(IROComplexDoubleVector B) { if (B == null) { throw new System.ArgumentNullException("B cannot be null."); } Compute(); if (!ispd) { throw new NotPositiveDefiniteException(); } else { if (B.Length != order) { throw new System.ArgumentException("The length of B must be the same as the order of the matrix."); } #if MANAGED // Copy right hand side. var X = new ComplexDoubleVector(B); // Solve L*Y = B; for (int i = 0; i < order; i++) { Complex sum = B[i]; for (int k = i - 1; k >= 0; k--) { sum -= l.data[i][k] * X.data[k]; } X.data[i] = sum / l.data[i][i]; } // Solve L'*X = Y; for (int i = order - 1; i >= 0; i--) { Complex sum = X.data[i]; for (int k = i + 1; k < order; k++) { sum -= ComplexMath.Conjugate(l.data[k][i]) * X.data[k]; } X.data[i] = sum / ComplexMath.Conjugate(l.data[i][i]); } return(X); #else Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B); Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, 1, l.data, order, rhs, B.Length); ComplexDoubleVector ret = new ComplexDoubleVector(order, B.Length); ret.data = rhs; return(ret); #endif } }
private static void zdrot(ComplexDoubleMatrix A, int Col1, int Col2, double c, double s) { // applies a plane rotation, where the c=cos and s=sin // Col1, Col2 - rotated columns of A Complex z; for (int i = 0; i < A.RowLength; i++) { z = c * A[i, Col1] + s * A[i, Col2]; A[i, Col2] = c * A[i, Col2] - s * A[i, Col1]; A[i, Col1] = z; } }
static ComplexDoubleLUDecompTest() { ComplexDoubleMatrix a = new ComplexDoubleMatrix(3); a[0,0] = new Complex(-1,1); a[0,1] = 5; a[0,2] = 6; a[1,0] = 3; a[1,1] = -6; a[1,2] = 1; a[2,0] = 6; a[2,1] = 8; a[2,2] = 9; lu = new ComplexDoubleLUDecomp(a); }
public static bool AreEqual(ComplexDoubleMatrix f1, ComplexDoubleMatrix f2, float delta) { if (f1.RowLength != f2.RowLength) return false; if (f1.ColumnLength != f2.ColumnLength) return false; for (int i = 0; i < f1.RowLength; i++) { for (int j = 0; j < f1.ColumnLength; j++) { if (!AreEqual(f1[i, j], f2[i, j], delta)) return false; } } return true; }
static ComplexDoubleCholeskyDecompTest() { ComplexDoubleMatrix a = new ComplexDoubleMatrix(3); a[0,0] = 2; a[0,1] = new Complex(1,-1); a[0,2] = 0; a[1,0] = new Complex(1,-1); a[1,1] = 2; a[1,2] = 0; a[2,0] = 0; a[2,1] = 0; a[2,2] = 3; cd = new ComplexDoubleCholeskyDecomp(a); }
public void SquareDecomp() { ComplexDoubleMatrix a = new ComplexDoubleMatrix(3); a[0, 0] = new Complex(1.1, 1.1); a[0, 1] = new Complex(2.2, -2.2); a[0, 2] = new Complex(3.3, 3.3); a[1, 0] = new Complex(4.4, -4.4); a[1, 1] = new Complex(5.5, 5.5); a[1, 2] = new Complex(6.6, -6.6); a[2, 0] = new Complex(7.7, 7.7); a[2, 1] = new Complex(8.8, -8.8); a[2, 2] = new Complex(9.9, 9.9); ComplexDoubleQRDecomp qrd = new ComplexDoubleQRDecomp(a); ComplexDoubleMatrix qq = qrd.Q.GetConjugateTranspose() * qrd.Q; ComplexDoubleMatrix qr = qrd.Q * qrd.R; ComplexDoubleMatrix I = ComplexDoubleMatrix.CreateIdentity(3); // determine the maximum relative error double MaxError = 0.0; for (int i = 0; i < 3; i++) { for (int j = 0; i < 3; i++) { double E = ComplexMath.Absolute((qq[i, j] - I[i, j])); if (E > MaxError) { MaxError = E; } } } Assert.IsTrue(MaxError < 1.0E-14); MaxError = 0.0; for (int i = 0; i < 3; i++) { for (int j = 0; i < 3; i++) { double E = ComplexMath.Absolute((qr[i, j] - a[i, j]) / a[i, j]); if (E > MaxError) { MaxError = E; } } } Assert.IsTrue(MaxError < 1.0E-14); }
///<summary>Computes the algorithm.</summary> protected override void InternalCompute() { #if MANAGED l = new ComplexDoubleMatrix(matrix); for (int j = 0; j < order; j++) { Complex[] rowj = l.data[j]; double d = 0.0; for (int k = 0; k < j; k++) { Complex[] rowk = l.data[k]; Complex s = Complex.Zero; for (int i = 0; i < k; i++) { s += rowk[i]*rowj[i]; } rowj[k] = s = (matrix.data[j][k] - s)/l.data[k][k]; d = d + (s*ComplexMath.Conjugate(s)).Real; } d = matrix.data[j][j].Real - d; if ( d <= 0.0 ) { ispd = false; return; } l.data[j][j] = new Complex(System.Math.Sqrt(d)); for (int k = j+1; k < order; k++) { l.data[j][k] = Complex.Zero; } } #else Complex[] factor = new Complex[matrix.data.Length]; Array.Copy(matrix.data, factor, matrix.data.Length); int status = Lapack.Potrf.Compute(Lapack.UpLo.Lower, order, factor, order); if (status != 0 ) { ispd = false; } l = new ComplexDoubleMatrix(order); l.data = factor; for (int i = 0; i < order; i++) { for (int j = 0; j < order; j++) { if ( j > i) { l.data[j*order+i] = 0; } } } #endif }
static ComplexDoubleLUDecompTest() { ComplexDoubleMatrix a = new ComplexDoubleMatrix(3); a[0, 0] = new Complex(-1, 1); a[0, 1] = 5; a[0, 2] = 6; a[1, 0] = 3; a[1, 1] = -6; a[1, 2] = 1; a[2, 0] = 6; a[2, 1] = 8; a[2, 2] = 9; lu = new ComplexDoubleLUDecomp(a); }
static ComplexDoubleCholeskyDecompTest() { ComplexDoubleMatrix a = new ComplexDoubleMatrix(3); a[0, 0] = 2; a[0, 1] = new Complex(1, -1); a[0, 2] = 0; a[1, 0] = new Complex(1, -1); a[1, 1] = 2; a[1, 2] = 0; a[2, 0] = 0; a[2, 1] = 0; a[2, 2] = 3; cd = new ComplexDoubleCholeskyDecomp(a); }
///<summary>Constructor for Cholesky decomposition class. The constructor performs the factorization of a Hermitian positive ///definite matrax and the Cholesky factored matrix is accessible by the <c>Factor</c> property. The factor is the lower ///triangular factor.</summary> ///<param name="matrix">The matrix to factor.</param> ///<exception cref="ArgumentNullException">matrix is null.</exception> ///<exception cref="NotSquareMatrixException">matrix is not square.</exception> ///<remarks>This class only uses the lower triangle of the input matrix. It ignores the ///upper triangle.</remarks> public ComplexDoubleCholeskyDecomp(IROComplexDoubleMatrix matrix) { if (matrix == null) { throw new System.ArgumentNullException("matrix cannot be null."); } if (matrix.Rows != matrix.Columns) { throw new NotSquareMatrixException("Matrix must be square."); } order = matrix.Columns; this.matrix = new ComplexDoubleMatrix(matrix); }
///<summary>Constructor for Cholesky decomposition class. The constructor performs the factorization of a Hermitian positive ///definite matrax and the Cholesky factored matrix is accessible by the <c>Factor</c> property. The factor is the lower ///triangular factor.</summary> ///<param name="matrix">The matrix to factor.</param> ///<exception cref="ArgumentNullException">matrix is null.</exception> ///<exception cref="NotSquareMatrixException">matrix is not square.</exception> ///<remarks>This class only uses the lower triangle of the input matrix. It ignores the ///upper triangle.</remarks> public ComplexDoubleCholeskyDecomp(IROComplexDoubleMatrix matrix) { if ( matrix == null ) { throw new System.ArgumentNullException("matrix cannot be null."); } if ( matrix.Rows != matrix.Columns ) { throw new NotSquareMatrixException("Matrix must be square."); } order = matrix.Columns; this.matrix = new ComplexDoubleMatrix(matrix); }
public void Multiply() { ComplexFloatVector a = new ComplexFloatVector(new float[4] { 0, 1, 2, 3 }); ComplexFloatVector b = new ComplexFloatVector(new float[4] { 4, 5, 6, 7 }); ComplexDoubleMatrix c = new ComplexDoubleMatrix(a.Length, b.Length); ComplexDoubleMatrix d = new ComplexDoubleMatrix(a.Length, b.Length); c = a * b; d = ComplexFloatVector.Multiply(a, b); Assert.AreEqual(c[0, 0], a[0] * b[0]); Assert.AreEqual(c[0, 1], a[0] * b[1]); Assert.AreEqual(c[0, 2], a[0] * b[2]); Assert.AreEqual(c[0, 3], a[0] * b[3]); Assert.AreEqual(c[1, 0], a[1] * b[0]); Assert.AreEqual(c[1, 1], a[1] * b[1]); Assert.AreEqual(c[1, 2], a[1] * b[2]); Assert.AreEqual(c[1, 3], a[1] * b[3]); Assert.AreEqual(c[2, 0], a[2] * b[0]); Assert.AreEqual(c[2, 1], a[2] * b[1]); Assert.AreEqual(c[2, 2], a[2] * b[2]); Assert.AreEqual(c[2, 3], a[2] * b[3]); Assert.AreEqual(c[3, 0], a[3] * b[0]); Assert.AreEqual(c[3, 1], a[3] * b[1]); Assert.AreEqual(c[3, 2], a[3] * b[2]); Assert.AreEqual(c[3, 3], a[3] * b[3]); Assert.AreEqual(d[0, 0], a[0] * b[0]); Assert.AreEqual(d[0, 1], a[0] * b[1]); Assert.AreEqual(d[0, 2], a[0] * b[2]); Assert.AreEqual(d[0, 3], a[0] * b[3]); Assert.AreEqual(d[1, 0], a[1] * b[0]); Assert.AreEqual(d[1, 1], a[1] * b[1]); Assert.AreEqual(d[1, 2], a[1] * b[2]); Assert.AreEqual(d[1, 3], a[1] * b[3]); Assert.AreEqual(d[2, 0], a[2] * b[0]); Assert.AreEqual(d[2, 1], a[2] * b[1]); Assert.AreEqual(d[2, 2], a[2] * b[2]); Assert.AreEqual(d[2, 3], a[2] * b[3]); Assert.AreEqual(d[3, 0], a[3] * b[0]); Assert.AreEqual(d[3, 1], a[3] * b[1]); Assert.AreEqual(d[3, 2], a[3] * b[2]); Assert.AreEqual(d[3, 3], a[3] * b[3]); }
private ComplexDoubleMatrix Pivot(IROComplexDoubleMatrix B) { int m = B.Rows; int n = B.Columns; ComplexDoubleMatrix ret = new ComplexDoubleMatrix(m, n); for (int i = 0; i < pivots.Length; i++) { for (int j = 0; j < n; j++) { ret.data[i][j] = B[pivots[i], j]; } } return(ret); }
///<summary>Multiply a <c>ComplexDoubleVector</c> with another <c>ComplexDoubleVector</c> as x*y^T</summary> ///<param name="lhs"><c>ComplexDoubleVector</c> as left hand operand.</param> ///<param name="rhs"><c>ComplexDoubleVector</c> as right hand operand.</param> ///<returns><c>ComplexDoubleVector</c> with results.</returns> public static ComplexDoubleMatrix operator *(ComplexDoubleVector lhs, ComplexDoubleVector rhs) { ComplexDoubleMatrix ret = new ComplexDoubleMatrix(lhs.data.Length, rhs.data.Length); #if MANAGED for (int i = 0; i < lhs.data.Length; i++) { for (int j = 0; j < rhs.data.Length; j++) { ret[i, j] = lhs.data[i] * rhs.data[j]; } } #else Blas.Geru.Compute(Blas.Order.ColumnMajor, lhs.data.Length, rhs.data.Length, 1, lhs.data, 1, rhs.data, 1, ret.data, lhs.data.Length); #endif return(ret); }
///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary> ///<param name="B">RHS side of the system.</param> ///<returns>the solution vector, X.</returns> ///<exception cref="ArgumentNullException">B is null.</exception> ///<exception cref="SingularMatrixException">A is singular.</exception> ///<exception cref="ArgumentException">The number of rows of A and the length of B must be the same.</exception> public ComplexDoubleVector Solve(IROComplexDoubleVector B) { if (B == null) { throw new System.ArgumentNullException("B cannot be null."); } Compute(); if (singular) { throw new SingularMatrixException(); } else { if (B.Length != order) { throw new System.ArgumentException("The length of B must be the same as the order of the matrix."); } #if MANAGED // Copy right hand side with pivoting ComplexDoubleVector X = Pivot(B); // Solve L*Y = B(piv,:) for (int k = 0; k < order; k++) { for (int i = k + 1; i < order; i++) { X[i] -= X[k] * factor[i][k]; } } // Solve U*X = Y; for (int k = order - 1; k >= 0; k--) { X[k] /= factor[k][k]; for (int i = 0; i < k; i++) { X[i] -= X[k] * factor[i][k]; } } return(X); #else Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B); Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, 1, factor, order, pivots, rhs, rhs.Length); return(new ComplexDoubleVector(rhs)); #endif } }
public void CtorCopy() { ComplexDoubleMatrix a = new ComplexDoubleMatrix(2, 2); a[0, 0] = new Complex(1, 1); a[0, 1] = new Complex(2, 2); a[1, 0] = new Complex(3, 3); a[1, 1] = new Complex(4, 4); ComplexDoubleMatrix b = new ComplexDoubleMatrix(a); Assert.AreEqual(a.RowLength, b.RowLength); Assert.AreEqual(a.ColumnLength, b.ColumnLength); Assert.AreEqual(a[0, 0], b[0, 0]); Assert.AreEqual(a[0, 1], b[0, 1]); Assert.AreEqual(a[1, 0], b[1, 0]); Assert.AreEqual(a[1, 1], b[1, 1]); }
public void IsPositiveDefiniteTest() { Assert.IsTrue(cd.IsPositiveDefinite); ComplexDoubleMatrix b = new ComplexDoubleMatrix(3); b[0, 0] = -2; b[0, 1] = 1; b[0, 2] = 0; b[1, 0] = 1; b[1, 1] = 2; b[1, 2] = 0; b[2, 0] = 0; b[2, 1] = 0; b[2, 2] = 3; ComplexDoubleCholeskyDecomp dcd = new ComplexDoubleCholeskyDecomp(b); Assert.IsFalse(dcd.IsPositiveDefinite); }
/// <summary> /// Get a copy of the Toeplitz matrix. /// </summary> /// <returns> /// The Toeplitz matrix /// </returns> public ComplexDoubleMatrix GetMatrix() { int i; // allocate memory for the matrix ComplexDoubleMatrix tm = new ComplexDoubleMatrix(m_Order); #if MANAGED // fill lower triangle for (i = 0; i < m_Order; i++) { Array.Copy(m_LeftColumn.data, 0, tm.data[i], i, m_Order - i); } tm = tm.GetTranspose(); // fill upper triangle for (i = 0; i < m_Order - 1; i++) { Array.Copy(m_TopRow.data, 1, tm.data[i], i + 1, m_Order - i - 1); } #else int j, k; // fill lower triangle for (i = 0; i < m_Order; i++) { for (j = i, k = 0; j < m_Order; j++, k++) { tm[j, i] = m_LeftColumn[k]; } } // fill upper triangle for (i = 0; i < m_Order; i++) { for (j = i + 1, k = 1; j < m_Order; j++, k++) { tm[i, j] = m_TopRow[k]; } } #endif return(tm); }
public void NonSymmFactorTest() { ComplexDoubleMatrix b = new ComplexDoubleMatrix(3); b[0,0] = 2; b[0,1] = 1; b[0,2] = 1; b[1,0] = 1; b[1,1] = 2; b[1,2] = 0; b[2,0] = 0; b[2,1] = 0; b[2,2] = 3; ComplexDoubleCholeskyDecomp dcd = new ComplexDoubleCholeskyDecomp(b); Assert.AreEqual(dcd.Factor[0,0].Real,1.414,TOLERENCE); Assert.AreEqual(dcd.Factor[0,1].Real,0.000,TOLERENCE); Assert.AreEqual(dcd.Factor[0,2].Real,0.000,TOLERENCE); Assert.AreEqual(dcd.Factor[1,0].Real,0.707,TOLERENCE); Assert.AreEqual(dcd.Factor[1,1].Real,1.225,TOLERENCE); Assert.AreEqual(dcd.Factor[1,2].Real,0.000,TOLERENCE); Assert.AreEqual(dcd.Factor[2,0].Real,0.000,TOLERENCE); Assert.AreEqual(dcd.Factor[2,1].Real,0.000,TOLERENCE); Assert.AreEqual(dcd.Factor[2,2].Real,1.732,TOLERENCE); }
public void SetupTestCases() { a = new ComplexDoubleMatrix(3); a[0, 0] = new Complex(1.1, 1.1); a[0, 1] = new Complex(2.2, -2.2); a[0, 2] = new Complex(3.3, 3.3); a[1, 0] = new Complex(4.4, -4.4); a[1, 1] = new Complex(5.5, 5.5); a[1, 2] = new Complex(6.6, -6.6); a[2, 0] = new Complex(7.7, 7.7); a[2, 1] = new Complex(8.8, -8.8); a[2, 2] = new Complex(9.9, 9.9); svd = new ComplexDoubleSVDDecomp(a, true); wa = new ComplexDoubleMatrix(2, 4); wa[0, 0] = new Complex(1.1, 1.1); wa[0, 1] = new Complex(2.2, -2.2); wa[0, 2] = new Complex(3.3, 3.3); wa[0, 3] = new Complex(4.4, -4.4); wa[1, 0] = new Complex(5.5, 5.5); wa[1, 1] = new Complex(6.6, -6.6); wa[1, 2] = new Complex(7.7, 7.7); wa[1, 3] = new Complex(8.8, -8.8); wsvd = new ComplexDoubleSVDDecomp(wa, true); la = new ComplexDoubleMatrix(4, 2); la[0, 0] = new Complex(1.1, 1.1); la[0, 1] = new Complex(2.2, -2.2); la[1, 0] = new Complex(3.3, 3.3); la[1, 1] = new Complex(4.4, -4.4); la[2, 0] = new Complex(5.5, 5.5); la[2, 1] = new Complex(6.6, -6.6); la[3, 0] = new Complex(7.7, 7.7); la[3, 1] = new Complex(8.8, -8.8); lsvd = new ComplexDoubleSVDDecomp(la, true); }
/// <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 ComplexDoubleMatrix Solve(IROComplexDoubleMatrix Y) { ComplexDoubleMatrix 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 Complex[] Inner; // inner product Complex[] G; // scaling constant Complex[] A; // reference to current order coefficients Complex scalar; // allocate memory for solution X = new ComplexDoubleMatrix(m_Order, M); Inner = new Complex[M]; G = new Complex[M]; // setup zero order solution scalar = Complex.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; }
/// <summary> /// Get a copy of the Toeplitz matrix. /// </summary> public ComplexDoubleMatrix GetMatrix() { int i, j; // allocate memory for the matrix ComplexDoubleMatrix tm = new ComplexDoubleMatrix(m_Order); #if MANAGED // fill top row Complex[] top = tm.data[0]; Array.Copy(m_LeftColumn.data, 0, top, 0, m_Order); if (m_Order > 1) { // fill bottom row (reverse order) Complex[] 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) { Complex[] top = new Complex[m_Order]; Array.Copy(m_LeftColumn.data, 0, top, 0, m_Order); tm.SetRow(0, top); // fill bottom row (reverse order) Complex[] bottom = new Complex[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++) { Complex[] temp = new Complex[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; }
/// <summary> /// Invert a symmetric square Toeplitz matrix. /// </summary> /// <param name="T">The left-most column of the symmetric Toeplitz matrix.</param> /// <returns>The inverse matrix.</returns> /// <exception cref="ArgumentNullException"> /// <B>T</B> is a null reference. /// </exception> /// <exception cref="RankException"> /// The length of <B>T</B> must be greater than zero. /// </exception> /// <exception cref="SingularMatrixException"> /// The Toeplitz matrix or one of the the leading sub-matrices is singular. /// </exception> /// <remarks> /// This static member combines the <b>UDL</b> decomposition and Trench's algorithm into a /// single algorithm. When compared to the non-static member it requires minimal data storage /// and suffers from no speed penalty. /// <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 ComplexDoubleMatrix Inverse(IROComplexDoubleVector T) { ComplexDoubleMatrix X; // check parameters if (T == null) { throw new System.ArgumentNullException("T"); } else if (T.Length < 1) { throw new System.RankException("The length of T must be greater than zero."); } else if (T.Length == 1) { X = new ComplexDoubleMatrix(1); X[0, 0] = Complex.One / T[0]; } else { int N = T.Length; Complex f, g; int i, j, l, k, m, n; X = new ComplexDoubleMatrix(N); // calculate the predictor coefficients ComplexDoubleVector Y = ComplexDoubleSymmetricLevinson.YuleWalker(T); // calculate gamma f = T[0]; for (i = 1, j = 0; i < N; i++, j++) { f += T[i] * Y[j]; } g = Complex.One / f; // calculate first row of inverse X[0, 0] = g; for (i = 1, j = 0; i < N; i++, j++) { X[0, i] = g * Y[j]; } // calculate successive rows of upper wedge for (i = 0, j = 1, k = N - 2; i < N / 2; i++, j++, k--) { for (l = j, m = i, n = N-1-j; l < N - j; l++, m++, n--) { X[j, l] = X[i, m] + g * (Y[i] * Y[m] - Y[k] * Y[n]); } } // this is symmetric matrix ... for (i = 0; i <= N / 2; i++) { for (j = i + 1; j < N - i; j++) { X[j, i] = X[i, j]; } } // and a persymmetric matrix. for (i = 0, j = N - 1; i < N; i++, j--) { for (k = 0, l = N - 1; k < j; k++, l--) { X[l, j] = X[i, k]; } } } return X; }
/// <summary> /// Solve a symmetric square Toeplitz system with a right-side matrix. /// </summary> /// <param name="T">The left-most column of the Toeplitz matrix.</param> /// <param name="Y">The right-side matrix of the system.</param> /// <returns>The solution matrix.</returns> /// <exception cref="ArgumentNullException"> /// <B>T</B> and/or <B>Y</B> are null references /// </exception> /// <exception cref="RankException"> /// The length of <B>T</B> does not match the number of rows in <B>Y</B>. /// </exception> /// <exception cref="SingularMatrixException"> /// The Toeplitz matrix or one of the the leading sub-matrices is singular. /// </exception> /// <remarks> /// This method solves the linear system <B>AX</B> = <B>Y</B>. Where /// <B>T</B> is a symmetric square Toeplitz matrix, <B>X</B> is an unknown /// matrix and <B>Y</B> is a known matrix. /// <para> /// This static member combines the <b>UDL</b> decomposition and the calculation of the solution into a /// single algorithm. When compared to the non-static member it requires minimal data storage /// and suffers from no speed penalty. /// </para> /// </remarks> public static ComplexDoubleMatrix Solve(IROComplexDoubleVector T, IROComplexDoubleMatrix Y) { ComplexDoubleMatrix X; // check parameters if (T == null) { throw new System.ArgumentNullException("T"); } else if (Y == null) { throw new System.ArgumentNullException("Y"); } else if (T.Length != Y.Columns) { throw new RankException("The length of T and Y are not equal."); } else { // allocate memory int N = T.Length; int M = Y.Rows; X = new ComplexDoubleMatrix(N, M); // solution matrix ComplexDoubleVector Z = new ComplexDoubleVector(N); // temporary storage vector Complex e; // prediction error int i, j, l, m; // setup zero order solution e = T[0]; if (e == Complex.Zero) { throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular."); } for (m = 0; m < M; m++) { X[0, m] = Y[0,m] / T[0]; } if (N > 1) { ComplexDoubleVector a = new ComplexDoubleVector(N - 1); // prediction coefficients Complex p; // reflection coefficient Complex inner; // inner product Complex k; // calculate solution for successive orders for (i = 1; i < N; i++) { // calculate first inner product inner = T[i]; for (j = 0, l = i - 1; j < i - 1; j++, l--) { inner += a[j] * T[l]; } // update predictor coefficients p = -(inner / e); for (j = 0, l = i - 2; j < i - 1; j++, l--) { Z[j] = a[j] + p * a[l]; } // copy vector for (j = 0; j < i - 1; j++) { a[j] = Z[j]; } a[i - 1] = p; e *= (Complex.One - p * p); if (e == Complex.Zero) { throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular."); } // update the solution matrix for (m = 0; m < M; m++) { // retrieve a copy of solution column for (j = 0; j < i; j++) { Z[j] = X[j, m]; } // calculate second inner product inner = Y[i, m]; for (j = 0, l = i; j < i; j++, l--) { inner -= Z[j] * T[l]; } // update solution vector k = inner / e; for (j = 0, l = i - 1; j < i; j++, l--) { Z[j] = Z[j] + k * a[l]; } Z[j] = k; // store solution column in matrix for (j = 0; j <= i; j++) { X[j, m] = Z[j]; } } } } } return X; }
///<summary> Constructor </summary> public ComplexDoubleMatrixEnumerator (ComplexDoubleMatrix matrix) { m=matrix; index=-1; length=m.RowLength*m.ColumnLength; }
private static void zscalColumn(ComplexDoubleMatrix A, int Col, int Start, Complex z) { // A part of column Col of matrix A from row Start to end multiply by z for(int i=Start; i<A.RowLength; i++) { A[i,Col]=A[i,Col]*z; } }
///<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 ComplexDoubleVector(mm); // singular values #if MANAGED // Derived from LINPACK code. // Initialize. u=new ComplexDoubleMatrix(rows,rows); // left vectors v=new ComplexDoubleMatrix(cols,cols); // right vectors ComplexDoubleVector e=new ComplexDoubleVector(cols); ComplexDoubleVector work=new ComplexDoubleVector(rows); int i, iter, j, k, kase, l, lp1, ls=0, lu, m, nct, nctp1, ncu, nrt, nrtp1; double b, c, cs=0.0, el, emm1, f, g, scale, shift, sl, sm, sn=0.0, smm1, t1, test, ztest, xnorm, enorm; Complex 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 Complex(xnorm,(double)0.0); if (dcabs1(s[l]) != 0.0) { if (dcabs1(matrix[l,l]) != 0.0) { s[l] = csign(s[l],matrix[l,l]); } zscalColumn(matrix, l, l, 1.0/s[l]); matrix[l,l] = Complex.One + matrix[l,l]; } s[l] = -s[l]; } for(j=lp1; j<cols; j++) { if (l < nct) { if (dcabs1(s[l]) != 0.0) { // 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 Complex(enorm, 0.0); if (dcabs1(e[l]) != 0.0) { if (dcabs1(e[lp1]) != 0.0) { e[l] = csign(e[l],e[lp1]); } zscalVector(e, lp1, 1.0/e[l]); e[lp1] = Complex.One + e[lp1]; } e[l] = ComplexMath.Conjugate(-e[l]); if (lp1 < rows && dcabs1(e[l]) != 0.0) { // apply the transformation. for(i=lp1; i<rows; i++) { work[i] = Complex.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++) { Complex 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] = Complex.Zero; } if (nrtp1 < m) { e[nrtp1-1] = matrix[nrtp1-1,m-1]; } e[m-1] = Complex.Zero; // if required, generate u. if (computeVectors) { for(j=nctp1-1; j<ncu; j++) { for(i=0; i < rows; i++) { u[i,j] = Complex.Zero; } u[j,j] = Complex.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, -Complex.One); u[l,l] = Complex.One + u[l,l]; for(i=0; i<l; i++) { u[i,l] = Complex.Zero; } } else { for(i=0; i<rows; i++) { u[i,l] = Complex.Zero; } u[l,l] = Complex.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] = Complex.Zero; } v[l,l] = Complex.One; } } // transform s and e so that they are double . for(i=0; i < m; i++) { if (dcabs1(s[i]) != 0.0) { t = new Complex(ComplexMath.Absolute(s[i]),0.0); 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 Complex(ComplexMath.Absolute(e[i]),0.0); 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] = Complex.Zero; break; } } if (l == m - 2) { kase = 4; } else { for(ls=m-1; ls > l; ls--) { test = 0.0; 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] = Complex.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] = Complex.Zero; for(k=m-2; k>=0; k--) { t1 = s[k].Real; drotg(ref t1,ref f,ref cs,ref sn); s[k] = new Complex(t1, 0.0); 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] = Complex.Zero; for(k=l; k <m; k++) { t1 = s[k].Real; drotg(ref t1, ref f, ref cs, ref sn); s[k] = new Complex(t1,0.0); 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.0; 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.0; c = (sm*emm1)*(sm*emm1); shift = 0.0; if (b != 0.0 || c != 0.0) { shift = System.Math.Sqrt(b*b+c); if (b < 0.0) { 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 Complex(f,0.0); } 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 Complex(f,0.0); 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 Complex(f,0.0); 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, -Complex.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 double[] d = new double[mm]; u = new ComplexDoubleMatrix(rows); v = new ComplexDoubleMatrix(cols); Complex[] a = new Complex[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 ComplexDoubleMatrix(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]; } } } double eps = System.Math.Pow(2.0,-52.0); double 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 void zswap(ComplexDoubleMatrix A, int Col1, int Col2) { // swap columns Col1,Col2 Complex z; for(int i=0; i < A.RowLength; i++) { z=A[i,Col1]; A[i,Col1]=A[i,Col2]; A[i,Col2]=z; } }
public void ExplicitToComplexDoubleMatrix() { ComplexDoubleMatrix a = new ComplexDoubleMatrix(2,2); a[0,0] = 1; a[0,1] = 2; a[1,0] = 3; a[1,1] = 4; ComplexFloatMatrix b = ComplexFloatMatrix.ToComplexFloatMatrix(a); Assert.AreEqual(a.RowLength, b.RowLength); Assert.AreEqual(a.ColumnLength, b.ColumnLength); Assert.AreEqual(b[0,0], a[0,0]); Assert.AreEqual(b[0,1], a[0,1]); Assert.AreEqual(b[1,0], a[1,0]); Assert.AreEqual(b[1,1], a[1,1]); }
public void Multiply() { ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3}); ComplexDoubleVector b = new ComplexDoubleVector(new double[4]{4,5,6,7}); ComplexDoubleMatrix c = new ComplexDoubleMatrix(a.Length,b.Length); ComplexDoubleMatrix d = new ComplexDoubleMatrix(a.Length,b.Length); c = a*b; d = ComplexDoubleVector.Multiply(a,b); Assert.AreEqual(c[0,0],a[0]*b[0]); Assert.AreEqual(c[0,1],a[0]*b[1]); Assert.AreEqual(c[0,2],a[0]*b[2]); Assert.AreEqual(c[0,3],a[0]*b[3]); Assert.AreEqual(c[1,0],a[1]*b[0]); Assert.AreEqual(c[1,1],a[1]*b[1]); Assert.AreEqual(c[1,2],a[1]*b[2]); Assert.AreEqual(c[1,3],a[1]*b[3]); Assert.AreEqual(c[2,0],a[2]*b[0]); Assert.AreEqual(c[2,1],a[2]*b[1]); Assert.AreEqual(c[2,2],a[2]*b[2]); Assert.AreEqual(c[2,3],a[2]*b[3]); Assert.AreEqual(c[3,0],a[3]*b[0]); Assert.AreEqual(c[3,1],a[3]*b[1]); Assert.AreEqual(c[3,2],a[3]*b[2]); Assert.AreEqual(c[3,3],a[3]*b[3]); Assert.AreEqual(d[0,0],a[0]*b[0]); Assert.AreEqual(d[0,1],a[0]*b[1]); Assert.AreEqual(d[0,2],a[0]*b[2]); Assert.AreEqual(d[0,3],a[0]*b[3]); Assert.AreEqual(d[1,0],a[1]*b[0]); Assert.AreEqual(d[1,1],a[1]*b[1]); Assert.AreEqual(d[1,2],a[1]*b[2]); Assert.AreEqual(d[1,3],a[1]*b[3]); Assert.AreEqual(d[2,0],a[2]*b[0]); Assert.AreEqual(d[2,1],a[2]*b[1]); Assert.AreEqual(d[2,2],a[2]*b[2]); Assert.AreEqual(d[2,3],a[2]*b[3]); Assert.AreEqual(d[3,0],a[3]*b[0]); Assert.AreEqual(d[3,1],a[3]*b[1]); Assert.AreEqual(d[3,2],a[3]*b[2]); Assert.AreEqual(d[3,3],a[3]*b[3]); }
private static void zdrot (ComplexDoubleMatrix A, int Col1, int Col2, double c, double s) { // applies a plane rotation, where the c=cos and s=sin // Col1, Col2 - rotated columns of A Complex z; for(int i=0; i < A.RowLength; i++) { z=c*A[i,Col1]+s*A[i,Col2]; A[i,Col2]=c*A[i,Col2]-s*A[i,Col1]; A[i,Col1]=z; } }
/// <summary> /// Get the inverse of the Toeplitz matrix. /// </summary> /// <returns>The inverse matrix.</returns> /// <exception cref="SingularMatrixException"> /// The Toeplitz matrix or one of the the leading sub-matrices is singular. /// </exception> /// <remarks> /// The class implicitly decomposes the inverse Toeplitz matrix into a <b>UDL</b> factorisation /// using the Levinson algorithm, before using Trench's algorithm to complete /// the calculation of the inverse. /// <para> /// Trench's algorithm requires approximately <b>N</b> squared FLOPS, compared to <b>N</b> cubed FLOPS /// if we simply multiplied the <b>UDL</b> factors (<b>N</b> is the matrix order). /// </para> /// </remarks> public ComplexDoubleMatrix GetInverse() { Compute(); if (m_IsSingular == true) { throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular."); } ComplexDoubleMatrix I = new ComplexDoubleMatrix(m_Order); // the solution matrix Complex[] A = m_LowerTriangle[m_Order-1]; Complex A1, A2, scale; #if MANAGED Complex[] current, previous; // references to rows in the solution int i, j, k, l; // setup the first row in wedge scale = m_Diagonal[m_Order-1]; current = I.data[0]; for (i = 0, j = m_Order - 1; i < m_Order; i++, j--) { current[i] = scale* A[j]; } // calculate values in the rest of the wedge for (i = 1; i < (1 + m_Order) / 2; i++) { previous = current; current = I.data[i]; A1 = A[m_Order - i - 1]; A2 = A[i - 1]; for (j = i, k = i - 1, l = m_Order - i - 1; j < m_Order - i; j++, k++, l--) { current[j] = previous[k] + scale * (A1 * A[l] - A2 * A[k]); } } #else int i, j, k, l; // setup the first row in wedge scale = m_Diagonal[m_Order-1]; for (i = 0, j = m_Order - 1; i < m_Order; i++, j--) { I[0, i] = scale* A[j]; } // calculate values in the rest of the wedge for (i = 1; i < (1 + m_Order) / 2; i++) { A1 = A[m_Order - i - 1]; A2 = A[i - 1]; for (j = i, k = i - 1, l = m_Order - i - 1; j < m_Order - i; j++, k++, l--) { I[i, j] = I[i - 1, k] + scale * (A1 * A[l] - A2 * A[k]); } } #endif // this is symmetric matrix ... for (i = 0; i < (1 + m_Order) / 2; i++) { for (j = i; j < m_Order - i; j++) { I[j, i] = I[i, j]; } } // and a persymmetric matrix. for (i = 0, j = m_Order - 1; i < m_Order; i++, j--) { for (k = 0, l = m_Order - 1; k < j; k++, l--) { I[l, j] = I[i, k]; } } return I; }
public void ForEach() { ComplexDoubleMatrix test = new ComplexDoubleMatrix(new Complex[2, 2] { { 1, 2 }, { 3, 4 } }); foreach (Complex f in test) Assert.IsTrue(test.Contains(f)); }
private static Complex zdotc(ComplexDoubleMatrix A, int Col1, int Col2, int Start) { Complex z=Complex.Zero; for(int i=Start; i < A.RowLength; i++) { z+=A[i,Col2]*ComplexMath.Conjugate(A[i,Col1]); } return z; }
private static double dznrm2Column(ComplexDoubleMatrix A, int Col, int Start) { // dznrm2Column returns the euclidean norm of a vector, // which is a part of column Col in matrix A, beginning from Start to end of column // so that dznrm2Column := sqrt( conjg( matrix' )*matrix ) double s=0; for(int i=Start; i < A.RowLength; i++) { s+=(A[i,Col]*ComplexMath.Conjugate(A[i,Col])).Real; } return System.Math.Sqrt(s); }
public void CurrentException2() { ComplexDoubleMatrix test = new ComplexDoubleMatrix(new Complex[2, 2] { { 1, 2 }, { 3, 4 } }); IEnumerator enumerator = test.GetEnumerator(); enumerator.MoveNext(); enumerator.MoveNext(); enumerator.MoveNext(); enumerator.MoveNext(); enumerator.MoveNext(); object value = enumerator.Current; }
///<summary>Constructor for SVD decomposition class.</summary> ///<param name="matrix">The matrix to decompose.</param> ///<exception cref="ArgumentNullException">matrix is null.</exception> public ComplexDoubleSVDDecomp(IROComplexDoubleMatrix matrix) { if ( matrix == null ) { throw new System.ArgumentNullException("matrix cannot be null."); } this.matrix = new ComplexDoubleMatrix(matrix); }