1. Умова задачі:
-
Розв'язати часткову проблему власних значень: знайти найбільше та найменше власні числа та відповідні їм власні вектори степеневим методом або методом скалярних добутків.
-
Розвязати повну проблему заданим методом.
А = |
|
Реалізувати: метод Крилова
2. Аналіз:
Розв'язати часткову проблему власних значень: знайти найбільше та найменше власні числа та відповідні їм власні вектори степеневим методом.
Найбільше власне число
MAX vlasne chyslo -> vector
9.48746
0.599225 0.235749 0.607512 0.46506
Вектор нев'язки:
Nevyzka:
3.35846e-06 6.1603e-08 -2.28712e-06 -1.3709e-06
Найменше власне число
MIN vlasne chyslo -> vector
2.48494
0.162471 -0.824281 0.421192 -0.341704
Вектор нев'язки:
Nevyzka:
-2.3894e-07 3.40265e-06 2.71955e-06 -4.96957e-06
3.Результат роботи:
Файл Input.txt:
7.14 1 1.07 1.12
1 3.28 1.3 0.16
1.07 1.3 6.32 2.1
1.12 0.16 2.1 5.22
Файл stepen.txt:
7.14 1 1.07 1.12
1 3.28 1.3 0.16
1.07 1.3 6.32 2.1
1.12 0.16 2.1 5.22
MAX vlasne chyslo -> vector
9.48746
0.599225 0.235749 0.607512 0.46506
MIN vlasne chyslo -> vector
2.48494
0.162471 -0.824281 0.421192 -0.341704
Nevyzka:
3.35846e-06 6.1603e-08 -2.28712e-06 -1.3709e-06
-2.3894e-07 3.40265e-06 2.71955e-06 -4.96957e-06
Файл Krilov.txt:
System's matrix:
1 7.14 54.3789 437.774 | -3690.85
0 1 11.9902 119.777 | -1148.93
0 1.07 18.0542 222.001 | -2416.85
0 1.12 16.2502 185.563 | -1944.31
Characteristic equation:
p^4+9.48746*p^3+ 5.9725*p^2+ 4.0151*p^1+ 2.48494
vlasne chyslo -> vector
2.48494
-0.986427 5.00452 -2.55724 2.07464
vlasne chyslo -> vector
4.0151
0.0214015 -0.304758 -0.243572 0.445093
vlasne chyslo -> vector
5.9725
-14.7144 -0.269917 10.0205 6.00629
vlasne chyslo -> vector
9.48746
48.3647 19.0278 49.0336 37.536
Nevyzka:
4.34474e-06 1.25427e-13 5.52966e-13 2.37295e-13
1.68121e-06 3.0278e-13 7.75524e-13 4.42541e-13
-4.19807e-06 1.19015e-14 2.58415e-13 -6.50521e-15
4.42459e-06 2.58266e-14 2.64233e-13 -5.2458e-14
4.Висновок:
Отримані значення найбільшого і найменшого власних чисел метода Крилова та степеневого метода співпали, а відповідні їм вектори є колінеарними, отже, розрахунки були проведені правильно і вони відповідають точності 10-5
6. Текст програми
#include<math.h>
#include<conio.h>
#include<stdio.h>
#include<iostream.h>
#include<fstream.h>
#include<stdlib.h>
# define N2 4
# define eps 0.00001
int KRULOV(double**,int,double*,double**);
void MetodGausa(double ,int , double );
double Bisec(double a, double b, double (*f)(double, double*, int) , double q[N2+1], int n)
{
double pol,rez;
if(fabs(f(a,q,n))<eps) rez=a;
else
{
if(fabs(f(b,q,n))<eps) rez=b;
else
while(1)
{
pol=(a+b)/2;
if(f(a,q,n)*f(pol,q,n)>0) a=pol;
else b=pol;
if(fabs(f(pol,q,n))<eps)
{rez=pol;
break;}
}
}
return(rez);
}
double func(double x, double a[N2+1], int n)
{
double rez;
int i;
rez=0;
for(i=0; i<n; i++)
rez+=a[i]*pow(x,i);
return(rez);
}
void MetodGausa(double a[][N2+1],int n, double x[N2])
{
int l,k,z,i,j;
double c,sum;
for (k=0; k<n-1; k++)
{
l=k;
for (i=k+1; i<n; i++)
if (abs(a[i][k])>abs(a[l][k])) l=k;
for (z=0; z<n+1; z++)
{
c=a[l][z];
a[l][z]=a[k][z];
a[k][z]=c;
}
for (i=k+1; i<n; i++)
{
c=a[i][k];
for ( j=0; j<n+1; j++)
a[i][j]=-(c/a[k][k])*a[k][j]+a[i][j];
}
}
for (i=n-1; i>=0; i--)
for (j=n; j<n+1; j++)
{
sum=0;
for (k=i+1; k<n; k++)
sum=sum+a[i][k]*a[k][j];
a[i][j]=(a[i][j]-sum)/a [i][i];
}
for(i=0;i<n;i++)
x[i]=a[i][n];
}
int FindLambda(double P[N2], double *L1, int n)
{
double Q[N2+1],L[N2];
double a1,b1,a,b,delta;
double fa; //znachenie funczii v tochke a
double fb; //znachenie funczii v tochke b
int k; //kol-vo reshenij polinoma
int i;
for(i=0; i<n; i++)
L[i]=1;
for(i=0; i<n; i++)
Q[i]=P[i];
Q[n]=1;
//a=max(fabs(Qi)) 0<=i<=n-1
a=0;
for(i=0; i<n; i++)
if (fabs(Q[i])>a) a=fabs(Q[i]);
//b=max(fabs(Qi)) 1<=i<=n
b=0;
for(i=1; i<n+1; i++)
if (fabs(Q[i])>b) b=fabs(Q[i]);
// [-b1;-a1] i [a1;b1]
a1=fabs(Q[0])/(fabs(Q[0])+b);
b1=(fabs(Q[n])+a)/fabs(Q[n]);
delta=(b1-a1)/1000;
k=0;
//cout<<" "<<a<<" "<<b;
//nahojdenie kornej na intervale [-b1; -a1]
a=-b1;
do
{
b=a+delta;
fa=func(a,Q,n+1);
fb=func(b,Q,n+1);
if ((fa*fb)<0 || fabs(fa*fb)<0+eps)
{ L[k]=Bisec(a,b,func,Q,n+1);
k++;}
a+=delta;
}
while (k<n && a<-a1);
//nahojdenie kornej na intervale [a1; b1]
a=a1;
do
{
b=a+delta;
fa=func(a,Q,n+1);
fb=func(b,Q,n+1);
if ((fa*fb)<0 || fabs(fa*fb)<0+eps)
{ L[k]=Bisec(a,b,func,Q,n+1);
k++;}
a+=delta;
}
while (k<n && a<b1);
for(i=0; i<k; i++)
L1[i]=L[i];
return(k);
} //end FindLambda
int KRULOV (double A[][N2], int n, double *Lam, double Vec1[][N2])
{
double B[N2+1][N2]; //vectora B0,B1,..,Bn
double tmpB[N2][N2+1]; //vectora B0..Bn obrazyjut matrizy
//dlya reshenija systemu metodom Gaysa
double p[N2+1]; //koef v vide x^3+p3*x^2+p2*x+p1
double Vec[N2][N2]; //sobsvennuj vector Vi=[Vo..V(n-1)]
//dlya sobstvennogo chisla Li, i=0..n-1
double Koef[N2], sum;
int i,j,k,m;
B[0][0]=1; //proizvolnuj vector B0={1 0 0..0}
for (j=1; j<n; j++)
B[0][j]=0;
for (i=1; i<n+1; i++) //opredelenie vectorov B: Bi=AB(i-1)
{
for (j=0; j<n; j++)
{
double sum;
sum=0;
for(k=0; k<n; k++)
sum=sum+A[j][k]*B[i-1][k];
B[i][j]=sum;
//cout<<B[i][j]<<" ";
}
//cout<<endl;
}
// cout<<endl;
//poluchaem vectornoe ravenstvo Bn=p1Bn-1 + p2Bn-2 +...+ pnB0
//bydem reshat ety systemy metodom Gaysa; rezyltat - vector p
for (i=0; i<n; i++) //obrazyem matrizy tmpB
{
for(j=0; j<n; j++)
tmpB[i][j]=B[j][i];
tmpB[i][n]=-B[n][i];
}
ofstream f4("Krilov.txt");
f4<<"System's matrix:"<<endl;
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
f4<<tmpB[i][j]<<" ";
f4<<"| "<<tmpB[i][n];
f4<<endl;
}
f4<<endl;
MetodGausa( tmpB,n,p); //metodom Gaysa opredelili vector p
m=FindLambda(p,Lam,n); //nahodim sobstvennue chisla
f4<<"Characteristic equation:"<<endl;
f4<<"p^4+"<<Lam[3]<<"*p^3+ "<<Lam[2]<<"*p^2+ "<<Lam[1]<<"*p^1+ "<<Lam[0] ;
f4<<endl<<endl;
///////opredelenie sobstvennuh vectorov///////////
for(i=0; i<m; i++) //inizializazija
for(j=0; j<n; j++)
Vec1[i][j]=0;
for(k=0; k<m; k++) //opredelyaem sobstvennuj vector dlya k-oj Lambdu
{
for (i=0; i<n; i++)
Koef[i]=1;
//Koef[n-1]=1;
for(i=n-2; i>=0; i--)
Koef[i]=Lam[k]*Koef[i+1]+p[i+1]*Koef[n-1];
for(i=0; i<n; i++)
{
sum=0;
for (j=0; j<n; j++)
sum+=B[j][i]*Koef[j];
Vec1[k][i]=sum;
}
} //konez zukla po k
for(i=0; i<m; i++)
{
f4<<endl<<"vlasne chyslo -> vector";
f4<<endl<<Lam[i]<<endl;
for (j=0; j<n; j++)
f4<< Vec1[i][j] <<" ";
}
//vector nevjazku
double nev[N2][N2];
double x[N2][N2];
for(k=0; k<m; k++)
for(i=0; i<n; i++)
{
nev[k][i]=0;
x[k][i]=0;
for(j=0; j<n; j++)
nev[k][i]=nev[k][i]+A[i][j]*Vec1[k][j];
x[k][i]=nev[k][i]-Lam[k]*Vec1[k][i];
}
f4<<endl<<endl<<"Nevyzka: "<<endl;
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
f4<<x[i][j]<<" ";
f4<<endl<<endl;
}
f4<<endl;
f4.close();
return(m);
} //konez prozedure KRULOV
double norm(double* x,int n)
{
double nor=0;
for (int i=0; i<n; i++)
nor+=x[i]*x[i];
return sqrt(nor);
}
double step(double A[][N2], int n,double* Vec1)
{
double x0[N2],x1[N2],y[N2],nev1[N2],nev2[N2],nev3[N2];
double Lam1=0;
int i;
x0[0]=1;
for (int j=1; j<n; j++)
x0[j]=0;
do {
for (int i=0; i<n; i++) {
y[i]=0;
for (int j=0; j<n; j++) {
y[i]+=A[i][j]*x0[j];
}
}
for (i=0; i<n; i++) {
Lam1=norm(y,n);
x1[i]=y[i]/Lam1;
nev2[i]=y[i]-Lam1*x0[i];
nev3[i]=nev2[i]-2*y[i];
nev1[i]=x0[i]-x1[i];
x0[i]=x1[i];
}
}
while ( (norm(nev2,n)>eps) && (norm(nev3,n)>eps) );
if (norm(nev2,n)>eps) Lam1=-Lam1;
for (int i=0; i<n; i++) Vec1[i]=x0[i];
return Lam1;
}
void STEPEN(double A[][N2], int n, double Lm1,double Lm2, double Vec1[],double Vec2[])
{
double Lamd=0;
int i;
ofstream f5("stepen.txt");
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
f5<<A[i][j]<<" ";
f5<<endl;
}
f5<<endl;
Lm1=step(A,n,Vec1);
double B[4][4];
for(i=0; i<n; i++)
for(int j=0; j<n; j++)
B[i][j]=A[i][j];
for (i=0; i<n; i++)
B[i][i]-=Lm1;
Lamd=step(B,n,Vec2);
Lm2=Lamd+Lm1;
f5<<endl<<"MAX vlasne chyslo -> vector";
f5<<endl<<Lm1<<endl;
for (i=0; i<n; i++)
f5<< Vec1[i] <<" ";
f5<< endl;
f5<<endl<<"MIN vlasne chyslo -> vector";
f5<<endl<<Lm2<<endl;
for (i=0; i<n; i++)
f5<< Vec2[i] <<" ";
f5<< endl;
//vector nevjazku
double x1[N2],x2[N2];
for (i=0; i<n; i++)
{
double nev1[N2];
double nev2[N2];
nev1[i]=0;
nev2[i]=0;
for (int j=0; j<n; j++) {
nev1[i]+=A[i][j]*Vec1[j];
nev2[i]+=A[i][j]*Vec2[j];
}
x1[i]=Lm1*Vec1[i]-nev1[i];
x2[i]=Lm2*Vec2[i]-nev2[i];
}
f5<<endl<<endl<<"Nevyzka: "<<endl;
for(i=0; i<n; i++)
f5<<x1[i]<<" ";
f5<<endl;
for(i=0; i<n; i++)
f5<<x2[i]<<" ";
f5<<endl;
f5.close();
}
int main()
{
double A[N2][N2];
double ljamda[N2],own[N2][N2];
double ljam1,ljam2;
double V1[N2],V2[N2];
const n=4;
clrscr();
ifstream f1("input.txt");
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
f1>>A[i][j];
f1.close();
KRULOV(A,n,ljamda,own);
STEPEN(A,n,ljam1,ljam2,V1,V2);
printf("Infoermation in file 'Krilov.txt'");
getch();
return 0;
}