Source code for diamondback.filters.WindowFilter

""" **Description**
        A window filter realizes a discrete difference equation as a function
        of a forward coefficient array of a specified order, consuming an
        incident signal and producing a reference signal.

        .. math::

            y_{n} = b_{n}\\ x_{n}

        A forward coefficient array of a specified order is defined.  A
        style, order, and normalization are specified.

        Style is in ( 'Blackman', 'Hamming', 'Hann', 'Kaiser' ).

        * | 'Blackman' filters demonstrate low resolution and spectral leakage
          | with improved rate of attenuation.

        * | 'Hamming' filters demonstrate minimal nearest side lobe magnitude
          | response.

        * | 'Hann' filters demonstrate high resolution and spectral leakage.

        * | 'Kaiser' filters demonstrate flexible resolution and spectral
          | leakage dependent upon a beta value of a Bessel function of the
          | first kind, with beta equal to 7.0.

        Normal condition scales a forward coefficient array to electively
        compensate for energy loss.

        .. math::

            b_{n} = b_{n}\\ \\frac{ N }{ \\sum_{0}^{N-1}\\ |\\ b_{n}\\ |}

    **Example**

        .. code-block:: python

            from diamondback import ComplexExponentialFilter, WindowFilter
            import numpy

            # Create an instance.

            obj = WindowFilter( style = 'Hann', order = 15, normal = True )

            # Filter an incident signal.

            x = ComplexExponentialFilter( 0.0 ).filter( numpy.ones( len( obj.b ) ) * 0.1 ).real
            y = obj.filter( x )

    **License**
        `BSD-3C.  <https://github.com/larryturner/diamondback/blob/master/license>`_
        © 2018 - 2024 Larry Turner, Schneider Electric Industries SAS. All rights reserved.

    **Author**
        Larry Turner, Schneider Electric, AI Hub, 2018-04-13.
"""

from typing import Union
import numpy
import scipy.signal

[docs] class WindowFilter( object ) : """ Window filter. """ STYLE = ( 'Blackman', 'Hamming', 'Hann', 'Kaiser' ) @property def b( self ) : return self._b def __init__( self, style : str, order : int, normal : bool = True ) -> None : """ Initialize. Arguments : style : str - in ( 'Blackman', 'Hamming', 'Hann', 'Kaiser' ). order : int. normal : bool. """ style = style.title( ) if ( style not in WindowFilter.STYLE ) : raise ValueError( f'style = {style} Expected Style in {WindowFilter.STYLE}' ) if ( order < 0 ) : raise ValueError( f'Order = {order} Expected Order in [ 0, inf )' ) if ( style == 'Kaiser' ) : window = ( style.lower( ), 7.0 ) else : window = style.lower( ) # type: ignore super( ).__init__( ) b = scipy.signal.get_window( window, order + 1, False ) if ( normal ) : b *= ( order + 1 ) / sum( abs( b ) ) self._b = numpy.array( b )
[docs] def filter( self, x : Union[ list, numpy.ndarray ] ) -> numpy.ndarray : """ Filters an incident signal and produces a reference signal. Arguments : x : Union[ list, numpy.ndarray ] - incident signal. Returns : y : numpy.ndarray - reference signal. """ if ( not isinstance( x, numpy.ndarray ) ) : x = numpy.array( list( x ) ) if ( ( len( x.shape ) != 1 ) or ( len( x ) != len( self.b ) ) ) : raise ValueError( f'X = {x}' ) return self.b * x