markailee1 发表于 2006-6-22 23:30

求广义特征值的广义雅可比方法

<P><BR>void JacobiEigen(matrix *matA, matrix *matB, double *m_adEigen)<BR>{<BR> // CMatrix matBBak,matR,matRT,matV;<BR> matrix matBBak,matR,matRT,matV;<BR> double dAlfa,dBeta,dBuf,dBuf1;<BR> double dA,dB,dC;<BR> double dError;<BR> int nRow;<BR> int iRow,iCol;<BR> int loop,loop1;<BR> // CArray&lt;double,double&amp;&gt; adBuf;// double向量<BR> // CUIntArray aiBuf;            // unsigned int vector<BR> double *adBuf;<BR> unsigned int *aiBuf;</P>
<P> nRow=matA-&gt;m;<BR> MatrixInit(&amp;matBBak,nRow,nRow);<BR> MatrixInit(&amp;matR,nRow,nRow);<BR> MatrixInit(&amp;matRT,nRow,nRow);<BR> MatrixInit(&amp;matV,nRow,nRow);<BR> MatrixCopy(&amp;matBBak,matB);</P>
<P> /* nRow=matA.GetRow();<BR> matBBak.Realloc(nRow,nRow);<BR> matR.Realloc(nRow,nRow);<BR> matRT.Realloc(nRow,nRow);<BR> matV.Realloc(nRow,nRow);<BR> matBBak=matB; */</P>
<P> // matV=0.0;<BR> MatrixZero(&amp;matV);<BR> for(loop=0;loop&lt;nRow;loop++)<BR>matV.a=1.0;<BR>//matV(loop,loop)=1.0;</P>
<P> dError=1.0e-12;</P>
<P> dBuf=0.0;<BR> for(loop=0;loop&lt;nRow;loop++){<BR>for(loop1=loop+1;loop1&lt;nRow;loop1++){<BR>   // dBuf1=matA(loop,loop1)*matA(loop,loop1)/(matA(loop,loop)*matA(loop1,loop1));<BR>   dBuf1=p2(matA-&gt;a) / (matA-&gt;a*matA-&gt;a);<BR>   if(dBuf&lt;fabs(dBuf1)){<BR>    dBuf=fabs(dBuf1);<BR>    iRow=loop;iCol=loop1;<BR>   }<BR>   // dBuf1=matB(loop,loop1)*matB(loop,loop1)/(matB(loop,loop)*matB(loop1,loop1));<BR>   dBuf1=p2(matB-&gt;a) / (matB-&gt;a*matB-&gt;a);<BR>   if(dBuf&lt;fabs(dBuf1)){<BR>    dBuf=fabs(dBuf1);<BR>    iRow=loop;iCol=loop1;<BR>   }<BR>}<BR> }</P>
<P> printf("nRow=%ddBuf=%f\n",nRow,dBuf);</P>
<P> while(dBuf&gt;dError){<BR>// matR=0.0;<BR>MatrixZero(&amp;matR);<BR>for(loop=0;loop&lt;nRow;loop++) matR.a=1.0; //matR(loop,loop)=1.0;<BR>// dA=matA(iRow,iRow)*matB(iRow,iCol)-matB(iRow,iRow)*matA(iRow,iCol);<BR>dA=matA-&gt;a * matB-&gt;a - matB-&gt;a * matA-&gt;a;<BR>// dC=-matA(iCol,iCol)*matB(iRow,iCol)+matB(iCol,iCol)*matA(iRow,iCol);<BR>dC=-matA-&gt;a * matB-&gt;a + matB-&gt;a * matA-&gt;a;<BR>if(dA==0.0&amp;&amp;dC==0.0){<BR>   dAlfa=0.0;<BR>   // dBeta=-matA(iRow,iCol)/matA(iCol,iCol);<BR>   dBeta=-matA-&gt;a/matA-&gt;a;<BR>}<BR>else{<BR>   // dB=matA(iRow,iRow)*matB(iCol,iCol)-matA(iCol,iCol)*matB(iRow,iRow);<BR>   dB=matA-&gt;a*matB-&gt;a - matA-&gt;a*matB-&gt;a;<BR>   if(dB&gt;=0.0){<BR>    dBuf=dB/2.0;<BR>    dAlfa=-dC/(dBuf+sqrt(dBuf*dBuf-dA*dC));<BR>   }<BR>   else{<BR>    dBuf=dB/2.0;<BR>    dAlfa=-dC/(dBuf-sqrt(dBuf*dBuf-dA*dC));<BR>   }<BR>   dBeta=dA/dC*dAlfa;<BR>}<BR> /* matR(iRow,iCol)=dAlfa;<BR>matR(iCol,iRow)=dBeta;<BR>matRT.Trans(matR);</P>
<P>matA=matRT*matA*matR;<BR>matB=matRT*matB*matR;<BR>matV*=matR;<BR> */<BR>matR.a=dAlfa;<BR>matR.a=dBeta;<BR>Transpose(&amp;matR,&amp;matRT);<BR>// 经过修改后的矩阵相乘功能简单而强大,省去了运算符重载。<BR>MatrixMultiply(&amp;matRT,matA,matA); MatrixMultiply(matA,&amp;matR,matA);<BR>MatrixMultiply(&amp;matRT,matB,matB); MatrixMultiply(matB,&amp;matR,matB);<BR>MatrixMultiply(&amp;matV,&amp;matR,&amp;matV);</P>
<P>printf("A:\n");MatrixPrint(matA); printf("B:\n");MatrixPrint(matB);</P>
<P>dBuf=0.0;<BR>for(loop=0;loop&lt;nRow;loop++){<BR>   for(loop1=loop+1;loop1&lt;nRow;loop1++){<BR>    // dBuf1=matA(loop,loop1)*matA(loop,loop1)/(matA(loop,loop)*matA(loop1,loop1));<BR>    dBuf1=p2(matA-&gt;a)/ (matA-&gt;a*matA-&gt;a);<BR>    if(dBuf&lt;fabs(dBuf1)){<BR>   dBuf=fabs(dBuf1);<BR>   iRow=loop;iCol=loop1;<BR>    }<BR>    // dBuf1=matB(loop,loop1)*matB(loop,loop1)/(matB(loop,loop)*matB(loop1,loop1));<BR>    dBuf1=p2(matB-&gt;a) / (matB-&gt;a*matB-&gt;a);<BR>    if(dBuf&lt;fabs(dBuf1)){<BR>   dBuf=fabs(dBuf1);<BR>   iRow=loop;iCol=loop1;<BR>    }<BR>   }<BR>}<BR>getch();<BR> }</P>
<P> /* matRT.Trans(matV);<BR> matR=matRT*matBBak; */<BR> MatrixTranspose(&amp;matV);<BR> MatrixMultiply(&amp;matRT,&amp;matBBak,&amp;matR);<BR> for(loop=0;loop&lt;nRow;loop++){<BR>dBuf=0.0;<BR>for(loop1=0;loop1&lt;nRow;loop1++){<BR>   // dBuf+=matR(loop,loop1)*matV(loop1,loop);<BR>   dBuf += matR.a*matV.a;<BR>}<BR>if(dBuf&lt;0.0) dBuf=-dBuf;<BR>dBuf=sqrt(dBuf);<BR>for(loop1=0;loop1&lt;nRow;loop1++)<BR>   matV.a /=dBuf;<BR>   // matV(loop1,loop)/=dBuf;<BR> }</P>
<P> // adBuf.SetSize(nRow);<BR> adBuf=(double*)malloc(sizeof(double)*nRow);<BR> for(loop=0;loop&lt;nRow;loop++){<BR>// adBuf=matA(loop,loop)/matB(loop,loop);<BR>adBuf=matA-&gt;a/matB-&gt;a;<BR> }<BR> // aiBuf.SetSize(nRow);<BR> aiBuf=(unsigned int *)malloc(sizeof(unsigned int)*nRow);<BR> aiBuf=0;<BR> for(loop=0;loop&lt;nRow;loop++){<BR>for(loop1=0;loop1&lt;loop;loop1++){<BR>   if(fabs(adBuf])&gt;fabs(adBuf)){<BR>    // aiBuf.InsertAt(loop1,loop);<BR>    for(iRow=nRow-1; iRow&gt;loop1; iRow--)<BR>   aiBuf=aiBuf;<BR>    aiBuf=loop;<BR>    break;<BR>   }<BR>}<BR>if(loop1==loop){<BR>   aiBuf=loop;<BR>}<BR> }</P>
<P> for(loop=0;loop&lt;nRow;loop++){<BR>m_adEigen=adBuf];<BR> }<BR> for(loop=0;loop&lt;nRow;loop++){<BR>for(loop1=0;loop1&lt;nRow;loop1++){<BR>   // matB(loop1,loop)=matV(loop1,aiBuf);<BR>   matB-&gt;a=matV.a];<BR>}<BR> }</P>
<P> // matrix and vector free<BR> MatrixFree(&amp;matBBak);<BR> MatrixFree(&amp;matR);<BR> MatrixFree(&amp;matRT);<BR> MatrixFree(&amp;matV);<BR> free(adBuf);<BR> free(aiBuf);<BR>}<BR></P>

markailee1 发表于 2006-6-22 23:32

还有我自编的简单矩阵库

<P>#include &lt;stdio.h&gt;<BR>#include &lt;malloc.h&gt;<BR>#include &lt;stdlib.h&gt;</P>
<P>#ifndef MATRIXLIB<BR>#define MATRIXLIB</P>
<P>typedef double type;<BR>typedef struct<BR>{<BR> type** a;<BR> int m,n;   // m,n for row,col<BR>}matrix;</P>
<P>type** Make2DArray(int row, int col);<BR>void Diliver2DArray(type** a,int row);</P>
<P>type** Make2DArray(int row, int col)<BR>{<BR> type** a;<BR> int i;</P>
<P> if( (a=(type**)malloc(row*sizeof(type*))) == NULL )<BR> {<BR>printf("memory not sufficent!");<BR>exit(0);<BR> }<BR> for( i=0; i&lt;row; i++)<BR>if( (a=(type*)malloc(col*sizeof(type))) == NULL )<BR>{<BR>   printf("momory not sifficent!");<BR>   exit(0);<BR>}<BR> return a;<BR>}</P>
<P>void Diliver2DArray(type** a,int row)<BR>{<BR> int i;<BR> for( i=0; i&lt;row; i++)<BR>free(a);<BR> free(a);<BR>}</P>
<P>void MatrixInit(matrix* a,int m,int n)<BR>{<BR> a-&gt;a = Make2DArray(m,n);<BR> a-&gt;m=m; a-&gt;n=n;<BR> // 是否应该将元素初始化为0???<BR>}<BR>void MatrixFree(matrix* a)<BR>{<BR> Diliver2DArray(a-&gt;a,a-&gt;m);<BR>}</P>
<P>// A=0, 矩阵A赋值为0<BR>void MatrixZero(matrix* A)<BR>{<BR> int i,j;<BR> for(i=0; i&lt;A-&gt;m; i++)<BR>for(j=0; j&lt;A-&gt;n; j++)<BR>   A-&gt;a=0;<BR>}</P>
<P>// A=B, <BR>void MatrixCopy(matrix *A, matrix *B)<BR>{<BR> int i,j;<BR> if( (A-&gt;m!=B-&gt;m) || (A-&gt;n!=B-&gt;n) ) {<BR>printf("cannot add matrix!\n");<BR>return ;<BR> }<BR> for(i=0; i&lt;B-&gt;m; i++)<BR>for(j=0; j&lt;B-&gt;n; j++)<BR>   A-&gt;a = B-&gt;a;<BR>}</P>
<P>// B=A-1, 矩阵A的逆阵<BR>void Inverse(matrix* A,matrix* B)<BR>{<BR>}</P>
<P>// C=A+B<BR>void MatrixAdd(matrix* A, matrix* B, matrix* C)<BR>{<BR> int i,j;<BR> if( (A-&gt;m!=B-&gt;m) || (B-&gt;m!=C-&gt;m) || (A-&gt;n!=B-&gt;n) || (B-&gt;n!=C-&gt;n) )<BR> {<BR>printf("cannot add matrix!\n");<BR>return ;<BR> }<BR> for(i=0; i&lt;A-&gt;m; i++)<BR>for(j=0; j&lt;A-&gt;n; j++)<BR>   C-&gt;a=A-&gt;a+B-&gt;a;<BR>}</P>
<P>// c=a*b, 将这个函数功能加强,即 a或b可以跟c相同。<BR>void MatrixMultiply(matrix* a, matrix* b, matrix* c)<BR>{<BR> int m=a-&gt;m, n1=a-&gt;n, m1=b-&gt;m, n=b-&gt;n,i,j,k;<BR> double tp=0;<BR> matrix temp;<BR> MatrixInit(&amp;temp,c-&gt;m,c-&gt;n);<BR> if(m1!=n1)<BR> {<BR>printf("cann't multiply!\n"); exit(0);<BR> }<BR> for(i=0; i&lt;m; i++)<BR>for(j=0; j&lt;n; j++)<BR>{<BR>   tp=0;<BR>   for(k=0; k&lt;n1; k++)<BR>    tp += a-&gt;a * b-&gt;a;<BR>   temp.a=tp;<BR>}<BR> // c=temp;<BR> MatrixCopy(c,&amp;temp);<BR> MatrixFree(&amp;temp);<BR>}</P>
<P>// 方阵A转置<BR>void MatrixTranspose(matrix *A)<BR>{<BR> int i,j;<BR> type temp;<BR> if(A-&gt;m!=A-&gt;n) {<BR>printf("cannot transpose !");<BR>return ;<BR> }<BR> for(i=0; i&lt;A-&gt;m; i++)<BR>for(j=0; j&lt;i; j++) {<BR>   temp=A-&gt;a;<BR>   A-&gt;a=A-&gt;a;<BR>   A-&gt;a=temp;<BR>}<BR>}</P>

<P>// B=A的转置<BR>void Transpose(matrix* A, matrix* B)<BR>{<BR> int i,j;<BR> if( (A-&gt;m != B-&gt;n) || (A-&gt;n != B-&gt;m) )<BR> {<BR>printf("cannot transpose!\n");<BR>return ;<BR> }<BR> for(i=0; i&lt;B-&gt;m; i++)<BR>for(j=0; j&lt;B-&gt;n; j++)<BR>   B-&gt;a=A-&gt;a;<BR>}<BR>// A=A*f 矩阵数乘<BR>void MatrixNumber(matrix* A, double f)<BR>{<BR> int i,j;<BR> for(i=0; i&lt;A-&gt;m; i++)<BR>for(j=0; j&lt;A-&gt;n; j++)<BR>   A-&gt;a *= f;<BR>}</P>
<P>// c=a*v 矩阵乘向量<BR>void MatrixMulVector(matrix* a, type* v, type* c)<BR>{<BR> int i,j, m=a-&gt;m, n=a-&gt;n;<BR> double tp=0;<BR> for(i=0; i&lt;m; i++)<BR> {<BR>tp=0;<BR>for(j=0; j&lt;n; j++)<BR>   tp += a-&gt;a*v;<BR>c=tp;<BR> }<BR>}</P>
<P>// 输出矩阵A,<BR>void MatrixPrint(matrix* A)<BR>{<BR> int i,j;<BR> for(i=0; i&lt;A-&gt;m; i++){<BR>for(j=0; j&lt;A-&gt;n; j++)<BR>   printf("%7.4f ",A-&gt;a);<BR>printf("\n");<BR> }<BR>}</P>

<P>#endif</P>

风花雪月 发表于 2006-6-25 08:57

回复:(markailee1)求广义特征值的广义雅可比方法

谢谢分享,希望以后多多支持
页: [1]
查看完整版本: 求广义特征值的广义雅可比方法