12/18 パターン認識(1)


試験について


前回の感想,質問より

Q.
ぼそぼそといじっていましたが、こんなもの見つけました。
irb(main):064:0> 5e-324
=> 4.94065645841247e-324
5*10^n の形であればちゃんと表示できると思ったんですが、そうでもないんですね。 なんでなんでしょ。
A.
丸め誤差を含まないのは 「16桁以下の整数」*2^n の形なので,5e-324は誤差を含んでいますが,それを 別にしても有効数字が少なすぎですね.どうも,教育用計算機システムに標準で入っているRuby処理系に 「科学的記数法で入力した数字を読み込んだ時に途中で誤差が蓄積する計算を行う」というバグがある ようです. 教育用計算機システムには,irb1.9 というコマンドも入っているので,そちらを使うと正しく表示されます.
以上の説明は勘違いでした.スライド「倍精度表現の精度」で説明したように,通常のIEEE 754の形式では,0に近い数は,10-308までしか表現できないのですが,IEEE 754の規格では,「非正規化数(Denormalized Number)」という形式が定義されていて,0に近い数字を有効数字を下げつつ無理やり表すことができるようです.5e-324は非正規化数で表されていたため,有効数字が落ちていたということのようです. irb1.9では正しく表示されていましたが,
Macintosh-7:~ ktanaka$ irb1.9
irb(main):001:0> a=5e-324
=> 5.0e-324
irb(main):002:0> a*1000
=> 4.94e-321
という結果をみると,「有効数字が十分でない時に余計な桁を表示しないようにしている」だけの違いなのかもしれません.
「科学的記数法で入力した数字を読み込んだ時に途中で誤差が蓄積する計算を行う」は,私がUtiLisp/Cを開発時に,自前の浮動小数点読み込み関数を作成して経験したバグです.症状が似ていたので今回も同様のバグを疑ったのですが,講義終了後にRuby 1.8.7ソース(tar+gz)を確認したところ,parse.cの9210 行目で,
		double d = strtod(tok(), 0);
のように,C言語標準のライブラリであるstrtodを使って変換していることが確認でき,その疑いが晴れました.
Q.
ガウスジョルダン法、整数のときになんとなく小数ででるのが気に食わないですね。 たぶんヤコビ法でも同じでしょう。 整数に近かったら一回代入して試してみるみたいな方法をとるのもありかも。 mathematicaとかmaximaとかはどうしてるんですかね。
A.
mathematicaやmaximaなどの数式処理では,有理数は有理数のまま扱うことが可能です. Rubyでも有理数は扱えます.gj.rbの
      a[k][i]=a[k][i]*1.0/akk
     a[k][i]=a[k][i]/akk
に変更してから,
 a=[[Rational(1,1),Rational(1,1),Rational(-1,1),Rational(2,1)],
    [Rational(3,1),Rational(5,1),Rational(-7,1),Rational(0,1)],
    [Rational(2,1),Rational(-3,1),Rational(1,1),Rational(5,1)]]
 gj(a)
と,有理数で入力を与えると,
 => [[(1/1), (0/1), (0/1), (3/1)], [(0/1), (1/1), (0/1), (1/1)], [(0/1), (0/1), (1/1), (2/1)]]
のように,有理数(この場合はすべて整数)で解が得られます.
Q.
def maxrow(a,k)
  r = a.length()
  t = a[k][k]
  i = k
  for j in k..(r-1)
    if t**2 < a[j][k]**2
      t = a[j][k]
      i = j
    end
  end
  i
end
ifの条件は, abs.rbを使わずに絶対値の大小を比べようと思い, 比較する値の2乗の大小を考えました.
A.
プログラムは正しく動くのですが, などの問題があるので,お勧めはしません.

前回の課題について


投票システム

vote.rbをダウンロードして,ホームディレクトリに保存してください.ドックからターミナルを起動して,
ruby vote.rb 選択肢番号
のように使います.

今日の練習,投票

関連リンク


今日の課題