⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eigenvaluevector.inl

📁 本程序是在CCS环境下运行的
💻 INL
字号:
// EigenvalueVector.inl		计算特征值特征向量函数(方法)定义
// Ver 1.0.0.0
// 版权所有(C) 何渝, 2002

// 最后修改: 2002.8.10

#ifndef _EIGENVALUEVECTOR_INL
#define _EIGENVALUEVECTOR_INL

//约化对称阵为对称三对角阵的豪斯荷尔德变换法
template <class _Ty>
int HouseholderTransform(matrix<_Ty>& a, matrix<_Ty>& q, 
									valarray<_Ty>& b, valarray<_Ty>& c)
{
	int j, k, stRank;
    _Ty h, f, g, h2;

	if(MatrixSymmetry(a)!=true)
		return int(0);			//矩阵a不是对称阵
	
	stRank = a.GetColNum();		// 矩阵阶数
	
    for(int i=0; i<stRank; i++)
		for(int j=0; j<stRank; j++)
			q(i,j)=a(i,j);

    for(i=stRank-1; i>=1; i--)
    { 
		h=0.0;
        if(i>1)
          for(k=0; k<i; k++)
			  h=h+q(i,k)*q(i,k);
        if(FloatEqual(h,0))
        {
			c[i]=0.0;
            if(i==1) c[i]=q(i,i-1);
            b[i]=0.0;
        }
        else
        { 
			c[i]=sqrt(h);
            if(q(i,i-1)>0.0) c[i]=-c[i];
            h=h-q(i,i-1)*c[i];
            q(i,i-1)=q(i,i-1)-c[i];
            f=0.0;
            for(j=0; j<i; j++)
            { 
				q(j,i) = q(i,j) / h;
                g = 0.0;
                for(k=0; k<=j; k++)
                  g = g + q(j,k) * q(i,k);
                if(j+1<i)
                  for(k=j+1; k<i; k++)
                    g = g + q(k,j) * q(i,k);
                c[j] = g / h;
                f = f + g * q(j,i);
            }
            h2 = f / (h+h);
            for(j=0; j<i; j++)
            { 
				f = q(i,j);
                g = c[j] -h2 * f;
                c[j] = g;
                for(k=0; k<=j; k++)
                    q(j,k)=q(j,k)-f*c[k]-g*q(i,k);
            }
            b[i]=h;
        }
    }
    for(i=0; i<stRank-1; i++) c[i]=c[i+1];
    c[stRank-1]=0.0;
    b[0]=0.0;
    for(i=0; i<stRank; i++)
    { if((b[i]!=0.0)&&(i-1>=0))
          for(j=0; j<i; j++)
          { 
			  g=0.0;
              for(k=0; k<i; k++)
				g=g+q(i,k)*q(k,j);
              for(k=0; k<i; k++)
                q(k,j)=q(k,j)-g*q(k,i);
          }
        b[i]=q(i,i);
		q(i,i)=1.0;
        if(i-1>=0)
          for(j=0; j<i; j++)
          { 
			  q(i,j)=0.0;
			  q(j,i)=0.0;
		  }
    }
	return int(1);	//正常返回
}

