function  acache = aggreg_cache(cache,compact_p)

%AGGREG_CACHE -- Sufficient statistics over cached PLM inputs.
%
%  acache = aggreg_cache(cache)
%  acache = aggreg_cache(cache,noise,compact_p)
%
%  CACHE is a structure array produced by CACHE_INPUTS.
%  When COMPACT_P is 1 (default), ACACHE is a single struct with fields:
%   1. arg -- ==cat(1,CACHE(:).arg), [Cx3], where C=length(CACHE)
%   2. N -- ==cat(1,CACHE(:).N), [Cx1] -- number of reps per condition
%   3. mnX -- for each row k, define X=CACHE(k).rep(1:N,:), size(X)=[N,R].
%             Then mnX(k,:)=mean(X) and sdX(k,:)=std(X,1).
%   4. sdX -- unit-wise standard deviations within conditions, [CxR]
% %#5. mnX1X -- ==(X'*X)./N for each k=1:C,  [RxRxC]
%
%  When COMPACT_P is 0, ACACHE is a structure array of the same size as
%  CACHE with fields: 'arg', 'N', 'rep' (which is a literal copy of the
%  full CACHE(k).rep),'mnX' (a row v. now, not a matrix),'sdX','mnX1X'.
%
%  Let W is a [Rx1] weight vector and Y:=X*W, [Nx1]=[NxR]*[Rx1].
%  We want to know the mean and variance of Y over the sample of N
%  input vectors X(n,:). They are (see INPUT_VARIABILITY):
%   # mean(Y) = mnX * W  , [1x1]=[1xR]*[Rx1]
%   # mean(Y^2) = W' * mnX1X * W , [1x1]=[1xR]*[RxR]*[Rx1]
%   # var(Y,1) = mean(Y^2)-(mean(Y))^2
%
%  See also CACHE_INPUTS, PLM_PROBAB1, AGGREG_CACHE_NOISE.

%  Original coding by Alexander Petrov, UC Irvine.
%  $Revision: 2.2 $  $Date: 2002/08/05 17:13 $

if (nargin<2)  compact_p = 1; end   % compact mode by default

C = prod(size(cache)) ;       % number of "conditions"
R = size(cache(1).rep,2) ;    % number of values in each representation

N = cat(1,cache(:).N) ;       % [Cx1]
mnX = zeros(C,R) ;
sdX = zeros(C,R) ;
%#mnX1X = zeros([R,R,C]) ;

%-- Do the main work
for k = 1:C
   X = cache(k).rep(1:N(k),:) ;     % [NxR]
   mnX(k,:) = mean(X) ;             % [1xR]
   sdX(k,:) = std(X,1) ;            % [1xR]
   %#mnX1X(:,:,k) = (X'*X)./N(k) ;    % [RxR]
end

%-- Pack depending on COMPACT_P and return
if (compact_p > 0)    % compact mode?
   acache.arg = cat(1,cache(:).arg) ;     % [Cx3]
   acache.N = N ;
   acache.mnX = mnX ;
   acache.sdX = sdX ;
   %#acache.mnX1X = mnX1X ;
else   % non-compact mode -- augment the original CACHE
   acache = cache ;
   for k = 1:C
      acache(k).mnX = mnX(k,:) ;
      acache(k).sdX = sdX(k,:) ;
      %#acache(k).mnX1X = mnX1X(:,:,k) ;
   end
end

%--- Return ACACHE
%%%%% End of file AGGREG_CACHE.M
