% ML exhaustive search for non-time-varying Gaussian h
%
% assumes that the symobls are -1 and +1
%
function min_b = get_GM_ML()

global z;
global N;
global Memory;
global var_noise;
global avg_h;
global Rh;
global HUGE_VAL;
global inv_Rh;
global inv_Rh_d;
global alpha;
global alpha2;

s = [-1; 1];
nsyms = size(s,1);
nstates = prod( nsyms*ones(1,N));	% nstates = nsyms ** N

c = ones( 1, N);

min_cost = HUGE_VAL;

for i = 1:nstates
  b = s(c);
  A = get_A( b, N, Memory);
  cost=0;
  for k=1:N
  
      if( length(var_noise) > 1)
        vn = var_noise(k);
      else
        vn = var_noise;
      end
      
      t=A(k,:)';
      if(k==1)
        G=inv(t*(t'/vn)+inv_Rh);
        q=t*(z(k)/vn)+inv_Rh_d;   
      else
       if(k==N)
         q=t*z(k)/vn+inv_Rh_d+alpha*inv_Rh*G*q;
         G=inv(t*(t'/vn)+inv_Rh-alpha2*inv_Rh*G*inv_Rh);
       else  
         q=t*z(k)/vn+(1-alpha)*inv_Rh_d+alpha*inv_Rh*G*q;
         G=inv(t*(t'/vn)+inv_Rh+alpha2*(inv_Rh-inv_Rh*G*inv_Rh));
       end
      end
      cost=cost+(log(det(G))+q'*G*q);
  end      
  
  cost=-cost;    
 
  if( cost < min_cost)
    min_cost = cost;
    min_b = b;
  end
  c = FSM_inc( c, nsyms);
end

