シェルスクリプトマガジン

test

AWKでデジタル信号処理(Vol.80掲載)

投稿日:2022.09.25 | カテゴリー: コード

著者:斉藤 博文

プログラミング言語「AWK」は、データストリーム(データの流れ)を逐次処理するのに適しています。本連載では、電子回路の分野でその特徴を生かし、シェルスクリプトを組み合わせてデジタル信号を処理します。第2回は、高周波ノイズを除去する「ローパスフィルタ」について解説します。

シェルスクリプトマガジン Vol.80は以下のリンク先でご購入できます。

図6 移動平均のプログラム(lpf.awk)

#! /usr/bin/gawk -f

BEGIN {
    # define number of order
    num_ord = num_ord ? num_ord : 7;

    # define length of ring buffers
    len_data_raw = num_ord + 1;
    len_data_lpf = 2;

    # initialize ring buffers
    for (i = 0; i < len_data_raw; i++) {
        arr_data_raw[i] = 0.0;
    }
    for (i = 0; i < len_data_lpf; i++) {
        arr_data_lpf[i] = 0.0;
    }

    # initialize index of ring buffers
    idx_data_raw = 0;
    idx_data_lpf = 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_lpf = num_data_raw % len_data_lpf;

    # clear number of data
    if (idx_data_raw == 0 && idx_data_lpf == 0) {
        num_data_raw = 0;
    }

    # store input raw data
    val_data_raw = $0;
    arr_data_raw[idx_data_raw] = val_data_raw;

    # apply low pass filter
    arr_data_lpf[idx_data_lpf] = lpf( \
            arr_data_raw, arr_data_lpf,
            idx_data_raw, idx_data_lpf,
            num_ord,
            len_data_raw, len_data_lpf);

    # print results
    print arr_data_lpf[idx_data_lpf];
}

図10 ずれ補正を加えた移動平均のプログラム(lpf_gd.awk)

#! /usr/bin/gawk -f

BEGIN {
    # define number of order
    num_ord = num_ord ? num_ord : 7;

    # define group delay
    val_gd = int((num_ord - 1) / 2);

    # define length of ring buffers
    len_data_raw = num_ord + 1;
    len_data_lpf = val_gd + 1;

    # initialize ring buffers
    for (i = 0; i < len_data_raw; i++) {
        arr_data_raw[i] = 0.0;
    }
    for (i = 0; i < len_data_lpf; i++) {
        arr_data_lpf[i] = 0.0;
    }

    # initialize index of ring buffers
    idx_data_raw = 0;
    idx_data_lpf = 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_lpf = num_data_raw % len_data_lpf;

    # clear number of data
    if (idx_data_raw == 0 && idx_data_lpf == 0) {
        num_data_raw = 0;
    }

    # store input raw data
    val_data_raw = $0;
    arr_data_raw[idx_data_raw] = val_data_raw;

    # apply low pass filter
    arr_data_lpf[idx_data_lpf] = lpf( \
            arr_data_raw, arr_data_lpf,
            idx_data_raw, idx_data_lpf,
            num_ord,
            len_data_raw, len_data_lpf);

    # print results
    print get_buffer(arr_data_raw, idx_data_raw - val_gd, len_data_raw), arr_data_lpf[idx_data_lpf];
}

# get value of ring buffer
function get_buffer(arr, idx, len) {
    if (idx < 0) {
        return arr[idx + len];
    }

    return arr[idx];
}

# low pass filter
function lpf(arr_x, arr_y, idx_x, idx_y, ord, len_x, len_y,   _ret, _gain) {
    _ret = 0.0;
    _gain = 1.0 / ord;

    _ret += get_buffer(arr_y, idx_y - 1, len_y);
    _ret += _gain * get_buffer(arr_x, idx_x, len_x);
    _ret -= _gain * get_buffer(arr_x, idx_x - ord, len_x);

    return _ret;
}

香川大学SLPからお届け!(Vol.80掲載)

投稿日:2022.09.25 | カテゴリー: コード

著者:佐々木 龍之介

今回は、数値解析アルゴリズムの一つである「ニュートン法」を紹介します。ニュートン法を利用すると、反復計算によって方程式の解を近似的に求められます。C言語を使ったサンプルプログラムを挙げながら、同手法について簡単に解説します。

シェルスクリプトマガジン Vol.80は以下のリンク先でご購入できます。

図3 「x2 – 1 = 0」という方程式の解を求めるCプログラムの例

#include <stdio.h>
#include <math.h>
#define e 0.000001

double f(double x) {
    return x*x - 1;
}

double df(double x) {
    return 2*x;
}

int main() {
    double x1 = 2.5, x2;
    while(1) {
        x2 = x1 - f(x1)/df(x1);
        if(fabs(f(x2)) < e) {
            break;
        }
        x1 = x2;
    }
    printf("%f\n", x2);
}

図4 「x2 – 1 = 0」という方程式の解を求めるCプログラムの改良版

