Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа - Поиск собственных чисел.doc
Скачиваний:
15
Добавлен:
02.05.2014
Размер:
113.15 Кб
Скачать

1. Умова задачі:

  1. Розв'язати часткову проблему власних значень: знайти найбільше та найменше власні числа та відповідні їм власні вектори степеневим методом або методом скалярних добутків.

  2. Розвязати повну проблему заданим методом.

А =

Реалізувати: метод Крилова

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;

}

11