function get_Gq(t, prev, next, el, vnum)

global G;
global q;
global alpha;
global alpha2;
global C_inv;
global var_noise;
global FIR_length;
global Nusers;
global Memory;
global states;
global Nchips;
global FIR_0;
global z;
global Nsyms;
global GG;
global qq;

global ex_gm;
global ex_p;

global Vparam;

% set up A
%
a = zeros( FIR_length, Nusers);

if( Vparam(4) == 1) % single trellis

  for u = 1:Nusers
    ui = (u-1)*Memory + [1:Memory];
    a(:,u) = [states(ui,next); states(ui(Memory),prev)];
  end

else % separate trellises

  for u = 1:Nusers
    if( u == vnum) % that's me
      us = [states(:,next); states(Memory,prev)];
    else
      u2_ex = ex_gm(:,:,u) * diag(ex_p(:,u)); % scale by p
      u2_ex = sum(u2_ex,2);                   %  then marginalize
      us = [flipud(states(:,1)); u2_ex];      % soft estimate
      us = us(t+Memory:-1:t);
    end
    a(:,u) = us;
  end

end

a = a(:);

% set up G and q
%
q = zeros( FIR_length*Nusers, Nchips);        

if( t == 1)

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

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

else % t > 1

  if( t < Nsyms)
     G = inv( a*(a'/var_noise) + C_inv + alpha2*(C_inv-C_inv*GG(:,:,el,prev,vnum)*C_inv) );
  else
     G = inv( a*(a'/var_noise) + C_inv - alpha2*C_inv*GG(:,:,el,prev,vnum)*C_inv );
  end

  for j = 1:Nchips
     q(:,j) = a*(z(j,t)/var_noise) + C_inv*(GG(:,:,el,prev,vnum)*(alpha*qq(:,j,el,prev,vnum)));
  end

end