//实对称三角阵全部特征值及特征向量QR法
template <class _Ty>
int EigenvalueVectorRealTriangleQR(valarray<_Ty>& b, 
					valarray<_Ty>& c, matrix<_Ty>& q, _Ty eps, int l)
{
	int i, k, m, it, stRank;
    _Ty h, g, p, r, e, s, d(0), f(0);

	stRank = q.GetColNum();		// 矩阵阶数
	
	c[stRank-1]=0.0;

    for(int j=0; j<stRank; j++)
    { 
		it=0;
        h=eps*(Abs(b[j])+Abs(c[j]));
        if(h>d) d=h;
        m=j;
        while((m<stRank)&&(Abs(c[m])>d)) m++;
        if(m!=j)
        {
			do
            {
				if(it==l)
                { 
					cout << "fail" << endl;
                    return(-1);				//出错
                }
                it++;
                g=b[j];
                p=(b[j+1]-g)/(2.0*c[j]);
                r=sqrt(p*p+1.0);
                if(p>0.0 || FloatEqual(p,0)) b[j]=c[j]/(p+r);
                else b[j]=c[j]/(p-r);
                h=g-b[j];
                for(i=j+1; i<stRank; i++)	b[i]=b[i]-h;
                f=f+h; 
				p=b[m]; 
				e=1.0; 
				s=0.0;
                for(i=m-1; i>=j; i--)
                {
					g=e*c[i];
					h=e*p;
                    if(Abs(p)>=Abs(c[i]))
                    {
						e=c[i]/p;
						r=sqrt(e*e+1.0);
                        c[i+1]=s*p*r;
						s=e/r; 
						e=1.0/r;
                    }
                    else
					{
						e=p/c[i]; 
						r=sqrt(e*e+1.0);
                        c[i+1]=s*c[i]*r;
                        s=1.0/r; 
						e=e/r;
                    }
                    p=e*b[i]-s*g;
                    b[i+1]=h+s*(e*g+s*b[i]);
                    for(k=0; k<stRank; k++)
                    { 
                        h=q(k,i+1);
						q(k,i+1)=s*q(k,i)+e*h;
                        q(k,i)=e*q(k,i)-s*h;
                    }
                }
                c[j]=s*p;
				b[j]=e*p;
            }while(Abs(c[j])>d);
        }
        b[j]=b[j]+f;
    }
    for(i=0; i<stRank; i++)
    { 
		k=i;
		p=b[i];
        if(i+1<stRank)
        {
			j=i+1;
            while((j<stRank)&&(b[j]<=p))
            {
				k=j;
				p=b[j];
				j=j+1;
			}
		}
        if(k!=i)
        { 
			b[k]=b[i]; 
			b[i]=p;
            for(j=0; j<stRank; j++)
            {
                p=q(j,i);
				q(j,i)=q(j,k);
				q(j,k)=p;
            }
        }
    }
    return(1);	//正常返回
}

//约化一般实矩阵为赫申伯格阵的初等相似变换法
template <class _Ty>
int HessenbergTransform(matrix<_Ty>& a)
{
	int i, stRank;
    _Ty t;
	
	stRank = a.GetColNum();		// 矩阵阶数
	if(stRank != a.GetRowNum())
		return int(0);			//矩阵a不是方阵

    for(int k=1; k<stRank-1; k++)
    { 
		_Ty d(0);
        for(int j=k; j<stRank; j++)
        { 
			t=a(j,k-1);
            if(Abs(t)>Abs(d))
            {
				d=t; 
				i=j;
			}
        }
        if(FloatNotEqual(d,0))
        { 
			if(i!=k)
            {
				for(j=k-1; j<stRank; j++)
					swap(a(i,j), a(k,j));
                for(j=0; j<stRank; j++)
					swap(a(j,i), a(j,k));
            }
            for(i=k+1; i<stRank; i++)
            { 
				t=a(i,k-1)/d; 
				a(i,k-1)=0.0;
                for(j=k; j<stRank; j++)
                    a(i,j)=a(i,j)-t*a(k,j);
                for(j=0; j<stRank; j++)
                    a(j,k)=a(j,k)+t*a(j,i);
            }
        }
    }
	return int(1);
}

