投稿日検索
2015年12月
 123456
78910111213
14151617181920
21222324252627
28293031  

カテゴリー検索

【お知らせ】
●2013年1月以降の投稿をRetinaディスプレイに対応

最新のコメント
  1. はじめまして.現在,こちらの車両群を管理している団体の者です. 2004年時点…

,

シェルスクリプトで画像処理(10)指数・対数

特にどの処理、ということはないのですが、本業の音声信号処理でも指数・対数は三角関数以上に頻繁に使うので備忘録として書いておきます

シェルスクリプトは元々小数を扱うのが面倒なのですが、指数に至っては冪は整数しか扱えません(T_T)
例えば半音階のピッチ比 2 ^ (1/12) の計算は不可ということになります

しかしこれには抜け道があって、式の変形をすることでシェルスクリプトでも動くものが作れます
x ^ y = e ^ (y*log(x)) とすれば動作します

え?この式でも自然底 e の冪は整数以外になるんじゃない?

いや、そうなんですけど抜け道があるんです!

上の式は e ^ ((1/12)*log(2)) と変形でき、これをワンラインで記述すると

echo "scale=6; e(1/12*l(2))" | bc -l

$ 1.059462(答え)
解ります?
つまり、このシェルでの e の冪は組み込み関数の引数として扱われ、数式上は冪として扱われていないんです
自然対数 log は関数 l になり、基数を引数として扱っています
bc コマンドのオプション -l は組み込み関数を使うためのものです

しかしこうやって頑張って記述しても困った問題が出てきます
例えば半音12個分(=1オクターブ) 2 ^ (12/12) = e ^ ((12/12)*log(2)) は誰がどう考えても答えは「2」で即答なんですが

echo "scale=6; e((12/12)*l(2))" | bc -l

$ 1.999999(答え)

これはとてもかっこ悪いです( ´・ω・`)

そこで困ったときの awk コマンド (o^-^o)
原形の演算式のまま放り込めます(最初からこれでやれば良かったんや…)

2 ^ (1/12)

awk 'BEGIN {print 2^(1/12)}'

$ 1.05946(答え)

2 ^ (12/12)

awk 'BEGIN {print 2^(12/12)}'

$ 2(答え)
この例ではファイルやパイプ処理からの入力が無いので、BEGIN で強制的にアクションを動かしています(BEGIN が無いと入力待ちで止まってしまいます)

シェル標準のように小数点以下を指定して表示する場合は printf を使うため少々複雑になりますが

awk 'BEGIN {printf("%.6fn",2^(1/12))}'

$ 1.059463(答え)
となります


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)