[PYTHON] Low-pass filter using closure

Introduction

I thought that if you put a variable to keep the history globally, the scope will expand and you don't like it, but you can hide it by using closures. This is a memo for myself.

code

import numpy as np

def get_lpf(alpha):
    prev = np.nan * np.ones(1)
    calc = lambda pre, new : alpha * prev + (1.-alpha) * new

    def lpf(val):
        prev[0] = calc(prev[0], val) if not np.isnan(prev[0]) else val
        return prev[0]

    return lpf

lpf = get_lpf(0.8)

for i in range(100):
    new = numpy.random.normal()
    filtered = lpf(new)
    
    print("new=%f, filt=%f" % (new, filtered) )

Commentary

prev = np.nan * np.ones(1)
calc = lambda pre, new : alpha * prev + (1.-alpha) * new

--Create a history-holding variable prev in the lpf generation function get_lpf --calc is a function that performs the LPF calculation $ y_n = \ alpha y_ {n-1} + (1- \ alpha) x_n $

prev[0] = calc(prev[0], val) if not np.isnan(prev[0]) else val

--If you set prev =, it will be recognized as a newly defined definition instead of a reference to an external variable, and an error will occur. --By defining an array of length 1 and referencing the elements of the array, it is forcibly treated as a reference. --Since prev is initialized with numpy.nan, it will be output as it is until it is no longer numpy.nan.

Recommended Posts

Low-pass filter using closure
Median filter using xarray (median filter)
closure
Write FizzBuzz using map (), reduce (), filter (), recursion