Adaptive IIR control

Filtered-U RLMS extends ANC adaptation into a recursive control law.

Unlike the FIR-based FXLMS family, Filtered-U RLMS adapts both a direct section and a recursive section. That gives it extra expressive power, but it also makes the controller much more sensitive to step size, order selection, and modeling mismatch.

Core Equations

The output includes both direct and recursive terms:

\[y(n) = \sum_{i=0}^{N-1} a_i(n) x(n-i) + \sum_{j=1}^{J} b_j(n) y(n-j)\]

The repository implementation filters both the reference and previous outputs through the secondary-path estimate before adaptation:

\[a_i(n+1) = a_i(n) - \mu_a e(n) x'(n-i)\] \[b_j(n+1) = b_j(n) - \mu_b e(n) y'(n-j)\]

The negative sign on the direct-path update is deliberate. It is one of the spots where the OCR source material was ambiguous, and the stable floating-point implementation resolves that ambiguity in favor of the ANC sign convention used elsewhere in the codebase.

Benchmark Interpretation

FU-RLMS posts the weakest positive headline result in the primary suite. That does not make it useless. It means the controller is expensive to tune and easy to drive into poor behavior when the recursive section amplifies modeling error.

Practical reading

The benchmark supports a cautious conclusion: FU-RLMS is a specialized tool, not a default baseline. Start with FIR controllers unless you have a concrete reason to want recursive dynamics in the control law.

Tuning Notes

Using It From C++

#include "anc/fu_rlms_controller.h"

anc::FuRlmsConfig config;
config.directOrder = 48;
config.recursiveOrder = 24;
config.secondaryEstimate = {0.0, 0.12, 0.38, 0.21, -0.05};
config.directStepSize = 0.01;
config.recursiveStepSize = 0.001;
config.leakage = 0.999;

anc::FuRlmsController controller(config);

for (std::size_t sample = 0; sample < reference.size(); ++sample) {
  const double control = controller.synthesize(reference[sample]);
  const double error = disturbance[sample] + secondaryPath(control);
  controller.adapt(error);
}

CLI Reproduction

build\Debug\anc_cli.exe `
  --algorithm fu-rlms `
  --summary analysis_output\raw\fu_rlms_bursty_broadband_summary.csv `
  --timeseries analysis_output\raw\fu_rlms_bursty_broadband_timeseries.csv `
  --samples 12000 `
  --controller-order 48 `
  --recursive-order 24 `
  --direct-step-size 0.01 `
  --recursive-step-size 0.001 `
  --leakage 0.999