function [U,S,V] = lyngby_scva_main(X, R, arg1, arg2, arg3, arg4, ...
    arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ...
    arg15, arg16)

% lyngby_scva_main     - Strother Canonical variate analysis
%
%	function [U,S,V] = lyngby_scva_main(X, R,
%	    'PropertyName', 'PropertyValue')
%
%       Input:  X   The datamatrix
%               R   The run structure
%               Property:
%                  'RidgeX'     { 0 } Canonical ridge parameter for X
%                  'RidgeY'     { 0 } Canonical ridge parameter for Y
%                  'Components' Number of canonicvalues maintained
%                  'SubsetComp' { size(X,2) } Number of subset
%                               component, ie, SVD components piped to
%                               CVA
%                  'Paradigm'   The paradigm
%                  'InitSVD'    { 1 (true) | 0 } Perform initial SVD on
%                               a rank-deficient X matrix. 
%
%       Output: U   Canonic sequences
%               S   Canonic values
%               V   Canonic images
%
%       This function performs canonical variate analysis (also called
%       canonical correlation analysis) with the Strother design
%       matrix. If the ridge parameters are defined and different from
%       zero the analysis is canonical ridge analysis.
%
%       Ref: Mardia, Multivariate Analysis
%
%       See also: lyngby_cva, lyngby_svd, lyngby_sdesign

% cvs : $Id: lyngby_scva_main.m,v 1.8 1999/07/09 13:54:18 fnielsen Exp $
%       $Revision: 1.8 $

    lyngby_global
    
    [Nxr, Nxc] = size(X);
    [Nrr, Nrc] = size(R);
    
    % Check input parameters
    if size(X,1) ~= size(R, 1)
      error(sprintf(['X and R do not have the same length. ',...
	    'X: %dx%d, R: %dx%d'], size(X), size(R)));
    end
    [Runs, ScansPerRun] = lyngby_runinfo(R);
    if length(ScansPerRun) > 1
      error(['This analysis cannot be run when the runs have ',...
	    'different length']);
    end
    
    % Default values
    ridgeX = 0;
    ridgeY = 0;
    paradigm = [];
    canValues = 5;
    subsetComp = Nxc;
    bInitSVD = 1;

    
    % Parse Properties
    n = 1;
    while n <= nargin-2
      eval(sprintf('arg = lower(arg%d);', n));
      if strcmp(arg, 'ridgex')
	n = n + 1;
	eval(sprintf('arg = arg%d;', n));
	if isreal(arg)
	  if length(arg) == 1
	    if arg <= 1 & arg >= 0 
	      ridgeX =  arg;
	    else
	      error(['Argument to ''RidgeX'' should ' ...
		    'be in the interval [0;1]']);
	    end
	  else
	    error(['Argument to ''RidgeX'' should ' ...
		  'be a single value']);
	  end
	else
	  error('Argument to ''RidgeX'' should be a value.'); 
	end
      elseif strcmp(arg, 'ridgey')
	n = n + 1;
	eval(sprintf('arg = arg%d;', n));
	if isreal(arg)
	  if length(arg) == 1
	    if arg <= 1 & arg >= 0 
	      ridgeY =  arg;
	    else
	      error(['Argument to ''RidgeY'' should ' ...
		    'be in the interval [0;1]']);
	    end
	  else
	    error(['Argument to ''RidgeY'' should ' ...
		  'be a single value']);
	  end
	else
	  error('Argument to ''RidgeY'' should be a value.'); 
	end
      elseif strcmp(arg, 'components')
	n = n + 1;
	eval(sprintf('arg = arg%d;', n));
	if isreal(arg)
	  if length(arg) == 1
	    if arg >= 1
	      canValues = arg;
	    else
	      error(['Argument to ''Components'' should ' ...
		    'be a larger than 1']);
	    end
	  else
	    error(['Argument to ''Components'' should ' ...
		  'be a single value']);
	  end
	else
	  error('Argument to ''Components'' should be a value.'); 
	end

      elseif strcmp(arg, 'subsetcomp')
	n = n + 1;
	eval(sprintf('arg = arg%d;', n));
	if isreal(arg)
	  if length(arg) == 1
	    if arg >= 1
	      subsetComp = arg;
	    else
	      error(['Argument to ''SubsetComp'' should ' ...
		    'be a larger than 1']);
	    end
	  else
	    error(['Argument to ''SubsetComp'' should ' ...
		  'be a single value']);
	  end
	else
	  error('Argument to ''SubsetComp'' should be a value.'); 
	end
	
      elseif strcmp(arg, 'paradigm')
	n = n + 1;
	eval(sprintf('arg = arg%d;', n));
	if isreal(arg)
	  if all(size(R) == size(arg))
	    paradigm = arg;
	  else
	    error(sprintf(['The argument to ''Paradigm'' should ' ...
		  'be of the same size as R. Paradigm: %dx%d, ' ...
		  'R: %dx%d'], size(arg), size(R)));
	  end
	else
	  error('The argument with ''Paradigm'' should be a vector.'); 
	end
      
      elseif strcmp(arg, 'initsvd')
	n = n + 1;
	eval(sprintf('arg = arg%d;', n));
	if isreal(arg)
	  if length(arg) == 1
	    bInitSVD = (arg ~= 0);
	  else
	    error(['Argument to ''InitSVD'' should ' ...
		  'be a single value']);
	  end
	else
	  error('Argument to ''InitSVD'' should be a value.'); 
	end
      
      else
	error(sprintf('Invalid property: %s', arg));
      end
      n = n + 1;
    end

          
    % Strother's design matrix
    Y = lyngby_sdesign(R);
    
    % Canonical variate analysis
    [U,S,V] = lyngby_cva(X, Y, 'RidgeX', ridgeX, 'RidgeY', ridgeY, ...
	'Components', canValues, ...
	'InitSVD', bInitSVD, ...
	'SubsetComp', subsetComp);
    
    % Flip the sign of the canonicsequence and image if we are
    % out of phase with the paradigm
    if ~isempty(paradigm)
      sgn = sign(paradigm' * Y * U);
      U = (ones(size(U,1),1) * sgn) .* U;
      V = (ones(size(V,1),1) * sgn) .* V; 
    end
    
    U = [zeros(1,size(U,2)) ; U];


