% ML cost function for Gauss-Markov h with known FIR_0
%
function cost = get_GM_ML_cost( b)

global z;

global Memory;
global Nusers;
global Nchips;

global Nsyms;
global FIR_length;
global FIR_0;
global C_inv;
global alpha;
global alpha2;
global var_noise;

A = [-ones(Memory,Nusers); reshape(b,Nsyms,Nusers)];

q = zeros( FIR_length*Nusers, Nchips);

%%
% t == 1
%
t = 1;
a = A(t+Memory:-1:t,:);
a = a(:);

for j = 1:Nchips
  h = FIR_0(:,:,j);
  q(:,j) = a*(z(j,t)/var_noise) + C_inv*(alpha*h(:));
end

G = inv( a*(a'/var_noise) + (1+alpha2)*C_inv );

cost = - Nchips * log(det(G));

for j = 1:Nchips
  cost = cost - q(:,j)'*G*q(:,j);
end

%%
% 2 <= t <= Nsyms-1
%
for t = 2:Nsyms-1

  a = A(t+Memory:-1:t,:);
  a = a(:);

  for j = 1:Nchips
    q(:,j) = a*(z(j,t)/var_noise) + C_inv*G*(alpha*q(:,j));
  end

  G = inv( a*(a'/var_noise) + C_inv + alpha2*(C_inv-C_inv*G*C_inv) );

  cost = cost - Nchips * log(det(G));

  for j = 1:Nchips
    cost = cost - q(:,j)'*G*q(:,j);
  end

end

%%
% t == Nsyms
%
t = Nsyms;
a = A(t+Memory:-1:t,:);
a = a(:);

for j = 1:Nchips
  q(:,j) = a*(z(j,t)/var_noise) + C_inv*G*(alpha*q(:,j));
end

G = inv( a*(a'/var_noise) + C_inv - alpha2*C_inv*G*C_inv );

cost = cost - Nchips * log(det(G));

for j = 1:Nchips
  cost = cost - q(:,j)'*G*q(:,j);
end
