summaryrefslogtreecommitdiff
path: root/TapTogglingAlgos/LeveragedLMS.m
diff options
context:
space:
mode:
authorDavit Grigoryan <[email protected]>2026-04-09 12:25:24 -0700
committerDavit Grigoryan <[email protected]>2026-04-22 02:37:26 -0700
commit14ca50edb249d5f4ef621903259d955deb3a2fc3 (patch)
treea1798764b97c2c351ea9c8ab1422886e9488d18b /TapTogglingAlgos/LeveragedLMS.m
public release v1.0HEADmain
Diffstat (limited to 'TapTogglingAlgos/LeveragedLMS.m')
-rw-r--r--TapTogglingAlgos/LeveragedLMS.m114
1 files changed, 114 insertions, 0 deletions
diff --git a/TapTogglingAlgos/LeveragedLMS.m b/TapTogglingAlgos/LeveragedLMS.m
new file mode 100644
index 0000000..ed20f67
--- /dev/null
+++ b/TapTogglingAlgos/LeveragedLMS.m
@@ -0,0 +1,114 @@
+classdef LeveragedLMS < handle
+ % Version: 0.2 (min-COM-based)
+ % Description:
+ % If the smallest registered COM is above 3dB for some period,
+ % then assume it is safe to turn off the most "insignificant"
+ % tap (which now is, kind of, the smallest one)
+ %
+ % However, if smallest COM drops below 3dB for some period,
+ % then activate the fallback mechanism and turn on the recently
+ % disabled tap and terminate the algorithm
+
+ properties
+ lastDisabledTap
+ internalFFETapsMask
+ lastUpdateTime
+ reachedHighErr
+
+ lastMeanErr
+ maxErr
+ reachedHighCOM
+ reducedErrSeqCounter
+ increasedErrSeqCounter
+
+ targetCounters
+ targetCounterIndex
+ end
+
+ methods
+ function obj = LeveragedLMS(LMSUpdateObj)
+ obj.lastDisabledTap = -1;
+ obj.internalFFETapsMask = LMSUpdateObj.FFE_TapsMask;
+ obj.lastUpdateTime = LMSUpdateObj.StartFFEAdaptTime * LMSUpdateObj.WindowSize;
+ obj.reachedHighErr = 0;
+
+ obj.lastMeanErr = inf;
+ obj.maxErr = 0;
+ obj.reachedHighCOM = 0;
+ obj.reducedErrSeqCounter = 0;
+ obj.increasedErrSeqCounter = 0;
+
+ obj.targetCounters = [2 1];
+ obj.targetCounterIndex = 1;
+ end
+
+ function FFETapsMask = GetFFETapsMask(obj, LMSUpdateObj)
+ initialTogglingStart = LMSUpdateObj.StartFFEAdaptTime + 5;
+
+ if ismember(LMSUpdateObj.IterCount, LMSUpdateObj.LearningRatesAdjustTimes * LMSUpdateObj.WindowSize)
+ obj.targetCounterIndex = obj.targetCounterIndex + 1;
+ end
+
+ obj.maxErr = max(obj.maxErr, max(abs(LMSUpdateObj.ErrorVec)));
+
+ if mod(LMSUpdateObj.IterCount, LMSUpdateObj.WindowSize) == 0 && ...
+ LMSUpdateObj.IterCount > initialTogglingStart * LMSUpdateObj.WindowSize && ~obj.reachedHighErr
+ %avgErr = mean(abs(LMSUpdateObj.ErrorVec));
+
+ dlevDiff1 = LMSUpdateObj.Dlev_0p5 - LMSUpdateObj.Dlev_0p16;
+ dlevDiff2 = LMSUpdateObj.Dlev_0p16 - LMSUpdateObj.Dlev_m0p16;
+ dlevDiff3 = LMSUpdateObj.Dlev_m0p16 - LMSUpdateObj.Dlev_m0p5;
+ minDlevDiff = min([dlevDiff1 dlevDiff2 dlevDiff3]);
+ t = minDlevDiff / 2;
+
+ minCOM = 20*log10(t / obj.maxErr);
+
+ if minCOM >= 3
+ obj.reducedErrSeqCounter = obj.reducedErrSeqCounter + 1;
+ obj.increasedErrSeqCounter = 0;
+ obj.reachedHighCOM = 1;
+ else
+ obj.reducedErrSeqCounter = 0;
+ if obj.reachedHighCOM
+ obj.increasedErrSeqCounter = obj.increasedErrSeqCounter + 1;
+ end
+ end
+ %obj.lastMeanErr = avgErr * 1.125;
+
+ obj.maxErr = 0;
+ end
+
+ weights = abs(LMSUpdateObj.TapWeights);
+
+ % Take into account the neighboring taps as well
+ weights_padded = [0 weights 0];
+ weights_avg = (weights_padded(1:end-2) + 2*weights_padded(2:end-1) + weights_padded(3:end)) / 3;
+ weights_avg(~obj.internalFFETapsMask) = inf;
+
+ [~, minTapIndex] = min(weights_avg);
+
+ if obj.reducedErrSeqCounter == obj.targetCounters(obj.targetCounterIndex) && ...
+ LMSUpdateObj.IterCount > initialTogglingStart * LMSUpdateObj.WindowSize && ~obj.reachedHighErr
+ obj.internalFFETapsMask(minTapIndex) = 0;
+ obj.lastDisabledTap = minTapIndex;
+ obj.lastUpdateTime = LMSUpdateObj.IterCount;
+ obj.reducedErrSeqCounter = 0;
+ obj.increasedErrSeqCounter = 0;
+ end
+
+ if obj.increasedErrSeqCounter == obj.targetCounters(obj.targetCounterIndex)*2 && ~obj.reachedHighErr
+ obj.reachedHighErr = 1;
+ if obj.lastDisabledTap ~= -1
+ obj.internalFFETapsMask(obj.lastDisabledTap) = 1;
+ end
+
+ % to make sure it throws an error in case tried being accessed
+ obj.lastDisabledTap = -1;
+ obj.reducedErrSeqCounter = 0;
+ obj.increasedErrSeqCounter = 0;
+ end
+
+ FFETapsMask = obj.internalFFETapsMask;
+ end
+ end
+end \ No newline at end of file