Generalized Normalized Gradient Descent (GNGD)

New in version 0.2.

Changed in version 1.0.0.

The generalized normalized gradient descent (GNGD) adaptive filter [1] is an extension of the NLMS adaptive filter (filter-nlms-label).

The GNGD filter can be created as follows

>>> import padasip as pa
>>> pa.filters.FilterGNGD(n)

where n is the size (number of taps) of the filter.

Content of this page:

See also

Adaptive Filters

Minimal Working Examples

If you have measured data you may filter it as follows

# creation of data
N = 500
x = np.random.normal(0, 1, (N, 4)) # input matrix
v = np.random.normal(0, 0.1, N) # noise
d = 2*x[:,0] + 0.1*x[:,1] - 4*x[:,2] + 0.5*x[:,3] + v # target

# identification
f = pa.filters.FilterGNGD(n=4, mu=0.1, w="random")
y, e, w = f.run(d, x)

# show results
plt.figure(figsize=(15,9))
plt.subplot(211);plt.title("Adaptation");plt.xlabel("samples - k")
plt.plot(d,"b", label="d - target")
plt.plot(y,"g", label="y - output");plt.legend()
plt.subplot(212);plt.title("Filter error");plt.xlabel("samples - k")
plt.plot(10*np.log10(e**2),"r", label="e - error [dB]");plt.legend()
plt.tight_layout()
plt.show()

An example how to filter data measured in real-time

import numpy as np
import matplotlib.pylab as plt
import padasip as pa 

# these two function supplement your online measurment
def measure_x():
    # it produces input vector of size 3
    x = np.random.random(3)
    return x
    
def measure_d(x):
    # meausure system output
    d = 2*x[0] + 1*x[1] - 1.5*x[2]
    return d
    
N = 100
log_d = np.zeros(N)
log_y = np.zeros(N)
filt = pa.filters.FilterGNGD(3, mu=1.)
for k in range(N):
    # measure input
    x = measure_x()
    # predict new value
    y = filt.predict(x)
    # do the important stuff with prediction output
    pass    
    # measure output
    d = measure_d(x)
    # update filter
    filt.adapt(d, x)
    # log values
    log_d[k] = d
    log_y[k] = y
    
### show results
plt.figure(figsize=(15,9))
plt.subplot(211);plt.title("Adaptation");plt.xlabel("samples - k")
plt.plot(log_d,"b", label="d - target")
plt.plot(log_y,"g", label="y - output");plt.legend()
plt.subplot(212);plt.title("Filter error");plt.xlabel("samples - k")
plt.plot(10*np.log10((log_d-log_y)**2),"r", label="e - error [dB]")
plt.legend(); plt.tight_layout(); plt.show()

References

[1]Danilo P Mandic. A generalized normalized gradient descent algorithm. IEEE Signal Processing Letters, 11(2):115–118, 2004.

Code Explanation

class padasip.filters.gngd.FilterGNGD(n, mu=1.0, eps=1.0, ro=0.1, w='random')[source]

Bases: padasip.filters.base_filter.AdaptiveFilter

Adaptive GNGD filter.

Args:

  • n : length of filter (integer) - how many input is input array (row of input matrix)

Kwargs:

  • mu : learning rate (float). Also known as step size. If it is too slow, the filter may have bad performance. If it is too high, the filter will be unstable. The default value can be unstable for ill-conditioned input data.

  • eps : compensation term (float) at the beginning. It is adaptive parameter.

  • ro : step size adaptation parameter (float) at the beginning. It is adaptive parameter.

  • w : initial weights of filter. Possible values are:

    • array with initial weights (1 dimensional array) of filter size
    • “random” : create random weights
    • “zeros” : create zero value weights
adapt(d, x)[source]

Adapt weights according one desired value and its input.

Args:

  • d : desired value (float)
  • x : input array (1-dimensional array)
run(d, x)[source]

This function filters multiple samples in a row.

Args:

  • d : desired value (1 dimensional array)
  • x : input matrix (2-dimensional array). Rows are samples, columns are input arrays.

Returns:

  • y : output value (1 dimensional array). The size corresponds with the desired value.
  • e : filter error for every sample (1 dimensional array). The size corresponds with the desired value.
  • w : history of all weights (2 dimensional array). Every row is set of the weights for given sample.