Skip to content

Commit

Permalink
Some SM functions
Browse files Browse the repository at this point in the history
still need testing + examples
  • Loading branch information
BruninLima committed Nov 10, 2021
1 parent 0765338 commit 3920789
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 23 deletions.
28 changes: 9 additions & 19 deletions examples/Jupyter Notebooks/LMS-example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,6 @@
"import pydaptivefiltering as pdf"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bd8ad797",
"metadata": {},
"outputs": [],
"source": [
"pdf.main.AdaptiveFilter.adapt_LM"
]
},
{
"cell_type": "code",
"execution_count": 2,
Expand Down Expand Up @@ -73,7 +63,7 @@
{
"cell_type": "code",
"execution_count": 3,
"id": "128e247d",
"id": "eee8ad93",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -94,7 +84,7 @@
},
{
"cell_type": "markdown",
"id": "061c17b2",
"id": "3027dced",
"metadata": {},
"source": [
"### desired signal"
Expand All @@ -103,7 +93,7 @@
{
"cell_type": "code",
"execution_count": 5,
"id": "4d548220",
"id": "78036c04",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -119,7 +109,7 @@
},
{
"cell_type": "markdown",
"id": "1612256e",
"id": "2798d8d4",
"metadata": {},
"source": [
"### Istanciating Adaptive Filter"
Expand All @@ -128,7 +118,7 @@
{
"cell_type": "code",
"execution_count": 6,
"id": "85edb896",
"id": "dc0f4344",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -137,7 +127,7 @@
},
{
"cell_type": "markdown",
"id": "a809666e",
"id": "a9b728bd",
"metadata": {},
"source": [
"### Adapting with the LMS Algorithm "
Expand All @@ -146,7 +136,7 @@
{
"cell_type": "code",
"execution_count": 7,
"id": "026a7d78",
"id": "1a857ecf",
"metadata": {},
"outputs": [
{
Expand All @@ -169,7 +159,7 @@
},
{
"cell_type": "markdown",
"id": "cd20c36d",
"id": "6c8d3b3b",
"metadata": {},
"source": [
"## Plotting"
Expand All @@ -178,7 +168,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "50f18f56",
"id": "48b87b98",
"metadata": {},
"outputs": [],
"source": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,22 @@ def LMS_example():
plt.gca().set_title('Learning Curve for MSE [dB]')
MSE = [abs(err)**2 for err in Output['errors']]
plt.gca().semilogy(MSE)

plt.grid()
plt.subplot(222)
plt.gca().set_title('Learning Curve for MSEmin [dB]')
MSEmin = [abs(n)**2 for n in ComplexNoise]
plt.gca().semilogy(MSEmin)

plt.grid()
plt.subplot(223)
plt.gca().set_title('Evolution of the Coefficients (Real Part)')
real_part = [coef.real for coef in Output['coefficients']]
plt.gca().plot(real_part)

plt.grid()
plt.subplot(224)
plt.gca().set_title('Evolution of the Coefficients (Imaginary Part)')
imag_part = [coef.imag for coef in Output['coefficients']]
plt.gca().plot(imag_part)
plt.grid()

plt.tight_layout(pad=4.0)
plt.show()
136 changes: 136 additions & 0 deletions pydaptivefiltering/SM/AP.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# SM.AP.py
#
# Implements the Set-membership Affine-Projection algorithm for COMPLEX valued data.
# (Algorithm 6.2 - book: Adaptive Filtering: Algorithms and Practical
# Implementation, Diniz)
#
# Authors:
# . Bruno Ramos Lima Netto - [email protected] & [email protected]
# . Guilherme de Oliveira Pinto - [email protected] & [email protected]
# . Markus Vinícius Santos Lima - mvsl20@gmailcom & [email protected]
# . Wallace Alves Martins - [email protected] & [email protected]
# . Luiz Wagner Pereira Biscainho - [email protected] & [email protected]
# . Paulo Sergio Ramirez Diniz - [email protected]

# Imports
import numpy as np
from time import time


def AP(Filter, desired_signal: np.ndarray, input_signal: np.ndarray, gamma_bar: float, gamma_barVector: np.ndarray, gamma: float, memoryLength: int, verbose: bool = False) -> dict:
"""
Description
-----------
Implements the Set-membership Affine-Projection algorithm for COMPLEX valued data.
(Algorithm 6.2 - book: Adaptive Filtering: Algorithms and Practical Implementation, Diniz)
Syntax
------
OutputDictionary = SM.AP(Filter, desired_signal, input_signal, step, verbose)
Inputs
-------
filter : Adaptive Filter filter object
desired : Desired signal numpy array (row vector)
input : Input signal to feed filter numpy array (row vector)
gamma_bar : Upper bound for the error modulus.
gamma_barVector : Upper bound vector for the error modulus. (COLUMN vector)
gamma : Regularization factor.
memoryLength : Reuse data factor.
verbose : Verbose boolean bool
Outputs
-------
dictionary:
outputs : Store the estimated output of each iteration. numpy array (collumn vector)
errors : Store the error for each iteration. numpy array (collumn vector)
coefficients : Store the estimated coefficients for each iteration. numpy array (collumn vector)
nUpdates : Number of filter coefficient updates.
Main Variables
---------
regressor
outputs_vector[k] represents the output errors at iteration k
FIR error vectors.
error_vector[k] represents the output errors at iteration k.
Misc Variables
--------------
tic
nIterations
Comments:
Set-membership filtering implies that the (adaptive) filter coefficients are only
updated if the magnitude of the error is greater than S.gamma_bar. In practice, we
choose S.gamma_bar as a function of the noise variance (sigma_n2). A commom choice
is S.gamma_bar = sqrt(5 * sigma_n2).
When SM-AP updates, it makes the a posteriori error equal to S.gamma_barVector and
therefore, each of the (S.memoryLength+1) elements of S.gamma_barVector must be less
or equal to S.gamma_bar (in modulus).
Authors
-------
. Bruno Ramos Lima Netto - [email protected] & [email protected]
. Guilherme de Oliveira Pinto - [email protected] & [email protected]
. Markus Vinícius Santos Lima - mvsl20@gmailcom & [email protected]
. Wallace Alves Martins - [email protected] & [email protected]
. Luiz Wagner Pereira Biscainho - [email protected] & [email protected]
. Paulo Sergio Ramirez Diniz - [email protected]
"""

# Initialization
tic = time()
nIterations = desired_signal.size

regressor = np.zeros(
(Filter.filter_order+1, memoryLength+1), dtype=input_signal.dtype)
error_vector = np.array([])
outputs_vector = np.array([])
nUpdates = 0
# Main Loop

# assert len(gamma_barVector) == memoryLength + 1
# assert gamma_barVector .<= gamma_bar

prefixedInput = np.concatenate(
(np.zeros(Filter.filter_order+1), input_signal))
prefixedDesired = np.concatenate((np.zeros(memoryLength+1), input_signal))

for it in range(nIterations):

regressor[:, 2:memoryLength+1] = regressor[:, 1:memoryLength]

regressor[:, 1] = prefixedInput[it+(Filter.filter_order):-1]

coefficients = Filter.coefficients

output_it = np.dot(regressor.conj(), coefficients)

error_it = prefixedDesired[it+memoryLength].conj() - output_it

if abs(error_it) > gamma_bar:
nUpdates += 1

auxTerm = (regressor.T.conj()*regressor +
gamma*np.eye(memoryLength+1))

coefficients = coefficients + regressor * \
(1/auxTerm) * (error_it - gamma_barVector.conj())

Filter.coefficients_history.append(coefficients)

error_vector = np.append(error_vector, error_it)
outputs_vector = np.append(outputs_vector, output_it)

Filter.coefficients = coefficients

if verbose == True:
print(" ")
print('Total runtime {:.03} ms'.format((time() - tic)*1000))

return {'outputs': outputs_vector,
'errors': error_vector, 'coefficients': Filter.coefficients_history}, nUpdates

# EOF
127 changes: 127 additions & 0 deletions pydaptivefiltering/SM/NLMS.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# SM.NLMS.py
#
# Implements the Set-membership Normalized LMS algorithm for COMPLEX valued data.
# (Algorithm 6.1 - book: Adaptive Filtering: Algorithms and Practical
# Implementation, Diniz)
#
# Authors:
# . Bruno Ramos Lima Netto - [email protected] & [email protected]
# . Guilherme de Oliveira Pinto - [email protected] & [email protected]
# . Markus Vinícius Santos Lima - mvsl20@gmailcom & [email protected]
# . Wallace Alves Martins - [email protected] & [email protected]
# . Luiz Wagner Pereira Biscainho - [email protected] & [email protected]
# . Paulo Sergio Ramirez Diniz - [email protected]

# Imports
import numpy as np
from time import time


def NLMS(Filter, desired_signal: np.ndarray, input_signal: np.ndarray, gamma_bar: float, gamma:float, verbose: bool = False) -> dict:
"""
Description
-----------
Implements the Set-membership Normalized LMS algorithm for COMPLEX valued data.
(Algorithm 6.1 - book: Adaptive Filtering: Algorithms and Practical Implementation, Diniz)
Syntax
------
OutputDictionary = SM.NLMS(Filter, desired_signal, input_signal, verbose)
Inputs
-------
filter : Adaptive Filter filter object
desired : Desired signal numpy array (row vector)
input : Input signal to feed filter numpy array (row vector)
gamma_bar : Upper bound for the error modulus.
gamma_barVector : Upper bound vector for the error modulus. (COLUMN vector)
gamma : Regularization factor.
memoryLength : Reuse data factor.
verbose : Verbose boolean bool
Outputs
-------
dictionary:
outputs : Store the estimated output of each iteration. numpy array (collumn vector)
errors : Store the error for each iteration. numpy array (collumn vector)
coefficients : Store the estimated coefficients for each iteration. numpy array (collumn vector)
Main Variables
---------
regressor
outputs_vector[k] represents the output errors at iteration k
FIR error vectors.
error_vector[k] represents the output errors at iteration k.
Misc Variables
--------------
tic
nIterations
Comments:
Set-membership filtering implies that the (adaptive) filter coefficients are only
updated if the magnitude of the error is greater than S.gamma_bar. In practice, we
choose S.gamma_bar as a function of the noise variance (sigma_n2). A commom choice
is S.gamma_bar = sqrt(5 * sigma_n2).
Authors
-------
. Bruno Ramos Lima Netto - [email protected] & [email protected]
. Guilherme de Oliveira Pinto - [email protected] & [email protected]
. Markus Vinícius Santos Lima - mvsl20@gmailcom & [email protected]
. Wallace Alves Martins - [email protected] & [email protected]
. Luiz Wagner Pereira Biscainho - [email protected] & [email protected]
. Paulo Sergio Ramirez Diniz - [email protected]
"""

# Initialization
tic = time()
nIterations = desired_signal.size

regressor = np.zeros(Filter.filter_order+1, dtype=input_signal.dtype)
error_vector = np.array([])
outputs_vector = np.array([])
nUpdates = 0

# Main Loop

prefixedInput = np.concatenate(
(np.zeros(Filter.filter_order), input_signal))

for it in range(nIterations):

regressor = prefixedInput[it+(Filter.filter_order):-1]

coefficients = Filter.coefficients

output_it = np.dot(coefficients.conj(), regressor)

error_it = desired_signal[it] - output_it

if abs(error_it) > gamma_bar:

nUpdates += 1

mu = 1 - (gamma_bar/abs(error_it))

else:

mu = 0

error_vector = np.append(error_vector, error_it)
outputs_vector = np.append(outputs_vector, output_it)

coefficients = coefficients + mu / (gamma + regressor.T.conj()*regressor)*(error_it.conj()*regressor)

Filter.coefficients = coefficients

if verbose == True:
print(" ")
print('Total runtime {:.03} ms'.format((time() - tic)*1000))

return {'outputs': outputs_vector,
'errors': error_vector, 'coefficients': Filter.coefficients_history}, nUpdates

# EOF
5 changes: 5 additions & 0 deletions pydaptivefiltering/SM/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from pydaptivefiltering.SM.AP import AP
from pydaptivefiltering.SM.NLMS import NLMS
# from pydaptivefiltering.SM.BNLMS import LMS_Newton
# from pydaptivefiltering.SM.sAP import LMS_Newton
# from pydaptivefiltering.SM.sPUAP import LMS_Newton
Empty file.
Loading

0 comments on commit 3920789

Please sign in to comment.