原です。

[ruby-list:28415] class Real から引っ越しです。

>正木です。

> >特定の数を表現する Cauchy 列を作ることはできるでしょうが、一般には
> >例えばある数列が Cauchy 列であるか否かを答える述語の様なものは作れ
> >ないのではないと思います。
>勿論その通りです、
>というより人工知能 program でも内蔵しない限り不可能です。
>== も定義できません。
>しかし Cauchy 列の四則演算は Cauchy 列ですから実用上は問題ないkuフで
>と思います。

そうですね。すでに Cauchy 列だとわかっているもの同士の演算は可能ですね。

>無限数列で実数を表す方法は 整数列を小数表現とみなす方法
>、連分数表現等色々ありますが 有理数の Cauchy 列で
>表現したものを idea が分かる程度に省略して書いておきます。
>下手に書き直すと bug が入りますので、元の形のままで書きます。
>
>Real.rb
>--------
>class Sequence
>   def initialize(list,*x)
>     @list=list
>     @x=x
>     @proc=eval("proc{"+yield+"}")
>   end
>   def [](n)
>     @list[n] || @list[n]=@proc.call(n,*@x)
>   end
>   def /(y)
>     x=self
>     case y
>     when Numeric
>      Sequence.new([],x,y){"|n,x,y| x[n]/y"}
>     else
>       Sequence.new([],x,y){"|n,x,y| x[n]/y[n]"}
>     end
>   end
>end
>class Real < Sequence
>   def +(y)
>     x=self
>     Real.new([],x,y){"|n,x,y| x[n]+y[n]"}
>   end
>
>   def -(y)
>     x=self
>     Real.new([],x,y){"|n,x,y| x[n]-y[n]"}
>   end
>
>   def -@
>     x=self
>     Real.new([],x){"|n,x| -x[n]"}
>   end
>
>
>   def *(y)
>     x=self
>     case y
>     when Numeric
>       Real.new([],x,y){"|n,x,y| x[n]*y"}
>     else
>       Real.new([],x,y){"|n,x,y| x[n]*y[n]"}
>     end
>   end
>
>   def /(y)
>     x=self
>     case y
>     when Numeric
>       Real.new([],x,y){"|n,x,y| x[n]/y"}
>     else
>       Real.new([],x,y){"|n,x,y| x[n]/y[n]"}
>     end
>   end
>   def each_index(n=0,m=nil)
>     if not m
>       i=n
>       loop do
>         yield(i)
>         i+=1
>       end
>     else
>       (n..m).each{|i| yield(i)}
>     end
>   end
>   def succ_each(n=0,m=nil)
>     each_index{|i| yield(self[i],self[i+1],i)}
>   end
>   def succ_find
>     r=nil;succ_each{|x,y,i| if yield(x,y,i) then r=x;break;end};r
>   end
>
>   def sqrt
>     x=self
>     Real.new([Rational(1)],x){"|n,x| a=self[n-1];y=x[n];(a+y/a)/2 "}
>   end
>   def print(n=16,r=10)
>     self.succ_find{|x,y,i| (x-y).abs < Rational(1,r**n)}.printd(n,r)
>   end
>end
>
>class Object
>   def Real(x)
>     Real.new([x],x){"|n,x| x"}
>   end
>end
>require "rational.rb"
>class Rational
>   def to_d(r=10)
>     a=@numerator
>     b=@denominator
>     Sequence.new([a],b,r){"|n,b,r| r*(self[n-1]%b)"}/b
>   end
>   def printd(n,r)
>     s=to_d(r)
>     print s[0],"."
>     for i in 1..n
>       printf("%x",s[i])
>     end
>   end
>end
>------
>sqrt.rb
>------
>require "Real.rb"
>x=ARGV.shift.to_i
>n=ARGV.shift.to_i
>r=10
>Real(x).sqrt.print(n,r);print "\n"
>
>-----
>例えば
>time ruby sqrt.rb 2 100
>とすると
>
>1.4142135623730950488016887242096980785696718753769480731766797379907324784621
>070388503875343276415727

大変興味深いです。

でもやっぱり Sequence の第二引数以降はいらないと思います。Seuence に汎用
性を持たせたいので、使途不明(?)なパラメータは排除しておきたいからです。

それと、漸化式は文字列でなくブロックで与えた方が気持ちがいいです。数式処理
をするなら別ですが、文字列に入るのは Ruby のコードですから、Ruby のコード
は地のコードにしておきたいという気持ちがあります。

でも、これらは趣味の問題かもしれません。(^^;

それから、これを Ruby のライブラリとするならば、やはり他の数クラスが乗っ
かっている coerce アーキテクチャに従うといいと思います。

もう一つ原理的な問題ですが、ここでは収束の判定に数列の隣り合った値の差を使っ
てますね。平方根をニュートン法で求めるならこれでもまずまずだと思いますが、一
般的にはまずいです。

例えば、1, 1, 0, 0, 0, 0,… という Cauchy 列は第2項で収束完了と判定され
てしまいます。

一般にはその数列に対する知識をもたないと、目的の精度まで得るにはどこまで計
算したらいいかはわからないので、、、それは Sequence オブジェクトが持つこと
にするのがいいのかな。