예제 #1
0
        ///<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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        ///<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);
        }