Compute output, error, and weights of LMS adaptive filter
The dsp.LMSFilter
System object™ implements an adaptive finite impulse response (FIR) filter that converges an
input signal to the desired signal using one of the following algorithms:
LMS
Normalized LMS
Sign-Data LMS
Sign-Error LMS
Sign-Sign LMS
For more details on each of these methods, see Algorithms.
The filter adapts its weights until the error between the primary input signal and the
desired signal is minimal. The mean square of this error (MSE) is computed using the msesim
function. The
predicted version of the MSE is determined using a Wiener filter in the msepred
function.
The maxstep
function
computes the maximum adaptation step size, which controls the speed of convergence.
For an overview of the adaptive filter methodology, and the most common applications the adaptive filters are used in, see Overview of Adaptive Filters and Applications.
To filter a signal using an adaptive FIR filter:
Create the dsp.LMSFilter
object and set its properties.
Call the object with arguments, as if it were a function.
To learn more about how System objects work, see What Are System Objects?.
Under specific conditions, this System object also supports SIMD code generation. For details, see Code Generation.
returns an LMS filter
object, lms
= dsp.LMSFilterlms
, that computes the filtered output, filter
error, and the filter weights for a given input and a desired signal using the least mean
squares (LMS) algorithm.
lms = dsp.LMSFilter(
returns an
LMS filter object with each specified property set to the specified value. Enclose each
property name in single quotes. You can use this syntax with the previous input
argument.Name,Value
)
Unless otherwise indicated, properties are nontunable, which means you cannot change their
values after calling the object. Objects lock when you call them, and the
release
function unlocks them.
If a property is tunable, you can change its value at any time.
For more information on changing property values, see System Design in MATLAB Using System Objects.
Method
— Method to calculate filter weights'LMS'
(default) | 'Normalized LMS'
| 'Sign-Data LMS'
| 'Sign-Error LMS'
| 'Sign-Sign LMS'
Method to calculate filter weights, specified as one of the following:
'LMS'
–– Solves the Weiner-Hopf equation and finds the
filter coefficients for an adaptive filter.
'Normalized LMS'
–– Normalized variation of the LMS
algorithm.
'Sign-Data LMS'
–– Correction to the filter weights at each
iteration depends on the sign of the input x
.
'Sign-Error LMS'
–– Correction applied to the current
filter weights for each successive iteration depends on the sign of the error,
err
.
'Sign-Sign LMS'
–– Correction applied to the current filter
weights for each successive iteration depends on both the sign of
x
and the sign of err
.
For more details on the algorithms, see Algorithms.
Length
— Length of FIR filter weights vector32
(default) | positive integerLength of the FIR filter weights vector, specified as a positive integer.
Example: 64
Example: 16
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
StepSizeSource
— Method to specify adaptation step size'Property'
(default) | 'Input port'
Method to specify the adaptation step size, specified as one of the following:
'Property'
–– The property StepSize specifies the size of each adaptation
step.
'Input port'
–– Specify the adaptation step size as one of
the inputs to the object.
StepSize
— Adaptation step size0.1
(default) | non-negative scalarAdaptation step size factor, specified as a non-negative scalar. For convergence of the normalized LMS method, the step size must be greater than 0 and less than 2.
A small step size ensures a small steady state error between the output y and the desired signal
d. If the step size is
small, the convergence speed of the filter decreases. To improve the convergence speed,
increase the step size. Note that if the step size is large, the filter can become
unstable. To compute the maximum step size the filter can accept without becoming
unstable, use the maxstep
function.
Tunable: Yes
This property applies when you set StepSizeSource to
'Property'
.
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
LeakageFactor
— Leakage factor used in leaky LMS method1
(default) | [0 1]
Leakage factor used when implementing the leaky LMS method, specified as a scalar in
the range [0 1]
. When the value equals 1, there is no leakage in the
adapting method. When the value is less than 1, the filter implements a leaky LMS
method.
Example: 0.5
Tunable: Yes
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
InitialConditions
— Initial conditions of filter weights0
(default) | scalar | vectorInitial conditions of filter weights, specified as a scalar or a vector of length equal to the value of the Length property. When the input is real, the value of this property must be real.
Example: 0
Example: [1 3 1 2 7 8 9 0 2 2 8 2]
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
Complex Number Support: Yes
AdaptInputPort
— Flag to adapt filter weightsfalse
(default) | true
Flag to adapt filter weights, specified as one of the following:
false
–– The object continuously updates the filter
weights.
true
–– An adaptation control input is provided to the
object when you call its algorithm. If the value of this input is non-zero, the
object continuously updates the filter weights. If the value of this input is
zero, the filter weights remain at their current value.
WeightsResetInputPort
— Flag to reset filter weightsfalse
(default) | true
Flag to reset filter weights, specified as one of the following:
false
–– The object does not reset weights.
true
–– A reset control input is provided to the object
when you call its algorithm. This setting enables the WeightsResetCondition property. The object
resets the filter weights based on the values of the
WeightsResetCondition
property and the reset input provided
to the object algorithm.
WeightsResetCondition
— Event to reset filter weights'Non-zero'
(default) | 'Rising edge'
| 'Falling edge'
| 'Either edge'
Event that triggers the reset of the filter weights, specified as one of the following. The object resets the filter weights whenever a reset event is detected in its reset input.
'Non-zero'
–– Triggers a reset operation at each sample, when the
reset input is not zero.
'Rising edge'
–– Triggers a reset operation when the reset
input does one of the following:
Rises from a negative value to either a positive value or zero.
Rises from zero to a positive value, where the rise is not a continuation of a rise from a negative value to zero.
'Falling edge'
–– Triggers a reset operation when the reset
input does one of the following:
Falls from a positive value to a negative value or zero.
Falls from zero to a negative value, where the fall is not a continuation of a fall from a positive value to zero.
'Either edge'
–– Triggers a reset operation when the reset
input is a rising edge or a falling edge.
The object resets the filter weights based on the value of this property and the
reset input r
provided to the object algorithm.
This property applies when you set the WeightsResetInputPort property to
true
.
WeightsOutput
— Method to output adapted filter weights'Last'
(default) | 'None'
| 'All'
Method to output adapted filter weights, specified as one of the following:
'Last'
(default) — The object returns a column vector of
weights corresponding to the last sample of the data frame. The length of the
weights vector is the value given by the Length property.
'All'
— The object returns a
FrameLength-by-Length matrix of weights. The
matrix corresponds to the full sample-by-sample history of weights for all
FrameLength samples of the input values. Each row in the matrix
corresponds to a set of LMS filter weights calculated for the corresponding input
sample.
'None'
— This setting disables the weights output.
RoundingMethod
— Rounding method for fixed-point operations'Floor'
(default) | 'Ceiling'
| 'Convergent'
| 'Nearest'
| 'Round'
| 'Simplest'
| 'Zero'
Specify the rounding mode for fixed-point operations. For more details, see rounding mode.
OverflowAction
— Overflow action for fixed-point operations'Wrap'
(default) | 'Saturate'
Overflow action for fixed-point operations, specified as one of the following:
'Wrap'
–– The object wraps the result of its fixed-point
operations.
'Saturate'
–– The object saturates the result of its
fixed-point operations.
For more details on overflow actions, see overflow mode for fixed-point operations.
StepSizeDataType
— Step size word length and fraction length settings'Same word length as first input'
(default) | 'Custom'
Step size word length and fraction length settings, specified as one of the following:
'Same word length as first input'
–– The object specifies
the word length of step size to be the same as that of the first input. The
fraction length is computed to get the best possible precision.
'Custom'
–– The step size data type is specified as a
custom numeric type through the CustomStepSizeDataType property.
For more information on the step size data type this object uses, see the Fixed Point section.
CustomStepSizeDataType
— Word and fraction lengths of step sizenumerictype([],16,15)
(default)Word and fraction lengths of the step size, specified as an autosigned numeric type with a word length of 16 and a fraction length of 15.
Example: numerictype([],32)
This property applies under the following conditions:
StepSizeSource property set to
'Property'
and StepSizeDataType set to
'Custom'
.
StepSizeSource
property set to 'Input
port'
.
LeakageFactorDataType
— Leakage factor word length and fraction length settings'Same word length as first input'
(default) | 'Custom'
Leakage factor word length and fraction length settings, specified as one of the following:
'Same word length as first input'
–– The object specifies
the word length of leakage factor to be the same as that of the first input. The
fraction length is computed to get the best possible precision.
'Custom'
–– The leakage factor data type is specified as a
custom numeric type through the CustomLeakageFactorDataType property.
For more information on the leakage factor data type this object uses, see the Fixed Point section.
CustomLeakageFactorDataType
— Word and fraction lengths of the leakage factornumerictype([],16,15)
(default)Word and fraction lengths of the leakage factor, specified as an autosigned numeric type with a word length of 16 and a fraction length of 15.
Example: numerictype([],32)
This property applies when you set the LeakageFactorDataType property to
'Custom'
.
WeightsDataType
— Weights word length and fraction length settings'Same as first input'
(default) | 'Custom'
Weights word length and fraction length settings, specified as one of the following:
'Same as first input'
–– The object specifies the data type
of the filter weights to be the same as that of the first input.
'Custom'
–– The data type of filter weights is specified as
a custom numeric type through the CustomWeightsDataType property.
For more information on the filter weights data type this object uses, see the Fixed Point section.
CustomWeightsDataType
— Word and fraction lengths of filter weightsnumerictype([],16,15)
(default)Word and fraction lengths of the filter weights, specified as an autosigned numeric type with a word length of 16 and a fraction length of 15.
Example: numerictype([],32,20)
This property applies when you set the WeightsDataType property to
'Custom'
.
EnergyProductDataType
— Energy product word length and fraction length settings'Same as first input'
(default) | 'Custom'
Energy product word length and fraction length settings, specified as one of the following:
'Same as first input'
–– The object specifies the data type
of the energy product to be the same as that of the first input.
'Custom'
–– The data type of the energy product is
specified as a custom numeric type through the CustomEnergyProductDataType property.
For more information on the energy product data type this object uses, see the Fixed Point section.
This property applies when you set the Method property to 'Normalized
LMS'
.
CustomEnergyProductDataType
— Word and fraction lengths of energy productnumerictype([],32,20)
(default)Word and fraction lengths of the energy product, specified as an autosigned numeric type with a word length of 32 and a fraction length of 20.
This property applies when you set the Method property to 'Normalized
LMS'
and EnergyProductDataType property to
'Custom'
.
EnergyAccumulatorDataType
— Energy accumulator word length and fraction length settings'Same as first input'
(default) | 'Custom'
Energy accumulator word length and fraction length settings, specified as one of the following:
'Same as first input'
–– The object specifies the data type
of the energy accumulator to be the same as that of the first input.
'Custom'
–– The data type of the energy accumulator is
specified as a custom numeric type through the CustomEnergyAccumulatorDataType
property.
For more information on the energy accumulator data type this object uses, see the Fixed Point section.
This property applies when you set the Method property to 'Normalized
LMS'
.
CustomEnergyAccumulatorDataType
— Word and fraction lengths of energy accumulatornumerictype([],32,20)
(default)Word and fraction lengths of the energy accumulator, specified as an autosigned numeric type with a word length of 32 and a fraction length of 20.
This property applies when you set the Method property to 'Normalized
LMS'
and EnergyAccumulatorDataType property to
'Custom'
.
ConvolutionProductDataType
— Convolution product word length and fraction length settings'Same as first input'
(default) | 'Custom'
Convolution product word length and fraction length settings, specified as one of the following:
'Same as first input'
–– The object specifies the data type
of the convolution product to be the same as that of the first input.
'Custom'
–– The data type of the convolution product is
specified as a custom numeric type through the CustomConvolutionProductDataType
property.
For more information on the convolution product data type this object uses, see the Fixed Point section.
CustomConvolutionProductDataType
— Word and fraction lengths of convolution productnumerictype([],32,20)
(default)Word and fraction lengths of the convolution product, specified as an autosigned numeric type with a word length of 32 and a fraction length of 20.
This property applies when you set the ConvolutionProductDataType property to
'Custom'
.
ConvolutionAccumulatorDataType
— Convolution accumulator word length and fraction length settings'Same as first input'
(default) | 'Custom'
Convolution accumulator word length and fraction length settings, specified as one of the following:
'Same as first input'
–– The object specifies the data type
of the convolution accumulator to be the same as that of the first input.
'Custom'
–– The data type of the convolution accumulator is
specified as a custom numeric type through the CustomConvolutionAccumulatorDataType
property.
For more information on the convolution accumulator data type this object uses, see the Fixed Point section.
CustomConvolutionAccumulatorDataType
— Word and fraction lengths of convolution accumulatornumerictype([],32,20)
(default)Word and fraction lengths of the convolution accumulator, specified as an autosigned numeric type with a word length of 32 and a fraction length of 20.
This property applies when you set the ConvolutionAccumulatorDataType property to
'Custom'
.
StepSizeErrorProductDataType
— Step size error product word length and fraction length settings'Same as first input'
(default) | 'Custom'
Step size error product word length and fraction length settings, specified as one of the following:
'Same as first input'
–– The object specifies the data type
of the step size error product to be the same as that of the first input.
'Custom'
–– The data type of the step size error product is
specified as a custom numeric type through the CustomStepSizeErrorProductDataType
property.
For more information on the step size error product data type this object uses, see the Fixed Point section.
CustomStepSizeErrorProductDataType
— Word and fraction lengths of step size error productnumerictype([],32,20)
(default)Word and fraction lengths of the step size error product, specified as an autosigned numeric type with a word length of 32 and a fraction length of 20.
This property applies when you set the StepSizeErrorProductDataType property to
'Custom'
.
WeightsUpdateProductDataType
— Filter weights update product word length and fraction length settings'Same as first input'
(default) | 'Custom'
Word and fraction length settings of the filter weights update product, specified as one of the following:
'Same as first input'
–– The object specifies the data type
of the filter weights update product to be the same as that of the first
input.
'Custom'
–– The data type of the filter weights update
product is specified as a custom numeric type through the CustomWeightsUpdateProductDataType
property.
For more information on the filter weights update product data type this object uses, see the Fixed Point section.
CustomWeightsUpdateProductDataType
— Word and fraction lengths of filter weights update productnumerictype([],32,20)
(default)Word and fraction lengths of the filter weights update product, specified as an autosigned numeric type with a word length of 32 and a fraction length of 20.
This property applies when you set the WeightsUpdateProductDataType property to
'Custom'
.
QuotientDataType
— Quotient word length and fraction length settings'Same as first input'
(default) | 'Custom'
Quotient word length and fraction length settings, specified as one of the following:
'Same as first input'
–– The object specifies the quotient
data type to be the same as that of the first input.
'Custom'
–– The quotient data type is specified as a custom
numeric type through the CustomQuotientDataType property.
For more information on the quotient data type this object uses, see the Fixed Point section.
This property applies when you set the Method property to 'Normalized
LMS'
.
CustomQuotientDataType
— Word and fraction lengths of quotientnumerictype([],32,20)
(default)Word and fraction lengths of the filter weights update product, specified as an autosigned numeric type with a word length of 32 and a fraction length of 20.
This property applies when you set the Method property to 'Normalized
LMS'
and QuotientDataType property to
'Custom'
.
[
filters the input signal, y
,err
,wts
] = lms(x
,d
)x
, using d
as the
desired signal, and returns the filtered output in y
, the filter
error in err
, and the estimated filter weights in
wts
. The LMS filter object estimates the filter weights needed to
minimize the error between the output signal and the desired signal.
[
filters the input signal, y
,err
] = lms(x
,d
)x
, using d
as the
desired signal, and returns the filtered output in y
and the filter
error in err
when the WeightsOutput property is set to
'None'
.
[___] = lms(
filters the input signal, x
,d
,mu
)x
, using d
as the
desired signal and mu
as the step size, when the StepSizeSource property is set to 'Input
port'
. These inputs can be used with either of the previous sets of
outputs.
[___] = lms(
filters the input signal, x
,d
,a
)x
, using d
as the
desired signal and a
as the adaptation control when the AdaptInputPort property is set to
true
. When a
is nonzero, the System object continuously updates the filter weights. When a
is
zero, the filter weights remain constant.
[___] = lms(
filters the input signal, x
,d
,r
)x
, using d
as the
desired signal and r
as a reset signal when the WeightsResetInputPort property is set to
true
. The WeightsResetCondition property can be used to set the
reset trigger condition. If a reset event occurs, the System object resets the filter weights to their initial values.
x
— Data inputThe signal to be filtered by the LMS filter. The input, x
,
and the desired signal, d
must have the same size, data type, and
complexity. If the input is fixed-point, the data type must be signed and must have
the same word length as the desired signal.
The input, x
can be a variable-size signal. You can change
the number of elements in the column vector even when the object is locked. The
System object locks when you call the object to run its algorithm.
Data Types: single
| double
| int8
| int16
| int32
| int64
| fi
Complex Number Support: Yes
d
— Desired signalThe LMS filter adapts its filter weights, wts
, to minimize
the error, err
, and converge the input signal
x
to the desired signal d
as closely as
possible.
The input, x
, and the desired signal, d
,
must have the same size, data type, and complexity. If the desired signal is
fixed-point, the data type must be signed and must have the same word length as the
data input.
The input, d
can be a variable-size signal. You can change
the number of elements in the column vector even when the object is locked. The
System object locks when you call the object to run its algorithm.
Data Types: single
| double
| int8
| int16
| int32
| int64
| fi
Complex Number Support: Yes
mu
— Step sizeAdaptation step size factor, specified as a scalar, nonnegative numeric value. For
convergence of the normalized LMS method, the step size should be greater than 0 and
less than 2. The data type of the step size input must match the data type of
x
and d
. If the data type is fixed-point,
the data type must be signed.
A small step size ensures a small steady state error between the output
y
and the desired signal d
. If the step
size is small, the convergence speed of the filter decreases. To improve the
convergence speed, increase the step size. Note that if the step size is large, the
filter can become unstable. To compute the maximum step size the filter can accept
without becoming unstable, use the maxstep
function.
This input is required when the StepSizeSource property is set to 'Input
port'
.
Data Types: single
| double
| int8
| int16
| int32
| int64
| fi
a
— Adaptation controlAdaptation control input that controls how the filter weights are updated. If the value of this input is non-zero, the object continuously updates the filter weights. If the value of this input is zero, the filter weights remain at their current value.
This input is required when the AdaptInputPort property is set to
true
.
Data Types: single
| double
| int8
| int16
| int32
| uint8
| uint16
| uint32
| logical
r
— Reset signalReset signal that resets the filter weights based on the values of the WeightsResetCondition property.
This input is required when the WeightsResetInputPort property is set to
true
.
Data Types: single
| double
| int8
| int16
| int32
| uint8
| uint16
| uint32
| logical
y
— Filtered outputFiltered output, returned as a scalar or a column vector. The object adapts its
filter weights to converge the input signal x
to match the
desired signal d
. The filter outputs the converged signal.
Data Types: single
| double
| int8
| int16
| int32
| int64
| fi
Complex Number Support: Yes
err
— Difference between output and desired signalDifference between the output signal y
and the desired signal
d
, returned as a scalar or a column vector. The data type of
err
matches the data type of y
. The
objective of the adaptive filter is to minimize this error. The object adapts its
weights to converge towards optimal filter weights that produce an output signal that
matches closely with the desired signal. For more details on how
err
is computed, see Algorithms.
Data Types: single
| double
| int8
| int16
| int32
| int64
| fi
wts
— Adaptive filter weightsAdaptive filter weights, returned as a scalar or a column vector of length specified by the value in Length.
Data Types: single
| double
| int8
| int16
| int32
| int64
| fi
To use an object function, specify the
System object as the first input argument. For
example, to release system resources of a System object named obj
, use
this syntax:
release(obj)
The mean squared error (MSE) measures the average of the squares of the errors between the desired signal and the primary signal input to the adaptive filter. Reducing this error converges the primary input to the desired signal. Determine the predicted value of MSE and the simulated value of MSE at each time instant using the msepred
and msesim
functions. Compare these MSE values with each other and with respect to the minimum MSE and steady-state MSE values. In addition, compute the sum of the squares of the coefficient errors given by the trace of the coefficient covariance matrix.
Note: If you are using R2016a or an earlier release, replace each call to the object with the equivalent step syntax. For example, obj(x)
becomes step(obj,x)
.
Initialization
Create a dsp.FIRFilter
System object™ that represents the unknown system. Pass the signal, x
, to the FIR filter. The output of the unknown system is the desired signal, d
, which is the sum of the output of the unknown system (FIR filter) and an additive noise signal, n
.
num = fir1(31,0.5); fir = dsp.FIRFilter('Numerator',num); iir = dsp.IIRFilter('Numerator',sqrt(0.75),... 'Denominator',[1 -0.5]); x = iir(sign(randn(2000,25))); n = 0.1*randn(size(x)); d = fir(x) + n;
LMS Filter
Create a dsp.LMSFilter
System object to create a filter that adapts to output the desired signal. Set the length of the adaptive filter to 32 taps, step size to 0.008, and the decimation factor for analysis and simulation to 5. The variable simmse
represents the simulated MSE between the output of the unknown system, d
, and the output of the adaptive filter. The variable mse
gives the corresponding predicted value.
l = 32; mu = 0.008; m = 5; lms = dsp.LMSFilter('Length',l,'StepSize',mu); [mmse,emse,meanW,mse,traceK] = msepred(lms,x,d,m); [simmse,meanWsim,Wsim,traceKsim] = msesim(lms,x,d,m);
Plot the MSE Results
Compare the values of simulated MSE, predicted MSE, minimum MSE, and the final MSE. The final MSE value is given by the sum of minimum MSE and excess MSE.
nn = m:m:size(x,1); semilogy(nn,simmse,[0 size(x,1)],[(emse+mmse)... (emse+mmse)],nn,mse,[0 size(x,1)],[mmse mmse]) title('Mean Squared Error Performance') axis([0 size(x,1) 0.001 10]) legend('MSE (Sim.)','Final MSE','MSE','Min. MSE') xlabel('Time Index') ylabel('Squared Error Value')
The predicted MSE follows the same trajectory as the simulated MSE. Both these trajectories converge with the steady-state (final) MSE.
Plot the Coefficient Trajectories
meanWsim
is the mean value of the simulated coefficients given by msesim
. meanW
is the mean value of the predicted coefficients given by msepred
.
Compare the simulated and predicted mean values of LMS filter coefficients 12,13,14, and 15.
plot(nn,meanWsim(:,12),'b',nn,meanW(:,12),'r',nn,... meanWsim(:,13:15),'b',nn,meanW(:,13:15),'r') PlotTitle ={'Average Coefficient Trajectories for';... 'W(12), W(13), W(14), and W(15)'}
PlotTitle = 2x1 cell
{'Average Coefficient Trajectories for'}
{'W(12), W(13), W(14), and W(15)' }
title(PlotTitle) legend('Simulation','Theory') xlabel('Time Index') ylabel('Coefficient Value')
In steady state, both the trajectories converge.
Sum of Squared Coefficient Errors
Compare the sum of the squared coefficient errors given by msepred
and msesim
. These values are given by the trace of the coefficient covariance matrix.
semilogy(nn,traceKsim,nn,traceK,'r') title('Sum-of-Squared Coefficient Errors') axis([0 size(x,1) 0.0001 1]) legend('Simulation','Theory') xlabel('Time Index') ylabel('Squared Error Value')
The maxstep
function computes the maximum step size of the adaptive filter. This step size keeps the filter stable at the maximum possible speed of convergence. Create the primary input signal, x
, by passing a signed random signal to an IIR filter. Signal x
contains 50 frames of 2000 samples each frame. Create an LMS filter with 32 taps and a step size of 0.1.
x = zeros(2000,50); IIRFilter = dsp.IIRFilter('Numerator',sqrt(0.75),'Denominator',[1 -0.5]); for k = 1:size(x,2) x(:,k) = IIRFilter(sign(randn(size(x,1),1))); end mu = 0.1; LMSFilter = dsp.LMSFilter('Length',32,'StepSize',mu);
Compute the maximum adaptation step size and the maximum step size in mean-squared sense using the maxstep
function.
[mumax,mumaxmse] = maxstep(LMSFilter,x)
mumax = 0.0625
mumaxmse = 0.0536
System identification is the process of identifying the coefficients of an unknown system using an adaptive filter. The general overview of the process is shown in System Identification –– Using an Adaptive Filter to Identify an Unknown System. The main components involved are:
The adaptive filter algorithm. In this example, set the Method
property of dsp.LMSFilter
to 'LMS'
to choose the LMS adaptive filter algorithm.
An unknown system or process to adapt to. In this example, the filter designed by fircband
is the unknown system.
Appropriate input data to exercise the adaptation process. For the generic LMS model, these are the desired signal $\mathit{d}\left(\mathit{k}\right)$ and the input signal $\mathit{x}\left(\mathit{k}\right)$.
The objective of the adaptive filter is to minimize the error signal between the output of the adaptive filter $\mathit{y}\left(\mathit{k}\right)$ and the output of the unknown system (or the system to be identified) $\mathit{d}\left(\mathit{k}\right)$. Once the error signal is minimized, the adapted filter resembles the unknown system. The coefficients of both the filters match closely.
Note: If you are using R2016a or an earlier release, replace each call to the object with the equivalent step syntax. For example, obj(x)
becomes step(obj,x)
.
Unknown System
Create a dsp.FIRFilter
object that represents the system to be identified. Use the fircband
function to design the filter coefficients. The designed filter is a lowpass filter constrained to 0.2 ripple in the stopband.
filt = dsp.FIRFilter; filt.Numerator = fircband(12,[0 0.4 0.5 1],[1 1 0 0],[1 0.2],... {'w' 'c'});
Pass the signal x
to the FIR filter. The desired signal d
is the sum of the output of the unknown system (FIR filter) and an additive noise signal n
.
x = 0.1*randn(250,1); n = 0.01*randn(250,1); d = filt(x) + n;
Adaptive Filter
With the unknown filter designed and the desired signal in place, create and apply the adaptive LMS filter object to identify the unknown filter.
Preparing the adaptive filter object requires starting values for estimates of the filter coefficients and the LMS step size (mu
). You can start with some set of nonzero values as estimates for the filter coefficients. This example uses zeros for the 13 initial filter weights. Set the InitialConditions
property of dsp.LMSFilter
to the desired initial values of the filter weights. For the step size, 0.8 is a good compromise between being large enough to converge well within 250 iterations (250 input sample points) and small enough to create an accurate estimate of the unknown filter.
Create a dsp.LMSFilter
object to represent an adaptive filter that uses the LMS adaptive algorithm. Set the length of the adaptive filter to 13 taps and the step size to 0.8.
mu = 0.8;
lms = dsp.LMSFilter(13,'StepSize',mu)
lms = dsp.LMSFilter with properties: Method: 'LMS' Length: 13 StepSizeSource: 'Property' StepSize: 0.8000 LeakageFactor: 1 InitialConditions: 0 AdaptInputPort: false WeightsResetInputPort: false WeightsOutput: 'Last' Show all properties
Pass the primary input signal x
and the desired signal d
to the LMS filter. Run the adaptive filter to determine the unknown system. The output y
of the adaptive filter is the signal converged to the desired signal d thereby minimizing the error e
between the two signals.
Plot the results. The output signal does not match the desired signal as expected, making the error between the two nontrivial.
[y,e,w] = lms(x,d); plot(1:250, [d,y,e]) title('System Identification of an FIR filter') legend('Desired','Output','Error') xlabel('Time index') ylabel('Signal value')
Compare the Weights
The weights vector w
represents the coefficients of the LMS filter that is adapted to resemble the unknown system (FIR filter). To confirm the convergence, compare the numerator of the FIR filter and the estimated weights of the adaptive filter.
The estimated filter weights do not closely match the actual filter weights, confirming the results seen in the previous signal plot.
stem([(filt.Numerator).' w]) title('System Identification by Adaptive LMS Algorithm') legend('Actual filter weights','Estimated filter weights',... 'Location','NorthEast')
Changing the Step Size
As an experiment, change the step size to 0.2. Repeating the example with mu = 0.2
results in the following stem plot. The filters do not converge, and the estimated weights are not good approxmations of the actual weights.
mu = 0.2; lms = dsp.LMSFilter(13,'StepSize',mu); [~,~,w] = lms(x,d); stem([(filt.Numerator).' w]) title('System Identification by Adaptive LMS Algorithm') legend('Actual filter weights','Estimated filter weights',... 'Location','NorthEast')
Increase the Number of Data Samples
Increase the frame size of the desired signal. Even though this increases the computation involved, the LMS algorithm now has more data that can be used for adaptation. With 1000 samples of signal data and a step size of 0.2, the coefficients are aligned closer than before, indicating an improved convergence.
release(filt); x = 0.1*randn(1000,1); n = 0.01*randn(1000,1); d = filt(x) + n; [y,e,w] = lms(x,d); stem([(filt.Numerator).' w]) title('System Identification by Adaptive LMS Algorithm') legend('Actual filter weights','Estimated filter weights',... 'Location','NorthEast')
Increase the number of data samples further by inputting the data through iterations. Run the algorithm on 4000 samples of data, passed to the LMS algorithm in batches of 1000 samples over 4 iterations.
Compare the filter weights. The weights of the LMS filter match the weights of the FIR filter very closely, indicating a good convergence.
release(filt); n = 0.01*randn(1000,1); for index = 1:4 x = 0.1*randn(1000,1); d = filt(x) + n; [y,e,w] = lms(x,d); end stem([(filt.Numerator).' w]) title('System Identification by Adaptive LMS Algorithm') legend('Actual filter weights','Estimated filter weights',... 'Location','NorthEast')
The output signal matches the desired signal very closely, making the error between the two close to zero.
plot(1:1000, [d,y,e]) title('System Identification of an FIR filter') legend('Desired','Output','Error') xlabel('Time index') ylabel('Signal value')
To improve the convergence performance of the LMS algorithm, the normalized variant (NLMS) uses an adaptive step size based on the signal power. As the input signal power changes, the algorithm calculates the input power and adjusts the step size to maintain an appropriate value. The step size changes with time, and as a result, the normalized algorithm converges faster with fewer samples in many cases. For input signals that change slowly over time, the normalized LMS algorithm can be a more efficient LMS approach.
For an example using the LMS approach, see System Identification of FIR Filter Using LMS Algorithm.
Note: If you are using R2016a or an earlier release, replace each call to the object with the equivalent step syntax. For example, obj(x)
becomes step(obj,x)
.
Unknown System
Create a dsp.FIRFilter
object that represents the system to be identified. Use the fircband
function to design the filter coefficients. The designed filter is a lowpass filter constrained to 0.2 ripple in the stopband.
filt = dsp.FIRFilter; filt.Numerator = fircband(12,[0 0.4 0.5 1],[1 1 0 0],[1 0.2],... {'w' 'c'});
Pass the signal x
to the FIR filter. The desired signal d
is the sum of the output of the unknown system (FIR filter) and an additive noise signal n
.
x = 0.1*randn(1000,1); n = 0.001*randn(1000,1); d = filt(x) + n;
Adaptive Filter
To use the normalized LMS algorithm variation, set the Method
property on the dsp.LMSFilter
to 'Normalized LMS'
. Set the length of the adaptive filter to 13 taps and the step size to 0.2.
mu = 0.2; lms = dsp.LMSFilter(13,'StepSize',mu,'Method',... 'Normalized LMS');
Pass the primary input signal x
and the desired signal d
to the LMS filter.
[y,e,w] = lms(x,d);
The output y
of the adaptive filter is the signal converged to the desired signal d thereby minimizing the error e
between the two signals.
plot(1:1000, [d,y,e]) title('System Identification by Normalized LMS Algorithm') legend('Desired','Output','Error') xlabel('Time index') ylabel('Signal value')
Compare the Adapted Filter to the Unknown System
The weights vector w represents the coefficients of the LMS filter that is adapted to resemble the unknown system (FIR filter). To confirm the convergence, compare the numerator of the FIR filter and the estimated weights of the adaptive filter.
stem([(filt.Numerator).' w]) title('System Identification by Normalized LMS Algorithm') legend('Actual filter weights','Estimated filter weights',... 'Location','NorthEast')
An adaptive filter adapts its filter coefficients to match the coefficients of an unknown system. The objective is to minimize the error signal between the output of the unknown system and the output of the adaptive filter. When these two outputs converge and match closely for the same input, the coefficients are said to match closely. The adaptive filter at this state resembles the unknown system. This example compares the rate at which this convergence happens for the normalized LMS (NLMS) algorithm and the LMS algorithm with no normalization.
Unknown System
Create a dsp.FIRFilter
that represents the unknown system. Pass the signal x
as an input to the unknown system. The desired signal d
is the sum of the output of the unknown system (FIR filter) and an additive noise signal n
.
filt = dsp.FIRFilter; filt.Numerator = fircband(12,[0 0.4 0.5 1],[1 1 0 0],[1 0.2],... {'w' 'c'}); x = 0.1*randn(1000,1); n = 0.001*randn(1000,1); d = filt(x) + n;
Adaptive Filter
Create two dsp.LMSFilter
objects, with one set to the LMS algorithm, and the other set to the normalized LMS algorithm. Choose an adaptation step size of 0.2 and set the length of the adaptive filter to 13 taps.
mu = 0.2; lms_nonnormalized = dsp.LMSFilter(13,'StepSize',mu,... 'Method','LMS'); lms_normalized = dsp.LMSFilter(13,'StepSize',mu,... 'Method','Normalized LMS');
Pass the primary input signal x
and the desired signal d
to both the variations of the LMS algorithm. The variables e1
and e2
represent the error between the desired signal and the output of the normalized and nonnormalized filters, respecitvely.
[~,e1,~] = lms_normalized(x,d); [~,e2,~] = lms_nonnormalized(x,d);
Plot the error signals for both variations. The error signal for the NLMS variant converges to zero much faster than the error signal for the LMS variant. The normalized version adapts in far fewer iterations to a result almost as good as the nonnormalized version.
plot([e1,e2]); title('Comparing the LMS and NLMS Conversion Performance'); legend('NLMS derived filter weights', ... 'LMS derived filter weights','Location', 'NorthEast'); xlabel('Time index') ylabel('Signal value')
Cancel additive noise, n, added to an unknown system using an LMS adaptive filter. The LMS filter adapts its coefficients until its transfer function matches the transfer function of the unknown system as closely as possible. The difference between the output of the adaptive filter and the output of the unknown system represents the error signal, e
. Minimizing this error signal is the objective of the adaptive filter.
The unknown system and the LMS filter process the same input signal, x
, and produce outputs d
and y
, respectively. If the coefficients of the adaptive filter match the coefficients of the unknown system, the error, e
, in effect represents the additive noise.
Note: If you are using R2016a or an earlier release, replace each call to the object with the equivalent step syntax. For example, obj(x)
becomes step(obj,x)
.
Create a dsp.FIRFilter
System object to represent the unknown system. Create a dsp.LMSFilter
object and set the length to 11 taps and the step size to 0.05. Create a sine wave to represent the noise added to the unknown system. View the signals in a time scope.
FrameSize = 100; NIter = 10; lmsfilt2 = dsp.LMSFilter('Length',11,'Method','Normalized LMS', ... 'StepSize',0.05); firfilt2 = dsp.FIRFilter('Numerator', fir1(10,[.5, .75])); sinewave = dsp.SineWave('Frequency',0.01, ... 'SampleRate',1,'SamplesPerFrame',FrameSize); scope = timescope('TimeUnits','Seconds',... 'YLimits',[-3 3],'BufferLength',2*FrameSize*NIter, ... 'ShowLegend',true,'ChannelNames', ... {'Noisy signal', 'Error signal'});
Create a random input signal, x and pass the signal to the FIR filter. Add a sine wave to the output of the FIR filter to generate the noisy signal, d. The signal, d is the output of the unknown system. Pass the noisy signal and the primary input signal to the LMS filter. View the noisy signal and the error signal in the time scope.
for k = 1:NIter x = randn(FrameSize,1); d = firfilt2(x) + sinewave(); [y,e,w] = lmsfilt2(x,d); scope([d,e]) end release(scope)
The error signal, e
, is the sinusoidal noise added to the unknown system. Minimizing the error signal minimizes the noise added to the system.
When the amount of computation required to derive an adaptive filter drives your development process, the sign-data variant of the LMS (SDLMS) algorithm might be a very good choice, as demonstrated in this example.
In the standard and normalized variations of the LMS adaptive filter, coefficients for the adapting filter arise from the mean square error between the desired signal and the output signal from the unknown system. The sign-data algorithm changes the mean square error calculation by using the sign of the input data to change the filter coefficients.
When the error is positive, the new coefficients are the previous coefficients plus the error multiplied by the step size µ. If the error is negative, the new coefficients are again the previous coefficients minus the error multiplied by µ — note the sign change.
When the input is zero, the new coefficients are the same as the previous set.
In vector form, the sign-data LMS algorithm is:
$$\mathit{w}\left(\mathit{k}+1\right)=\mathit{w}\left(\mathit{k}\right)+\mu \mathit{e}\left(\mathit{k}\right)\mathrm{sgn}\left(\mathit{x}\left(\mathit{k}\right)\right),$$
where
$$\mathrm{sgn}\left(\mathit{x}\left(\mathit{k}\right)\right)=\{\begin{array}{c}1,\text{\hspace{0.17em}}\mathit{x}\left(\mathit{k}\right)>0\\ 0,\text{\hspace{0.17em}}\mathit{x}\left(\mathit{k}\right)=0\\ -1,\text{\hspace{0.17em}}\mathit{x}\left(\mathit{k}\right)<0\end{array}$$
with vector $\mathit{w}$ containing the weights applied to the filter coefficients and vector $\mathit{x}$ containing the input data. The vector $\mathit{e}$ is the error between the desired signal and the filtered signal. The objective of the SDLMS algorithm is to minimize this error. Step size is represented by $\mu $.
With a smaller $\mu $, the correction to the filter weights gets smaller for each sample, and the SDLMS error falls more slowly. A larger $\mu $ changes the weights more for each step, so the error falls more rapidly, but the resulting error does not approach the ideal solution as closely. To ensure a good convergence rate and stability, select $\mu $ within the following practical bounds.
$$0<\mu <\frac{1}{\mathit{N}\left\{\mathrm{InputSignalPower}\right\}},$$
where $\mathit{N}$ is the number of samples in the signal. Also, define $\mu $ as a power of two for efficient computing.
Note: How you set the initial conditions of the sign-data algorithm profoundly influences the effectiveness of the adaptation process. Because the algorithm essentially quantizes the input signal, the algorithm can become unstable easily.
A series of large input values, coupled with the quantization process might result in the error growing beyond all bounds. Restrain the tendency of the sign-data algorithm to get out of control by choosing a small step size $\left(\mu \ll 1\right)$ and setting the initial conditions for the algorithm to nonzero positive and negative values.
In this noise cancellation example, set the Method
property of dsp.LMSFilter
to 'Sign-Data LMS'
. This example requires two input data sets:
Data containing a signal corrupted by noise. In the block diagram under Noise or Interference Cancellation –– Using an Adaptive Filter to Remove Noise from an Unknown System, this is the desired signal $\mathit{d}\left(\mathit{k}\right)$. The noise cancellation process removes the noise from the signal.
Data containing random noise. In the block diagram under Noise or Interference Cancellation –– Using an Adaptive Filter to Remove Noise from an Unknown System, this is $\mathit{x}\left(\mathit{k}\right)$. The signal $\mathit{x}\left(\mathit{k}\right)$ is correlated with the noise that corrupts the signal data. Without the correlation between the noise data, the adapting algorithm cannot remove the noise from the signal.
For the signal, use a sine wave. Note that signal
is a column vector of 1000 elements.
signal = sin(2*pi*0.055*(0:1000-1)');
Now, add correlated white noise to signal
. To ensure that the noise is correlated, pass the noise through a lowpass FIR filter and then add the filtered noise to the signal.
noise = randn(1000,1); filt = dsp.FIRFilter; filt.Numerator = fir1(11,0.4); fnoise = filt(noise); d = signal + fnoise;
fnoise
is the correlated noise and d
is now the desired input to the sign-data algorithm.
To prepare the dsp.LMSFilter
object for processing, set the initial conditions of the filter weights and mu
(StepSize
). As noted earlier in this section, the values you set for coeffs
and mu
determine whether the adaptive filter can remove the noise from the signal path.
In System Identification of FIR Filter Using LMS Algorithm, you constructed a default filter that sets the filter coefficients to zeros. In most cases that approach does not work for the sign-data algorithm. The closer you set your initial filter coefficients to the expected values, the more likely it is that the algorithm remains well behaved and converges to a filter solution that removes the noise effectively.
For this example, start with the coefficients used in the noise filter (filt.Numerator
), and modify them slightly so the algorithm has to adapt.
coeffs = (filt.Numerator).'-0.01; % Set the filter initial conditions. mu = 0.05; % Set the step size for algorithm updating.
With the required input arguments for dsp.LMSFilter
prepared, construct the LMS filter object, run the adaptation, and view the results.
lms = dsp.LMSFilter(12,'Method','Sign-Data LMS',... 'StepSize',mu,'InitialConditions',coeffs); [~,e] = lms(noise,d); L = 200; plot(0:L-1,signal(1:L),0:L-1,e(1:L)); title('Noise Cancellation by the Sign-Data Algorithm'); legend('Actual signal','Result of noise cancellation',... 'Location','NorthEast'); xlabel('Time index') ylabel('Signal values')
When dsp.LMSFilter
runs, it uses far fewer multiplication operations than either of the standard LMS algorithms. Also, performing the sign-data adaptation requires only multiplication by bit shifting when the step size is a power of two.
Although the performance of the sign-data algorithm as shown in this plot is quite good, the sign-data algorithm is much less stable than the standard LMS variations. In this noise cancellation example, the processed signal is a very good match to the input signal, but the algorithm could very easily grow without bound rather than achieve good performance.
Changing the weight initial conditions (InitialConditions
) and mu
(StepSize
), or even the lowpass filter you used to create the correlated noise, can cause noise cancellation to fail.
In the standard and normalized variations of the LMS adaptive filter, the coefficients for the adapting filter arise from calculating the mean square error between the desired signal and the output signal from the unknown system, and applying the result to the current filter coefficients. The sign-error LMS (SELMS) algorithm replaces the mean square error calculation by using the sign of the error to modify the filter coefficients.
When the error is positive, the new coefficients are the previous coefficients plus the error multiplied by the step size $\mu $. If the error is negative, the new coefficients are the previous coefficients minus the error multiplied by $\mu $ — note the sign change. When the input is zero, the new coefficients are the same as the previous set.
In vector form, the sign-error LMS algorithm is:
$\mathit{w}\left(\mathit{k}+1\right)=\mathit{w}\left(\mathit{k}\right)+\mu \mathrm{sgn}\left(\mathit{e}\left(\mathit{k}\right)\right)\left(\mathit{x}\left(\mathit{k}\right)\right)$,
where
$$\mathrm{sgn}\left(\mathit{e}\left(\mathit{k}\right)\right)=\{\begin{array}{c}1,\text{\hspace{0.17em}}\mathit{e}\left(\mathit{k}\right)>0\\ 0,\text{\hspace{0.17em}}\mathit{e}\left(\mathit{k}\right)=0\\ -1,\text{\hspace{0.17em}}\mathit{e}\left(\mathit{k}\right)<0\end{array}$$
with vector $\mathit{w}$ containing the weights applied to the filter coefficients and vector $\mathit{x}$ containing the input data. The vector $\mathit{e}$ is the error between the desired signal and the filtered signal. The objective of the SELMS algorithm is to minimize this error.
With a smaller $\mu $, the correction to the filter weights gets smaller for each sample and the SELMS error falls more slowly. A larger $\mu $ changes the weights more for each step so the error falls more rapidly, but the resulting error does not approach the ideal solution as closely. To ensure a good convergence rate and stability, select $\mu $ within the following practical bounds.
$$0<\mu <\frac{1}{\mathit{N}\left\{\mathrm{InputSignalPower}\right\}}$$
where $\mathit{N}$ is the number of samples in the signal. Also, define $\mu $ as a power of two for efficient computation.
Note: How you set the initial conditions of the sign-error algorithm profoundly influences the effectiveness of the adaptation process. Because the algorithm essentially quantizes the error signal, the algorithm can become unstable easily.
A series of large error values, coupled with the quantization process might result in the error growing beyond all bounds. Restrain the tendency of the sign-error algorithm to become unstable by choosing a small step size $\left(\mu \ll 1\right)$ and setting the initial conditions for the algorithm to nonzero positive and negative values.
In this noise cancellation example, set the Method
property of dsp.LMSFilter
to 'Sign-Error LMS'
. This example requires two input data sets:
Data containing a signal corrupted by noise. In the block diagram under Noise or Interference Cancellation –– Using an Adaptive Filter to Remove Noise from an Unknown System, this is the desired signal $\mathit{d}\left(\mathit{k}\right)$. The noise cancellation process removes the noise from the signal.
Data containing random noise. In the block diagram under Noise or Interference Cancellation –– Using an Adaptive Filter to Remove Noise from an Unknown System, this is $\mathit{x}\left(\mathit{k}\right)$. The signal $\mathit{x}\left(\mathit{k}\right)$ is correlated with the noise that corrupts the signal data. Without the correlation between the noise data, the adapting algorithm cannot remove the noise from the signal.
For the signal, use a sine wave. Note that signal
is a column vector of 1000 elements.
signal = sin(2*pi*0.055*(0:1000-1)');
Now, add correlated white noise to signal
. To ensure that the noise is correlated, pass the noise through a lowpass FIR filter and then add the filtered noise to the signal.
noise = randn(1000,1); filt = dsp.FIRFilter; filt.Numerator = fir1(11,0.4); fnoise = filt(noise); d = signal + fnoise;
fnoise
is the correlated noise and d
is now the desired input to the sign-error algorithm.
To prepare the dsp.LMSFilter
object for processing, set the initial conditions of the filter weights (InitialConditions
) and mu
(StepSize
). As noted earlier in this section, the values you set for coeffs
and mu
determine whether the adaptive filter can remove the noise from the signal path.
In System Identification of FIR Filter Using LMS Algorithm, you constructed a default filter that sets the filter coefficients to zeros. In most cases that approach does not work for the sign-error algorithm. The closer you set your initial filter coefficients to the expected values, the more likely it is that the algorithm remains well behaved and converges to a filter solution that removes the noise effectively.
For this example, start with the coefficients used in the noise filter (filt.Numerator
) and modify them slightly so the algorithm has to adapt.
coeffs = (filt.Numerator).'-0.01; % Set the filter initial conditions. mu = 0.05; % Set the step size for algorithm updating.
With the required input arguments for dsp.LMSFilter
prepared, run the adaptation and view the results.
lms = dsp.LMSFilter(12,'Method','Sign-Error LMS',... 'StepSize',mu,'InitialConditions',coeffs); [~,e] = lms(noise,d); L = 200; plot(0:199,signal(1:200),0:199,e(1:200)); title('Noise cancellation performance by the sign-error LMS algorithm'); legend('Actual signal','Error after noise reduction',... 'Location','NorthEast') xlabel('Time index') ylabel('Signal value')
When the sign-error LMS algorithm runs, it uses far fewer multiplication operations than either of the standard LMS algorithms. Also, performing the sign-error adaptation requires only bit shifting multiples when the step size is a power of two.
Although the performance of the sign-error algorithm as shown in this plot is quite good, the sign-error algorithm is much less stable than the standard LMS variations. In this noise cancellation example, the adapted signal is a very good match to the input signal, but the algorithm could very easily become unstable rather than achieve good performance.
Changing the weight initial conditions (InitialConditions
) and mu
(StepSize
), or even the lowpass filter you used to create the correlated noise, can cause noise cancellation to fail and the algorithm to become useless.
The sign-sign LMS algorithm (SSLMS) replaces the mean square error calculation by using the sign of the input data to change the filter coefficients. When the error is positive, the new coefficients are the previous coefficients plus the error multiplied by the step size $\mu $. If the error is negative, the new coefficients are the previous coefficients minus the error multiplied by $\mu $ — note the sign change. When the input is zero, the new coefficients are the same as the previous set.
In essence, the algorithm quantizes both the error and the input by applying the sign operator to them.
In vector form, the sign-sign LMS algorithm is:
$$w(k+1)=w\left(k\right)+\mu \mathrm{sgn}\left(e\left(k\right)\right)\mathrm{sgn}\left(x\left(k\right)\right),$$
where
$$\mathrm{sgn}\left(\mathit{z}\left(\mathit{k}\right)\right)=\{\begin{array}{c}1,\text{\hspace{0.17em}}\mathit{z}\left(\mathit{k}\right)>0\\ 0,\text{\hspace{0.17em}}\mathit{z}\left(\mathit{k}\right)=0\\ -1,\text{\hspace{0.17em}}\mathit{z}\left(\mathit{k}\right)<0\end{array}$$
$$\mathit{z}\left(\mathit{k}\right)=\mathit{e}\left(\mathit{k}\right)\mathrm{sgn}\left(\mathit{x}\left(\mathit{k}\right)\right)$$
Vector $\mathit{w}$ contains the weights applied to the filter coefficients and vector $\mathit{x}$ contains the input data. The vector $\mathit{e}$ is the error between the desired signal and the filtered signal. The objective of the SSLMS algorithm is to minimize this error.
With a smaller $\mu $, the correction to the filter weights gets smaller for each sample and the SSLMS error falls more slowly. A larger $\mu $ changes the weights more for each step, so the error falls more rapidly, but the resulting error does not approach the ideal solution as closely. To ensure a good convergence rate and stability, select $\mu $ within the following practical bounds.
$$0<\mu <\frac{1}{\mathit{N}\left\{\mathrm{InputSignalPower}\right\}}$$
where $\mathit{N}$ is the number of samples in the signal. Also, define $\mu $ as a power of two for efficient computation
Note:
How you set the initial conditions of the sign-sign algorithm profoundly influences the effectiveness of the adaptation process. Because the algorithm essentially quantizes the input signal and the error signal, the algorithm can become unstable easily.
A series of large error values, coupled with the quantization process might result in the error growing beyond all bounds. Restrain the tendency of the sign-sign algorithm to become unstable by choosing a small step size $\left(\mu \ll 1\right)$ and setting the initial conditions for the algorithm to nonzero positive and negative values.
In this noise cancellation example, set the Method
property of dsp.LMSFilter
to 'Sign-Sign LMS'
. This example requires two input data sets:
Data containing a signal corrupted by noise. In the block diagram under Noise or Interference Cancellation –– Using an Adaptive Filter to Remove Noise from an Unknown System, this is the desired signal $\mathit{d}\left(\mathit{k}\right)$. The noise cancellation process removes the noise from the signal.
Data containing random noise. In the block diagram under Noise or Interference Cancellation –– Using an Adaptive Filter to Remove Noise from an Unknown System, this is $\mathit{x}\left(\mathit{k}\right)$. The signal $\mathit{x}\left(\mathit{k}\right)$ is correlated with the noise that corrupts the signal data. Without the correlation between the noise data, the adapting algorithm cannot remove the noise from the signal.
For the signal, use a sine wave. Note that signal
is a column vector of 1000 elements.
signal = sin(2*pi*0.055*(0:1000-1)');
Now, add correlated white noise to signal
. To ensure that the noise is correlated, pass the noise through a lowpass FIR filter, then add the filtered noise to the signal.
noise = randn(1000,1); filt = dsp.FIRFilter; filt.Numerator = fir1(11,0.4); fnoise = filt(noise); d = signal + fnoise;
fnoise
is the correlated noise and d
is now the desired input to the sign-sign algorithm.
To prepare the dsp.LMSFilter
object for processing, set the initial conditions of the filter weights (InitialConditions
) and mu
(StepSize
). As noted earlier in this section, the values you set for coeffs
and mu
determine whether the adaptive filter can remove the noise from the signal path. In System Identification of FIR Filter Using LMS Algorithm, you constructed a default filter that sets the filter coefficients to zeros. Usually that approach does not work for the sign-sign algorithm.
The closer you set your initial filter coefficients to the expected values, the more likely it is that the algorithm remains well behaved and converges to a filter solution that removes the noise effectively. For this example, you start with the coefficients used in the noise filter (filt.Numerator
), and modify them slightly so the algorithm has to adapt.
coeffs = (filt.Numerator).' -0.01; % Set the filter initial conditions.
mu = 0.05;
With the required input arguments for dsp.LMSFilter
prepared, run the adaptation and view the results.
lms = dsp.LMSFilter(12,'Method','Sign-Sign LMS',... 'StepSize',mu,'InitialConditions',coeffs); [~,e] = lms(noise,d); L = 200; plot(0:199,signal(1:200),0:199,e(1:200)); title('Noise cancellation performance by the sign-sign LMS algorithm'); legend('Actual signal','Error after noise reduction',... 'Location','NorthEast') xlabel('Time index') ylabel('Signal value')
When dsp.LMSFilter
runs, it uses far fewer multiplication operations than either of the standard LMS algorithms. Also, performing the sign-sign adaptation requires only bit shifting multiples when the step size is a power of two.
Although the performance of the sign-sign algorithm as shown in this plot is quite good, the sign-sign algorithm is much less stable than the standard LMS variations. In this noise cancellation example, the adapted signal is a very good match to the input signal, but the algorithm could very easily become unstable rather than achieve good performance.
Changing the weight initial conditions (InitialConditions
) and mu (StepSize
), or even the lowpass filter you used to create the correlated noise, can cause noise cancellation to fail and the algorithm to become useless.
Note: This example runs only in R2017a or later. If you are using a release earlier than R2017a, the object does not output a full sample-by-sample history of filter weights. If you are using a release earlier than R2016b, replace each call to the function with the equivalent step
syntax. For example, myObject(x)
becomes step(myObject,x)
.
Initialize the dsp.LMSFilter
System object and set the WeightsOutput
property to 'All'
. This setting enables the LMS filter to output a matrix of weights with dimensions [FrameLength Length]
, corresponding to the full sample-by-sample history of weights for all FrameLength
samples of input values.
FrameSize = 15000; lmsfilt3 = dsp.LMSFilter('Length',63,'Method','LMS', ... 'StepSize',0.001,'LeakageFactor',0.99999, ... 'WeightsOutput','All'); % full Weights history w_actual = fir1(64,[0.5 0.75]); firfilt3 = dsp.FIRFilter('Numerator',w_actual); sinewave = dsp.SineWave('Frequency',0.01, ... 'SampleRate',1,'SamplesPerFrame',FrameSize); scope = timescope('TimeUnits','Seconds', ... 'YLimits',[-0.25 0.75],'BufferLength',2*FrameSize, ... 'ShowLegend',true,'ChannelNames', ... {'Coeff 33 Estimate','Coeff 34 Estimate','Coeff 35 Estimate', ... 'Coeff 33 Actual','Coeff 34 Actual','Coeff 35 Actual'});
Run one frame and output the full adaptive weights history, w
.
x = randn(FrameSize,1); % Input signal d = firfilt3(x) + sinewave(); % Noise + Signal [~,~,w] = lmsfilt3(x,d);
Each row in w
is a set of weights estimated for the respective input sample. Each column in w
gives the complete history of a specific weight. Plot the actual weight and the entire history of the 33rd, 34th, and 35th weight. In the plot, you can see that the estimated weight output eventually converges with the actual weight as the adaptive filter receives input samples and continues to adapt.
idxBeg = 33; idxEnd = 35; scope([w(:,idxBeg:idxEnd), repmat(w_actual(idxBeg:idxEnd),FrameSize,1)])
The LMS filter algorithm is defined by the following equations.
$$\begin{array}{c}y(n)={w}^{T}(n-1)u(n)\\ e(n)=d(n)-y(n)\\ w(n)=\alpha w(n-1)+f(u(n),e(n),\mu )\end{array}$$
The various LMS adaptive filter algorithms available in this System object are defined as:
LMS –– Solves the Weiner-Hopf equation and finds the filter coefficients for an adaptive filter.
$$f(u(n),e(n),\mu )=\mu e(n){u}^{*}(n)$$
Normalized LMS –– Normalized variation of the LMS algorithm.
$$f(u(n),e(n),\mu )=\mu e(n)\frac{{u}^{\ast}(n)}{\epsilon +{u}^{H}(n)u(n)}$$
In Normalized LMS, to overcome potential numerical instability in the update of the weights, a small positive constant, ε, has been added in the denominator. For double-precision floating-point input, ε is 2.2204460492503131e-016. For single-precision floating-point input, ε is 1.192092896e-07. For fixed-point input, ε is 0.
Sign-Data LMS –– Correction to the filter weights at each iteration depends on the sign of the input u(n).
$$f(u(n),e(n),\mu )=\mu e(n)\text{sign}(u(n))$$
where u(n) is real.
Sign-Error LMS –– Correction applied to the current filter weights for each successive iteration depends on the sign of the error, e(n).
$$f(u(n),e(n),\mu )=\mu \text{sign}(e(n)){u}^{*}(n)$$
Sign-Sign LMS –– Correction applied to the current filter weights for each successive iteration depends on both the sign of u(n) and the sign of e(n).
$$f(u(n),e(n),\mu )=\mu \text{sign}(e(n))\text{sign}(u(n))$$
where u(n) is real.
The variables are as follows:
Variable | Description |
---|---|
n |
The current time index |
u(n) |
The vector of buffered input samples at step n |
u*(n) |
The complex conjugate of the vector of buffered input samples at step n |
w(n) |
The vector of filter weight estimates at step n |
y(n) |
The filtered output at step n |
e(n) |
The estimation error at step n |
d(n) |
The desired response at step n |
µ |
The adaptation step size |
α | The leakage factor (0 < α ≤ 1) |
ε | A constant that corrects any potential numerical instability that occurs during the update of weights. |
[1] Hayes, M.H. Statistical Digital Signal Processing and Modeling. New York: John Wiley & Sons, 1996.
Usage notes and limitations:
See System Objects in MATLAB Code Generation (MATLAB Coder).
The dsp.LMSFilter
System object supports SIMD code generation using Intel AVX2 technology under these
conditions:
Method
is set to 'LMS'
or
'Normalized LMS'
.
WeightsOutput
is set to 'None'
or
'Last'
.
Input signal is real-valued.
Input signal has a data type of single
or
double
.
The SIMD technology significantly improves the performance of the generated code.
The following diagrams show the data types used within the
dsp.LMSFilter
object for fixed-point signals. The table summarizes the
definitions of the variables used in the diagrams:
Variable | Definition |
---|---|
u | Input vector |
W | Vector of filter weights |
µ | Step size |
e | Error |
Q | Quotient, $$Q=\frac{\mu \cdot e}{u\text{'}u}$$ |
Product u'u | Product data type in Energy calculation diagram |
Accumulator u'u | Accumulator data type in Energy calculation diagram |
Product W'u | Product data type in Convolution diagram |
Accumulator W'u | Accumulator data type in Convolution diagram |
Product $$\mu \cdot e$$ | Product data type in Product of step size and error diagram |
Product $$Q\cdot u$$ | Product and accumulator data type in Weight update diagram. ^{1} |
^{1}The accumulator data type for this quantity is automatically set to be the same as the product data type. The minimum, maximum, and overflow information for this accumulator is logged as part of the product information. Autoscaling treats this product and accumulator as one data type.
You can set the data type of the properties, weights, products, quotient, and accumulators in the System object properties. Fixed-point inputs, outputs, and System object properties must have the following characteristics:
The input signal and the desired signal must have the same word length, but their fraction lengths can differ.
The step size and leakage factor must have the same word length, but their fraction lengths can differ.
The output signal and the error signal have the same word length and the same fraction length as the desired signal.
The quotient and the product output of the u'u, W'u, $$\mu \cdot e$$, and $$Q\cdot u$$ operations must have the same word length, but their fraction lengths can differ.
The accumulator data type of the u'u and W'u operations must have the same word length, but their fraction lengths can differ.
The output of the multiplier is in the product output data type if at least one of the inputs to the multiplier is real. If both of the inputs to the multiplier are complex, the result of the multiplication is in the accumulator data type. For details on the complex multiplication performed, see Multiplication Data Types.
dsp.AdaptiveLatticeFilter
| dsp.AffineProjectionFilter
| dsp.BlockLMSFilter
| dsp.FastTransversalFilter
| dsp.FilteredXLMSFilter
| dsp.FIRFilter
| dsp.FrequencyDomainAdaptiveFilter
| dsp.KalmanFilter
| dsp.RLSFilter
A modified version of this example exists on your system. Do you want to open this version instead?
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
Select web siteYou can also select a web site from the following list:
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.