コード例 #1
0
ファイル: eig.cs プロジェクト: wdxa/ILNumerics
 /// <summary>
 /// find all eigenvalues of symmetric (hermitian) matrix
 /// </summary>
 /// <param name="A">input matrix, Size [n x n], symmetric (hermitian for complex A) </param> 
 /// <returns>array of size [n,1] with eigenvalues of A.</returns>
 /// <remarks><para>For computation the Lapack functions dsyevr, ssyevr, chesvr and zheesv are used. </para>
 /// <para>Since A is symmetric, the eigenvalues will always be real. Therefore the return value will be of the same inner type as A.</para></remarks>
 /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if A is not square.</exception>
 public static /*!HC:HCCls1*/ ILArray<double> eigSymm (/*!HC:HCCls1*/ ILArray<double> A) {
     if (A.IsEmpty) {
         return /*!HC:HCCls1*/ ILArray<double> .empty(A.Dimensions); 
     }
     int n = A.Dimensions[0]; 
     if (n != A.Dimensions[1])
         throw new ILArgumentException("eigSymm: input matrix A must be square and symmetric/hermitian.");
     /*!HC:HCCls1*/ ILArray<double> ret = null; 
     int m = 0,info = 0; 
     /*!HC:HCCls1*/ ILArray<double> tmpA = A.copyUpperTriangle(n); 
     /*!HC:HCClsReal*/ ILArray<double> w = new /*!HC:HCClsReal*/ ILArray<double> (new /*!HC:HCArrReal*/ double [n],1,n); 
     /*!HC:HCArr1*/ double [] z = new /*!HC:HCArr1*/ double [1]; ; 
     int [] isuppz = new int[2 * n];
     /*!HC:lapack_???evr*/ Lapack.dsyevr ('N','A','U',n,tmpA.m_data,n,0,0,0,0,0,ref m,w.m_data,z,1,isuppz,ref info);
     ret = /*!HC:HCClsConv3*/ /**/ (w); 
     return ret; 
 }
 /// <summary>
 /// find all eigenvalues and -vectors of symmetric (hermitian) matrix
 /// </summary>
 /// <param name="A">input matrix, Size [n x n], symmetric (hermitian for complex A) </param> 
 /// <param name="V">output: n eigenvectors as columns. Size [n x n]. If V is null on input, the eigenvectors will not be computed and V is not changed. </param>
 /// <returns>diagonal matrix of size [n,n] with eigenvalues of A on the main diagonal.</returns>
 /// <remarks><para>For computation the Lapack functions dsyevr, ssyevr, chesvr and zheesv are used. </para>
 /// <para>Since A is symmetric, the eigenvalues will always be real. Therefore the return value will be of the same inner type as A.</para></remarks>
 /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if A is not square.</exception>
 public static /*!HC:HCCls1*/ ILArray<double> eigSymm (/*!HC:HCCls1*/ ILArray<double> A, ref /*!HC:HCCls1*/ ILArray<double> V) {
     if (A.IsEmpty) {
         V = /*!HC:HCCls1*/ ILArray<double> .empty(A.Dimensions); 
         return /*!HC:HCCls1*/ ILArray<double> .empty(A.Dimensions); 
     }
     int n = A.Dimensions[0]; 
     if (n != A.Dimensions[1])
         throw new ILArgumentException("eigSymm: input matrix A must be square and symmetric/hermitian.");
     /*!HC:HCCls1*/ ILArray<double> ret = null; 
     int m = 0,ldz = 0,info = 0; 
     /*!HC:HCCls1*/ ILArray<double> tmpA = A.copyUpperTriangle(n); 
     /*!HC:HCClsReal*/ ILArray<double> w = new /*!HC:HCClsReal*/ ILArray<double> (new /*!HC:HCArrReal*/ double [n],n,1); 
     /*!HC:HCArr1*/ double [] z; 
     char jobz;
     if (object.Equals(V,null)) {
         z = new /*!HC:HCArr1*/ double [1]; 
         jobz = 'N';
         ldz = 1; 
     } else {
         z = new /*!HC:HCArr1*/ double [n * n];
         jobz = 'V';
         ldz = n; 
     } 
     int [] isuppz = new int[2 * n];
     /*!HC:lapack_???evr*/ Lapack.dsyevr (jobz,'A','U',n,tmpA.m_data,n,1,n,0,0,0,ref m,w.m_data,z,ldz,isuppz,ref info);
     if (info != 0) 
         throw new ILException("eigSymm: error returned from lapack: " + info); 
     if (jobz == 'V') {
         V =  new  /*!HC:HCCls1*/ ILArray<double> (z,n,n);
         V = V[null,ILMath.vector(0,m-1)]; 
         ret = ILMath.diag(/*!HC:HCClsConv3*/ /**/ (w)); 
     } else {
         ret = /*!HC:HCClsConv3*/ /**/ (w);
     }
     return ret; 
 }
 /// <summary>
 /// find some eigenvalues and -vectors of symmetric (hermitian) matrix
 /// </summary>
 /// <param name="A">input matrix, Size [n x n], symmetric (hermitian for complex A) </param> 
 /// <param name="V">output: n eigenvectors as columns. Size [n x n]. If V is null on input, the eigenvectors will not be computed and V is not changed. </param>
 /// <param name="rangeStart">specify the lowest limit for the range of eigenvalues to be queried.</param>
 /// <param name="rangeEnd">specify the upper limit for the range of eigenvalues to be queried.</param>
 /// <returns>diagonal matrix of size [n,n] with eigenvalues of A on the main diagonal.</returns>
 /// <remarks><para>For computation the Lapack functions dsyevr, ssyevr, chesvr and zheesv are used. </para>
 /// <para>Since A is symmetric, the eigenvalues will always be real. Therefore the return value will be of the same inner type as A.</para></remarks>
 /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if A is not square or <paramref name="rangeEnd"/> &lt; <paramref name="rangeStart"/></exception>
 public static /*!HC:HCCls1*/ ILArray<double> eigSymm (/*!HC:HCCls1*/ ILArray<double> A, ref /*!HC:HCCls1*/ ILArray<double> V, int rangeStart, int rangeEnd) {
     if (A.IsEmpty) {
         V = /*!HC:HCCls1*/ ILArray<double> .empty(A.Dimensions); 
         return /*!HC:HCCls1*/ ILArray<double> .empty(A.Dimensions); 
     }
     int n = A.Dimensions[0]; 
     if (n != A.Dimensions[1])
         throw new ILArgumentException("eigSymm: input matrix A must be square and symmetric/hermitian.");
     /*!HC:HCCls1*/ ILArray<double> ret = null; 
     int m = 0,ldz = 0,info = 0; 
     if (rangeEnd < rangeStart || rangeStart < 1) 
         throw new ILArgumentException("eigSymm: invalid range of eigenvalues requested");
     /*!HC:HCCls1*/ ILArray<double> tmpA = A.copyUpperTriangle(n); 
     /*!HC:HCClsReal*/ ILArray<double> w = new /*!HC:HCClsReal*/ ILArray<double> (new /*!HC:HCArrReal*/ double [n],1,n); 
     /*!HC:HCArr1*/ double [] z; 
     char jobz;
     if (object.Equals(V,null)) {
         z = new /*!HC:HCArr1*/ double [1]; 
         jobz = 'N';
         ldz = 1; 
     } else {
         z = new /*!HC:HCArr1*/ double [n * n];
         jobz = 'V';
         ldz = n; 
     } 
     int [] isuppz = new int[2 * n];
     /*!HC:lapack_???evr*/ Lapack.dsyevr (jobz,'I','U',n,tmpA.m_data,n,0,0,rangeStart,rangeEnd,0,ref m,w.m_data,z,ldz,isuppz,ref info);
     ret = ILMath.diag(/*!HC:HCClsConv3*/ /**/ (w)); 
     if (jobz == 'V') {
         V =  new  /*!HC:HCCls1*/ ILArray<double> (z,n,n);
         V = V[null,ILMath.vector(0,m-1)]; 
     }
     return ret; 
 }
