THESE CODES WERE DEVELOPED WITH MATLAB 3 SOME CALLS MAY HAVE TO BE ADAPTED TO LATER VERSIONS OF MATLAB. THANKS IN ADVANCE FOR YOUR INTEREST & FEEDBACK, P. COMON Please do not change the contents of these codes without renaming them and adding comments in header (date, nature, and author of corrections). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ================================================================================ function [F,delta]=aci(Y) % Comon, version 6 march 92 % English comments added in 1994 % [F,delta]=aci(Y) % Y is the observations matrix % This routine outputs a matrix F such that Y=F*Z, Z=pinv(F)*Y, % and components of Z are uncorrelated and approximately independent % F is Nxr, where r is the dimension Z; % Entries of delta are sorted in decreasing order; % Columns of F are of unit norm; % The entry of largest modulus in each column of F is positive real. % Initial and final values of contrast can be fprinted for checking. % REFERENCE: P.Comon, "Independent Component Analysis, a new concept?", % Signal Processing, Elsevier, vol.36, no 3, April 1994, 287-314. % [N,TT]=size(Y);T=max(N,TT);N=min(N,TT); if TT==N, Y=Y';[N,T]=size(Y);end; % Y est maintenant NxT avec N-1);t=t(j); %%%%% test et conditionnement if abs(t)<1/T, A=eye(2); %fprintf('pas de rotation plane pour cette paire\n'); else, A(1,1)=1/sqrt(1+t*t);A(2,2)=A(1,1);A(1,2)=t*A(1,1);A(2,1)=-A(1,2); end; %%%%% filtrage de la sortie S=A*e; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ================================================================================ function e=ecar2(A,B) % e=ecar2(A,B) % Comon, version 24 may 1991 % English comments added in 1994 % Measures the gap between two matrices, up to a Diag*Permutation: % Gap is null iff: % B=A*D*P, or B=A*P*D, or A=B*D*P, or A=B*P*D, % where D regular diagonal and P permutation [m,n]=size(A);[p,q]=size(B); if(m~=n|p~=q),error('les matrices doivent etre carrees'),end; if(m~=p),error('les matrices ntol);r=length(I); %s=ones(r,1)./s(I);L=V(:,I)*S(I,I); % L est Nxr %A=U(:,I)'*QA';F=L; % ici A*A'=I et A est rxP, F est Nxr %%% seconde version (variante avec cholesky) %%% % [qq,rr]=qr(AA');L=rr';A=qq';F=L;r=N; %%% troisieme version (a utiliser si "svd would not converge" se repete) %%% [V,S2]=eig(AA*AA');s2=diag(S2); [ss,Js]=sort(-s2);ss=sqrt(-ss);Ss=diag(ss); % ss=Ps*sqrt(s2); E=eye(N);Ps=E(:,Js)';Vs=V*Ps'; % norm(AA*AA'-Vs*diag(ss.*ss)*Vs')=0 tol=max(size(Ss))*norm(Ss)*eps;I=find(ss>tol);r=length(I); ss=ones(r,1)./ss(I);L=Vs(:,I)*Ss(I,I); % L est Nxr A=inv(Ss(I,I))*Vs(:,I)'*AA;F=L; % ici A*A'=I et A est rxP, F est Nxr % norm(A*A'-eye(r)) % controle eventuel du blanchiment % NB: une difference peut exister entre les versions, du a l'indetermination de % phase des vecteurs propres, ou a la presence de val propres multiples. %%%%%% CONTRASTE INITIAL %%%%%% contraste=Kum'*Kum; %fprintf('Borne contraste=%g\n',contraste); for i=1:r,B(i,1:P)=A(i,:).^4;end;G=B*Kum;contraste=G'*G; %fprintf('contraste initial=%g\n',contraste); if nargout>2,rep=1;psi(rep)=contraste;gap(rep)=ecar2(A0,F);end; %%%%%% ETAPES 3 & 4 & 5: transformation orthogonale %%%%%% if N==2,K=1;else,K=1+round(sqrt(N));end; % K=nbre max de balayages Rot=eye(r); for k=1:K, %%%%%% debut balayages %fprintf('Balayage n%g\n', k) Q=eye(r); for i=1:r-1,for j= i+1:r, Ai=A(i,:);Aj=A(j,:); qij=tfuniV(Ai,Aj,Kum); %%%%%% traitement de la paire Qij=eye(r);Qij(i,i)=qij(1,1);Qij(i,j)=qij(1,2); Qij(j,i)=qij(2,1);Qij(j,j)=qij(2,2); F=F*Qij';A=Qij*A; if nargout>2,rep=rep+1; for ic=1:r,B(ic,1:P)=A(ic,:).^4;end; G=B*Kum;psi(rep)=G'*G;gap(rep)=ecar2(A0,F); end; end;end; end; %%%%%% fin balayages %%%%%% CONTRASTE FINAL %%%%%% for i=1:r,B(i,1:P)=A(i,:).^4;end;G=B*Kum;contraste=G'*G; fprintf('contraste final=%g\n',contraste); %%%%%% ETAPE 6: norme des colonnes %%%%%% delta=diag(sqrt(sum(F.*conj(F)))); %%%%%% ETAPE 7: classement par ordre descendant %%%%%% [d,I]=sort(-diag(delta));E=eye(r);P=E(:,I)';delta=P*delta*P';F=F*P'; %%%%%% ETAPE 8: normalisation des colonnes %%%%%% F=F*inv(delta); %%%%%% ETAPE 9: phase des colonnes %%%%%% [y,I]=max(abs(F)); for i=1:r,Lambda(i)=conj(F(I(i),i));end;Lambda=Lambda./abs(Lambda); F=F*diag(Lambda); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ================================================================================ function q=tfuniV(Ai,Aj,Kum) % q=tfuniV(Ai,Aj,Kum) % P.Comon, version 8 march 1992. % English comments added in 1994 % Orthogonal direct real transform, q % for separating 2 sources in presence of noise % Sources are assumed zero-mean and standardized, but only their % standardized cumulants, Kum, are neede as input % REFERENCE: P.Comon, "Independent Component Analysis, a new concept?", % Signal Processing, Elsevier, vol.36, no 3, April 1994, 287-314. % %%%%% cumulants d'ordre 4 Aii=Ai.*Ai;Aij=Ai.*Aj;Ajj=Aj.*Aj; q1111=(Aii.*Aii)*Kum; q1112=(Aii.*Aij)*Kum; q1122=(Aii.*Ajj)*Kum; q1222=(Aij.*Ajj)*Kum; q2222=(Ajj.*Ajj)*Kum; %%%%% racine de Pw(x): si t est la tangente de l'angle, x=t-1/t. u=q1111+q2222-6*q1122;v=q1222-q1112;z=q1111*q1111+q2222*q2222; c4=q1111*q1112-q2222*q1222; c3=z-4*(q1112*q1112+q1222*q1222)-3*q1122*(q1111+q2222); c2=3*v*u; c1=3*z-2*q1111*q2222-32*q1112*q1222-36*q1122*q1122; c0=-4*(u*v+4*c4); %c0=q1112*q2222-q1222*q1111-3*q1112*q1111+3*q1222*q2222-6*q1122*q1112+6*q1122*q1222;c0=4*c0 Pw=[c4 c3 c2 c1 c0];R=roots(Pw);I=find(abs(imag(R))-1);t=t(j); %%%%% test et conditionnement if abs(t)