Giáo trình C - Chương 10: Giải hệ phương trình đại số tuyến tính
Giả sử ta có một hệ ph-ơng trình dạng số phức dạng AX = B trong đó A = C + jD , B
= E +jF và X = Y + jZ . Ta viết lại ph-ơng trình d-ới dạng :
(C + jD)(Y + jZ) = (E +jF) Nhân biểu thức về trái và cân bằng phần thựcvới phần thực và phần ảo với phần ảo ta
nhận đ-ợc hệ mới :
+ F = CZ DY
E = DZ - CY
Nh-vậy chúng ta nhận đ-ợc một hệ gồm 2n ph-ơng trình số thực . Giảihệ này và kết hợp
các phần thực à phần ảo ta nhận đ-ợc nghiệm của hệ ph-ơng trình ban đầu .
1x
06.101.02.12.03.1x
2.101.001.02.1x
1
3
1
2
1
1
1
2
2
2
3
2
1 2 01 106 01 0 948 0 9992
1 3 0 2 0 9992 01 0 948 100536
1 4 0 2 0 9992 0 2 100536 0 999098
x
x
x
= − − =
= − − =
= − − =
⎧
⎨
⎪⎪⎪
⎩
⎪⎪⎪
ì ì
ì ì
ì ì
, . . . . .
, . . . . .
, . . . . .
và cứ thế tiếp tục . Ch−ơng trình mô tả thuật toán Gauss - Seidel nh− sau :
170
Ch−ơng trình 10-8
#include
#include
#include
#include
#include
#define max 6
void main()
{
float b[max],x[max];
float a[max][max];
int i,j,k,n,dem,t1;
float t,s,d,w,epsi;
char tl;
clrscr();
printf("Cho so an so n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a : \n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
printf("\n");
t1=1;
flushall();
while (t1)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
171
scanf("%f",&a[i][j]);
flushall();
}
if (toupper(tl)=='K')
t1=0;
}
printf("Ma tran a\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran b : \n");
for (i=1;i<=n;i++)
{
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
printf("\n");
printf("Ma tran b");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %10.5f\n",i,b[i]);
printf("\n");
t1=1;
flushall();
while (t1)
{
printf("Co sua ma tran b khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("b[%d] = ",i);
scanf("%f",&b[i]);
flushall();
}
if (toupper(tl)=='K')
t1=0;
}
printf("\n");
printf("Ma tran b");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %10.5f\n",i,b[i]);
printf("\n");
172
printf("Cho so lan lap k : ");
scanf("%d",&k);
printf("\n");
w=1;
epsi=1e-8;
for (i=1;i<=n;i++)
x[i]=0.0;
dem = 0;
do
{
dem=dem+1;
for (i=1;i<=n;i++)
{
s=0.0;
for (j=1;j<=n;j++)
s=s+a[i][j]*x[j];
d=x[i];
x[i]=(1-w)*d+w*(-s+a[i][i]*d+b[i])/a[i][i];
t=fabs(d-x[i]);
}
}
while ((demepsi*fabs(x[n])));
if (t<epsi*fabs(x[n]))
{
printf("Nghiem sau %d lan lap la :\n",dem);
for (i=1;i<=n;i++)
printf("x[%d] = %12.8f\n",i,x[i]);
}
else
{
printf("Khong dat do chinh xac sau %d lan lap\n",k);
printf("Nghiem cua lan lap cuoi cung la : \n");
for (i=1;i<=n;i++)
printf("x[%d] = %12.8f\n",i,x[i]);
}
getch();
}
Đ7. Ph−ơng pháp Cramer
Một tr−ờng hợp riêng của hệ ph−ơng trình , trong đó số ph−ơng trình bằng số ẩn , nghĩa
là hệ có dạng :
11 1 12 2 13 3 1n 1
21 1 22 2 23 3 2 2
1 1 2 2 3 3
a x a x a x a x b
a x a x a x a x b
a x a x a x a x b
n
n n
n n n nn n n
+ + + + =
+ + + + =
+ + + + =
⎧
⎨
⎪⎪⎪
⎩
⎪⎪⎪
...
...
...
......
trong đó A= (aij) là một ma trận không suy biến . một hệ ph−ơng trình nh− vậy có tên là hệ
thống Cramer
173
Định lí Crame : Hệ thống Crame có nghiệm duy nhất đ−ợc cho bởi công thức :
i
i
x
A
A
n= =
( )
(i ,..., )1
trong đó A(i) là ma trận nhận đ−ợc từ A bằng cách thay cột thứ i bởi cột B=[ b1 ,...,bn]T
Nh− vậy để giải hệ bằng ph−ơng pháp Cramer chúng ta lần l−ợt tính các định thức
của ma trận và ma trận thay thế rồi tìm nghiệm theo công thức Cramer. Ch−ơng trình sau mô
tả thuật toán này,
Ch−ơng trình 10-.9
// Cramer;
#include
#include
#include
#define max 50
void main()
{
float r[max][max],a[max][max];
float b[max],x[max];
float delta[max];
int i,j,k,l,t,n,ok1,ok2,t1;
float c,d;
char tl;
clrscr();
printf("Cho so an cua phuong trinh n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a : \n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
printf("\n");
t1=1;
flushall();
while (t1)
{
174
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[",i,",",j,"] = ");
scanf("%f",&a[i][j]);
flushall();
}
if (toupper(tl)=='K')
t1=0;
}
printf("Ma tran a \n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran b : \n");
for (i=1;i<=n;i++)
{
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
printf("\n");
printf("Ma tran b ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %10.5f\n",i,b[i]);
printf("\n");
t1=1;
flushall();
while (t1)
{
printf("Co sua ma tran b khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("b[%d] = ",i);
scanf("%f",&b[i]);
flushall();
}
175
if (toupper(tl)=='K')
t1=0;
}
printf("\n");
printf("Ma tran b\n");
printf("\n");
for (i=1;i<=n;i++)
printf("%10.5f",b[i]);
printf("\n");
//thay b vao tung cot cua a de tinh cac dinh thuc
for (k=0;k<=n;k++)
{
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)//thay cot b vao a
if (i==k)
r[j][i]=b[j];
else
r[j][i]=a[j][i];
//tinh dinh thuc
d=1.0;
i=1;
ok2=1;
while (ok2&&(i<=n))
{
if (r[i][i]==0.0)
{
ok1=1;
t=t+1;
while (ok1&&(t<=n))
if (r[t][i]!=0)
{
for (j=i;j<=n;j++)
{
c=r[i][j];
r[i][j]=r[t][j];
r[k][j]=c;
}
d=-d;
ok1=0;
}
else
t=t+1;
if (k>n)
{
printf("\n");
printf("** MA TRAN SUY BIEN **");
ok2=0;
d=0.0;
}
176
}
if (r[i][i]!=0)
{
c=r[i][i];
for (j=i+1;j<=n;j++)
r[i][j]=r[i][j]/c;
for (t=i+1;t<=n;t++)
{
c=r[t][i];
for (j=i+1;j<=n;j++)
r[t][j]=r[t][j]-r[i][j]*c;
}
}
i=i+1;
}
if (ok2)
for (i=1;i<=n;i++)
d=d*r[i][i];
delta[k]=d;
}
if (delta[0]==0.0)
printf("He da cho vo nghiem\n");
else
{
printf("\nNGHIEM CUA HE :\n");
printf("\n");
for (i=1;i<=n;i++)
{
x[i]=delta[i]/delta[0];
printf("x[%d] = %10.5f\n",i,x[i]);
}
}
getch();
}
Đ8. Hệ ph−ơng trình số phức
Giả sử ta có một hệ ph−ơng trình dạng số phức dạng AX = B trong đó A = C + jD , B
= E +jF và X = Y + jZ . Ta viết lại ph−ơng trình d−ới dạng :
(C + jD)(Y + jZ) = (E +jF)
Nhân biểu thức về trái và cân bằng phần thực với phần thực và phần ảo với phần ảo ta
nhận đ−ợc hệ mới :
⎩⎨
⎧ + F = CZ DY E =DZ - CY
Nh− vậy chúng ta nhận đ−ợc một hệ gồm 2n ph−ơng trình số thực . Giải hệ này và kết hợp
các phần thực à phần ảo ta nhận đ−ợc nghiệm của hệ ph−ơng trình ban đầu . Ch−ơng trình
giải hệ ph−ơng trình nh− vậy cho ở d−ới đây :
177
Ch−ơng trình 10-10
#include
#include
#include
#include
#include
#define max 20
void main()
{
int i,j,k,l,n,m;
float s,t,a[max][max],b[max][max],x[max];
clrscr();
printf("Cho so an so cua phuong trinh n = ");
scanf("%d",&n);
printf("Cho phan thuc cua cac he so,ke ca ve phai\n");
for (i=1;i<=n;i++)
for (j=1;j<=n+1;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Cho phan ao cua cac he so,ke ca ve phai\n");
for (i=1;i<=n;i++)
for (j=1;j<=n+1;j++)
{
printf("b[%d][%d] = ",i,j);
scanf("%f",&b[i][j]);
}
for (i=1;i<=n;i++)
a[i][2*n+1]=a[i][n+1];
for (i=n+1;i<=2*n;i++)
a[i][2*n+1]=b[i-n][n+1];
for (i=n+1;i<=2*n;i++)
for (j=1;j<=n;j++)
a[i][j]=b[i-n][j];
for (i=1;i<=n;i++)
for (j=n+1;j<=2*n;j++)
a[i][j]=-b[i][j-n];
for (i=n+1;i<=2*n;i++)
for (j=n+1;j<=2*n;j++)
a[i][j]=a[i-n][j-n];
m=2*n;
for (k=1;k<=m-1;k++)
{
s=0.0;
178
for (i=k;i<=m;i++)
{
t=fabs(a[i][k]);
if (s<=t)
{
s=t;
l=i;
}
}
for (j=k;j<=m+1;j++)
{
s=a[k][j];
a[k][j]=a[l][j];
a[l][j]=s;
}
if (fabs(a[k][k]/a[1][1])<=1e-08)
{
printf("Ma tran suy bien\n");
getch();
exit(1);
}
for (i=k+1;i<=m;i++)
{
s=a[i][k]/a[k][k];
a[i][k]=0.0;
for (j=k+1;j<=m+1;j++)
a[i][j]-=s*a[k][j];
}
}
x[m]=a[m][m+1]/a[m][m];
for (i=m-1;i>=1;i--)
{
s=a[i][m+1];
for (j=i+1;j<=m;j++)
s-=a[i][j]*x[j];
x[i]=s/a[i][i];
}
printf("\n");
printf("Nghiem phuc cua he\n");
for (i=1;i<=n;i++)
if (x[i+n]<0)
printf("%10.5f-%10.5fj\n",x[i],fabs(x[i+n]));
else
printf("%10.5f+%10.5fj\n",x[i],x[i+n]);
getch();
}
Dùng ch−ơng trình này giải hệ ph−ơng trình :
179
( ) ( ) ( ) ( )
( ) ( ) ( )
( ) ( ) ( )
( ) ( ) ( )
3 7 2 4 1 3 4 2 8 36
5 6 2 5 3 4 10
4 5 1 2 5 6 13 3
2 4 1 2 3 10 6
+ + − + + − + + = +
− + + + − + = +
+ + + + − − + = −
+ + − + − = − +
⎧
⎨
⎪⎪
⎩
⎪⎪
j x j y j z j r j
j x j z j r j
j x j y j z r j
j x j y j r j
Ta nhận đ−ợc các nghiệm x = 2 + 3j ; y = 1 - 2j ; z = -1 + 4j và r = 1- j
Ngoài các ph−ơng pháp nêu trên ta thấy rằng từ hệ ph−ơng trình AX = B ta có thể tìm
nghiệm X của hệ bằng cách viết lại ph−ơng trình d−ới dạng X = B/A =A-1B với A-1 là ma
trận nghịch đảo của A . Do vậy tr−ớc hết ta cần tìm A-1 và sau đó tính tích A-1B.
File đính kèm:
Giao_Trinh_C_Chuong10_CachgiaihePT.pdf

