function [Co,X,Y] = subcorr_gui(A,B,GUI);
%SUBCORR_GUI - Subcorr function custom to the gui features
% function [Co,X,Y] = subcorr_gui(A,B,GUI);
% GUI.REG is a regularization switch
% GUI is a struction with regularization fields to match
% See REGCHECK
% Note that BOTH A and B are regularized in this call.
%
% approaches Truncated Condition and Truncated Energy have
%  effectively the regularization built in by simply truncating the space.
%  Column normalization should
%  have already been done before the call, if requested.
%  Here we are only concerned with Tikhonov regularization by building the
%  filter functions, if requested.

%<autobegin> ---------------------- 26-May-2004 11:34:33 -----------------------
% --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
%
% CATEGORY: Inverse Modeling
%
% Alphabetical list of external functions (non-Matlab):
%   toolbox\regsubspace.m
%   toolbox\subcorr_gui.m  NOTE: Routine calls itself explicitly
%
% At Check-in: $Author: Mosher $  $Revision: 13 $  $Date: 5/26/04 10:02a $
%
% This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 24-May-2004
% 
% Principal Investigators and Developers:
% ** Richard M. Leahy, PhD, Signal & Image Processing Institute,
%    University of Southern California, Los Angeles, CA
% ** John C. Mosher, PhD, Biophysics Group,
%    Los Alamos National Laboratory, Los Alamos, NM
% ** Sylvain Baillet, PhD, Cognitive Neuroscience & Brain Imaging Laboratory,
%    CNRS, Hopital de la Salpetriere, Paris, France
% 
% See BrainStorm website at http://neuroimage.usc.edu for further information.
% 
% Copyright (c) 2004 BrainStorm by the University of Southern California
% This software distributed  under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPL
% license can be found at http://www.gnu.org/copyleft/gpl.html .
% 
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%<autoend> ------------------------ 26-May-2004 11:34:33 -----------------------

% ----------------------------- Script History ---------------------------------
% 1994 by John C. Mosher, Ph.D.
% 10/29/99 JCM, some optimizations.
% JCM 10-May-2002 Adjustments to display in command window, not message window
% 19-May-2004 JCM Comments Cleaning
% ----------------------------- Script History ---------------------------------


[Ua,Sa,Va]= svd(A,0);
[Ub,Sb,Vb]= svd(B,0);

% trim the subspace to the appropriate size
Ua = regsubspace(GUI,Ua,Sa);
Ub = regsubspace(GUI,Ub,Sb);

C = Ua'*Ub;

if(nargout < 2)  % want only angles
   
   Co = svd(C);
   too_big = find(Co > 1);	% numerical error
   Co(too_big) = 1; % matlab 5.3 allows scalar to vector mapping
   too_small = find(Co < 0); % more numerical error
   Co(too_small) = 0; % the null case is also adequately handled
   return
   
else % nargout is 2 or more
   
   % trim to the rank
   rnk_a = size(Ua,2);
   rnk_b = size(Ub,2);

   if(length(Sa) > 1),
      Sa = diag(Sa);
   end
   if(length(Sb) > 1),
      Sb = diag(Sb);
   end
   
   Sa = Sa(1:rnk_a);
   Va = Va(:,1:rnk_a);
   
   Sb = Sb(1:rnk_b);
   Vb = Vb(:,1:rnk_b);
      
   [Uc,Co,Vc] = svd(C);
   if(min(size(Co))==1),
      Co = Co(1);
   else,
      Co = diag(Co);
   end
   too_big = find(Co > 1);	% numerical error
   Co(too_big) = ones(length(too_big),1);
   too_small = find(Co < 0);	% numerical error
   Co(too_small) = zeros(length(too_small),1);
   
   switch GUI.REG
   case 'Tikhonov'
      Lambda = Sa(1)/GUI.Tikhonov; % relative condition setting
      Fa = Sa.^2 ./ (Sa.^2 + Lambda^2);
      Lambda = Sb(1)/GUI.Tikhonov; % relative condition setting
      Fb = Sb.^2 ./ (Sb.^2 + Lambda^2);
      VaSai = Va*diag(Fa./Sa); % filtered
      VbSbi = Vb*diag(Fb./Sb);
   otherwise
      % all other conditions are truncated types
      VaSai = Va*diag(1../Sa);
      VbSbi = Vb*diag(1../Sb);
   end
   
   X = VaSai*Uc;
   Y = VbSbi*Vc;
   
   % debugging comments
   switch GUI.REG
   case 'Tikhonov'
      
      % don't send to the message window,
      %  too detailed, more of a debugging set
      disp('Subcorr gui Comments:')
      disp(['Co:          ',sprintf('%.4f ',Co)]);
      disp(['Regularized: ',sprintf('%.4f ',subcorr_gui(A*X(:,1),B*Y(:,1),struct('REG','None')))])
      disp(['Filters a and b: ',sprintf('%.3f ',Fa) ' ; ' sprintf('%.3f ',Fb)])
      
   otherwise
      % nothing, orientation not altered
   end
   
   return
   
end

return
