طريقة هوزهولدر طريقة هوزهولدر
قيم الموضوع
(1 تصويت)


 
  

 


مصطلحات


العربية: طريقة التفكيك LU
الإنجليزية: Householder Method
الفرنسية: Méthode de Householder


المبدأ

  • يساعد الخوارزم على الحصول على نظمة مثلثية مكافئة والى حل للنظمة.

  • لتكن  A(1) = A  و b(1) = b.

  • نضرب (في اليسار) الجدول(A(1) | b(1))  في مصفوفة متعامدة ومتماثلة على الشكل التالي :

H(1) = I - 2u.uT نختار u بحيث تكون المصفوفةH(1)A(1)   كما يلي :

   و   

النظمة الأصلية مكافئة للنظمة الجديدة A(2)x = b(2)

  • نضرب بعد ذلك(A(2) | b(2)) في المصفوفةH(2)  (متعامدة و متماثلة، تم إنشاءها كالمصفوفة H(1)) بطريقة تنعدم فيها العناصر ما فوق القطر للعمود الثاني، وهكذا حتى تصبح المصفوفة مثلثية علوية.

  • ونحل بعد ذلك النظمة المثلثية.


الخوارزم

 المرحلة 1التحويل المثلثي للمصفوفة A، أي تحويل النظمة إلى نظمة مكافئة ذات مصفوفة مثلثية علوية.

A(1) = A, b(1) = b.

 

المرحلة 2: حل النظمة المثلثية A(n) x = b(n)


مثال

لنحل النظمة  Ax=b  بحيث:

  و 

الحلول الصحيحة هي :  x1 = 32/7,  x2 = 47/14,  x3 = 16/7,  x4 = -18/7.

 

حل يدوي ( باستعمال الكسر و الجذور)

 المرحلة 1التحويل المثلثي لـ A، تحويل العمود الأول

= -2
= -2 =(-2- 8) = 372 + 16
= 8 + 2


         = (8 + 2)(-4) + (4)(2) + (-16)(6) + (6)(10) = -60 - 8

         = (8 + 2)(3) + (4)(-6) + (-16)(-2) + (6)(-15) = -58 + 6

         = (8 + 2)(7) + (4)(4) + (-16)(-15) + (6)(10) = 372 + 14

         = (8 + 2)(12) + (4)(1) + (-16)(-19) + (6)(1) = 410 + 24










البرمجة

#include <math.h>
#include <conio.h>
#define NMAX 5
#define NMAX1 6
int sl_householder_aff(double a[NMAX][NMAX],double b[NMAX],int n);
main() { double a[NMAX][NMAX]; double b[NMAX]; int i,j,n; int err; n=4; clrscr(); printf("Méthode de Householder\n"); a[1][1]=8;a[1][2]=-4;a[1][3]=3;a[1][4]=7;b[1]=12; a[2][1]=4;a[2][2]=2;a[2][3]=-6;a[2][4]=4;b[2]=1; a[3][1]=-16;a[3][2]=6;a[3][3]=-2;a[3][4]=-15;b[3]=-19; a[4][1]=6;a[4][2]=10;a[4][3]=-15;a[4][4]=10;b[4]=1; printf(" A(1) b(1)\n"); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) printf("%12.6e ",a[i][j]); printf(" I %12.6e",b[i]); printf("\n"); } err=sl_householder_aff(a,b,n); if(err==1) { printf("Solution :\n"); for(j=1;j<=n;j++) printf("x%d = %22.16e\n",j,b[j]); } else printf("Erreur, matrice singulière\n"); }

نتائج البرنامج

في كل مرحلة يظهر البرنامج ما يلي:

  • المصفوفة A(k)

  • العنصر الثاني b(k)

			 A(1)                               b(1)
 8.00000e+00 -4.00000e+00  3.00000e+00  7.00000e+00  I   1.20000e+01
 4.00000e+00  2.00000e+00 -6.00000e+00  4.00000e+00  I   1.00000e+00
-1.60000e+01  6.00000e+00 -2.00000e+00 -1.50000e+01  I  -1.90000e+01
 6.00000e+00  1.00000e+01 -1.50000e+01  1.00000e+01  I   1.00000e+00
			 A(2)                               b(2)
