[#27711] Re: [ruby-list:41557] Re: Windowsにおける共有フォルダーでのDir.globは一覧を返さない? — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

16 messages 2005/11/15
[#27717] Re: [ruby-list:41557] Re:Windowsにおける共有フォルダーでのDir.globは一覧を返さない? — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/11/16

山本です。

[#27718] Re: [ruby-list:41557] Re:Windowsにおける共有フォルダーでのDir.globは一覧を返さない? — "U.Nakamura" <usa@...> 2005/11/16

こんにちは、なかむら(う)です。

[#27719] Re: [ruby-list:41557] Re:Windowsにおける共有フォルダーでのDir.globは一覧を返さない? — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/11/16

山本です。

[#27720] Re: [ruby-list:41557] Re:Windowsにおける共有フォルダーでのDir.globは一覧を返さない? — "U.Nakamura" <usa@...> 2005/11/16

こんにちは、なかむら(う)です。

[#27721] Re: [ruby-list:41557] Re:Windowsにおける共有フォルダーでのDir.globは一覧を返さない? — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/11/16

山本です。

[#27722] Re: [ruby-list:41557] Re:Windowsにおける共有フォルダーでのDir.globは一覧を返さない? — "U.Nakamura" <usa@...> 2005/11/16

こんにちは、なかむら(う)です。

[#27723] Re: [ruby-list:41557] Re:Windowsにおける共有フォルダーでのDir.globは一覧を返さない? — 小西 弘将 <konishih@...6.so-net.ne.jp> 2005/11/16

 小西 弘将です。

[#27735] FNM_CASEFOLD on case-sensitive system — nobuyoshi nakada <nobuyoshi.nakada@...>

なかだです。

15 messages 2005/11/18
[#27737] Re: FNM_CASEFOLD on case-sensitive system — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/11/18

山本です。

[#27758] File.dirname("///foo/bar/baz/qux") on cygwin — Tanaka Akira <akr@...17n.org>

次に cygwin における

26 messages 2005/11/19
[#27768] Re: File.dirname("///foo/bar/baz/qux") on cygwin — "U.Nakamura" <usa@...> 2005/11/21

こんにちは、なかむら(う)です。

[#27769] Re: File.dirname("///foo/bar/baz/qux") on cygwin — Tanaka Akira <akr@...17n.org> 2005/11/21

In article <20051121093604.3A67.USA@garbagecollect.jp>,

[#27770] Re: File.dirname("///foo/bar/baz/qux") on cygwin — "U.Nakamura" <usa@...> 2005/11/21

こんにちは、なかむら(う)です。

[#27771] Re: File.dirname("///foo/bar/baz/qux") on cygwin — WATANABE Hirofumi <eban@...> 2005/11/21

わたなべです。

[#27772] Re: File.dirname("///foo/bar/baz/qux") on cygwin — Tanaka Akira <akr@...17n.org> 2005/11/21

In article <1191-Mon21Nov2005112905+0900-eban@os.rim.or.jp>,

[#27773] Re: File.dirname("///foo/bar/baz/qux") on cygwin — "U.Nakamura" <usa@...> 2005/11/21

こんにちは、なかむら(う)です。

[#27774] Re: File.dirname("///foo/bar/baz/qux") on cygwin — Tanaka Akira <akr@...17n.org> 2005/11/21

In article <20051121120453.3A70.USA@garbagecollect.jp>,

[#27776] Re: File.dirname("///foo/bar/baz/qux") on cygwin — Tanaka Akira <akr@...17n.org> 2005/11/21

In article <87ek5a665s.fsf@m17n.org>,

[#27777] Re: File.dirname("///foo/bar/baz/qux") on cygwin — "U.Nakamura" <usa@...> 2005/11/21

こんにちは、なかむら(う)です。

[#27778] Re: File.dirname("///foo/bar/baz/qux") on cygwin — nobuyoshi nakada <nobuyoshi.nakada@...> 2005/11/21

なかだです。

[#27779] Re: File.dirname("///foo/bar/baz/qux") on cygwin — "U.Nakamura" <usa@...> 2005/11/21

こんにちは、なかむら(う)です。

[#27781] Re: File.dirname("///foo/bar/baz/qux") on cygwin — nobuyoshi nakada <nobuyoshi.nakada@...> 2005/11/21

なかだです。

[#27782] Re: File.dirname("///foo/bar/baz/qux") on cygwin — "U.Nakamura" <usa@...> 2005/11/21

こんにちは、なかむら(う)です。

[#27783] Re: File.dirname("///foo/bar/baz/qux") on cygwin — nobuyoshi nakada <nobuyoshi.nakada@...> 2005/11/21

なかだです。

[#27766] 1.8.4 preview2? — "URABE Shyouhei aka.mput" <root@...>

卜部です。間が空きましたが

17 messages 2005/11/20
[#27798] Re: 1.8.4 preview2? — Yukihiro Matsumoto <matz@...> 2005/11/21

まつもと ゆきひろです

[#27818] Re: [ ruby-Bugs-2872 ] TCPServer should not use SO_REUSEADDR in Cygwin port — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>

山本です。

15 messages 2005/11/25
[#27819] Re: [ ruby-Bugs-2872 ] TCPServer should not use SO_REUSEADDR in Cygwin port — Yukihiro Matsumoto <matz@...> 2005/11/25

まつもと ゆきひろです

[#27821] Re: [ ruby-Bugs-2872 ] TCPServer should not use SO_REUSEADDR in Cygwin port — "U.Nakamura" <usa@...> 2005/11/25

こんにちは、なかむら(う)です。

[#27823] Re: [ ruby-Bugs-2872 ] TCPServer should not use SO_REUSEADDR in Cygwin port — "U.Nakamura" <usa@...> 2005/11/25

こんにちは、なかむら(う)です。

[#27839] ruby 1.8 dumps core — Tanaka Akira <akr@...17n.org>

最近、boron でやっている chkbuild で ruby-1.8 が test-all 中

32 messages 2005/11/28
[#27862] Re: ruby 1.8 dumps core — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/11/28

山本です。

[#27911] Re: ruby 1.8 dumps core — Tanaka Akira <akr@...17n.org> 2005/12/01

In article <20051130210645.7228E2B0.ocean@m2.ccsnet.ne.jp>,

[#28046] Re: ruby 1.8 dumps core — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/12/19

山本です。

[#28048] Re: ruby 1.8 dumps core — Tanaka Akira <akr@...17n.org> 2005/12/19

In article <20051219120911.F876DDD0.ocean@m2.ccsnet.ne.jp>,

[#28050] Re: ruby 1.8 dumps core — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/12/19

山本です。

[#28057] Re: ruby 1.8 dumps core — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/12/19

山本です。

[#27871] Numeric と Complex — Yukihiro Matsumoto <matz@...>

まつもと ゆきひろです

37 messages 2005/11/29
[#27872] Re: Numeric と Complex — keiju@... (石塚圭樹) 2005/11/29

けいじゅ@いしつかです.

[#27873] Re: Numeric と Complex — Yukihiro Matsumoto <matz@...> 2005/11/29

まつもと ゆきひろです

[#27875] Re: Numeric と Complex — keiju@... (石塚圭樹) 2005/11/29

けいじゅ@いしつかです.

[ruby-dev:27730] Re: Matrix class is broken without mathn

From: Shin-ichiro HARA <sinara@...>
Date: 2005-11-17 17:02:49 UTC
List: ruby-dev #27730
原です。

ちょっと間が空いてしまいました。すいません。Integer成分の
determinantの話の続きです。

In [ruby-dev:27700]
>けいじゅ@いしつかです.

>>でも、quoを使った方が現状よりは(クレームの頻度の点で)かなりまし
>>じゃないですかね。実際にdetを計算したいのはFloatの行列が多いらしい
>>し。
>
>ましなのは理解しますが, Rationalをrequireするよりましな理由がわかりま
>せんが?

私が誤解しているのか、どうも石塚さんの話がぴんとこないのです
が、、、私は、現行ではRationalをrequireするだけでなく、更に
各成分をRational化してdetに放り込まなくてはならないのが問題
だと思うのです。

>det計算中Rationalをrequireする場合,
>すべてがIntegerの場合, 結果は必ずInitegerになり,
>行列中1要素でもFloatが入っている場合, 結果は必ずFloatになり, 
>Rationalになることはありません.

今回問題になっているのは、整数行列の行列式はどうあつかうべき
か、ですよね?

>ですので, (内部の計算がどうなっているかは別として), それぞれの
>クラスに応じた自然な結果が出ることが必ず保証できます.

細かい話ですが、整数行列の成分をRational(x, 1)で全て有理数
化してdetを計算させると、結果はRationalですよね。mathn.rbを
導入するとIntegerですけど。

>あと, パフォーマンスのことを気にするなら, 最初っから要素は
>Floatにすべきだと思います.

私がquoを使った方がいいと思うのは、整数行列のdetを計算したと
きとんでもない値が出るのを防げるからという理由で、ただその一
点に尽きます。

それに対して石塚さんはrational.rbをrequireして各成分、
Rational()でラップしてくれ、と主張しているわけですよね。
私はそれは面倒すぎるのではないかと、そして今後も忘れて
意図しない結果に悩む人が大勢出るのではないかと思います。
それならちょっとかっこ悪くても「quoでFloat」でいいのでは
ないでしょうか。

現行をquo式にしたメリットデメリットまとめると、

--------------------------------------------------------------
成分               | 現行               | quo式               
-------------------+--------------------+---------------------
全てInteger        | NG                 | 戻値:Float          
                   |                    | 誤差が気になることも
-------------------+--------------------+---------------------
全てInteger        | NG                 | 戻値:Rational       
rationa.rb導入のみ |                    | 遅い                
-------------------+--------------------+---------------------
全てRational       | 戻値:Rational      | 戻値:Rational       
                   | 遅さは気にならない | 遅さは気にならない  
-------------------+--------------------+---------------------
全てFloat          | 戻値:Float         | 戻値:Float          
                   | 誤差は気にならない | 誤差は気にならない  
-------------------+--------------------+---------------------

となります。「遅さは気にならない」とは、Rational計算である
のが明白なので遅いことは覚悟が出来ている、、という意味です。
:-) 
quo式は、rational.rbをrequireしてるか否かで結果が違うのが確
かに気持ちが悪いのですが、それ以上にとにかく現行の"NG"は良く
ないのではないか。

quo式で困るとしたら、rational.rbをrequireしている状態で、整
数行列のdetをFloatで高速に欲しい人(いるのか?)ですが、その
人には各成分Float()してからquo式detを計算してもらうことにし
ます。

どうでしょう。


更にもう一つ提案なんですが、整数行列のdetの計算には、互除法
を使ったそこそこ速いのがあります:

  def determinant_e
    size = row_size - 1
    a = to_a

    det = 1
    0.upto(size) do |k|
      (k + 1).upto(size) do |i|
        until a[i][k].zero?
          q = a[k][k] / a[i][k]
          k.upto(size) do |j|
            a[k][j] -= a[i][j] * q
          end
          a[k], a[i] = a[i], a[k]
          det *= -1
        end
      end
      if a[k][k].zero?
        return 0
      else
        det *= a[k][k]
      end
    end
    det
  end

これは、整数行列をRatinal()してから、現行detを計算するより
かなり速いです。次は15次行列の整数成分の行列式を5回計算させ
たのにかかった時間です。

determinant         : 4.278sec.
determinant_e       : 0.329sec.

上段が各成分をRational()して現行のdetによる計算です。
拡張ライブラリのrational.soを使っても1.4秒でした。

このdeterminant_eの面白いのは、IntegerとRationalの混合した
成分を持つ行列でも正しく動作する所です。まとめると、

------------------------------------------------------------
成分               | quo式                | determinant_e
-------------------+----------------------+-----------------
全てInteger        | 戻値:Float           | 戻値:Integer    
                   | 誤差が気になることも | やや遅い        
-------------------+----------------------+-----------------
全てInteger        | 戻値:Rational        | 戻値:Integer    
rationa.rb導入のみ | 遅い                 | やや遅い        
-------------------+----------------------+-----------------
全てRational       | 戻値:Rational        | 戻値:Rational   
                   | 気にならない遅さ     | 気にならない遅さ
-------------------+----------------------+-----------------
全てFloat          | 戻値:Float           | NG              
                   | 気にならない誤差     |                 
-------------------+----------------------+-----------------

そこで提案なんですが、Matrix のdetはquo式にし、と同時に
determinant_e(det_iという名前もいいですが)も定義しておいて、

  【整数行列を扱う場合の注意】
    整数行列の行列式を計算させるときは、Matrix#det_iを使いましょ
    う。Matrix#detは、rational.rbをrequireしていない状態でFloat、
    requireしている状態でRationalを返します。

と、マニュアルに記述するのです。

どうでしょう?

ちなみに、determinant_eは[ruby-math:625]のコードをシンプルに
したものです。他にも幾つかバリエーションを試してみたのですが、
結局[ruby-math:625]のコードが速いのでこちらの方がいいかもし
れません。

テストスクリプトを載せます。

#!/usr/local/bin/ruby
require "matrix"
require "rational"

class Matrix
  def determinant_e
    size = row_size - 1
    a = to_a

    det = 1
    0.upto(size) do |k|
      (k + 1).upto(size) do |i|
        until a[i][k].zero?
          q = a[k][k] / a[i][k]
          k.upto(size) do |j|
            a[k][j] -= a[i][j] * q
          end
          a[k], a[i] = a[i], a[k]
          det *= -1
        end
      end
      if a[k][k].zero?
        return 0
      else
        det *= a[k][k]
      end
    end
    det
  end

  alias det_e determinant_e

  #[ruby-math:625]
  def determinant_625
    return 0 unless square?
    
    size = row_size - 1
    a = to_a
    
    det = 1
    k = 0
    begin 
      if a[k][k].zero?
        i = k
        begin
          return 0 if (i += 1) > size
        end while a[i][k].zero?
        a[i], a[k] = a[k], a[i]
        det *= -1
      end
      (k + 1).upto(size) do |i|
        q = a[i][k] / a[k][k]
        k.upto(size) do |j|
          a[i][j] -= a[k][j] * q
        end
        unless a[i][k].zero?
          a[i], a[k] = a[k], a[i]
          det *= -1
          redo
        end
      end
      det *= a[k][k]
    end while (k += 1) <= size
    det
  end
end

class Test
  attr_reader :value
  def initialize(name)
    @name = name
    @value = nil
    @time = 0.0
  end

  def stime(v = nil)
    t = Time.now
    @value = yield
    @time += Time.now - t
    if v && v != @value
      puts "Test Failed: #{@value} != #{v}"
      exit
    end
  end

  def to_s
    sprintf("%-30s: %3.3fsec.", @name, @time)
  end
end

def test(dim, num, range = 100)
  tr = Test.new("determinant(rational)")
  te = Test.new("determinant_e(int)")
  t1 = Test.new("determinant_e(int & rational)")
  tm = Test.new("determinant_625(int)")
  tf = Test.new("determinant(float)")

  num.times do
    a = (0...dim).map{(0...dim).map{rand(2*range+1)-range}}
    m = Matrix[*a]
    mr = Matrix[*a.map{|b| b.map{|c| Rational(c, 1)}}]
    m1 = Matrix[*a.map{|b| b.map{|c|
          rand(2).zero? ? Rational(c, 1) : c}}]
    mf = Matrix[*a.map{|b| b.map{|c| Float(c)}}]

        
    tr.stime{Matrix[*mr].det}
    te.stime(tr.value){Matrix[*m].determinant_e}
    t1.stime(tr.value){Matrix[*m1].determinant_e}
    tm.stime(tr.value){Matrix[*m].determinant_625}
    tf.stime(){Matrix[*mf].determinant}
  end

  puts "--- #{dim}-dim, #{num}times ---"
  puts tr, te, t1, tm, tf
  puts
end

test(5, 500)
test(10, 20)
test(15, 5)
test(20, 2)


以下、テストの結果:

--- 5-dim, 500times ---
determinant(rational)         : 4.503sec.
determinant(rational)         : 0.647sec. (with rational.so)
determinant_e(int)            : 1.158sec.
determinant_e(int & rational) : 7.313sec.
determinant_625(int)          : 0.703sec.
determinant(float)            : 0.193sec.

--- 10-dim, 20times ---
determinant(rational)         : 3.058sec.
determinant(rational)         : 0.786sec. (with rational.so)
determinant_e(int)            : 0.421sec.
determinant_e(int & rational) : 4.223sec.
determinant_625(int)          : 0.251sec.
determinant(float)            : 0.077sec.

--- 15-dim, 5times ---
determinant(rational)         : 4.278sec.
determinant(rational)         : 1.390sec. (with rational.so)
determinant_e(int)            : 0.329sec.
determinant_e(int & rational) : 5.347sec.
determinant_625(int)          : 0.238sec.
determinant(float)            : 0.027sec.

--- 20-dim, 2times ---
determinant(rational)         : 5.384sec.
determinant(rational)         : 2.208sec. (with rational.so)
determinant_e(int)            : 0.884sec.
determinant_e(int & rational) : 6.511sec.
determinant_625(int)          : 0.766sec.
determinant(float)            : 0.024sec.


In This Thread