/** * ����в����ȷ����������ѷ���� * * @param mtxResult - CMatrix���ö����ط��������� * @return bool �ͣ�����������Ƿ�ɹ� */ public bool GetRootsetTlvs(Matrix mtxResult) { int i,j,k; double a,beta,q,c,h; // δ֪������ int n = mtxLECoef.GetNumColumns(); // ��ʼ��������� mtxResult.Init(n, 1); double[] x = mtxResult.GetData(); // �������� double[] pDataConst = mtxLEConst.GetData(); // ����T���� double[] t = new double[n]; // ����T���� for (i=0; i<n; ++i) t[i] = mtxLECoef.GetElement(0, i); // ��ʱ���� double[] s = new double[n]; double[] y = new double[n]; // ���в����ȷ����飬�����ñ�������� a=t[0]; if (a == 0.0) { return false; } // ����ѷ������� y[0]=1.0; x[0]=pDataConst[0]/a; for (k=1; k<=n-1; k++) { beta=0.0; q=0.0; for (j=0; j<=k-1; j++) { beta=beta+y[j]*t[j+1]; q=q+x[j]*t[k-j]; } if (a == 0.0) { return false; } c=-beta/a; s[0]=c*y[k-1]; y[k]=y[k-1]; if (k!=1) { for (i=1; i<=k-1; i++) s[i]=y[i-1]+c*y[k-i-1]; } a=a+c*beta; if (a == 0.0) { return false; } h=(pDataConst[k]-q)/a; for (i=0; i<=k-1; i++) { x[i]=x[i]+h*s[i]; y[i]=s[i]; } x[k]=h*y[k]; } return true; }
/** * ���������С��������Ĺ����淨 * * @param mtxResult - Matrix�����ط��������� * @param mtxAP - Matrix������ϵ������Ĺ�������� * @param mtxU - Matrix������U���� * @param mtxV - Matrix������V���� * @param eps - ���ƾ��� * @return bool �ͣ�����������Ƿ�ɹ� */ public bool GetRootsetGinv(Matrix mtxResult, Matrix mtxAP, Matrix mtxU, Matrix mtxV, double eps) { int i,j; // ���̸�����δ֪������ int m = mtxLECoef.GetNumRows(); int n = mtxLECoef.GetNumColumns(); // ��ʼ�������� mtxResult.Init(n, 1); double[] pDataConst = mtxLEConst.GetData(); double[] x = mtxResult.GetData(); // ��ʱ���� Matrix mtxA = new Matrix(mtxLECoef); // ���������� if (! mtxA.InvertUV(mtxAP, mtxU, mtxV, eps)) return false; double[] pAPData = mtxAP.GetData(); // ��� for (i=0; i<=n-1; i++) { x[i]=0.0; for (j=0; j<=m-1; j++) x[i]=x[i]+pAPData[i*m+j]*pDataConst[j]; } return true; }
/** * ���Գ�����������Ĺ����ݶȷ� * * @param mtxResult - CMatrix���ö����ط��������� * @param eps - ���ƾ��� */ public void GetRootsetGrad(Matrix mtxResult, double eps) { int i,k; double alpha,beta,d,e; // δ֪������ int n = GetNumUnknowns(); // ��ʼ�������� mtxResult.Init(n, 1); double[] x = mtxResult.GetData(); // ������ʱ���� Matrix mtxP = new Matrix(n, 1); double[] p = mtxP.GetData(); double[] pDataCoef = mtxLECoef.GetData(); double[] pDataConst = mtxLEConst.GetData(); double[] r = new double[n]; for (i=0; i<=n-1; i++) { x[i]=0.0; p[i]=pDataConst[i]; r[i]=pDataConst[i]; } i=0; while (i<=n-1) { Matrix mtxS = mtxLECoef.Multiply(mtxP); double[] s = mtxS.GetData(); d=0.0; e=0.0; for (k=0; k<=n-1; k++) { d=d+p[k]*pDataConst[k]; e=e+p[k]*s[k]; } alpha=d/e; for (k=0; k<=n-1; k++) x[k]=x[k]+alpha*p[k]; Matrix mtxQ = mtxLECoef.Multiply(mtxResult); double[] q = mtxQ.GetData(); d=0.0; for (k=0; k<=n-1; k++) { r[k]=pDataConst[k]-q[k]; d=d+r[k]*s[k]; } beta=d/e; d=0.0; for (k=0; k<=n-1; k++) d=d+r[k]*r[k]; // ���㾫�ȣ������� d=Math.Sqrt(d); if (d<eps) break; for (k=0; k<=n-1; k++) p[k]=r[k]-beta*p[k]; i=i+1; } }
/** * ��ʵ�Գƾ�������ֵ�������������ſɱȹ��ط� * * @param dblEigenValue - һά���飬����Ϊ����Ľ���������ʱ�������ֵ * @param mtxEigenVector - ����ʱ������������������е�i��Ϊ������ * dblEigenValue�е�j������ֵ��Ӧ���������� * @param eps - ���㾫�� * @return bool�ͣ�����Ƿ�ɹ� */ public bool ComputeEvJacobi(double[] dblEigenValue, Matrix mtxEigenVector, double eps) { int i,j,p,q,u,w,t,s; double ff,fm,cn,sn,omega,x,y,d; if (! mtxEigenVector.Init(numColumns, numColumns)) return false; for (i=0; i<=numColumns-1; i++) { mtxEigenVector.elements[i*numColumns+i]=1.0; for (j=0; j<=numColumns-1; j++) if (i!=j) mtxEigenVector.elements[i*numColumns+j]=0.0; } ff=0.0; for (i=1; i<=numColumns-1; i++) { for (j=0; j<=i-1; j++) { d=elements[i*numColumns+j]; ff=ff+d*d; } } ff=Math.Sqrt(2.0*ff); ff=ff/(1.0*numColumns); bool nextLoop = false; while (true) { for (i=1; i<=numColumns-1; i++) { for (j=0; j<=i-1; j++) { d=Math.Abs(elements[i*numColumns+j]); if (d>ff) { p=i; q=j; u=p*numColumns+q; w=p*numColumns+p; t=q*numColumns+p; s=q*numColumns+q; x=-elements[u]; y=(elements[s]-elements[w])/2.0; omega=x/Math.Sqrt(x*x+y*y); if (y<0.0) omega=-omega; sn=1.0+Math.Sqrt(1.0-omega*omega); sn=omega/Math.Sqrt(2.0*sn); cn=Math.Sqrt(1.0-sn*sn); fm=elements[w]; elements[w]=fm*cn*cn+elements[s]*sn*sn+elements[u]*omega; elements[s]=fm*sn*sn+elements[s]*cn*cn-elements[u]*omega; elements[u]=0.0; elements[t]=0.0; for (j=0; j<=numColumns-1; j++) { if ((j!=p)&&(j!=q)) { u=p*numColumns+j; w=q*numColumns+j; fm=elements[u]; elements[u]=fm*cn+elements[w]*sn; elements[w]=-fm*sn+elements[w]*cn; } } for (i=0; i<=numColumns-1; i++) { if ((i!=p)&&(i!=q)) { u=i*numColumns+p; w=i*numColumns+q; fm=elements[u]; elements[u]=fm*cn+elements[w]*sn; elements[w]=-fm*sn+elements[w]*cn; } } for (i=0; i<=numColumns-1; i++) { u=i*numColumns+p; w=i*numColumns+q; fm=mtxEigenVector.elements[u]; mtxEigenVector.elements[u]=fm*cn+mtxEigenVector.elements[w]*sn; mtxEigenVector.elements[w]=-fm*sn+mtxEigenVector.elements[w]*cn; } nextLoop = true; break; } } if (nextLoop) break; } if (nextLoop) { nextLoop = false; continue; } nextLoop = false; // ����ﵽ����Ҫ���˳�ѭ�������ؽ�� if (ff<eps) { for (i=0; i<numColumns; ++i) dblEigenValue[i] = GetElement(i,i); return true; } ff=ff/(1.0*numColumns); } }
/** * ��˹�����¶������� * * @param mtxResult - CMatrix���ö����ط��������� * @param eps - ���ƾ��� * @return bool �ͣ�����������Ƿ�ɹ� */ public bool GetRootsetGaussSeidel(Matrix mtxResult, double eps) { int i,j,u,v; double p,t,s,q; // δ֪������ int n = mtxLECoef.GetNumColumns(); // ��ʼ�������� mtxResult.Init(n, 1); double[] x = mtxResult.GetData(); // ϵ���볣�� double[] pDataCoef = mtxLECoef.GetData(); double[] pDataConst = mtxLEConst.GetData(); // ��� for (i=0; i<=n-1; i++) { u=i*n+i; p=0.0; x[i]=0.0; for (j=0; j<=n-1; j++) { if (i!=j) { v=i*n+j; p=p+Math.Abs(pDataCoef[v]); } } if (p>=Math.Abs(pDataCoef[u])) return false; } // ���ȿ��� p=eps+1.0; while (p>=eps) { p=0.0; for (i=0; i<=n-1; i++) { t=x[i]; s=0.0; for (j=0; j<=n-1; j++) if (j!=i) s=s+pDataCoef[i*n+j]*x[j]; x[i]=(pDataConst[i]-s)/pDataCoef[i*n+i]; q=Math.Abs(x[i]-t)/(1.0+Math.Abs(x[i])); if (q>p) p=q; } } return true; }
/** * һ��ʵ���������ֵ�ֽ⣬�ֽ�ɹ���ԭ����Խ���Ԫ�ؾ��Ǿ��������ֵ * * @param mtxU - ���طֽ���U���� * @param mtxV - ���طֽ���V���� * @param eps - ���㾫�� * @return bool�ͣ�����Ƿ�ɹ� */ public bool SplitUV(Matrix mtxU, Matrix mtxV, double eps) { int i,j,k,l,it,ll,kk,ix,iy,mm,nn,iz,m1,ks; double d,dd,t,sm,sm1,em1,sk,ek,b,c,shh; double[] fg = new double[2]; double[] cs = new double[2]; int m = numRows; int n = numColumns; // ��ʼ��U, V���� if (! mtxU.Init(m, m) || ! mtxV.Init(n, n)) return false; // ��ʱ������ int ka = Math.Max(m, n) + 1; double[] s = new double[ka]; double[] e = new double[ka]; double[] w = new double[ka]; // ָ����������Ϊ60 it=60; k=n; if (m-1<n) k=m-1; l=m; if (n-2<m) l=n-2; if (l<0) l=0; // ѭ���������� ll=k; if (l>k) ll=l; if (ll>=1) { for (kk=1; kk<=ll; kk++) { if (kk<=k) { d=0.0; for (i=kk; i<=m; i++) { ix=(i-1)*n+kk-1; d=d+elements[ix]*elements[ix]; } s[kk-1]=Math.Sqrt(d); if (s[kk-1]!=0.0) { ix=(kk-1)*n+kk-1; if (elements[ix]!=0.0) { s[kk-1]=Math.Abs(s[kk-1]); if (elements[ix]<0.0) s[kk-1]=-s[kk-1]; } for (i=kk; i<=m; i++) { iy=(i-1)*n+kk-1; elements[iy]=elements[iy]/s[kk-1]; } elements[ix]=1.0+elements[ix]; } s[kk-1]=-s[kk-1]; } if (n>=kk+1) { for (j=kk+1; j<=n; j++) { if ((kk<=k)&&(s[kk-1]!=0.0)) { d=0.0; for (i=kk; i<=m; i++) { ix=(i-1)*n+kk-1; iy=(i-1)*n+j-1; d=d+elements[ix]*elements[iy]; } d=-d/elements[(kk-1)*n+kk-1]; for (i=kk; i<=m; i++) { ix=(i-1)*n+j-1; iy=(i-1)*n+kk-1; elements[ix]=elements[ix]+d*elements[iy]; } } e[j-1]=elements[(kk-1)*n+j-1]; } } if (kk<=k) { for (i=kk; i<=m; i++) { ix=(i-1)*m+kk-1; iy=(i-1)*n+kk-1; mtxU.elements[ix]=elements[iy]; } } if (kk<=l) { d=0.0; for (i=kk+1; i<=n; i++) d=d+e[i-1]*e[i-1]; e[kk-1]=Math.Sqrt(d); if (e[kk-1]!=0.0) { if (e[kk]!=0.0) { e[kk-1]=Math.Abs(e[kk-1]); if (e[kk]<0.0) e[kk-1]=-e[kk-1]; } for (i=kk+1; i<=n; i++) e[i-1]=e[i-1]/e[kk-1]; e[kk]=1.0+e[kk]; } e[kk-1]=-e[kk-1]; if ((kk+1<=m)&& (e[kk-1]!=0.0)) { for (i=kk+1; i<=m; i++) w[i-1]=0.0; for (j=kk+1; j<=n; j++) for (i=kk+1; i<=m; i++) w[i-1]=w[i-1]+e[j-1]*elements[(i-1)*n+j-1]; for (j=kk+1; j<=n; j++) { for (i=kk+1; i<=m; i++) { ix=(i-1)*n+j-1; elements[ix]=elements[ix]-w[i-1]*e[j-1]/e[kk]; } } } for (i=kk+1; i<=n; i++) mtxV.elements[(i-1)*n+kk-1]=e[i-1]; } } } mm=n; if (m+1<n) mm=m+1; if (k<n) s[k]=elements[k*n+k]; if (m<mm) s[mm-1]=0.0; if (l+1<mm) e[l]=elements[l*n+mm-1]; e[mm-1]=0.0; nn=m; if (m>n) nn=n; if (nn>=k+1) { for (j=k+1; j<=nn; j++) { for (i=1; i<=m; i++) mtxU.elements[(i-1)*m+j-1]=0.0; mtxU.elements[(j-1)*m+j-1]=1.0; } } if (k>=1) { for (ll=1; ll<=k; ll++) { kk=k-ll+1; iz=(kk-1)*m+kk-1; if (s[kk-1]!=0.0) { if (nn>=kk+1) { for (j=kk+1; j<=nn; j++) { d=0.0; for (i=kk; i<=m; i++) { ix=(i-1)*m+kk-1; iy=(i-1)*m+j-1; d=d+mtxU.elements[ix]*mtxU.elements[iy]/mtxU.elements[iz]; } d=-d; for (i=kk; i<=m; i++) { ix=(i-1)*m+j-1; iy=(i-1)*m+kk-1; mtxU.elements[ix]=mtxU.elements[ix]+d*mtxU.elements[iy]; } } } for (i=kk; i<=m; i++) { ix=(i-1)*m+kk-1; mtxU.elements[ix]=-mtxU.elements[ix]; } mtxU.elements[iz]=1.0+mtxU.elements[iz]; if (kk-1>=1) { for (i=1; i<=kk-1; i++) mtxU.elements[(i-1)*m+kk-1]=0.0; } } else { for (i=1; i<=m; i++) mtxU.elements[(i-1)*m+kk-1]=0.0; mtxU.elements[(kk-1)*m+kk-1]=1.0; } } } for (ll=1; ll<=n; ll++) { kk=n-ll+1; iz=kk*n+kk-1; if ((kk<=l) && (e[kk-1]!=0.0)) { for (j=kk+1; j<=n; j++) { d=0.0; for (i=kk+1; i<=n; i++) { ix=(i-1)*n+kk-1; iy=(i-1)*n+j-1; d=d+mtxV.elements[ix]*mtxV.elements[iy]/mtxV.elements[iz]; } d=-d; for (i=kk+1; i<=n; i++) { ix=(i-1)*n+j-1; iy=(i-1)*n+kk-1; mtxV.elements[ix]=mtxV.elements[ix]+d*mtxV.elements[iy]; } } } for (i=1; i<=n; i++) mtxV.elements[(i-1)*n+kk-1]=0.0; mtxV.elements[iz-n]=1.0; } for (i=1; i<=m; i++) for (j=1; j<=n; j++) elements[(i-1)*n+j-1]=0.0; m1=mm; it=60; while (true) { if (mm==0) { ppp(elements,e,s,mtxV.elements,m,n); return true; } if (it==0) { ppp(elements,e,s,mtxV.elements,m,n); return false; } kk=mm-1; while ((kk!=0) && (Math.Abs(e[kk-1])!=0.0)) { d=Math.Abs(s[kk-1])+Math.Abs(s[kk]); dd=Math.Abs(e[kk-1]); if (dd>eps*d) kk=kk-1; else e[kk-1]=0.0; } if (kk==mm-1) { kk=kk+1; if (s[kk-1]<0.0) { s[kk-1]=-s[kk-1]; for (i=1; i<=n; i++) { ix=(i-1)*n+kk-1; mtxV.elements[ix]=-mtxV.elements[ix];} } while ((kk!=m1) && (s[kk-1]<s[kk])) { d=s[kk-1]; s[kk-1]=s[kk]; s[kk]=d; if (kk<n) { for (i=1; i<=n; i++) { ix=(i-1)*n+kk-1; iy=(i-1)*n+kk; d=mtxV.elements[ix]; mtxV.elements[ix]=mtxV.elements[iy]; mtxV.elements[iy]=d; } } if (kk<m) { for (i=1; i<=m; i++) { ix=(i-1)*m+kk-1; iy=(i-1)*m+kk; d=mtxU.elements[ix]; mtxU.elements[ix]=mtxU.elements[iy]; mtxU.elements[iy]=d; } } kk=kk+1; } it=60; mm=mm-1; } else { ks=mm; while ((ks>kk) && (Math.Abs(s[ks-1])!=0.0)) { d=0.0; if (ks!=mm) d=d+Math.Abs(e[ks-1]); if (ks!=kk+1) d=d+Math.Abs(e[ks-2]); dd=Math.Abs(s[ks-1]); if (dd>eps*d) ks=ks-1; else s[ks-1]=0.0; } if (ks==kk) { kk=kk+1; d=Math.Abs(s[mm-1]); t=Math.Abs(s[mm-2]); if (t>d) d=t; t=Math.Abs(e[mm-2]); if (t>d) d=t; t=Math.Abs(s[kk-1]); if (t>d) d=t; t=Math.Abs(e[kk-1]); if (t>d) d=t; sm=s[mm-1]/d; sm1=s[mm-2]/d; em1=e[mm-2]/d; sk=s[kk-1]/d; ek=e[kk-1]/d; b=((sm1+sm)*(sm1-sm)+em1*em1)/2.0; c=sm*em1; c=c*c; shh=0.0; if ((b!=0.0)||(c!=0.0)) { shh=Math.Sqrt(b*b+c); if (b<0.0) shh=-shh; shh=c/(b+shh); } fg[0]=(sk+sm)*(sk-sm)-shh; fg[1]=sk*ek; for (i=kk; i<=mm-1; i++) { sss(fg,cs); if (i!=kk) e[i-2]=fg[0]; fg[0]=cs[0]*s[i-1]+cs[1]*e[i-1]; e[i-1]=cs[0]*e[i-1]-cs[1]*s[i-1]; fg[1]=cs[1]*s[i]; s[i]=cs[0]*s[i]; if ((cs[0]!=1.0)||(cs[1]!=0.0)) { for (j=1; j<=n; j++) { ix=(j-1)*n+i-1; iy=(j-1)*n+i; d=cs[0]*mtxV.elements[ix]+cs[1]*mtxV.elements[iy]; mtxV.elements[iy]=-cs[1]*mtxV.elements[ix]+cs[0]*mtxV.elements[iy]; mtxV.elements[ix]=d; } } sss(fg,cs); s[i-1]=fg[0]; fg[0]=cs[0]*e[i-1]+cs[1]*s[i]; s[i]=-cs[1]*e[i-1]+cs[0]*s[i]; fg[1]=cs[1]*e[i]; e[i]=cs[0]*e[i]; if (i<m) { if ((cs[0]!=1.0)||(cs[1]!=0.0)) { for (j=1; j<=m; j++) { ix=(j-1)*m+i-1; iy=(j-1)*m+i; d=cs[0]*mtxU.elements[ix]+cs[1]*mtxU.elements[iy]; mtxU.elements[iy]=-cs[1]*mtxU.elements[ix]+cs[0]*mtxU.elements[iy]; mtxU.elements[ix]=d; } } } } e[mm-2]=fg[0]; it=it-1; } else { if (ks==mm) { kk=kk+1; fg[1]=e[mm-2]; e[mm-2]=0.0; for (ll=kk; ll<=mm-1; ll++) { i=mm+kk-ll-1; fg[0]=s[i-1]; sss(fg,cs); s[i-1]=fg[0]; if (i!=kk) { fg[1]=-cs[1]*e[i-2]; e[i-2]=cs[0]*e[i-2]; } if ((cs[0]!=1.0)||(cs[1]!=0.0)) { for (j=1; j<=n; j++) { ix=(j-1)*n+i-1; iy=(j-1)*n+mm-1; d=cs[0]*mtxV.elements[ix]+cs[1]*mtxV.elements[iy]; mtxV.elements[iy]=-cs[1]*mtxV.elements[ix]+cs[0]*mtxV.elements[iy]; mtxV.elements[ix]=d; } } } } else { kk=ks+1; fg[1]=e[kk-2]; e[kk-2]=0.0; for (i=kk; i<=mm; i++) { fg[0]=s[i-1]; sss(fg,cs); s[i-1]=fg[0]; fg[1]=-cs[1]*e[i-1]; e[i-1]=cs[0]*e[i-1]; if ((cs[0]!=1.0)||(cs[1]!=0.0)) { for (j=1; j<=m; j++) { ix=(j-1)*m+i-1; iy=(j-1)*m+kk-2; d=cs[0]*mtxU.elements[ix]+cs[1]*mtxU.elements[iy]; mtxU.elements[iy]=-cs[1]*mtxU.elements[ix]+cs[0]*mtxU.elements[iy]; mtxU.elements[ix]=d; } } } } } } } }
/** * ��ʵ�Գƾ�������ֵ�������������ſɱȷ� * * @param dblEigenValue - һά���飬����Ϊ����Ľ���������ʱ�������ֵ * @param mtxEigenVector - ����ʱ������������������е�i��Ϊ������ * dblEigenValue�е�j������ֵ��Ӧ���������� * @param nMaxIt - �������� * @param eps - ���㾫�� * @return bool�ͣ�����Ƿ�ɹ� */ public bool ComputeEvJacobi(double[] dblEigenValue, Matrix mtxEigenVector, int nMaxIt, double eps) { int i,j,p = 0,q = 0,u,w,t,s,l; double fm,cn,sn,omega,x,y,d; if (! mtxEigenVector.Init(numColumns, numColumns)) return false; l=1; for (i=0; i<=numColumns-1; i++) { mtxEigenVector.elements[i*numColumns+i]=1.0; for (j=0; j<=numColumns-1; j++) if (i!=j) mtxEigenVector.elements[i*numColumns+j]=0.0; } while (true) { fm=0.0; for (i=1; i<=numColumns-1; i++) { for (j=0; j<=i-1; j++) { d=Math.Abs(elements[i*numColumns+j]); if ((i!=j) && (d>fm)) { fm=d; p=i; q=j; } } } if (fm<eps) { for (i=0; i<numColumns; ++i) dblEigenValue[i] = GetElement(i,i); return true; } if (l>nMaxIt) return false; l=l+1; u=p*numColumns+q; w=p*numColumns+p; t=q*numColumns+p; s=q*numColumns+q; x=-elements[u]; y=(elements[s]-elements[w])/2.0; omega=x/Math.Sqrt(x*x+y*y); if (y<0.0) omega=-omega; sn=1.0+Math.Sqrt(1.0-omega*omega); sn=omega/Math.Sqrt(2.0*sn); cn=Math.Sqrt(1.0-sn*sn); fm=elements[w]; elements[w]=fm*cn*cn+elements[s]*sn*sn+elements[u]*omega; elements[s]=fm*sn*sn+elements[s]*cn*cn-elements[u]*omega; elements[u]=0.0; elements[t]=0.0; for (j=0; j<=numColumns-1; j++) { if ((j!=p) && (j!=q)) { u=p*numColumns+j; w=q*numColumns+j; fm=elements[u]; elements[u]=fm*cn+elements[w]*sn; elements[w]=-fm*sn+elements[w]*cn; } } for (i=0; i<=numColumns-1; i++) { if ((i!=p) && (i!=q)) { u=i*numColumns+p; w=i*numColumns+q; fm=elements[u]; elements[u]=fm*cn+elements[w]*sn; elements[w]=-fm*sn+elements[w]*cn; } } for (i=0; i<=numColumns-1; i++) { u=i*numColumns+p; w=i*numColumns+q; fm=mtxEigenVector.elements[u]; mtxEigenVector.elements[u]=fm*cn+mtxEigenVector.elements[w]*sn; mtxEigenVector.elements[w]=-fm*sn+mtxEigenVector.elements[w]*cn; } } }
/** * һ��ʵ�����QR�ֽ⣬�ֽ�ɹ���ԭ����ΪR���� * * @param mtxQ - ���طֽ���Q���� * @return bool�ͣ�����Ƿ�ɹ� */ public bool SplitQR(Matrix mtxQ) { int i,j,k,l,nn,p,jj; double u,alpha,w,t; if (numRows < numColumns) return false; // ��ʼ��Q���� if (! mtxQ.Init(numRows, numRows)) return false; // �Խ���Ԫ�ص�λ�� for (i=0; i<=numRows-1; i++) { for (j=0; j<=numRows-1; j++) { l=i*numRows+j; mtxQ.elements[l]=0.0; if (i==j) mtxQ.elements[l]=1.0; } } // ��ʼ�ֽ� nn=numColumns; if (numRows == numColumns) nn=numRows-1; for (k=0; k<=nn-1; k++) { u=0.0; l=k*numColumns+k; for (i=k; i<=numRows-1; i++) { w=Math.Abs(elements[i*numColumns+k]); if (w>u) u=w; } alpha=0.0; for (i=k; i<=numRows-1; i++) { t=elements[i*numColumns+k]/u; alpha=alpha+t*t; } if (elements[l]>0.0) u=-u; alpha=u*Math.Sqrt(alpha); if (alpha == 0.0) return false; u=Math.Sqrt(2.0*alpha*(alpha-elements[l])); if ((u+1.0)!=1.0) { elements[l]=(elements[l]-alpha)/u; for (i=k+1; i<=numRows-1; i++) { p=i*numColumns+k; elements[p]=elements[p]/u; } for (j=0; j<=numRows-1; j++) { t=0.0; for (jj=k; jj<=numRows-1; jj++) t=t+elements[jj*numColumns+k]*mtxQ.elements[jj*numRows+j]; for (i=k; i<=numRows-1; i++) { p=i*numRows+j; mtxQ.elements[p]=mtxQ.elements[p]-2.0*t*elements[i*numColumns+k]; } } for (j=k+1; j<=numColumns-1; j++) { t=0.0; for (jj=k; jj<=numRows-1; jj++) t=t+elements[jj*numColumns+k]*elements[jj*numColumns+j]; for (i=k; i<=numRows-1; i++) { p=i*numColumns+j; elements[p]=elements[p]-2.0*t*elements[i*numColumns+k]; } } elements[l]=alpha; for (i=k+1; i<=numRows-1; i++) elements[i*numColumns+k]=0.0; } } // ����Ԫ�� for (i=0; i<=numRows-2; i++) { for (j=i+1; j<=numRows-1;j++) { p=i*numRows+j; l=j*numRows+i; t=mtxQ.elements[p]; mtxQ.elements[p]=mtxQ.elements[l]; mtxQ.elements[l]=t; } } return true; }
/** * ��������Ƿֽ⣬�ֽ�ɹ���ԭ����ΪQ���� * * @param mtxL - ���طֽ���L���� * @param mtxU - ���طֽ���U���� * @return bool�ͣ�����Ƿ�ɹ� */ public bool SplitLU(Matrix mtxL, Matrix mtxU) { int i,j,k,w,v,ll; // ��ʼ��������� if (! mtxL.Init(numColumns, numColumns) || ! mtxU.Init(numColumns, numColumns)) return false; for (k=0; k<=numColumns-2; k++) { ll=k*numColumns+k; if (elements[ll] == 0.0) return false; for (i=k+1; i<=numColumns-1; i++) { w=i*numColumns+k; elements[w]=elements[w]/elements[ll]; } for (i=k+1; i<=numColumns-1; i++) { w=i*numColumns+k; for (j=k+1; j<=numColumns-1; j++) { v=i*numColumns+j; elements[v]=elements[v]-elements[w]*elements[k*numColumns+j]; } } } for (i=0; i<=numColumns-1; i++) { for (j=0; j<i; j++) { w=i*numColumns+j; mtxL.elements[w]=elements[w]; mtxU.elements[w]=0.0; } w=i*numColumns+i; mtxL.elements[w]=1.0; mtxU.elements[w]=elements[w]; for (j=i+1; j<=numColumns-1; j++) { w=i*numColumns+j; mtxL.elements[w]=0.0; mtxU.elements[w]=elements[w]; } } return true; }
/** * Լ���Գƾ���Ϊ�Գ����Խ���ĺ�˹�ɶ��±任�� * * @param mtxQ - ���غ�˹�ɶ��±任�ij˻�����Q * @param mtxT - ������õĶԳ����Խ��� * @param dblB - һά���飬����Ϊ����Ľ��������ضԳ����Խ�������Խ���Ԫ�� * @param dblC - һά���飬����Ϊ����Ľ�����ǰn-1��Ԫ�ط��ضԳ����Խ���� * �ζԽ���Ԫ�� * @return bool�ͣ�����Ƿ�ɹ� */ public bool MakeSymTri(Matrix mtxQ, Matrix mtxT, double[] dblB, double[] dblC) { int i,j,k,u; double h,f,g,h2; // ��ʼ������Q��T if (! mtxQ.Init(numColumns, numColumns) || ! mtxT.Init(numColumns, numColumns)) return false; if (dblB == null || dblC == null) return false; for (i=0; i<=numColumns-1; i++) { for (j=0; j<=numColumns-1; j++) { u=i*numColumns+j; mtxQ.elements[u]=elements[u]; } } for (i=numColumns-1; i>=1; i--) { h=0.0; if (i>1) { for (k=0; k<=i-1; k++) { u=i*numColumns+k; h=h+mtxQ.elements[u]*mtxQ.elements[u]; } } if (h == 0.0) { dblC[i]=0.0; if (i==1) dblC[i]=mtxQ.elements[i*numColumns+i-1]; dblB[i]=0.0; } else { dblC[i]=Math.Sqrt(h); u=i*numColumns+i-1; if (mtxQ.elements[u]>0.0) dblC[i]=-dblC[i]; h=h-mtxQ.elements[u]*dblC[i]; mtxQ.elements[u]=mtxQ.elements[u]-dblC[i]; f=0.0; for (j=0; j<=i-1; j++) { mtxQ.elements[j*numColumns+i]=mtxQ.elements[i*numColumns+j]/h; g=0.0; for (k=0; k<=j; k++) g=g+mtxQ.elements[j*numColumns+k]*mtxQ.elements[i*numColumns+k]; if (j+1<=i-1) for (k=j+1; k<=i-1; k++) g=g+mtxQ.elements[k*numColumns+j]*mtxQ.elements[i*numColumns+k]; dblC[j]=g/h; f=f+g*mtxQ.elements[j*numColumns+i]; } h2=f/(h+h); for (j=0; j<=i-1; j++) { f=mtxQ.elements[i*numColumns+j]; g=dblC[j]-h2*f; dblC[j]=g; for (k=0; k<=j; k++) { u=j*numColumns+k; mtxQ.elements[u]=mtxQ.elements[u]-f*dblC[k]-g*mtxQ.elements[i*numColumns+k]; } } dblB[i]=h; } } for (i=0; i<=numColumns-2; i++) dblC[i]=dblC[i+1]; dblC[numColumns-1]=0.0; dblB[0]=0.0; for (i=0; i<=numColumns-1; i++) { if ((dblB[i]!=(double)0.0) && (i-1>=0)) { for (j=0; j<=i-1; j++) { g=0.0; for (k=0; k<=i-1; k++) g=g+mtxQ.elements[i*numColumns+k]*mtxQ.elements[k*numColumns+j]; for (k=0; k<=i-1; k++) { u=k*numColumns+j; mtxQ.elements[u]=mtxQ.elements[u]-g*mtxQ.elements[k*numColumns+i]; } } } u=i*numColumns+i; dblB[i]=mtxQ.elements[u]; mtxQ.elements[u]=1.0; if (i-1>=0) { for (j=0; j<=i-1; j++) { mtxQ.elements[i*numColumns+j]=0.0; mtxQ.elements[j*numColumns+i]=0.0; } } } // ����Գ����ԽǾ��� for (i=0; i<numColumns; ++i) { for (j=0; j<numColumns; ++j) { mtxT.SetElement(i, j, 0); k = i - j; if (k == 0) mtxT.SetElement(i, j, dblB[j]); else if (k == 1) mtxT.SetElement(i, j, dblC[j]); else if (k == -1) mtxT.SetElement(i, j, dblC[i]); } } return true; }
/** * ������������ֵ�ֽⷨ���ֽ�ɹ���ԭ����Խ���Ԫ�ؾ��Ǿ��������ֵ * * @param mtxAP - ����ԭ����Ĺ�������� * @param mtxU - ���طֽ���U���� * @param mtxV - ���طֽ���V���� * @param eps - ���㾫�� * @return bool�ͣ�����Ƿ�ɹ� */ public bool InvertUV(Matrix mtxAP, Matrix mtxU, Matrix mtxV, double eps) { int i,j,k,l,t,p,q,f; // ��������ֵ�ֽ� if (! SplitUV(mtxU, mtxV, eps)) return false; int m = numRows; int n = numColumns; // ��ʼ����������� if (! mtxAP.Init(n, m)) return false; // ������������ j=n; if (m<n) j=m; j=j-1; k=0; while ((k<=j) && (elements[k*n+k]!=0.0)) k=k+1; k=k-1; for (i=0; i<=n-1; i++) { for (j=0; j<=m-1; j++) { t=i*m+j; mtxAP.elements[t]=0.0; for (l=0; l<=k; l++) { f=l*n+i; p=j*m+l; q=l*n+l; mtxAP.elements[t]=mtxAP.elements[t]+mtxV.elements[f]*mtxU.elements[p]/elements[q]; } } } return true; }
/** * ��ʵϵ����������ȫ������QR���� * * @param n - ����ʽ���̵Ĵ��� * @param dblCoef - һά���飬����Ϊn+1�������ݴ������δ��n�ζ���ʽ���̵� * n+1��ϵ�� * @param xr - һά���飬����Ϊn������n������ʵ�� * @param xi - һά���飬����Ϊn������n�������鲿 * @param nMaxIt - �������� * @param eps - ���ȿ��Ʋ��� * @return bool �ͣ�����Ƿ�ɹ� */ public bool GetRootQr(int n, double[] dblCoef, double[] xr, double[] xi, int nMaxIt, double eps) { // ��ʼ������ Matrix mtxQ = new Matrix(); mtxQ.Init(n, n); double[] q = mtxQ.GetData(); // ������겮����� for (int j=0; j<=n-1; j++) q[j]=-dblCoef[n-j-1]/dblCoef[n]; for (int j=n; j<=n*n-1; j++) q[j]=0.0; for (int i=0; i<=n-2; i++) q[(i+1)*n+i]=1.0; // ����겮����������ֵ��������������Ϊ���̵Ľ� if (mtxQ.ComputeEvHBerg(xr, xi, nMaxIt, eps)) return true; return false; }