function [y,e,w,u,ref,symbolCounter,weightUpdateCounter] ...
  = equalizercmacore(x,sps,u,ref,...
  symbolCounter,weightUpdateCounter,w,sigConst,...
  adaptWeights,trainingFlag,weightUpdatePeriod,stepSize,modulus,nff,nfb)
% Core CMA equalizer algorithm

%   Copyright 2018-2024 The MathWorks, Inc.

%#codegen

% Preallocate output
outputLength = (length(x) / sps);
y = zeros([outputLength 1], 'like', x);
e = zeros([outputLength 1], 'like', x);

for p=1:outputLength
  % Update tap delay line
  for idx=nff:-1:sps+1
    u(idx) = u(idx-sps);
  end
  for q=1:sps
    u(q,1) = x(p*sps-q+1,1);
  end
  if nfb > 0
    for idx=nff+nfb:-1:nff+2
      u(idx) = u(idx-1);
    end
    u(nff+1) = ref;
  end
  symbolCounter = symbolCounter + 1;
  weightUpdateCounter = weightUpdateCounter + 1;
  
  % Filter
  yTemp = w' * u;
  
  % Calculate error signal
  eTemp = yTemp * (modulus - abs(yTemp).^2);
  
  % Decide on the symbol value for DFE
  [~,idx] = min(abs(sigConst - yTemp));
  ref = sigConst(idx);
  
  if adaptWeights
    % Update tap weights
    if (trainingFlag == true) ...
        || (weightUpdateCounter == weightUpdatePeriod)
      weightUpdateCounter = 0;
      w = w + stepSize*u*conj(eTemp);
    end
  end
  
  % Assign output
  y(p,1) = yTemp;
  e(p,1) = eTemp;
end