#include <stdio.h>
#include <math.h>
#define e 0.000001

double f(double x) {
    return x*x - 1;
}

double df(double x) {
    return 2*x;
}

int main() {
    double x1 = 2.5, x2;
    while(1) {
        x2 = x1 - f(x1)/df(x1);
        if(fabs(x2 - x1) < e) {
            break;
        }
        x1 = x2;
    }
    printf("%f\n", x2);
}

図5 √2の近似解を求めるCプログラムの例

#include <stdio.h>
#include <math.h>
#define e 0.000001

double f(double x) {
    return x*x - 2;
}

double df(double x) {
    return 2*x;
}

double g(double x) {
    return x - f(x) / df(x);
}

int main() {
    double x1 = 2.0, x2;
    while(1){
        x2 = g(x1);
        if(fabs(x2 - x1) < e) {
            break;
        }
        x1 = x2;
        printf("%f\n", x2);
    }

    printf("√2= %f\n", x2);
}

Pythonあれこれ(Vol.80掲載)

投稿日:2022.09.25 | カテゴリー: コード

著者:飯尾 淳

本連載では「Pythonを昔から使っているものの、それほど使いこなしてはいない」という筆者が、いろいろな日常業務をPythonで処理することで、立派な「蛇使い」に育つことを目指します。その過程を温
かく見守ってください。皆さんと共に勉強していきましょう。第10回は、データを可視化する例として、プログラムの対話型実行環境「Jupyter Notebook」をローカル環境で動かして簡単な地理情報を表示させてみます。

シェルスクリプトマガジン Vol.80は以下のリンク先でご購入できます。

図7 町丁目データを地図上に重ねて表示するためのコード

for _, r in df.iterrows():
    sim_geo = gpd.GeoSeries(r['geometry'])
    geo_j = sim_geo.to_json()
    geo_j = folium.GeoJson(data=geo_j,
      style_function=lambda x: {'fillColor': 'grey', 'color': 'grey', 
        'weight': 0.5, 'fill_opacity': 0.3, 'line_opacity': 0.1 })
    folium.Popup(r['Name']).add_to(geo_j)
    geo_j.add_to(m)
m

図10 駅の位置と乗降客数のデータをまとめるためのコード

df2 = pd.merge(df_stations.drop('Description', axis=1), \
                df_passengers, on='Name')
df2.head()

図12 駅の位置を地図に表示するためのコード(その1)

for _, row in df2.iterrows():
    folium.Marker(
        location=[row['geometry'].y, row['geometry'].x],
        popup=row['Name']
    ).add_to(m)
m

図14 駅の位置を地図に表示するためのコード(その2)

m = folium.Map(location=[35.65, 139.34], \
       zoom_start=12, tiles=‘openstreetmap’)

for _, r in df.iterrows():
    sim_geo = gpd.GeoSeries(r['geometry'])
    geo_j = sim_geo.to_json()
    geo_j = folium.GeoJson(data=geo_j,
      style_function=lambda x: {'fillColor': 'grey', 'color': 'grey', 
        'weight': 0.5, 'fill_opacity': 0.3, 'line_opacity': 0.1 })
    folium.Popup(r['Name']).add_to(geo_j)
    geo_j.add_to(m)

for _, row in df2.iterrows():
    folium.CircleMarker(
        location=[row['geometry'].y, row['geometry'].x],
        radius=3,
        color='red',
        fill_color='red',
        weight=2
    ).add_to(m)
m

図16 「緯度」「経度」「乗降客数」のカラムを持つデータフレームを作成するためのコード

