児玉 です.
∞の扱いと超準的な計算のクラスについて.
超実数(HyperReal)クラスを試作中.
# 理論的には面白いけど実用性は???

From: EGUCHI Osamu <eguchi / shizuokanet.ne.jp>
Subject: [ruby-math:00268] Re: Infinity(was Polynomial.rb and floating
 point exception)
Date: Thu, 20 Apr 2000 10:39:49 +0900
Message-ID: <20000420103949H.eguchi / shizuokanet.ne.jp>
....
> > >       ∞<=>∞ の扱いはどうしましょうか?
> > >      -1,0,1 を返すっていうのは, 結構つらいものがあります.
> > 
> > この件はむかしえぐちさん議論しましたね…確か NaN を返すのが
> > 良いということになったと思います。
> 
> この時の ∞ は Float::Infinity 的な(IEE754 の)浮動小数点演算での
> 無限大でしたが、今回の無限大はより数学的な方(Math::Infinity?)で
> 関連はあるけど別個の問題だと思います。

今のところ, 比較で判定出来ない場合は NaN を返しています.
こうしてしまうと, 通常の Comparable モジュールの動作との
整合性が問題になりますが...


> > Float の Inf と NaN はどう頑張っても整合しないので、もしやる
> > なら IEEE754_NaN IEEE754_Inf といった InfinityClass の定数を
> > 持つのがいいと思います。この件はむかし石塚さんと議論したので
> > 探してみて下さい。
> 
> NaN が返るような演算は、数学的には無効や不定な場合ですので
> IEE754 な文脈以外(数学的な文脈)では、基本的に NaN は不要では?

Float を使ってしまうと,
計算途中で IEEE754 的な Inf や NaN が出てしまうので,
うまく整合性がとれればそのほうが望ましいです.
が, 完全な調整は思い付かないので,
必要な場合に意図的に Inf や NaN を
InfinityClass の対応する定数に変換します.
ここまでで,一応, 素朴な Infinity の扱いは完成.
クラス名は InfinityClass のまま.

数学的な文脈で押し通そうとすると,
超実数(HyperReal)を定義して
Epsilon や Infinity を数として計算できるようにしてしまうのが
最も根本的な解決のような気がします.
# 実用的な価値はちょっと疑問.
超準的な計算では, 無限小 や ∞ の強さもわかるので
無限小/無限小, 無限小*∞, ∞/∞ 等の計算が解釈可能となります.
ただし真の0(無限小でなく) については,
0*∞=0 で, 0/0 や 1/0 は定義されません.
HyperReal クラスの試作では
以下のように計算できるところまで確認しています.

例1.
x〜1 のときの (x^2-1)/(x^2+x-2) の値
#注1. 〜 は普通 2重波線で書き, (x)-(1) が無限小と云うこと.
#注2. x=1 とすると 0/0
#    x-->1+0 のとき (x^2-1)/(x^2+x-2)-->2/3
--------# 例1.  0/0, ∞/∞ の例
$ cat test1.rb
require "hyperreal"

# x=1 # 通常の Integer を与える. ZeroDivisionErrorになる.
# printf "%s\n", (x*x-1)/(x*x+x-2)

x=1.0 # 通常の Float を与える.
printf "%s\n", (x*x-1)/(x*x+x-2)

x=HyperReal::Epsilon+1 # 超準的な数を与える.
print ((x*x-1)/(x*x+x-2)),"\n"

x=HyperReal::Infinity # ∞
printf "%s\n", (x*x*2+x*3+4)/(x*x*5+x*6+7)

$ ruby test1.rb
NaN  <-------ダメダメ
2/3  <------- 勝利! (^_^)v
2/5
----------ここまで

例2. 微分は単に dx=無限小 としたときの,
df/dx = (f(x+dx)-f(x))/dx の標準実数部分として計算できる.
# ライプニッツ的微分.
Polynomial クラスに derivative があるので, そのほうが良いけど...
--------# 例2.  微分の例
$ cat test2.rb
require "hyperreal"
require "polynomial"

f=Poly("5x^3+6x^2+7x+8"); x=2; dx=HyperReal::Epsilon
df=(f.substitute(dx+x)-f.substitute(x))
# 超準解析的に...
printf "f=%s, f'(%s)=%s\n",f, x, df/dx
# Polynomial クラスの微分で...
printf "f'=%s, f'(%s)=%s\n", f.derivative, x, f.derivative.substitute(x)

$ ruby test.rb
f=5x^(3)+6x^(2)+7x+8, f'(2)=91
f'=15x^(2)+12x+7, f'(2)=91
--------ここまで
-- 
K.Kodama(kodama / kobe-kosen.ac.jp)