next up previous contents index
suivant: Réduction de Hessenberg monter: La décomposition de Cholesky précédent: Le programme de factorisation   Table des matières   Index

Le programme optimisé de factorisation de Cholesky par identification

 
//A:=[[1,0,-1],[0,2,4],[-1,4,11]]
//A:=[[1,1,1],[1,2,4],[1,4,11]]
//A:=[[1,0,-2],[0,2,6],[0,2,11]]
//A:=[[1,-2,4],[-2,13,-11],[4,-11,21]]
//A:=[[-1,-2,4],[-2,13,-11],[4,-11,21]] (pas def pos)
//A:=[[24,66,13],[66,230,-11],[13,-11,210]]
choleski(A):={
  local j,n,l,k,CC,D,c2,s;
  n:=size(A);
  A:=1/2*(A+tran(A));
  CC:=makemat(0,n,n);
  D:=makemat(0,n,n);
  for (j:=0;j<n;j++) {
    s:=0;
    for (k:=0;k<j;k++) {
      s:=s+(CC[j,k])^2/CC[k,k];
    }
    c2:=normal(A[j,j]-s); 
    //if (c2<=0) {return "pas definie positive ";}
    CC[j,j]:=c2;
    D[j,j]:=normal(1/sqrt(c2));
    for (l:=j+1;l<n;l++) {
      s:=0;
      for (k:=0;k<j;k++) {
	s:=s+CC[l,k]*CC[j,k]/CC[k,k];
      }
      CC[l,j]:=normal(A[l,j]-s);
    }
  }
return normal(CC*D);
}
Avec cette méthode, pour obtenir les coefficients diagonaux ont utilise la même relation de récurrence que pour les autres coefficients. De plus on peut effectuer directement et facilement la multiplication par D sans avoir à définir D en multipliant les colonnes de CC par la même valeur 1/sqrt(c) avec c=CC[k,k]...
donc on écrit :
 
choleskii(A):={
  local j,n,l,k,CC,c,s;
  n:=size(A);
  A:=1/2*(A+tran(A));
  CC:=makemat(0,n,n);
  for (j:=0;j<n;j:=j+1) { 
     for (l:=j;l<n;l++) {
      s:=0;
      for (k:=0;k<j;k++) {
	//if (CC[k,k]<=0) {return "pas definie positive ";}
	if (CC[k,k]==0) {return "pas definie";}
	s:=s+CC[l,k]*CC[j,k]/CC[k,k];
      }
      CC[l,j]:=A[l,j]-s;
    }
  } 
  for (k:=0;k<n;k++) {
    c:=CC[k,k];
    for (j:=k;j<n;j++) {
      CC[j,k]:=normal(CC[j,k]/sqrt(c));
    }
  }
  return CC;
}
Avec la traduction pour avoir une fonction interne à Xcas :
 
cholesky(_args)={
gen args=(_args+mtran(_args))/2;
matrice &A=*args._VECTptr;
int n=A.size(),j,k,l;
vector<vecteur> C(n,vecteur(n)), D(n,vecteur(n));
for (j=0;j<n;j++) {
gen s;
for (k=0;k<j;k++)
s=s+pow(C[j][k],2)/C[k][k];
gen c2=A[j][j]-s;
if (is_strictly_positive(-c2)) 
setsizeerr("Not a positive define matrice");
C[j][j]=c2;
D[j][j]=normal(1/sqrt(c2));
for (l=j+1;l<n;l++) {
s=0;
for (k=0;k<j;k++) 
s=s+C[l][k]*C[j][k]/C[k][k];
C[l][j]=A[l][j]-s;
}
}
matrice Cmat,Dmat;
vector_of_vecteur2matrice(C,Cmat);
vector_of_vecteur2matrice(D,Dmat);
return Cmat*Dmat;
}


Documentation de giac écrite par Renée De Graeve