著者:斉藤博文
プログラミング言語「AWK」は、データストリーム(データの流れ)を逐次処理するのに適しています。本連載では、電子回路の分野でその特徴を生かし、シェルスクリプトを組み合わせてデジタル信号を処理します。第4回は「微分フィルタ」を使って目的の波形を取り出す方法を紹介します。
シェルスクリプトマガジン Vol.82は以下のリンク先でご購入できます。
図10 微分フィルタの差分方程式のAWKプログラム(dif.awk)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
#! /usr/bin/gawk -f BEGIN { # define number of order num_ord = num_ord ? num_ord : 31; # define length of ring buffers len_data_raw = num_ord + 1; len_data_dif = 1; # initialize ring buffers for (i = 0; i < len_data_raw; i++) { arr_data_raw[i] = 0.0; } for (i = 0; i < len_data_dif; i++) { arr_data_dif[i] = 0.0; } # initialize index of ring buffers idx_data_raw = 0; idx_data_dif = 0; # initialize number of data num_data_raw = 0; } { # add number of data num_data_raw++; # update index of ring buffers (write pointers) idx_data_raw = num_data_raw % len_data_raw; idx_data_dif = num_data_raw % len_data_dif; # clear number of data if (idx_data_raw == 0 && idx_data_dif == 0) { num_data_raw = 0; } # store input raw data val_data_raw = $0; arr_data_raw[idx_data_raw] = val_data_raw; # apply differential filter arr_data_dif[idx_data_dif] = dif(arr_data_raw, idx_data_raw, num_ord, len_data_raw); # print results print arr_data_dif[idx_data_dif]; } # get value of ring buffer function get_buffer(arr, idx, len) { if (idx < 0) { return arr[idx + len]; } return arr[idx]; } # differential filter function dif(arr_x, idx_x, ord, len_x, _ret, _half, i) { _ret = 0.0; _half = int((ord - 1) / 2); for (i = 0; i < ord; i++) { _ret += (_half - i) * get_buffer(arr_x, idx_x - i, len_x); } return _ret; } |
図12 群遅延を考慮したAWKプログラム(dif_gd.awk)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
#! /usr/bin/gawk -f BEGIN { # define number of order num_ord = num_ord ? num_ord : 31; # define group delay val_gd = int((num_ord - 1) / 2); # define length of ring buffers len_data_raw = num_ord + 1; len_data_dif = 1; # initialize ring buffers for (i = 0; i < len_data_raw; i++) { arr_data_raw[i] = 0.0; } for (i = 0; i < len_data_dif; i++) { arr_data_dif[i] = 0.0; } # initialize index of ring buffers idx_data_raw = 0; idx_data_dif = 0; # initialize number of data num_data_raw = 0; } { # add number of data num_data_raw++; # update index of ring buffers (write pointers) idx_data_raw = num_data_raw % len_data_raw; idx_data_dif = num_data_raw % len_data_dif; # clear number of data if (idx_data_raw == 0 && idx_data_dif == 0) { num_data_raw = 0; } # store input raw data val_data_raw = $0; arr_data_raw[idx_data_raw] = val_data_raw; # apply differential filter arr_data_dif[idx_data_dif] = dif(arr_data_raw, idx_data_raw, num_ord, len_data_raw); # print results print get_buffer(arr_data_raw, idx_data_raw - val_gd, len_data_raw), arr_data_dif[idx_data_dif]; } # get value of ring buffer function get_buffer(arr, idx, len) { if (idx < 0) { return arr[idx + len]; } return arr[idx]; } # differential filter function dif(arr_x, idx_x, ord, len_x, _ret, _half, _gain i) { _ret = 0.0; _half = int((ord - 1) / 2); _gain = 0.0; for (i = 0; i < ord; i++) { _gain += (_half - i)^2; } for (i = 0; i < ord; i++) { _ret += (_half - i) * get_buffer(arr_x, idx_x - i, len_x); } return _ret / _gain; } |
図14 係数の補正を加えた関数dif()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# differential filter function dif(arr_x, idx_x, ord, len_x, _ret, _half, _gain i) { _ret = 0.0; _half = int((ord - 1) / 2); _gain = 0.0; for (i = 0; i < ord; i++) { _gain += (_half - i)^2; } for (i = 0; i < ord; i++) { _ret += (_half - i) * get_buffer(arr_x, idx_x - i, len_x); } return _ret / _gain; } |