df3 = pd.DataFrame(data={'Lat': df2[‘geometry'].y,
                         'Lng': df2['geometry'].x, 
                         'Passengers': df2['Passengers']})
 
df3.head()

Raspberry Piを100%活用しよう(Vol.80掲載)

投稿日:2022.09.25 | カテゴリー: コード

著者:米田 聡

小型コンピュータボード「Raspberry Pi」(ラズパイ)向けにさまざまな拡張ボードが発売されています。その拡張ボードとラズパイを組み合わせれば、ラズパイでいろいろなことが簡単に試せます。第13回は、照明用などの高輝度LEDの明るさを制御できる拡張基板を扱います。

シェルスクリプトマガジン Vol.80は以下のリンク先でご購入できます。

図5 LEDの明るさを制御するプログラム(ADRSZSW.py)

import RPi.GPIO as GPIO
import smbus
import time

ADDR=0x56   # I2Cアドレス
SW=5        # スイッチのGPIO
bus = None  

value: int = 0x0    # 明るさの値

# スイッチのコールバック関数
def switch(ch):
        global value
        value += 0x05
        # デューティ比を書き込む
        bus.write_byte_data(ADDR, 0x01, (value & 0xFF))
        # デューティー比を読み出す
        current = bus.read_byte_data(ADDR,0)
        print(current)

if __name__ == "__main__":
        bus = smbus.SMBus(1)
        bus.write_byte_data(ADDR, 0x01, 0)

        # GPIOの設定
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(SW, GPIO.IN)
        GPIO.add_event_detect(SW, GPIO.FALLING, callback=switch, bouncetime=200)

        try:
                while True:
                        time.sleep(30)
        except KeyboardInterrupt:
                pass
        GPIO.remove_event_detect(SW)
        GPIO.cleanup(SW)

特集1 Linux初心者テストにチャレンジ!(Vol.80記載)

投稿日:2022.09.25 | カテゴリー: コード

著者:長原 宏治

Linuxエンジニアの認定試験としては「LPIC」が有名ですが、より幅広くLinux初学者を対象とする「Linux Essentials」という認定試験が2020年から開始されています。本特集では出題範囲に対する理解を確認できる例題を挙げながら、Linux Essentials試験の内容を紹介します。つまずきがちな部分について問う例題を盛り込みましたので、腕に覚えがある人もぜひチャレンジしてみてください。

シェルスクリプトマガジン Vol.80は以下のリンク先でご購入できます。

Part3 演習問題集の解答と解説

図1 問3-3-1の解答例

#!/bin/bash
codefile=data.csv
prefecture=$1
grep $prefecture $codefile | sort -t , -k 5 | cut -d , -f 3 | tail -n +2

図2 問3-3-2の解答例

#!/bin/bash
codefile=data.csv
if [ $# -le 0 ]
then
  echo Usage: $0 PREFACTURE... >&2
  exit 1
fi
for prefecture in $*
do
  echo ${prefecture}:
  grep $prefecture $codefile | sort -t , -k 5 | cut -d, -f 3 | tail -n +2
done
exit 0

シェルスクリプトマガジンvol.80 Web掲載記事まとめ

投稿日:2022.09.25 | カテゴリー: コード

004 レポート 6GHz帯の無線LAN国内解禁
005 レポート Zen 4採用のRyzenプロセッサ出荷
006 製品レビュー パソコン「LAVIE GX(GX750/EAB)」
007 NEWS FLASH
008 特集1 Red Hat Enterprise Linux 9/森若和雄
022 特集2 Linux初心者テストにチャレンジ!/長原宏治 コード掲載
042 緊急特集 チャットサービスを立ち上げよう/麻生二郎
058 Raspberry Piを100%活用しよう/米田聡 コード掲載
062 Pythonあれこれ/飯尾淳 コード掲載
068 NFT/桑原滝弥、イケヤシロウ
070 中小企業手作りIT化奮戦記/菅雄一
075 Hello Nogyo!
076 法林浩之のFIGHTING TALKS/法林浩之
078 香川大学SLPからお届け!/佐々木龍之介 コード掲載
082 タイ語から分かる現地生活/つじみき
088 AWKでデジタル信号処理/斉藤博文 コード掲載
096 Bash入門/大津真
104 Techパズル/gori.sh
105 コラム「ユニケージ黎明(れいめい)期」/シェル魔人

Vol.80

投稿日:2022.09.25 | カテゴリー: バックナンバー

 2022年5月、企業向けLinuxディストリビューション「Red Hat Enterprise Linux 9」(RHEL 9)がリリースされました。多くのシステムで利用されているRHEL 7のライフサイクルは、2024年6月(延長しても2026年6月)で終了するので、アップデートの有力な候補です。特集1では、このRHEL 9に関して、サブスクリプション、無償利用、主要ソフト、主要サービス、リリーススケジュール、ライフサイクル、導入・使用方法、RHEL 7/8利用者に役立つ情報などを分かりやすく解説しています。
 特集2では、Linux初心者向けのテストを用意しています。このテストは、非営利組織「LPI」(Linux Professional Institute)が実施しているLinux技術者認定試験「Linux Essentials」を基にしています。Linuxを勉強し始めた人にお薦めの内容になっていますので、ぜひお読みください。
 このほか、緊急特集として、オープンソースソフトウエア「Mattermost」で人気の「Slack」と似たチャットサービスを無料で立ち上げる方法を紹介しています。インターネット上には無料でも使える魅力あるサービスが多数あります。ただし、SlackやHerokuのように利用規約が変更されると、無料で使える範囲が変わったり、無料で使えなくなったりします。影響を受けないように自分でサービスを立ち上げてみるのはいかがでしょうか。
 今回も読み応え十分のシェルスクリプトマガジン Vol.80。お見逃しなく!

※記事掲載のコードはこちら。記事の補足情報はこちら

※読者アンケートはこちら

Vol.80 補足情報

投稿日:2022.09.14 | カテゴリー: コード

Pythonあれこれ

 記事中で使用するデータファイルは以下のWebページから入手できます。

https://github.com/shellscript-magazine/python_this_and_that/releases/tag/ver1.0

情報は随時更新致します。

  • shell-mag ブログの 2022年9月 のアーカイブを表示しています。

  • -->