コード例 #2
0
ファイル: eig.cs プロジェクト: wdxa/ILNumerics
 /// <summary>
 /// find some eigenvalues and -vectors of symmetric (hermitian) matrix
 /// </summary>
 /// <param name="A">input matrix, Size [n x n], symmetric (hermitian for complex A) </param> 
 /// <param name="V">output: n eigenvectors as columns. Size [n x n]. If V is null on input, the eigenvectors will not be computed and V is not changed. </param>
 /// <param name="rangeStart">The eigenvalues will be returned by increasing size. This will determine the number of the first eigenvalue to be returned.</param>
 /// <param name="rangeEnd">Determine the number of the last eigenvalue to be returned.</param>
 /// <returns>diagonal matrix of size [n,n] with eigenvalues of A on the main diagonal.</returns>
 /// <remarks><para>For computation the Lapack functions dsyevr, ssyevr, chesvr and zheesv are used. </para>
 /// <para>Since A is symmetric, the eigenvalues will always be real. Therefore the return value will be of the same inner type as A.</para></remarks>
 /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if A is not square or <paramref name="rangeEnd"/> &lt; <paramref name="rangeStart"/> or if either one is &lt;= 0.</exception>
 public static /*!HC:HCCls1*/ ILArray<double> eigSymm (/*!HC:HCCls1*/ ILArray<double> A, ref /*!HC:HCCls1*/ ILArray<double> V, /*!HC:HCArrReal*/ double rangeStart, /*!HC:HCArrReal*/ double rangeEnd) {
     if (A.IsEmpty) {
         V = /*!HC:HCCls1*/ ILArray<double> .empty(A.Dimensions); 
         return /*!HC:HCCls1*/ ILArray<double> .empty(A.Dimensions); 
     }
     int n = A.Dimensions[0]; 
     if (n != A.Dimensions[1])
         throw new ILArgumentException("eigSymm: input matrix A must be square and symmetric/hermitian.");
     /*!HC:HCCls1*/ ILArray<double> ret = null; 
     int m = 0,ldz = 0,info = 0; 
     if (rangeStart > rangeEnd) 
         throw new ILArgumentException("eigSymm: invalid range of eigenvalues requested");
     /*!HC:HCCls1*/ ILArray<double> tmpA = A.copyUpperTriangle(n); 
     /*!HC:HCClsReal*/ ILArray<double> w = new /*!HC:HCClsReal*/ ILArray<double> (new /*!HC:HCArrReal*/ double [n],1,n); 
     /*!HC:HCArr1*/ double [] z; 
     char jobz;
     if (object.Equals(V,null)) {
         z = new /*!HC:HCArr1*/ double [1]; 
         jobz = 'N';             
         ldz = 1; 
     } else {
         z = new /*!HC:HCArr1*/ double [n * n];
         jobz = 'V';
         ldz = n; 
     } 
     int [] isuppz = new int[2 * n];
     /*!HC:lapack_???evr*/ Lapack.dsyevr (jobz,'V','U',n,tmpA.m_data,n,rangeStart,rangeEnd,0,0,0, ref m,w.m_data,z,ldz,isuppz,ref info);
     ret = ILMath.diag(/*!HC:HCClsConv3*/ /**/ (w)); 
     if (jobz == 'V') {
         V =  new  /*!HC:HCCls1*/ ILArray<double> (z,n,n);
         V = V[null,ILMath.vector(0,m-1)]; 
     }
コード例 #3
0
ファイル: eig.cs プロジェクト: wdxa/ILNumerics
 /// <summary>
 /// find eigenvalues  and eigenvectors 
 /// </summary>
 /// <param name="A">input: square matrix, size [n x n]</param>
 /// <param name="V">output (optional): eigenvectors</param>   
 /// <param name="propsA">matrix properties, on input - if specified, 
 /// will be used to choose the proper method of solution. On exit will be 
 /// filled according to the properties of A.</param>
 /// <param name="balance">true: permute A in order to increase the 
 /// numerical stability, false: do not permute A.</param>
 /// <returns>eigenvalues as vector (if V is null) or as diagonoal 
 /// matrix (if V was requested, i.e. not equaled null).</returns>
 /// <remarks><para>The eigenvalues of A are found by use of the 
 /// Lapack functions dgeevx, sgeevx, cgeevx and zgeevx. </para>
 /// <para>The arrays returned will be of complex inner type, 
 /// since no further constraints are set on the structure of 
 /// A (it may be nonsymmetric). Use 
 /// <see cref="ILNumerics.BuiltInFunctions.ILMath.eigSymm(ILArray&lt;double&gt;)"/> 
 /// or <see cref="ILNumerics.BuiltInFunctions.ILMath.eigSymm(ILArray&lt;double&gt;,ref ILArray&lt;double&gt;)"/> 
 /// functions for computing the real eigenvalues of symmetric 
 /// matrices explicitly.</para>
 /// <para>Depending on the parameter <paramref name="balance"/>, 
 /// A will be balanced first. This includes permutations and 
 /// scaling of A in order to improve the conditioning of the 
 /// eigenvalues.</para></remarks>
 /// <seealso cref="ILNumerics.BuiltInFunctions.ILMath.eig(ILArray&lt;double&gt;)"/>
 /// <seealso cref="ILNumerics.BuiltInFunctions.ILMath.eig(ILArray&lt;double&gt;,ref ILArray&lt;complex&gt;,ref MatrixProperties,bool)"/>
 /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if a 
 /// is not square</exception>
 public static /*!HC:HCClsCmplx*/ ILArray<complex> eig(/*!HC:HCCls1*/ ILArray<double> A, ref /*!HC:HCClsCmplx*/ ILArray<complex> V, ref MatrixProperties propsA, bool balance) {
     if (A.IsEmpty) {
         V = /*!HC:HCClsCmplx*/ ILArray<complex> .empty(A.Dimensions); 
         return /*!HC:HCClsCmplx*/ ILArray<complex> .empty(A.Dimensions); 
     }
     /*!HC:HCClsCmplx*/ ILArray<complex> ret = null;  
     int n = A.Dimensions[0]; 
     bool createVR = (object.Equals(V,null))? false:true; 
     if (n != A.Dimensions[1]) 
         throw new ILArgumentException("eig: matrix A must be square!");
     propsA |= MatrixProperties.Square; 
     if (((propsA & MatrixProperties.Hermitian) != 0 || ILMath.ishermitian(A))) {
         propsA |= MatrixProperties.Hermitian; 
         /*!HC:HCCls1*/ ILArray<double> Vd = null; 
         if (createVR) 
             Vd = /*!HC:HCCls1*/ ILArray<double> .empty(0,0);
         /*!HC:HCCls1*/ ILArray<double> tmpRet = eigSymm(A,ref Vd);
         if (createVR)
             V = /*!HC:HCCls2Cmplx*/ ILMath.tocomplex (Vd); 
         ret = /*!HC:HCCls2Cmplx*/ ILMath.tocomplex (tmpRet);
     } else {
         // nonsymmetric case
         char bal = (balance)? 'B':'N', jobvr;  
         /*!HC:HCCls1*/ ILArray<double> tmpA = (/*!HC:HCCls1*/ ILArray<double> )A.Clone(); 
         /*!HC:HCArr1*/ double [] vr = null;
         /*!HC:HCArr1*/ double [] wr = ILMemoryPool.Pool.New</*!HC:HCArr1*/ double >(n); 
         /*!HC:HCArrWI*/ 
         double[] wi = ILMemoryPool.Pool.New<double>(n); 
         /*!HC:HCArrReal*/ double [] scale  = ILMemoryPool.Pool.New</*!HC:HCArrReal*/ double >(n);
         /*!HC:HCArrReal*/ double [] rconde = ILMemoryPool.Pool.New</*!HC:HCArrReal*/ double >(n); 
         /*!HC:HCArrReal*/ double [] rcondv = ILMemoryPool.Pool.New</*!HC:HCArrReal*/ double >(n); 
         /*!HC:HCArrReal*/ double abnrm = 0; 
         int ldvr, ilo = 0, ihi = 0, info = 0;
         if (createVR) {
             ldvr = n;
             vr = ILMemoryPool.Pool.New</*!HC:HCArr1*/ double >(n * n);
             jobvr = 'V'; 
         } else {
             ldvr = 1; 
             vr = new /*!HC:HCArr1*/ double [1]; 
             jobvr = 'N'; 
         }
         /*!HC:HC?geevx*/
         Lapack.dgeevx(bal,'N',jobvr,'N',n,tmpA.m_data,n,wr,wi,new /*!HC:HCArr1*/ double [1],1,vr,ldvr,ref ilo,ref ihi,scale,ref abnrm,rconde,rcondv,ref info);   
         if (info != 0) 
             throw new ILArgumentException("eig: error in Lapack '?geevx': (" + info + ")");
         // create eigenvalues 
         /*!HC:HCArrCmplx*/ complex [] retArr = ILMemoryPool.Pool.New</*!HC:HCArrCmplx*/ complex >(n); 
         for (int i = 0; i < n; i++) {
             /*!HC:HCSortEVal*/
             retArr[i].real = wr[i]; retArr[i].imag = wi[i]; 
         }
         ret = new /*!HC:HCClsCmplx*/ ILArray<complex> (retArr,n,1);
         if (createVR) {
             #region HCSortEVec
             complex [] VArr = ILMemoryPool.Pool.New< complex >(n * n);
             for (int c = 0; c < n; c++) {
                 if (wi[c] != 0 && wi[c+1] != 0 && c < n-1) {
                     ilo = n * c; ihi = ilo + n;
                     for (int r = 0; r < n; r++) {
                         VArr[ilo].real = vr[ilo];
                         VArr[ilo].imag = vr[ihi];  
                         VArr[ihi].real = vr[ilo];  
                         VArr[ihi].imag = -vr[ihi]; 
                         ilo++; ihi++; 
                     }
                     c++; 
                 } else {
                     ilo = n * c;
                     for (int r = 0; r < n; r++) {
                         VArr[ilo].real = vr[ilo];
                         ilo++; 
                     }
                 }
             }
             V = new ILArray<complex> (VArr,n,n); 
             #endregion HYCALPER
             if (createVR) 
                 ret = ILMath.diag(ret); 
         }
     }
     return ret; 
 }