//求赫申伯格阵全部特征值QR法
template <class _Ty>
int EigenvalueVectorHessenbergQR(matrix<_Ty>& a,  
						valarray<complex<_Ty> >& uv, _Ty eps, int jt)
{
	
	int i, j, k, l, it(0), stRank;
    _Ty b,c,w,g,xy,p,q,r,x,s,e,f,z,y;

	stRank = a.GetColNum();		// 矩阵阶数

    while(stRank!=0)
    { 
		l=stRank-1;
        while((l>0)&&(Abs(a(l,l-1))>eps*(Abs(a(l-1,l-1))+Abs(a(l,l))))) l=l-1;
        if(l==stRank-1)
        { 
			uv[stRank-1]=complex<_Ty>(a(stRank-1,stRank-1),0);
            stRank=stRank-1;
			it=0;
        }
        else if(l==stRank-2)
        { 
			b=-(a(stRank-1,stRank-1)+a(stRank-2,stRank-2));
            c=a(stRank-1,stRank-1)*a(stRank-2,stRank-2)-a(stRank-1,stRank-2)*a(stRank-2,stRank-1);
            w=b*b-4.0*c;
            y=sqrt(Abs(w));
            if(w>0.0)
            { 
				xy=1.0;
                if(b<0.0) xy=-1.0;
				uv[stRank-1]=complex<_Ty>((-b-xy*y)/2.0, 0);
				uv[stRank-2]=complex<_Ty>(c/(uv[stRank-1].real()), 0);
            }
            else
            {
				uv[stRank-1]=complex<_Ty>(-b/2.0, y/2.0);
				uv[stRank-2]=complex<_Ty>(uv[stRank-1].real(),-uv[stRank-1].imag());
            }
            stRank=stRank-2; 
			it=0;
        }
        else
        { 
			if(it>=jt)
            { printf("fail\n");
                return(-1);		//出错!
            }
            it=it+1;
            for(j=l+2; j<stRank; j++)	a(j,j-2)=0.0;
            for(j=l+3; j<stRank; j++)    a(j,j-3)=0.0;
            for(k=l; k<stRank-1; k++)
            { 
				if(k!=l)
                {
					p=a(k,k-1);
					q=a(k+1,k-1);
                    r=0.0;
                    if(k!=stRank-2) r=a(k+2,k-1);
                }
                else
                {
					x=a(stRank-1,stRank-1)+a(stRank-2,stRank-2);
                    y=a(stRank-2,stRank-2)*a(stRank-1,stRank-1)-a(stRank-2,stRank-1)*a(stRank-1,stRank-2);
                    p=a(l,l)*(a(l,l)-x)+a(l,l+1)*a(l+1,l)+y;
                    q=a(l+1,l)*(a(l,l)+a(l+1,l+1)-x);
                    r=a(l+1,l)*a(l+2,l+1);
                }
                if(FloatNotEqual((Abs(p)+Abs(q)+Abs(r)),0))
                { 
					xy=1.0;
                    if(p<0.0) xy=-1.0;
                    s=xy*sqrt(p*p+q*q+r*r);
                    if(k!=l) a(k,k-1)=-s;
                    e=-q/s;
					f=-r/s; 
					x=-p/s;
                    y=-x-f*r/(p+s);
                    g=e*r/(p+s);
                    z=-x-e*q/(p+s);
                    for(j=k; j<stRank; j++)
                    {	
                        p=x*a(k,j)+e*a(k+1,j);
                        q=e*a(k,j)+y*a(k+1,j);
                        r=f*a(k,j)+g*a(k+1,j);
                        if(k!=stRank-2)
                        { 
                            p=p+f*a(k+2,j);
                            q=q+g*a(k+2,j);
                            r=r+z*a(k+2,j);
							a(k+2,j)=r;
                        }
                        a(k+1,j)=q; 
						a(k,j)=p;
                    }
                    j=k+3;
                    if(j>=stRank-1) j=stRank-1;
                    for(i=l; i<=j; i++)
                    {	
                        p=x*a(i,k)+e*a(i,k+1);
                        q=e*a(i,k)+y*a(i,k+1);
                        r=f*a(i,k)+g*a(i,k+1);
                        if(k!=stRank-2)
                        { 
                            p=p+f*a(i,k+2);
                            q=q+g*a(i,k+2);
                            r=r+z*a(i,k+2); 
							a(i,k+2)=r;
                        }
                        a(i,k+1)=q; 
						a(i,k)=p;
                    }
                }
            }
        }
    }
    return(1);
}

