// TP D'INFORMATIQUE : ANALYSE EN COMPOSANTES PRINCIPALES
//
// pour exécuter ce script sous scilab, 2 solutions :
// 1 --> exec /chemin/acp.sce 
// 2 dans l'éditeur, le menu >Fichier>Éxécuter et sélectionner votre fichier en .sce
// fonctions utilisées en préalable :

function cov=covariance(A)
  // vecteur (1,p) des moyennes des colonnes (=variables)
  moyenne = mean(A,"r");			
  // nombre de lignes dans la matrice A = nbre d'individus
  n = size(A,"r")				
  // matrice recentrée 
  Acent = A - ones(n,1)*moyenne; 	
  // matrice de covariance (Remarque: on a divisé par n-1 et non par n)
  cov=(Acent'*Acent)/(n-1);			
endfunction;

function c=correlation(A)
  cov=covariance(A);
  // vecteur contenant l'inverse des écarts-types
  ectinv=(1)./sqrt(diag(cov));	
  // matrice des corrélations
  c=diag(ectinv)*cov*diag(ectinv); 
endfunction;

function [c]=val_prop(A); 
//renvoie les valeurs propres ordonnées de manière décroissante
  [Diag,Base]=bdiag(A);	// diagonalisation	
  // classement décroissant des valeurs propres
  c=gsort(diag(Diag));                		
endfunction;

function c=vect_prop(A); 
// renvoie les vecteurs propres de A 
// classés par valeurs propres corresp décroissantes
  [Diag,Base]=bdiag(A);
  // diagonalisation
  if Base(:,1)==-abs(Base(:,1)) then Base=-1*Base; end; 
  // afin que les coef du 1er vect prop ne soient pas tous < 0.
  [Valpr,k]=gsort(diag(Diag));
  // classement décroissant des valeurs propres
  c = Base(:,k);
endfunction;

function c=acp_indiv(A);	
//Coordonnées des projetés des individus 
// dans la base des vecteurs propres
  mat_cor=correlation(A);
  X=centrer_reduire(A);
  VectP=vect_prop(mat_cor);
  // les vecteurs propres 
  c = X*VectP;
  // nouvelles coordonnees 
endfunction;

function c=centrer_reduire(A) 
// permet de centrer et de réduire la matrice A
  moyenne = mean(A,"r");         
  //vecteur (1,d) des moyennes des colonnes(=variables)
  cov=covariance(A);
  n = size(A,"r");             			
  //nombre de lignes dans la matrice A=nbre d'individus
  Acent = A - ones(n,1)*moyenne; 			
  // A centre
  c=Acent*(diag((1)./sqrt(diag(cov)))); 
endfunction;

function c=acp_var(A);	
//Coordonnées des variables dans le cercle des correlations
  mat_cor=correlation(A);
  X=centrer_reduire(A);
  VectP=vect_prop(mat_cor); 	
  // les vecteurs propres 
  ValP=val_prop(mat_cor); 		
  // les valeurs propres
  c = VectP*diag(sqrt(ValP));  		
endfunction;

// Matrice des données :

//M=[-1 1 0 ; 0 0 -1 ; 0 0 1 ; 1 -1 0]
//poids, taille, mois de naissance 
//M=[160 64 4 ; 170 66 8 ; 180 84 9 ; 190 86 3]
//isolants
//M=[55 25 14 16 ; 25 36 18 20 ; 90 25 30 15 ; 18 35 28 20 ; 18 42 34 20 ; 70 21 36 18 ; 25 32 41 20 ; 35 25 49 20 ; 150 18 50 13 ; 130 19 54 15 ; 35 26 106 20]
//eaux minérales
M=[78 357 24 4.5 10 1 5 7.2 ; 190 1300 85 44 38 10 165 6 ; 486 403 84 10 1187 3.2 9.1 7.2 ; 555 403 110 11 1479 4 14 7.2 ; 90 4368 11 322 174 132 1708 6.6 ; 202 402 43 8 336 2 4.7 7.5 ; 11.5 71 8 13.5 8.1 6.2 11.6 6.95 ; 103 2989 10 235 138 66 1172 6.8 ; 253 820 11 4 25 3 7 6]


m=centrer_reduire(M) 

// Matrice des corrélations :

r=correlation(m)
val_prop(r)
vect_prop(r)
acp_indiv(m)
acp_var(m)