///<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 ComplexFloatMatrix Solve(IROComplexFloatMatrix 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; ComplexFloatMatrix 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 ComplexFloat[] rhs = ComplexFloatMatrix.ToLinearComplexArray(B); Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, B.Columns, factor, order, pivots, rhs, B.Rows); ComplexFloatMatrix ret = new ComplexFloatMatrix(order, B.Columns); ret.data = rhs; return(ret); #endif } }
///<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 ComplexFloatMatrix Solve(IROComplexFloatMatrix 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 ComplexFloatMatrix(B); for (int c = 0; c < cols; c++) { // Solve L*Y = B; for (int i = 0; i < order; i++) { ComplexFloat 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--) { ComplexFloat 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 ComplexFloat[] rhs = ComplexFloatMatrix.ToLinearComplexArray(B); Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, B.Columns, l.data, order, rhs, B.Rows); ComplexFloatMatrix ret = new ComplexFloatMatrix(order, B.Columns); ret.data = rhs; return(ret); #endif } }
///<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 ComplexFloatVector Solve(IROComplexFloatVector 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 ComplexFloatVector(B); // Solve L*Y = B; for (int i = 0; i < order; i++) { ComplexFloat 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--) { ComplexFloat 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 ComplexFloat[] rhs = ComplexFloatMatrix.ToLinearComplexArray(B); Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, 1, l.data, order, rhs, B.Length); ComplexFloatVector ret = new ComplexFloatVector(order, B.Length); ret.data = rhs; return(ret); #endif } }
///<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 ComplexFloatVector Solve(IROComplexFloatVector 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 ComplexFloatVector 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 ComplexFloat[] rhs = ComplexFloatMatrix.ToLinearComplexArray(B); Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, 1, factor, order, pivots, rhs, rhs.Length); return(new ComplexFloatVector(rhs)); #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; } } }
/// <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 (!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; var ret = new ComplexFloatMatrix(n, nx); #if MANAGED var X = new ComplexFloatMatrix(B); // Compute Y = transpose(Q)*B var 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); }