2009年1月23日金曜日

浮動小数点

ちょっと,浮動小数点の演算でハマっていた所があったのでメモがてら.

とある事情で,文字認識実験をしていました.その実験は,平仮名46文字を認識するというもので,認識手法の中に重み付きユークリッド距離というものがありました.重み付きユークリッド距離とは,

D(x, u) = √(∑(x[i]-u[i])^2/v[i])

x : 未知の文字の特徴ベクトル
u : ある字種の平均特徴ベクトル
v : uの分散ベクトル

というもので,適当にJavaで組んであるものを動かしていました.ところが,ある文字に対しては,非常に良い認識率が得られるが,ある文字は全く認識できない(認識率0%),という事態になってしまいました.
ファイルの読み込みや,計算式を入念にチェックしましたが,原因が見つかりませんでした.

よくよく考え,D(x, u)を出力してみました.

結果
NaN

ここでやっと原因が分かりました.単に0.0f/0.0fという演算が発生していたというだけのことです(上の式の場合x[i]-u[i]=0.0fかつ,v[i]=0.0fとなっていた).

そんなわけで,この問題は解決しましたが,浮動小数点における特殊な数について少しばかり調べてみました.上の実験では,Java,float型を使用してましたので,それに限りますが.
ちなみに,JDKのバージョンは1.6.0_06です.

Float.POSITIVE_INFINITY
正の無限大です.Floatクラスでの定義は,
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
でした.

Float.NEGATIVE_INFINITY
正の無限大です.Floatクラスでの定義は,
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
でした.

Float.NaN
Not a Number(=非数)です.Floatクラスでの定義は,
public static final float NaN = 0.0f / 0.0f;

NaNの発生条件には以下のようなものがあります.

異符号の無限大同士の加算
同符号の無限大同士の減算
0と無限大の乗算
0同士の除算
無限大同士の除算
被除数が無限大の剰余
除数が0の剰余
負数の平方根
値が未定義となる逆三角関数,対数関数

また,この定数は特殊であり,
NaN op something (op -> "==", "<", ">", "<=", ">=")
は必ずfalseであり,
NaN != something
は必ずtrueとなります.

実際,あるfloat値がNaNかどうかを返すメソッドboolean isNaN(float)は以下のように定義されていました.

static public boolean isNaN(float v) {
return (v != v);
}

vがNaNの時にだけ,v != vはtrueとなります.

今日はこんなところで.

2009年1月17日土曜日

カオス #1 エノン写像

近頃,カオス理論に興味を持っています.理論は非常に難しいですが,それらを可視化した画像が非常に綺麗ですので,それらをちょこちょこっと紹介しようと思います.

エノン写像(Hénon map)
エノン写像とは,フランスの天文学者Hénonが考案したモデルで,次の式で定義される写像です.

x(t+1)=1-ax(t)^2+by(t)
y(t+1)=x(t)

手計算でも,コンピュータでも計算できる写像です.
で,下の図がa=1.4,b=0.3とした時のアトラクターです.


Fig.1 Hénon attractor(a=1.4, b=0.3)

アトラクター(attractor)とは,「力学系が十分長い時間を経た後に発展する集合」です.雑に言うと,ある初期値x(0),y(0)から,x(t),y(t)をどんどん計算していき,その時の(x(t), y(t))をプロットしたものです(実際には初期値から1000回程度計算させ,それ以降の(x, y)をプロットしています).写像を適用していった時の軌道みたいなものです.

このエノン写像.特徴は以下のとおりです(勿論,ここに挙げたものはほんの一部です).

・初期値x(0),y(0)を変化させても,アトラクターはほとんど変化しない.
・パラメータa,bにより,アトラクターは大きく変化する.
・自己相似性(フラクタル)をもつ.

上の図では,太い曲線があるように見えますが,実際は無数の曲線で構成されています.理論的にはどれだけ拡大しても,無限に曲線が見えますが,計算時間が有限ですので,途中で消えてしまいます.

最後に,少しずつパラメータを変えていくことにより,生成されるアトラクタのアニメーションを.



今回はこんな処で.

2009年1月13日火曜日

電子工作 #3 矩形波発生器

こんばんは,ここ最近色々弄っていたものについて.

まず,この頃,適当な部品を組み合わせ,電子楽器もどきを作ろうと思っていました.
音を鳴らすためには,適当な発振器で信号を生成して,それをスピーカに通せばそれだけで音が鳴ります.
で,音階も制御できないとマズイです,面白くないです.音階は発振器の周波数に対応するので,てっとり早く発振器の周波数を変えられる必要があります.
という事で,前回用いた発振回路と同じものを用いれば良いという結論に至りました(RまたはCを変えるだけで周波数を変えられます).
問題は,音の数ですが,3オクターブ位出せればいいかと思っていました.が,仮に一つの音に一つの発振回路を割り当てた場合,かなり費用がかかります.また,実際の回路制作にも負担がかかります.散々色々考えた挙句,下のような回路にしました.



可変抵抗+スイッチの部分は,実際にはもっと沢山(12個位)あります.また,トランジスタ付近は,増幅回路ですので無くても動きます.
ポイントは発振回路を一つにして,回路中の抵抗値と,静電容量(コンデンサ)をスイッチで変更できるようにしたことです.T=3RCから,f=1/3RC,つまり,静電容量が1/2倍になると周波数が2倍になり,1オクターブ上昇するということです.ですので,コンデンサ部分でオクターブを制御して,抵抗部分でドレミファ…を制御するということになります.

制作ですが今回は,ブレッドボードに組んだだけです(実験的に設計しただけですので).

この回路を作成した後,大変だったのは,音調整です.可変抵抗で地道に音合わせをする必要があるので,中々面倒でした.
実際に音を鳴らしてみましたが,矩形波による「ビー」という音が割と明瞭に聞こえます.増幅回路を通すとかなり大きな音が出ます.

又機会があれば,実際に基盤に組むか,その他の電子楽器もどきでも作ってみようかと思います.