function [S, A] = lyngby_ica_nbs_est(X, varargin)

% lyngby_ica_nbs_est    - Non-symmetric Bell & Sejnowski ICA
%
%       function [S, A] = lyngby_ica_nbs_est(X, varargin)
%
%       Input:    X    Data matrix, objects x sensors
%
%       Property: Components [ {20} | positive integer ] 
%
%       Output:   S    Source matrix, objects x sources
%                 A    Mixing matrix, sources x sensors
%
%       Independent component analysis with non-symmetric Bell and
%       Sejnowski, ie, non-square mixing  matrix. Optimization of the
%       mixing matrix is done by conjugate gradient optimization. The
%       estimated mixing matrix is square and is applied on the right
%       side of the source matrix:  
%
%                          X = S * A
%
%       An initial singular value decomposition is performed and the
%       ordinary ICA algorithm is performed in the subspace.
%       The optimization is performed with conjugate gradient
%       implemented in lyngby_opt_cg via the lyngby_ica_bs_est
%       function. 
%
%       The property 'Components' governs how many sources are
%       found. It will be the minimum of the rank of X and the number
%       given by 'Components'.
%
%       Example:
%         Strue = randn(500, 2).^3;
%         Atrue = [ 3 4 -8 ; 1 4 2 ];
%         X = Strue * Atrue;
%         [S, A] = lyngby_ica_nbs_est(X, 'components', 2);
%         figure, plot(X(:,1), X(:,2), '.', ...
%               5*[-A(1,1) A(1,1)], 5*[-A(1,2) A(1,2)], 'r-', ...
%               5*[-A(2,1) A(2,1)], 5*[-A(2,2) A(2,2)], 'g-')
% 
%       See also LYNGBY, LYNGBY_ICA_BS_EST, LYNGBY_ICA_MS_EST,
%                LYNGBY_SVD, LYNGBY_OPT_CG. 
%
% $Id: lyngby_ica_nbs_est.m,v 1.1 2003/02/20 17:43:34 fnielsen Exp $




    % Default values
    icaComponents = 20;

    
    % Read properties
    n = 1;
    while n < length(varargin)
      arg = lower(varargin{n});

      if strcmp(arg, 'components') 
	n = n + 1;
	arg = lower(varargin{n});
	if isnumeric(arg) & length(arg)==1 & round(arg)==arg & arg >0
	  icaComponents = arg; 
	else
	  error(sprintf(['Argument with ''Components'' should be '...
		'a string']));
	end
      
      else
	error(sprintf('Invalid property: %s', arg));
      end
      n = n + 1;
    end

    
    % Singular value decomposition
    [U,L,V] = lyngby_svd(X, 'reduceComponents', icaComponents);
    
    % Ordinary Bell and Sejnowski ICA
    [S, B] = lyngby_ica_bs_est(U);

    % Project back in X-space
    A = B * diag(L) * V';














