%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Train Gaussian + Uniform on bounded data
%
% ( e.g. -180 <= angle <= 180 )

function gu = em_train_gu( data, u_min, u_max )
  
  if nargin < 3
    error( [ mfilename ' needs 3 input arguments.' ] );
  end
  
  data = data(:);
  
  % Define the uniform pdf
  
  gu.u_min = u_min;
  gu.u_max = u_max;
  gu.u_pdf = 1 ./ ( u_max - u_min );
  gu.u_prior = 0.5;
  
  % Initialize the Gaussian pdf
  
  gu.g_mu  = mean( data );
  gu.g_sigma = std( data );
  gu.g_prior = 1 - gu.u_prior;
  
  % Run a few iterations of EM
  
  for a = 1:20
    
    % E: compute posteriors
    
    log_post = compute_post_gu( gu, data );
  
    % M: re-evaluate priors
    
    tmp = [  my_logsum_fast( reshape( log_post( :,:,1 ), [], 1 ) );
	     my_logsum_fast( reshape( log_post( :,:,2 ), [], 1 ) ) ];
    
    priors = exp( tmp - my_logsum_fast( tmp ) )
    priors = priors / sum( priors );
    
    gu.u_prior = priors( 1 );
    gu.g_prior = priors( 2 );
    
    
    % M: re-evaluate parameters of the Gaussian
    % ( the uniform pdf is fixed )
    
    w     = exp( log_post( :,:, 2 ) );
    w     = w(:) / sum( w(:) );
    
    gu.g_mu  = data(:).' * w(:);
    gu.g_sigma = sqrt( ( ( data(:).' - gu.g_mu ) .^ 2 ) * w(:) );
  
  end
  
  
