EigenvalueVector.inl
上传用户:fxromeo
上传日期:2010-04-08
资源大小:89k
文件大小:12k
开发平台:

Visual C++

  1. // EigenvalueVector.inl 计算特征值特征向量函数(方法)定义
  2. // Ver 1.0.0.0
  3. // 版权所有(C) 何渝, 2002
  4. // 最后修改: 2002.8.10
  5. #ifndef _EIGENVALUEVECTOR_INL
  6. #define _EIGENVALUEVECTOR_INL
  7. //约化对称阵为对称三对角阵的豪斯荷尔德变换法
  8. template <class _Ty>
  9. int HouseholderTransform(matrix<_Ty>& a, matrix<_Ty>& q, 
  10. valarray<_Ty>& b, valarray<_Ty>& c)
  11. {
  12. int j, k, stRank;
  13.     _Ty h, f, g, h2;
  14. if(MatrixSymmetry(a)!=true)
  15. return int(0); //矩阵a不是对称阵
  16. stRank = a.GetColNum(); // 矩阵阶数
  17.     for(int i=0; i<stRank; i++)
  18. for(int j=0; j<stRank; j++)
  19. q(i,j)=a(i,j);
  20.     for(i=stRank-1; i>=1; i--)
  21.     { 
  22. h=0.0;
  23.         if(i>1)
  24.           for(k=0; k<i; k++)
  25.   h=h+q(i,k)*q(i,k);
  26.         if(FloatEqual(h,0))
  27.         {
  28. c[i]=0.0;
  29.             if(i==1) c[i]=q(i,i-1);
  30.             b[i]=0.0;
  31.         }
  32.         else
  33.         { 
  34. c[i]=sqrt(h);
  35.             if(q(i,i-1)>0.0) c[i]=-c[i];
  36.             h=h-q(i,i-1)*c[i];
  37.             q(i,i-1)=q(i,i-1)-c[i];
  38.             f=0.0;
  39.             for(j=0; j<i; j++)
  40.             { 
  41. q(j,i) = q(i,j) / h;
  42.                 g = 0.0;
  43.                 for(k=0; k<=j; k++)
  44.                   g = g + q(j,k) * q(i,k);
  45.                 if(j+1<i)
  46.                   for(k=j+1; k<i; k++)
  47.                     g = g + q(k,j) * q(i,k);
  48.                 c[j] = g / h;
  49.                 f = f + g * q(j,i);
  50.             }
  51.             h2 = f / (h+h);
  52.             for(j=0; j<i; j++)
  53.             { 
  54. f = q(i,j);
  55.                 g = c[j] -h2 * f;
  56.                 c[j] = g;
  57.                 for(k=0; k<=j; k++)
  58.                     q(j,k)=q(j,k)-f*c[k]-g*q(i,k);
  59.             }
  60.             b[i]=h;
  61.         }
  62.     }
  63.     for(i=0; i<stRank-1; i++) c[i]=c[i+1];
  64.     c[stRank-1]=0.0;
  65.     b[0]=0.0;
  66.     for(i=0; i<stRank; i++)
  67.     { if((b[i]!=0.0)&&(i-1>=0))
  68.           for(j=0; j<i; j++)
  69.           { 
  70.   g=0.0;
  71.               for(k=0; k<i; k++)
  72. g=g+q(i,k)*q(k,j);
  73.               for(k=0; k<i; k++)
  74.                 q(k,j)=q(k,j)-g*q(k,i);
  75.           }
  76.         b[i]=q(i,i);
  77. q(i,i)=1.0;
  78.         if(i-1>=0)
  79.           for(j=0; j<i; j++)
  80.           { 
  81.   q(i,j)=0.0;
  82.   q(j,i)=0.0;
  83.   }
  84.     }
  85. return int(1); //正常返回
  86. }
  87. //实对称三角阵全部特征值及特征向量QR法
  88. template <class _Ty>
  89. int EigenvalueVectorRealTriangleQR(valarray<_Ty>& b, 
  90. valarray<_Ty>& c, matrix<_Ty>& q, _Ty eps, int l)
  91. {
  92. int i, k, m, it, stRank;
  93.     _Ty h, g, p, r, e, s, d(0), f(0);
  94. stRank = q.GetColNum(); // 矩阵阶数
  95. c[stRank-1]=0.0;
  96.     for(int j=0; j<stRank; j++)
  97.     { 
  98. it=0;
  99.         h=eps*(Abs(b[j])+Abs(c[j]));
  100.         if(h>d) d=h;
  101.         m=j;
  102.         while((m<stRank)&&(Abs(c[m])>d)) m++;
  103.         if(m!=j)
  104.         {
  105. do
  106.             {
  107. if(it==l)
  108.                 { 
  109. cout << "fail" << endl;
  110.                     return(-1); //出错
  111.                 }
  112.                 it++;
  113.                 g=b[j];
  114.                 p=(b[j+1]-g)/(2.0*c[j]);
  115.                 r=sqrt(p*p+1.0);
  116.                 if(p>0.0 || FloatEqual(p,0)) b[j]=c[j]/(p+r);
  117.                 else b[j]=c[j]/(p-r);
  118.                 h=g-b[j];
  119.                 for(i=j+1; i<stRank; i++) b[i]=b[i]-h;
  120.                 f=f+h; 
  121. p=b[m]; 
  122. e=1.0; 
  123. s=0.0;
  124.                 for(i=m-1; i>=j; i--)
  125.                 {
  126. g=e*c[i];
  127. h=e*p;
  128.                     if(Abs(p)>=Abs(c[i]))
  129.                     {
  130. e=c[i]/p;
  131. r=sqrt(e*e+1.0);
  132.                         c[i+1]=s*p*r;
  133. s=e/r; 
  134. e=1.0/r;
  135.                     }
  136.                     else
  137. {
  138. e=p/c[i]; 
  139. r=sqrt(e*e+1.0);
  140.                         c[i+1]=s*c[i]*r;
  141.                         s=1.0/r; 
  142. e=e/r;
  143.                     }
  144.                     p=e*b[i]-s*g;
  145.                     b[i+1]=h+s*(e*g+s*b[i]);
  146.                     for(k=0; k<stRank; k++)
  147.                     { 
  148.                         h=q(k,i+1);
  149. q(k,i+1)=s*q(k,i)+e*h;
  150.                         q(k,i)=e*q(k,i)-s*h;
  151.                     }
  152.                 }
  153.                 c[j]=s*p;
  154. b[j]=e*p;
  155.             }while(Abs(c[j])>d);
  156.         }
  157.         b[j]=b[j]+f;
  158.     }
  159.     for(i=0; i<stRank; i++)
  160.     { 
  161. k=i;
  162. p=b[i];
  163.         if(i+1<stRank)
  164.         {
  165. j=i+1;
  166.             while((j<stRank)&&(b[j]<=p))
  167.             {
  168. k=j;
  169. p=b[j];
  170. j=j+1;
  171. }
  172. }
  173.         if(k!=i)
  174.         { 
  175. b[k]=b[i]; 
  176. b[i]=p;
  177.             for(j=0; j<stRank; j++)
  178.             {
  179.                 p=q(j,i);
  180. q(j,i)=q(j,k);
  181. q(j,k)=p;
  182.             }
  183.         }
  184.     }
  185.     return(1); //正常返回
  186. }
  187. //约化一般实矩阵为赫申伯格阵的初等相似变换法
  188. template <class _Ty>
  189. int HessenbergTransform(matrix<_Ty>& a)
  190. {
  191. int i, stRank;
  192.     _Ty t;
  193. stRank = a.GetColNum(); // 矩阵阶数
  194. if(stRank != a.GetRowNum())
  195. return int(0); //矩阵a不是方阵
  196.     for(int k=1; k<stRank-1; k++)
  197.     { 
  198. _Ty d(0);
  199.         for(int j=k; j<stRank; j++)
  200.         { 
  201. t=a(j,k-1);
  202.             if(Abs(t)>Abs(d))
  203.             {
  204. d=t; 
  205. i=j;
  206. }
  207.         }
  208.         if(FloatNotEqual(d,0))
  209.         { 
  210. if(i!=k)
  211.             {
  212. for(j=k-1; j<stRank; j++)
  213. swap(a(i,j), a(k,j));
  214.                 for(j=0; j<stRank; j++)
  215. swap(a(j,i), a(j,k));
  216.             }
  217.             for(i=k+1; i<stRank; i++)
  218.             { 
  219. t=a(i,k-1)/d; 
  220. a(i,k-1)=0.0;
  221.                 for(j=k; j<stRank; j++)
  222.                     a(i,j)=a(i,j)-t*a(k,j);
  223.                 for(j=0; j<stRank; j++)
  224.                     a(j,k)=a(j,k)+t*a(j,i);
  225.             }
  226.         }
  227.     }
  228. return int(1);
  229. }
  230. //求赫申伯格阵全部特征值QR法
  231. template <class _Ty>
  232. int EigenvalueVectorHessenbergQR(matrix<_Ty>& a,  
  233. valarray<complex<_Ty> >& uv, _Ty eps, int jt)
  234. {
  235. int i, j, k, l, it(0), stRank;
  236.     _Ty b,c,w,g,xy,p,q,r,x,s,e,f,z,y;
  237. stRank = a.GetColNum(); // 矩阵阶数
  238.     while(stRank!=0)
  239.     { 
  240. l=stRank-1;
  241.         while((l>0)&&(Abs(a(l,l-1))>eps*(Abs(a(l-1,l-1))+Abs(a(l,l))))) l=l-1;
  242.         if(l==stRank-1)
  243.         { 
  244. uv[stRank-1]=complex<_Ty>(a(stRank-1,stRank-1),0);
  245.             stRank=stRank-1;
  246. it=0;
  247.         }
  248.         else if(l==stRank-2)
  249.         { 
  250. b=-(a(stRank-1,stRank-1)+a(stRank-2,stRank-2));
  251.             c=a(stRank-1,stRank-1)*a(stRank-2,stRank-2)-a(stRank-1,stRank-2)*a(stRank-2,stRank-1);
  252.             w=b*b-4.0*c;
  253.             y=sqrt(Abs(w));
  254.             if(w>0.0)
  255.             { 
  256. xy=1.0;
  257.                 if(b<0.0) xy=-1.0;
  258. uv[stRank-1]=complex<_Ty>((-b-xy*y)/2.0, 0);
  259. uv[stRank-2]=complex<_Ty>(c/(uv[stRank-1].real()), 0);
  260.             }
  261.             else
  262.             {
  263. uv[stRank-1]=complex<_Ty>(-b/2.0, y/2.0);
  264. uv[stRank-2]=complex<_Ty>(uv[stRank-1].real(),-uv[stRank-1].imag());
  265.             }
  266.             stRank=stRank-2; 
  267. it=0;
  268.         }
  269.         else
  270.         { 
  271. if(it>=jt)
  272.             { printf("failn");
  273.                 return(-1); //出错!
  274.             }
  275.             it=it+1;
  276.             for(j=l+2; j<stRank; j++) a(j,j-2)=0.0;
  277.             for(j=l+3; j<stRank; j++)    a(j,j-3)=0.0;
  278.             for(k=l; k<stRank-1; k++)
  279.             { 
  280. if(k!=l)
  281.                 {
  282. p=a(k,k-1);
  283. q=a(k+1,k-1);
  284.                     r=0.0;
  285.                     if(k!=stRank-2) r=a(k+2,k-1);
  286.                 }
  287.                 else
  288.                 {
  289. x=a(stRank-1,stRank-1)+a(stRank-2,stRank-2);
  290.                     y=a(stRank-2,stRank-2)*a(stRank-1,stRank-1)-a(stRank-2,stRank-1)*a(stRank-1,stRank-2);
  291.                     p=a(l,l)*(a(l,l)-x)+a(l,l+1)*a(l+1,l)+y;
  292.                     q=a(l+1,l)*(a(l,l)+a(l+1,l+1)-x);
  293.                     r=a(l+1,l)*a(l+2,l+1);
  294.                 }
  295.                 if(FloatNotEqual((Abs(p)+Abs(q)+Abs(r)),0))
  296.                 { 
  297. xy=1.0;
  298.                     if(p<0.0) xy=-1.0;
  299.                     s=xy*sqrt(p*p+q*q+r*r);
  300.                     if(k!=l) a(k,k-1)=-s;
  301.                     e=-q/s;
  302. f=-r/s; 
  303. x=-p/s;
  304.                     y=-x-f*r/(p+s);
  305.                     g=e*r/(p+s);
  306.                     z=-x-e*q/(p+s);
  307.                     for(j=k; j<stRank; j++)
  308.                     {
  309.                         p=x*a(k,j)+e*a(k+1,j);
  310.                         q=e*a(k,j)+y*a(k+1,j);
  311.                         r=f*a(k,j)+g*a(k+1,j);
  312.                         if(k!=stRank-2)
  313.                         { 
  314.                             p=p+f*a(k+2,j);
  315.                             q=q+g*a(k+2,j);
  316.                             r=r+z*a(k+2,j);
  317. a(k+2,j)=r;
  318.                         }
  319.                         a(k+1,j)=q; 
  320. a(k,j)=p;
  321.                     }
  322.                     j=k+3;
  323.                     if(j>=stRank-1) j=stRank-1;
  324.                     for(i=l; i<=j; i++)
  325.                     {
  326.                         p=x*a(i,k)+e*a(i,k+1);
  327.                         q=e*a(i,k)+y*a(i,k+1);
  328.                         r=f*a(i,k)+g*a(i,k+1);
  329.                         if(k!=stRank-2)
  330.                         { 
  331.                             p=p+f*a(i,k+2);
  332.                             q=q+g*a(i,k+2);
  333.                             r=r+z*a(i,k+2); 
  334. a(i,k+2)=r;
  335.                         }
  336.                         a(i,k+1)=q; 
  337. a(i,k)=p;
  338.                     }
  339.                 }
  340.             }
  341.         }
  342.     }
  343.     return(1);
  344. }
  345. //实对称阵特征值及特征向量雅可比法
  346. template <class _Ty>
  347. int EigenvalueVectorRealSymmetryJacobi(matrix<_Ty>& a,  
  348. matrix<_Ty>& v, _Ty eps, int jt)
  349. {
  350. int j, p, q, l(1), stRank;
  351.     _Ty fm,cn,sn,omega,x,y,d;
  352. if(MatrixSymmetry(a)!=true) //不是对称阵
  353. return(0);
  354. stRank = a.GetColNum(); // 矩阵阶数
  355.     for(int i=0; i<stRank; i++)
  356.     {
  357. v(i,i)=1.0;
  358.         for(j=0; j<stRank; j++)
  359.           if(i!=j) v(i,j)=0.0;
  360.     }
  361.     while(1)
  362.     { 
  363. fm=0.0;
  364.         for(i=1; i<stRank; i++)
  365.         for(j=0; j<i; j++)
  366.         {
  367. d=Abs(a(i,j));
  368.             if((i!=j)&&(d>fm))
  369.             {
  370. fm=d; 
  371. p=i;
  372. q=j;
  373. }
  374.         }
  375.         if(fm<eps)  return(1);
  376.         if(l>jt)  return(-1);
  377.         l=l+1;
  378.         x=-a(p,q);
  379. y=(a(q,q)-a(p,p))/2.0;
  380.         omega=x/sqrt(x*x+y*y);
  381.         if(y<0.0) omega=-omega;
  382.         sn=1.0+sqrt(1.0-omega*omega);
  383.         sn=omega/sqrt(2.0*sn);
  384.         cn=sqrt(1.0-sn*sn);
  385.         fm=a(p,p);
  386.         a(p,p)=fm*cn*cn+a(q,q)*sn*sn+a(p,q)*omega;
  387.         a(q,q)=fm*sn*sn+a(q,q)*cn*cn-a(p,q)*omega;
  388.         a(p,q)=0.0; 
  389. a(q,p)=0.0;
  390.         for(j=0; j<stRank; j++)
  391.         if((j!=p)&&(j!=q))
  392.         {
  393.             fm=a(p,j);
  394.             a(p,j)=fm*cn+a(q,j)*sn;
  395.             a(q,j)=-fm*sn+a(q,j)*cn;
  396.         }
  397.         for(i=0; i<stRank; i++)
  398.           if((i!=p)&&(i!=q))
  399.           { 
  400.               fm=a(i,p);
  401.               a(i,p)=fm*cn+a(i,q)*sn;
  402.               a(i,q)=-fm*sn+a(i,q)*cn;
  403.           }
  404.         for(i=0; i<stRank; i++)
  405.         {
  406.             fm=v(i,p);
  407.             v(i,p)=fm*cn+v(i,q)*sn;
  408.             v(i,q)=-fm*sn+v(i,q)*cn;
  409.         }
  410.     }
  411.     return(1);
  412. }
  413. //实对称阵特征值及特征向量雅可比过关法
  414. template <class _Ty>
  415. int EigenvalueVectorRealSymmetryJacobiB(matrix<_Ty>& a,  
  416. matrix<_Ty>& v, _Ty eps)
  417. {
  418. int j, p, q, stRank;
  419.     _Ty fm, cn, sn, omega, x, y, d;
  420. if(MatrixSymmetry(a)!=true)
  421. return(-1);
  422. stRank = a.GetColNum(); //矩阵阶数
  423.     for(int i=0; i<stRank; i++)
  424.     { v(i,i)=1.0;
  425.         for(j=0; j<stRank; j++)
  426.           if(i!=j) v(i,j)=0.0;
  427.     }
  428.     _Ty ff(0);
  429.     for(i=1; i<stRank; i++)
  430. for(j=0; j<i; j++)
  431. {
  432. d=a(i,j);
  433. ff=ff+d*d;
  434. }
  435.     ff=sqrt(2.0*ff);
  436.   loop0:
  437.     ff=ff/(1.0*stRank);
  438.   loop1:
  439.     for(i=1; i<stRank; i++)
  440.         for(j=0; j<i; j++)
  441.         { 
  442. d=Abs(a(i,j));
  443.             if(d>ff)
  444.             { 
  445. p=i;
  446. q=j;
  447.                 goto loop;
  448.             }
  449.         }
  450. if(ff<eps) return(1); //成功返回
  451.     goto loop0;
  452.   loop:
  453.     x=-a(p,q);
  454. y=(a(q,q)-a(p,p))/2.0;
  455.     omega=x/sqrt(x*x+y*y);
  456.     if(y<0.0) omega=-omega;
  457.     sn=1.0+sqrt(1.0-omega*omega);
  458.     sn=omega/sqrt(2.0*sn);
  459.     cn=sqrt(1.0-sn*sn);
  460.     fm=a(p,p);
  461.     a(p,p)=fm*cn*cn+a(q,q)*sn*sn+a(p,q)*omega;
  462.     a(q,q)=fm*sn*sn+a(q,q)*cn*cn-a(p,q)*omega;
  463.     a(p,q)=0.0;
  464. a(q,p)=0.0;
  465.     for(j=0; j<stRank; j++)
  466.         if((j!=p)&&(j!=q))
  467.         {
  468.             fm=a(p,j);
  469.             a(p,j)=fm*cn+a(q,j)*sn;
  470.             a(q,j)=-fm*sn+a(q,j)*cn;
  471.         }
  472.     for(i=0; i<stRank; i++)
  473.         if((i!=p)&&(i!=q))
  474.         {
  475. fm=a(i,p);
  476.             a(i,p)=fm*cn+a(i,q)*sn;
  477.             a(i,q)=-fm*sn+a(i,q)*cn;
  478.         }
  479.     for(i=0; i<stRank; i++)
  480.     { 
  481.         fm=v(i,p);
  482.         v(i,p)=fm*cn+v(i,q)*sn;
  483.         v(i,q)=-fm*sn+v(i,q)*cn;
  484.     }
  485.     goto loop1;
  486. }
  487. #endif // _EIGENVALUEVECTOR_INL