//实对称阵特征值及特征向量雅可比法
template <class _Ty>
int EigenvalueVectorRealSymmetryJacobi(matrix<_Ty>& a,  
										matrix<_Ty>& v, _Ty eps, int jt)
{
	int j, p, q, l(1), stRank;
    _Ty fm,cn,sn,omega,x,y,d;
	
	if(MatrixSymmetry(a)!=true)	//不是对称阵
		return(0);					

	stRank = a.GetColNum();		// 矩阵阶数

    for(int i=0; i<stRank; i++)
    {
		v(i,i)=1.0;
        for(j=0; j<stRank; j++)
          if(i!=j) v(i,j)=0.0;
    }
    while(1)
    { 
		fm=0.0;
        for(i=1; i<stRank; i++)
        for(j=0; j<i; j++)
        {
			d=Abs(a(i,j));
            if((i!=j)&&(d>fm))
            {
				fm=d; 
				p=i;
				q=j;
			}
        }
        if(fm<eps)  return(1);
        if(l>jt)  return(-1);
        l=l+1;
        x=-a(p,q);
		y=(a(q,q)-a(p,p))/2.0;
        omega=x/sqrt(x*x+y*y);
        if(y<0.0) omega=-omega;
        sn=1.0+sqrt(1.0-omega*omega);
        sn=omega/sqrt(2.0*sn);
        cn=sqrt(1.0-sn*sn);
        fm=a(p,p);
        a(p,p)=fm*cn*cn+a(q,q)*sn*sn+a(p,q)*omega;
        a(q,q)=fm*sn*sn+a(q,q)*cn*cn-a(p,q)*omega;
        a(p,q)=0.0; 
		a(q,p)=0.0;
        for(j=0; j<stRank; j++)
        if((j!=p)&&(j!=q))
        {
            fm=a(p,j);
            a(p,j)=fm*cn+a(q,j)*sn;
            a(q,j)=-fm*sn+a(q,j)*cn;
        }
        for(i=0; i<stRank; i++)
          if((i!=p)&&(i!=q))
          { 
              fm=a(i,p);
              a(i,p)=fm*cn+a(i,q)*sn;
              a(i,q)=-fm*sn+a(i,q)*cn;
          }
        for(i=0; i<stRank; i++)
        {
            fm=v(i,p);
            v(i,p)=fm*cn+v(i,q)*sn;
            v(i,q)=-fm*sn+v(i,q)*cn;
        }
    }
    return(1);
}

//实对称阵特征值及特征向量雅可比过关法
template <class _Ty>
int EigenvalueVectorRealSymmetryJacobiB(matrix<_Ty>& a,  
												matrix<_Ty>& v, _Ty eps)
{
	int j, p, q, stRank;
    _Ty fm, cn, sn, omega, x, y, d;

	if(MatrixSymmetry(a)!=true)
		return(-1);

	stRank = a.GetColNum();		//矩阵阶数

    for(int i=0; i<stRank; i++)
    { v(i,i)=1.0;
        for(j=0; j<stRank; j++)
          if(i!=j) v(i,j)=0.0;
    }
    _Ty ff(0);
    for(i=1; i<stRank; i++)
		for(j=0; j<i; j++)
		{
			d=a(i,j);
			ff=ff+d*d;
		}
    ff=sqrt(2.0*ff);
  loop0:
    ff=ff/(1.0*stRank);
  loop1:
    for(i=1; i<stRank; i++)
        for(j=0; j<i; j++)
        { 
			d=Abs(a(i,j));
            if(d>ff)
            { 
				p=i;
				q=j;
                goto loop;
            }
        }
	if(ff<eps) return(1);	//成功返回
    goto loop0;
  loop:
    x=-a(p,q);
	y=(a(q,q)-a(p,p))/2.0;
    omega=x/sqrt(x*x+y*y);
    if(y<0.0) omega=-omega;
    sn=1.0+sqrt(1.0-omega*omega);
    sn=omega/sqrt(2.0*sn);
    cn=sqrt(1.0-sn*sn);
    fm=a(p,p);
    a(p,p)=fm*cn*cn+a(q,q)*sn*sn+a(p,q)*omega;
    a(q,q)=fm*sn*sn+a(q,q)*cn*cn-a(p,q)*omega;
    a(p,q)=0.0;
	a(q,p)=0.0;
    for(j=0; j<stRank; j++)
        if((j!=p)&&(j!=q))
        {
            fm=a(p,j);
            a(p,j)=fm*cn+a(q,j)*sn;
            a(q,j)=-fm*sn+a(q,j)*cn;
        }
    for(i=0; i<stRank; i++)
        if((i!=p)&&(i!=q))
        {
			fm=a(i,p);
            a(i,p)=fm*cn+a(i,q)*sn;
            a(i,q)=-fm*sn+a(i,q)*cn;
        }
    for(i=0; i<stRank; i++)
    { 
        fm=v(i,p);
        v(i,p)=fm*cn+v(i,q)*sn;
        v(i,q)=-fm*sn+v(i,q)*cn;
    }
    goto loop1;
}

#endif			// _EIGENVALUEVECTOR_INL

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -