///<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 ComplexFloatMatrix GetInverse() { Compute(); if (!ispd) { throw new NotPositiveDefiniteException(); } else { #if MANAGED var ret = ComplexFloatMatrix.CreateIdentity(order); ret = Solve(ret); return(ret); #else ComplexFloat[] inverse = new ComplexFloat[l.data.Length]; Array.Copy(l.data, inverse, l.data.Length); Lapack.Potri.Compute(Lapack.UpLo.Lower, order, inverse, order); ComplexFloatMatrix ret = new ComplexFloatMatrix(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 SquareDecomp() { ComplexFloatMatrix a = new ComplexFloatMatrix(3); a[0, 0] = new ComplexFloat(1.1f, 1.1f); a[0, 1] = new ComplexFloat(2.2f, -2.2f); a[0, 2] = new ComplexFloat(3.3f, 3.3f); a[1, 0] = new ComplexFloat(4.4f, -4.4f); a[1, 1] = new ComplexFloat(5.5f, 5.5f); a[1, 2] = new ComplexFloat(6.6f, -6.6f); a[2, 0] = new ComplexFloat(7.7f, 7.7f); a[2, 1] = new ComplexFloat(8.8f, -8.8f); a[2, 2] = new ComplexFloat(9.9f, 9.9f); ComplexFloatQRDecomp qrd = new ComplexFloatQRDecomp(a); ComplexFloatMatrix qq = qrd.Q.GetConjugateTranspose() * qrd.Q; ComplexFloatMatrix qr = qrd.Q * qrd.R; ComplexFloatMatrix I = ComplexFloatMatrix.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-6); 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 < 2.4E-6); }
///<summary>Calculates the inverse of the matrix.</summary> ///<returns>the inverse of the matrix.</returns> ///<exception cref="SingularMatrixException">matrix is singular.</exception> public ComplexFloatMatrix GetInverse() { Compute(); if (singular) { throw new SingularMatrixException(); } else { #if MANAGED ComplexFloatMatrix ret = ComplexFloatMatrix.CreateIdentity(order); ret = Solve(ret); return(ret); #else ComplexFloat[] inverse = new ComplexFloat[factor.Length]; Array.Copy(factor, inverse, factor.Length); Lapack.Getri.Compute(order, inverse, order, pivots); ComplexFloatMatrix ret = new ComplexFloatMatrix(order, order); ret.data = inverse; 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 ComplexFloatMatrix(matrix); // create a copy var u = new ComplexFloatVector[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_ = ComplexFloatMatrix.CreateIdentity(m); for (int i = minmn - 1; i >= 0; i--) { Householder.UA(u[i], q_, i, m - 1, i, m - 1); } #else qr = ComplexFloatMatrix.ToLinearComplexArray(matrix); jpvt = new int[n]; jpvt[0] = 1; Lapack.Geqp3.Compute(m, n, qr, m, jpvt, out tau); r_ = new ComplexFloatMatrix(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] = ComplexFloat.Zero; } } } q_ = new ComplexFloatMatrix(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] = ComplexFloat.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; } } }