///<inheritdoc cref="SingularValueDecomposition.Decompose( ///DoubleMatrix, out DoubleMatrix, out DoubleMatrix)"/> public static DoubleMatrix Decompose( ComplexMatrix matrix, out ComplexMatrix leftSingularVectors, out ComplexMatrix conjugateTransposedRightSingularVectors) { #region Input validation if (matrix is null) { throw new ArgumentNullException(nameof(matrix)); } #endregion int m = matrix.NumberOfRows; int n = matrix.NumberOfColumns; int min_m_n = m < n ? m : n; Complex[] a = matrix.AsColumnMajorDenseArray(); double[] s = new double[min_m_n]; Complex[] u = new Complex[m * m]; Complex[] vt = new Complex[n * n]; int lapackInfo; double[] superb = new double[min_m_n - 1]; lapackInfo = SafeNativeMethods.LAPACK.ZGESVD( matrix_layout: SafeNativeMethods.LAPACK.ORDER.ColMajor, jobu: 'A', jobvt: 'A', m, n, a, lda: m, s, u, ldu: m, vt, ldvt: n, superb); if (lapackInfo > 0) { throw new InvalidOperationException( ImplementationServices.GetResourceString( "STR_EXCEPT_ALG_DOES_NOT_CONVERGE")); } DoubleMatrix values = DoubleMatrix.Dense(m, n); for (int i = 0; i < min_m_n; i++) { values[i, i] = s[i]; } leftSingularVectors = ComplexMatrix.Dense(m, m, u, copyData: false); conjugateTransposedRightSingularVectors = ComplexMatrix.Dense(n, n, vt, copyData: false); return(values); }
/// <summary> /// Computes eigenvalues and eigenvectors of the /// specified Hermitian complex matrix. /// </summary> /// <param name="matrix"> /// The matrix containing the lower or upper triangular part of the matrix /// whose spectral decomposition must be computed. /// </param> /// <param name="lowerTriangularPart"> /// <c>true</c> if <paramref name="matrix"/> contains the lower /// triangular part of the matrix to be decomposed; /// <c>false</c> if <paramref name="matrix"/> contains /// its upper triangular part. /// </param> /// <param name="eigenvectors"> /// A matrix whose columns represent the eigenvectors /// of the decomposed matrix. /// </param> /// <returns> /// A diagonal matrix containing the eigenvalues /// of the decomposed matrix, in ascending order. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="matrix"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="matrix"/> is not square. /// </exception> public static DoubleMatrix Decompose( ComplexMatrix matrix, bool lowerTriangularPart, out ComplexMatrix eigenvectors) { #region Input validation if (matrix is null) { throw new ArgumentNullException(nameof(matrix)); } if (!matrix.IsSquare) { throw new ArgumentException( message: ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_SQUARE"), paramName: nameof(matrix)); } #endregion int m = matrix.NumberOfRows; double[] valuesArray = new double[m]; Complex[] vectorsArray = matrix.AsColumnMajorDenseArray(); int info = SafeNativeMethods.LAPACK.ZHEEV( matrix_layout: SafeNativeMethods.LAPACK.ORDER.ColMajor, jobz: 'V', uplo: lowerTriangularPart ? 'L' : 'U', n: m, a: vectorsArray, lda: m, w: valuesArray); if (info > 0) { throw new InvalidOperationException( message: ImplementationServices.GetResourceString( "STR_EXCEPT_ALG_DOES_NOT_CONVERGE")); } DoubleMatrix eigenvalues = DoubleMatrix.Sparse(m, m, m); for (int i = 0; i < m; i++) { eigenvalues[i, i] = valuesArray[i]; } eigenvectors = ComplexMatrix.Dense(m, m, vectorsArray, copyData: false); Debug.Assert(eigenvalues != null); Debug.Assert(eigenvectors != null); return(eigenvalues); }
///<inheritdoc cref="SingularValueDecomposition ///.GetSingularValues(DoubleMatrix)"/> public static DoubleMatrix GetSingularValues( ComplexMatrix matrix) { #region Input validation if (matrix is null) { throw new ArgumentNullException(nameof(matrix)); } #endregion int m = matrix.NumberOfRows; int n = matrix.NumberOfColumns; int min_m_n = m < n ? m : n; Complex[] a = matrix.AsColumnMajorDenseArray(); double[] s = new double[min_m_n]; Complex[] u = null; Complex[] vt = null; int lapackInfo; double[] superb = new double[min_m_n - 1]; lapackInfo = SafeNativeMethods.LAPACK.ZGESVD( matrix_layout: SafeNativeMethods.LAPACK.ORDER.ColMajor, jobu: 'N', jobvt: 'N', m, n, a, lda: m, s: s, u, ldu: m, vt, ldvt: n, superb); if (lapackInfo > 0) { throw new InvalidOperationException( ImplementationServices.GetResourceString( "STR_EXCEPT_ALG_DOES_NOT_CONVERGE")); } DoubleMatrix values = DoubleMatrix.Dense(min_m_n, 1, s, copyData: false); return(values); }