はじめに
履歴を残すための変数をグローバルで置くとスコープが広がって嫌だな〜と思ってましたが、クロージャを使えば隠しておけるんですね。自分用のメモです。
コード
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) )
解説的なもの
prev = np.nan * np.ones(1)
calc = lambda pre, new : alpha * prev + (1.-alpha) * new
- 履歴保持用の変数
prev
をlpfの生成用関数get_lpf
内で作る -
calc
はLPFの計算 $y_n = \alpha y_{n-1} + (1-\alpha)x_n$ を実行する関数
prev[0] = calc(prev[0], val) if not np.isnan(prev[0]) else val
-
prev =
としてしまうと、外部変数の参照ではなく新たに定義したと認識されてエラーになる - 長さ1の配列を定義し、配列の要素を参照するようにすることで、無理やり参照扱いにする
-
prev
はnumpy.nan
で初期化しているので、numpy.nan
でなくなるまではそのまま出力する