-1.92873e+01  3.11086e+00  3.00716e+00 -1.92873e+01  I  -2.12575e+01
 0.00000e+00  3.04237e+00 -5.99895e+00  1.46588e-01  I  -3.87516e+00
 0.00000e+00  1.83053e+00 -2.00420e+00  4.13647e-01  I   5.00651e-01
 0.00000e+00  1.15636e+01 -1.49984e+01  4.21988e+00  I  -6.31274e+00
			 A(3)                               b(3)
-1.92873e+01  3.11086e+00  3.00716e+00 -1.92873e+01  I  -2.12575e+01
 0.00000e+00 -1.20964e+01  1.61499e+01 -4.13347e+00  I   6.93356e+00
 0.00000e+00  0.00000e+00  6.73959e-01 -1.03883e-01  I   1.80760e+00
 0.00000e+00  0.00000e+00  1.91966e+00  9.50616e-01  I   1.94336e+00
			 A(4)                               b(4)
-1.92873e+01  3.11086e+00  3.00716e+00 -1.92873e+01  I  -2.12575e+01
 0.00000e+00 -1.20964e+01  1.61499e+01 -4.13347e+00  I   6.93356e+00
 0.00000e+00  0.00000e+00 -2.03453e+00 -8.62532e-01  I  -2.43243e+00
 0.00000e+00  0.00000e+00  0.00000e+00  4.12918e-01  I  -1.06179e+00
Solution :
x1 =  4.571428571428572e+00
x2 =  3.357142857142857e+00
x3 =  2.285714285714285e+00
x4 = -2.571428571428572e+00

 الدالة الرئيسية sl_householder_aff

  • معايير الدالة

a : المصفوفة
b : العنصر الثاني
n : درجة المصفوفة

القيمة الرجعية

ترجع القيمة 1 عندما تكون المصفوفة مقلوبة رقميا والقيمة 0 إذا كان عكس ذلك.
إذا كانت قيمة الرجوع هي 1 فسيكون الحل في الجدول b.
خلال كل كرة يتم إظهار المصفوفة Ak والعنصر الثاني bk.
تساوي الثابتة NMAX البعد القصوي للمصفوفة زائد 1، وتساوي الثابتة N2MAX القيمة NMAX+1

int sl_householder_aff(double a[NMAX][NMAX],double b[NMAX],int n)
{
int i,j,k,err,sgn;
double s,nu;
double aa[NMAX][NMAX];
double bb[NMAX],v[NMAX];
double gam[NMAX1];
err=1;
k=1;
while(err==1 && k<n)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
aa[i][j]=0;
v[i]=0;
}
s=0;
for(i=k;i<=n;i++)
s+=a[i][k]*a[i][k];
if(a[k][k]<0) sgn=-1; else sgn=1;
aa[k][k]=-sgn*sqrt(s);
v[k]=a[k][k]-aa[k][k];
nu=-aa[k][k]*v[k];
if (fabs(nu)<1e-15) err=0;
else
{
for(i=k+1;i<=n;i++)
v[i]=a[i][k];
for(j=k+1;j<=n;j++)
{
s=0;
for(i=k;i<=n;i++)
s+=v[i]*a[i][j];
gam[j]=s/nu;
s=0;
for(i=k;i<=n;i++)
s+=v[i]*b[i];
gam[n+1]=s/nu;
}
for(i=k;i<=n;i++)
{
for(j=k+1;j<=n;j++)
aa[i][j]=a[i][j]-gam[j]*v[i];
bb[i]=b[i]-gam[n+1]*v[i];
}
for(i=k;i<=n;i++)
{
for(j=k;j<=n;j++)
a[i][j]=aa[i][j];
b[i]=bb[i];
}
k++;
printf(" A(%d) b(%d)\n",k,k);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
printf("%12.6e ",a[i][j]);
printf(" I %12.6e",b[i]);
printf("\n");
}
}
}
if(fabs(a[n][n])<1e-15)err=0;
if(err==1)
{
b[n]=b[n]/a[n][n];
for(i=n-1;i>0;i--)
{
s=b[i];
for(j=i+1;j<=n;j++)
s-=a[i][j]*b[j];
b[i]=s/a[i][i];
}
}
return(err);
}
مقالات أخرى من نفس الفئة « طريقة تشوليسكي طريقة تفكيك QR »

أضف تعليقا


إصنعها يريد أن يتأكد أنك لست روبوتا، لذلك أحسب ما يلي:

كود امني
تحديث