--- /dev/null
+function [x, y] = pdm_adaptiveCMA(rx, ry)
+ taps = 19; % ODD taps
+ hxx = zeros(taps, 1);
+ hxy = zeros(taps, 1);
+ hyx = zeros(taps, 1);
+ hyy = zeros(taps, 1);
+ %% hxx: real indices -K, ..., 0, ..., K. K = floor(taps/2)
+ %% MATLAB indices 1 1+K taps
+ %% initialize hxx, hxx[0] = 1, hxx[k] = hxx[-k] = 0
+ hxx(ceil(taps/2)) = 1;
+ hxy(ceil(taps/2)) = 1;
+ hyx(ceil(taps/2)) = 1;
+ hyy(ceil(taps/2)) = 1;
+
+ mu = 1e-3;
+ numSymbs = length(rx);
+
+ %% Check average energy of symbols
+ rx = rx / sqrt(mean(abs(rx) .^ 2));
+ ry = ry / sqrt(mean(abs(ry) .^ 2));
+
+ x = zeros(numSymbs, 1);
+ y = zeros(numSymbs, 1);
+ converged = 0;
+ convergeCount = 0;
+ convergeIdx = Inf;
+
+ for it = 1:numSymbs
+ if it <= (taps - 1) / 2;
+ xp = [zeros((taps - 1) / 2 - it + 1, 1); rx(1:it + (taps - 1) / 2)];
+ yp = [zeros((taps - 1) / 2 - it + 1, 1); ry(1:it + (taps - 1) / 2)];
+ elseif it + (taps - 1) / 2 > numSymbs
+ xp = [rx(it - (taps - 1) / 2 : end); zeros(it + (taps - 1) / 2 - numSymbs, 1)];
+ yp = [ry(it - (taps - 1) / 2 : end); zeros(it + (taps - 1) / 2 - numSymbs, 1)];
+ else
+ xp = rx(it - (taps - 1) / 2 : it + (taps - 1) / 2);
+ yp = ry(it - (taps - 1) / 2 : it + (taps - 1) / 2);
+ end
+
+ xout = sum(hxx .* xp) + sum(hxy .* yp);
+ yout = sum(hyx .* xp) + sum(hyy .* yp);
+ ex = 1 - abs(xout) ^ 2;
+ ey = 1 - abs(yout) ^ 2;
+
+ if abs(ex) < 0.01
+ convergeCount = convergeCount + 1;
+ else
+ convergeCount = 0;
+ end
+ if ~converged && convergeCount >= 10
+ converged = 1;
+ convergeIdx = it;
+ end
+
+ x(it) = xout;
+ y(it) = yout;
+
+ hxx = hxx + mu * ex * xout * conj(xp);
+ hxy = hxy + mu * ex * xout * conj(yp);
+ hyx = hyx + mu * ey * yout * conj(xp);
+ hyy = hyy + mu * ey * yout * conj(yp);
+
+
+ if sum(abs(hxx - hyx)) < 0.01 && sum(abs(hxy - hyy)) < 0.01
+ hxx = 0.5 * (hxx + flipud(conj(hyy)));
+ hyy = conj(flipud(hxx));
+ hxy = 0.5 * (hxy - conj(flipud(hyx)));
+ hyx = -conj(flipud(hxy));
+ end
+
+ end
+end