% eigenvector projection (arbitrary dimension)
% argument is pattern matrix (data) and desired output dimensionality (odim)
% noutf - number of output attributes
% Output: rpm    - returns projected rotated centered pattern matrix
%         proj   - projection matrix
%         retvar - percentage of retained variance
function [rpm,proj,retvar] = pca_an(d,odim, noutf)
  numcol = size(d,2);
  data = d(:,1:(numcol-noutf));
 % get size of pattern matrix. # patterns and # features (dimensionality)
  [meanv,stdv,opm] = normalize(data,[],[]);
  [npat,dim] = size(opm);
 if (dim < odim)
  error('Desired output dimensionality >= input dimensionality');
 end
 % center the pattern matrix by subtracting the mean vector from each pattern
 m = mean(opm);
 pm = opm - repmat(m,npat,1);   % repmat: npat x dim mtx  from 1 x dim vector
 % compute covariance matrix and perform eigenanalysis
 c = cov(pm);
 [vecs,vals] = eig(c);  %note vals is a dim x dim diagonal mtx
 % calculate total variance in this data = sum of eigenvalues
 s2 = trace(vals);
 % sort eigenvalues. index is the array of permutation indices
 [sv,index]=sort(diag(vals));
 % form projection matrix.  First coord has highest variance, etc.
 proj = fliplr(vecs(:,index(dim-odim+1:dim)));    % yecccch
 % project matrix
 rpm = pm * proj;
 % compute % of variance retained;
 s3 = sum(sv(dim-odim+1:dim));
 retvar = 100.0*s3/s2;
% fprintf(1,'%f%% of variance retained\n',100.0*s3/s2);

 rpm = [rpm(:,1:odim) d(:,(numcol-noutf+1):numcol)];
 
 return;