Project

General

Profile

Actions

Bug #2652

closed

three bugs of Matrix::Scalar

Added by mame (Yusuke Endoh) over 15 years ago. Updated over 14 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 1.9.2dev (2009-11-16 trunk 25792) [i686-linux]
Backport:
[ruby-dev:40153]

Description

=begin
連投すみません。
[ruby-dev:40149] と全く同じ内容ですが、subject に [Bug:trunk] を
つけ忘れたので再送します。

=====

遠藤です。

Matrix::Scalar の定義に 3 つおかしいところを見つけました。
nodoc なクラスですが、どれも単純な問題だと思うので報告します。

○ WrongArgType が未定義
$ ./ruby -rmatrix -e 'Matrix[[0]].coerce(1).first + Matrix[[0]]'
/home/mame/work/ruby/lib/matrix.rb:979:in +': uninitialized constant Matrix::Scalar::WrongArgType (NameError) from -e:1:in '

ただの定義忘れだと思います。

○ Matrix#powered_by が未定義
$ ./ruby -rmatrix -e '2 ** Matrix[[1]]'
/home/mame/work/ruby/lib/matrix.rb:1032:in **': undefined method powered_by' for Matrix[[1]]:Matrix (NoMethodError)
from -e:1:in **' from -e:1:in '

そもそも 2 ** Matrix[[1]] に意味はないと思うので、Matrix::Scalar#** は
引数が Matrix だったら例外にすべきではないでしょうか。

○ when Numeric の後に when Scalar がある
Scalar は Numeric のサブクラスなので、when Scalar は実行されません。
もし実行されるようになったとしても、other.value という記述があり、
Scalar は value というメソッドを提供していないので NoMethodError になる
と思います。

--- a/lib/matrix.rb
+++ b/lib/matrix.rb
@@ -27,6 +27,7 @@ module ExceptionForMatrix # :nodoc:
def_exception("ErrDimensionMismatch", "#{self.name} dimension mismatch")
def_exception("ErrNotRegular", "Not Regular Matrix")
def_exception("ErrOperationNotDefined", "This operation(%s) can\'t defined")

  • def_exception("WrongArgType", "wrong argument type %s (expected %s)")
    end

@@ -977,8 +978,6 @@ class Matrix
Scalar.new(@value + other)
when Vector, Matrix
Scalar.Raise WrongArgType, other.class, "Numeric or Scalar"

  •  when Scalar
    
  •    Scalar.new(@value + other.value)
    else
      x, y = other.coerce(self)
      x + y
    

@@ -991,8 +990,6 @@ class Matrix
Scalar.new(@value - other)
when Vector, Matrix
Scalar.Raise WrongArgType, other.class, "Numeric or Scalar"

  •  when Scalar
    
  •    Scalar.new(@value - other.value)
    else
      x, y = other.coerce(self)
      x - y
    

@@ -1029,10 +1026,8 @@ class Matrix
case other
when Numeric
Scalar.new(@value ** other)

  •  when Vector
    
  •    Scalar.Raise WrongArgType, other.class, "Numeric or Scalar or Matrix"
    
  •  when Matrix
    
  •    other.powered_by(self)
    
  •  when Vector, Matrix
    
  •    Scalar.Raise WrongArgType, other.class, "Numeric or Scalar"
    else
      x, y = other.coerce(self)
      x ** y
    

--
Yusuke ENDOH
=end

Actions #1

Updated by keiju (Keiju Ishitsuka) over 15 years ago

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

In [ruby-dev:40153] the message: "[ruby-dev:40153] [Bug:trunk] three
bugs of Matrix::Scalar", on Jan/26 00:32(JST) Yusuke ENDOH writes:

連投すみません。
[ruby-dev:40149] と全く同じ内容ですが、subject に [Bug:trunk] を
つけ忘れたので再送します。

あー.
こっちにリプライしなくちゃ行けなかったんですね....

一連のメイルをまとめると以下のパッチではいかがでしょう?

斎藤さんの [ruby-dev:40176]

  •  Vector.Raise WrongArgType, x.class, "Numeric or Matrix"
    

の話がありましたが, 元々 WrongArgType が定義されていない. また, Matrix
等では, ErrOperationNotDefined を使っていたのでこちらに統一しました.

あと, 斎藤さんの メッセージが不親切との指摘を考慮しエラーメッセージも
少し修正しました.

異論がなければコミットしたいと思います.

diff --git a/matrix.rb b/matrix.rb
index 90e393c..f417323 100644
--- a/matrix.rb
+++ b/matrix.rb
@@ -26,7 +26,8 @@ module ExceptionForMatrix # :nodoc:

def_exception("ErrDimensionMismatch", "\#{self.name} dimension mismatch")
def_exception("ErrNotRegular", "Not Regular Matrix")
  • def_exception("ErrOperationNotDefined", "This operation(%s) can\'t defined")
  • def_exception("ErrOperationNotDefined", "Operation(%s) can\'t be defined: %s op %s")
  • def_exception("ErrOperationNotImplement", "Sorry, Operation(%s) not implemented: %s op %s")
    end

@@ -497,7 +498,7 @@ class Matrix
def +(m)
case m
when Numeric

  •  Matrix.Raise ErrOperationNotDefined, "+"
    
  •  Matrix.Raise ErrOperationNotDefined, "+", self.class, m.class
    
    when Vector
    m = Matrix.column_vector(m)
    when Matrix
    @@ -525,7 +526,7 @@ class Matrix
    def -(m)
    case m
    when Numeric
  •  Matrix.Raise ErrOperationNotDefined, "-"
    
  •  Matrix.Raise ErrOperationNotDefined, "-", self.class, m.class
    
    when Vector
    m = Matrix.column_vector(m)
    when Matrix
    @@ -649,9 +650,9 @@ class Matrix
    x *= x
    end
    elsif other.kind_of?(Float) || defined?(Rational) && other.kind_of?(Rational)
  •  Matrix.Raise ErrOperationNotDefined, "**"
    
  •  Matrix.Raise ErrOperationNotImplement, "**", self.class, other.class
    
    else
  •  Matrix.Raise ErrOperationNotDefined, "**"
    
  •  Matrix.Raise ErrOperationNotDefined, "**", self.class, other.class
    
    end
    end

@@ -976,9 +977,7 @@ class Matrix
when Numeric
Scalar.new(@value + other)
when Vector, Matrix

  •    Scalar.Raise TypeError, other.class, "Numeric or Scalar"
    
  •  when Scalar
    
  •    Scalar.new(@value + other.value)
    
  •    Scalar.Raise ErrOperationNotDefined, "+", @value.class, other.class
     else
       x, y = other.coerce(self)
       x + y
    

@@ -990,9 +989,7 @@ class Matrix
when Numeric
Scalar.new(@value - other)
when Vector, Matrix

  •    Scalar.Raise WrongArgType, other.class, "Numeric or Scalar"
    
  •  when Scalar
    
  •    Scalar.new(@value - other.value)
    
  •    Scalar.Raise ErrOperationNotDefined, "-", @value.class, other.class
     else
       x, y = other.coerce(self)
       x - y
    

@@ -1016,7 +1013,7 @@ class Matrix
when Numeric
Scalar.new(@value / other)
when Vector

  •    Scalar.Raise WrongArgType, other.class, "Numeric or Scalar or Matrix"
    
  •    Scalar.Raise ErrOperationNotDefined, "/", @value.class, other.class
     when Matrix
       self * other.inverse
     else
    

@@ -1030,9 +1027,10 @@ class Matrix
when Numeric
Scalar.new(@value ** other)
when Vector

  •    Scalar.Raise WrongArgType, other.class, "Numeric or Scalar or Matrix"
    
  •    Scalar.Raise ErrOperationNotDefined, "**", @value.class, other.class
     when Matrix
    
  •    other.powered_by(self)
    
  •    #other.powered_by(self)
    
  •    Scalar.Raise ErrOperationNotImplement, "**", @value.class, other.class
     else
       x, y = other.coerce(self)
       x ** y
    

@@ -1214,6 +1212,8 @@ class Vector
Vector.elements(els, false)
when Matrix
Matrix.column_vector(self) * x

  • when Vector

  •  Vector.Raise ErrOperationNotDefined, "*", self.class, x.class
    

    else
    s, x = x.coerce(self)
    s * x
    @@ -1258,6 +1258,22 @@ class Vector
    end
    end

  • Vector division.

  • def /(x)

  • case x

  • when Numeric

  •  els = @elements.collect{|e| e / x}
    
  •  Vector.elements(els, false)
    
  • when Matrix, Vector

  •  Vector.Raise ErrOperationNotDefined, "/", self.class, x.class
    
  • else

  •  s, x = x.coerce(self)
    
  •  s / x
    
  • end

  • end

  • #--

    VECTOR FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

    #++
    __
    ---------------------------------------------------->> 石塚 圭樹 <<---
    ---------------------------------->> e-mail: <<---

=end

Actions #2

Updated by mame (Yusuke Endoh) over 15 years ago

=begin
遠藤です。

2010年1月27日19:50 石塚圭樹 :

一連のメイルをまとめると以下のパッチではいかがでしょう?

いいと思いました。

ひとつだけ気になったこと。ErrOperationNotImplement よりは
ErrOperationNotImplemented の方がよくないでしょうか。

これがコミットされたら、以下のテストをコミットしたいと思います。

diff --git a/test/matrix/test_matrix.rb b/test/matrix/test_matrix.rb
index 6b9b587..526d7a3 100644
--- a/test/matrix/test_matrix.rb
+++ b/test/matrix/test_matrix.rb
@@ -10,6 +10,15 @@ class TestMatrix < Test::Unit::TestCase
@n1 = Matrix[[2,3,4], [5,6,7]]
end

  • def test_matrix
  • assert_equal(1, @m1[0, 0])
  • assert_equal(2, @m1[0, 1])
  • assert_equal(3, @m1[0, 2])
  • assert_equal(4, @m1[1, 0])
  • assert_equal(5, @m1[1, 1])
  • assert_equal(6, @m1[1, 2])
  • end
  • def test_identity
    assert_same @m1, @m1
    assert_not_same @m1, @m2
    @@ -153,4 +162,297 @@ class TestMatrix < Test::Unit::TestCase
    assert_equal(45, Matrix[[7,6], [3,9]].determinant)
    assert_equal(-18, Matrix[[2,0,1],[0,-2,2],[1,2,3]].determinant)
    end
  • def test_new_matrix
  • assert_raise(TypeError) { Matrix[Object.new] }
  • o = Object.new
  • def o.to_ary; [1,2,3]; end
  • assert_equal(@m1, Matrix[o, [4,5,6]])
  • end
  • def test_rows
  • assert_equal(@m1, Matrix.rows([[1, 2, 3], [4, 5, 6]]))
  • end
  • def test_columns
  • assert_equal(@m1, Matrix.columns([[1, 4], [2, 5], [3, 6]]))
  • end
  • def test_diagonal
  • assert_equal(Matrix[[3,0,0],[0,2,0],[0,0,1]], Matrix.diagonal(3, 2, 1))
  • assert_equal(Matrix[[4,0,0,0],[0,3,0,0],[0,0,2,0],[0,0,0,1]],
    Matrix.diagonal(4, 3, 2, 1))
  • end
  • def test_scalar
  • assert_equal(Matrix[[2,0,0],[0,2,0],[0,0,2]], Matrix.scalar(3, 2))
  • assert_equal(Matrix[[2,0,0,0],[0,2,0,0],[0,0,2,0],[0,0,0,2]],
    Matrix.scalar(4, 2))
  • end
  • def test_identity2
  • assert_equal(Matrix[[1,0,0],[0,1,0],[0,0,1]], Matrix.identity(3))
  • assert_equal(Matrix[[1,0,0],[0,1,0],[0,0,1]], Matrix.unit(3))
  • assert_equal(Matrix[[1,0,0],[0,1,0],[0,0,1]], Matrix.I(3))
  • assert_equal(Matrix[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],
    Matrix.identity(4))
  • end
  • def test_zero
  • assert_equal(Matrix[[0,0,0],[0,0,0],[0,0,0]], Matrix.zero(3))
  • assert_equal(Matrix[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],
    Matrix.zero(4))
  • assert_equal(Matrix[[0]], Matrix.zero(1))
  • end
  • def test_row_vector
  • assert_equal(Matrix[[1,2,3,4]], Matrix.row_vector([1,2,3,4]))
  • end
  • def test_column_vector
  • assert_equal(Matrix[[1],[2],[3],[4]], Matrix.column_vector([1,2,3,4]))
  • end
  • def test_empty
  • m = Matrix.empty(2, 0)
  • assert_equal(Matrix[ [], [] ], m)
  • n = Matrix.empty(0, 3)
  • assert_equal(Matrix.columns([ [], [], [] ]), n)
  • assert_equal(Matrix[[0, 0, 0], [0, 0, 0]], m * n)
  • end
  • def test_row
  • assert_equal(Vector[1, 2, 3], @m1.row(0))
  • assert_equal(Vector[4, 5, 6], @m1.row(1))
  • a = []; @m1.row(0) {|x| a << x }
  • assert_equal([1, 2, 3], a)
  • end
  • def test_column
  • assert_equal(Vector[1, 4], @m1.column(0))
  • assert_equal(Vector[2, 5], @m1.column(1))
  • assert_equal(Vector[3, 6], @m1.column(2))
  • a = []; @m1.column(0) {|x| a << x }
  • assert_equal([1, 4], a)
  • end
  • def test_collect
  • assert_equal(Matrix[[1, 4, 9], [16, 25, 36]], @m1.collect {|x| x ** 2 })
  • end
  • def test_minor
  • assert_equal(Matrix[[1, 2], [4, 5]], @m1.minor(0..1, 0..1))
  • assert_equal(Matrix[[2], [5]], @m1.minor(0..1, 1..1))
  • assert_equal(Matrix[[4, 5]], @m1.minor(1..1, 0..1))
  • assert_equal(Matrix[[1, 2], [4, 5]], @m1.minor(0, 2, 0, 2))
  • assert_equal(Matrix[[4, 5]], @m1.minor(1, 1, 0, 2))
  • assert_equal(Matrix[[2], [5]], @m1.minor(0, 2, 1, 1))
  • assert_raise(ArgumentError) { @m1.minor(0) }
  • end
  • def test_regular?
  • assert(Matrix[[1, 0], [0, 1]].regular?)
  • assert(Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].regular?)
  • assert(!Matrix[[1, 0, 0], [0, 0, 1], [0, 0, 1]].regular?)
  • assert(!Matrix[[1, 0, 0], [0, 1, 0]].regular?)
  • end
  • def test_singular?
  • assert(!Matrix[[1, 0], [0, 1]].singular?)
  • assert(!Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].singular?)
  • assert(Matrix[[1, 0, 0], [0, 0, 1], [0, 0, 1]].singular?)
  • assert(Matrix[[1, 0, 0], [0, 1, 0]].singular?)
  • end
  • def test_square?
  • assert(Matrix[[1, 0], [0, 1]].square?)
  • assert(Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].square?)
  • assert(Matrix[[1, 0, 0], [0, 0, 1], [0, 0, 1]].square?)
  • assert(!Matrix[[1, 0, 0], [0, 1, 0]].square?)
  • end
  • def test_compare_by_row_vectors
  • assert(@m1.compare_by_row_vectors([[1, 2, 3], [4, 5, 6]]))
  • end
  • def test_mul
  • assert_equal(Matrix[[2,4],[6,8]], Matrix[[2,4],[6,8]] * Matrix.I(2))
  • assert_equal(Matrix[[4,8],[12,16]], Matrix[[2,4],[6,8]] * 2)
  • assert_equal(Matrix[[4,8],[12,16]], 2 * Matrix[[2,4],[6,8]])
  • assert_equal(Matrix[[14,32],[32,77]], @m1 * @m1.transpose)
  • assert_equal(Matrix[[17,22,27],[22,29,36],[27,36,45]], @m1.transpose * @m1)
  • assert_equal(Vector[14,32], @m1 * Vector[1,2,3])
  • o = Object.new
  • def o.coerce(m)
  •  [m, m.transpose]
    
  • end
  • assert_equal(Matrix[[14,32],[32,77]], @m1 * o)
  • end
  • def test_add
  • assert_equal(Matrix[[6,0],[-4,12]], Matrix.scalar(2,5) +
    Matrix[[1,0],[-4,7]])
  • assert_equal(Matrix[[3,5,7],[9,11,13]], @m1 + @n1)
  • assert_equal(Matrix[[3,5,7],[9,11,13]], @n1 + @m1)
  • assert_equal(Matrix[[2],[4],[6]], Matrix[[1],[2],[3]] + Vector[1,2,3])
  • assert_raise(Matrix::ErrOperationNotDefined) { @m1 + 1 }
  • o = Object.new
  • def o.coerce(m)
  •  [m, m]
    
  • end
  • assert_equal(Matrix[[2,4,6],[8,10,12]], @m1 + o)
  • end
  • def test_sub
  • assert_equal(Matrix[[4,0],[4,-2]], Matrix.scalar(2,5) -
    Matrix[[1,0],[-4,7]])
  • assert_equal(Matrix[[-1,-1,-1],[-1,-1,-1]], @m1 - @n1)
  • assert_equal(Matrix[[1,1,1],[1,1,1]], @n1 - @m1)
  • assert_equal(Matrix[[0],[0],[0]], Matrix[[1],[2],[3]] - Vector[1,2,3])
  • assert_raise(Matrix::ErrOperationNotDefined) { @m1 - 1 }
  • o = Object.new
  • def o.coerce(m)
  •  [m, m]
    
  • end
  • assert_equal(Matrix[[0,0,0],[0,0,0]], @m1 - o)
  • end
  • def test_div
  • assert_equal(Matrix[[0,1,1],[2,2,3]], @m1 / 2)
  • assert_equal(Matrix[[1,1],[1,1]], Matrix[[2,2],[2,2]] / Matrix.scalar(2,2))
  • o = Object.new
  • def o.coerce(m)
  •  [m, Matrix.scalar(2,2)]
    
  • end
  • assert_equal(Matrix[[1,1],[1,1]], Matrix[[2,2],[2,2]] / o)
  • end
  • def test_exp
  • assert_equal(Matrix[[67,96],[48,99]], Matrix[[7,6],[3,9]] ** 2)
  • assert_equal(Matrix.I(5), Matrix.I(5) ** -1)
  • assert_raise(Matrix::ErrOperationNotImplemented) { Matrix.I(5) ** 1.0 }
  • assert_raise(Matrix::ErrOperationNotDefined) { Matrix.I(5) ** Object.new }
  • end
  • def test_det
  • assert_in_delta(45.0, Matrix[[7,6],[3,9]].det, 0.0001)
  • assert_in_delta(0.0, Matrix[[0,0],[0,0]].det, 0.0001)
  • assert_in_delta(-7.0, Matrix[[0,0,1],[0,7,6],[1,3,9]].det, 0.0001)
  • assert_in_delta(0,0, @m1.det, 0.0001)
  • end
  • def test_det_e
  • assert_equal(45, Matrix[[7,6],[3,9]].det_e)
  • assert_equal(0, Matrix[[0,0],[0,0]].det_e)
  • assert_equal(-7, Matrix[[0,0,1],[0,7,6],[1,3,9]].det_e)
  • assert_equal(0, @m1.det_e)
  • end
  • def test_rank2
  • assert_equal(2, Matrix[[7,6],[3,9]].rank)
  • assert_equal(0, Matrix[[0,0],[0,0]].rank)
  • assert_equal(3, Matrix[[0,0,1],[0,7,6],[1,3,9]].rank)
  • assert_equal(2, @m1.rank)
  • end
  • def test_rank_e
  • assert_equal(2, Matrix[[7,6],[3,9]].rank_e)
  • assert_equal(0, Matrix[[0,0],[0,0]].rank_e)
  • assert_equal(3, Matrix[[0,0,1],[0,7,6],[1,3,9]].rank_e)
  • assert_equal(2, @m1.rank_e)
  • end
  • def test_trace
  • assert_equal(1+5+9, Matrix[[1,2,3],[4,5,6],[7,8,9]].trace)
  • end
  • def test_transpose
  • assert_equal(Matrix[[1,4],[2,5],[3,6]], @m1.transpose)
  • end
  • def test_row_vectors
  • assert_equal([Vector[1,2,3], Vector[4,5,6]], @m1.row_vectors)
  • end
  • def test_column_vectors
  • assert_equal([Vector[1,4], Vector[2,5], Vector[3,6]], @m1.column_vectors)
  • end
  • def test_elements_to_f
  • assert_equal(Matrix[[0.5,1.0,1.5],[2.0,2.5,3.0]], @m1.elements_to_f / 2)
  • end
  • def test_elements_to_i
  • assert_equal(Matrix[[0,1,1],[2,2,3]], (@m1.elements_to_f /
    2).elements_to_i)
  • end
  • def test_elements_to_r
  • assert_equal(@m1.collect {|x| Rational(x, 2) }, @m1.elements_to_r / 2)
  • end
  • def test_to_s
  • assert_equal("Matrix[[1, 2, 3], [4, 5, 6]]", @m1.to_s)
  • assert_equal("Matrix.empty(0, 0)", Matrix[].to_s)
  • assert_equal("Matrix.empty(1, 0)", Matrix[[]].to_s)
  • end
  • def test_inspect
  • assert_equal("Matrix[[1, 2, 3], [4, 5, 6]]", @m1.inspect)
  • assert_equal("Matrix.empty(0, 0)", Matrix[].inspect)
  • assert_equal("Matrix.empty(1, 0)", Matrix[[]].inspect)
  • end
  • def test_scalar_add
  • s1 = @m1.coerce(1).first
  • assert_equal(Matrix[[1]], (s1 + 0) * Matrix[[1]])
  • assert_raise(Matrix::ErrOperationNotDefined) { s1 + Vector[0] }
  • assert_raise(Matrix::ErrOperationNotDefined) { s1 + Matrix[[0]] }
  • o = Object.new
  • def o.coerce(x)
  •  [1, 1]
    
  • end
  • assert_equal(2, s1 + o)
  • end
  • def test_scalar_sub
  • s1 = @m1.coerce(1).first
  • assert_equal(Matrix[[1]], (s1 - 0) * Matrix[[1]])
  • assert_raise(Matrix::ErrOperationNotDefined) { s1 - Vector[0] }
  • assert_raise(Matrix::ErrOperationNotDefined) { s1 - Matrix[[0]] }
  • o = Object.new
  • def o.coerce(x)
  •  [1, 1]
    
  • end
  • assert_equal(0, s1 - o)
  • end
  • def test_scalar_mul
  • s1 = @m1.coerce(1).first
  • assert_equal(Matrix[[1]], (s1 * 1) * Matrix[[1]])
  • assert_equal(Vector[2], s1 * Vector[2])
  • assert_equal(Matrix[[2]], s1 * Matrix[[2]])
  • o = Object.new
  • def o.coerce(x)
  •  [1, 1]
    
  • end
  • assert_equal(1, s1 * o)
  • end
  • def test_scalar_div
  • s1 = @m1.coerce(1).first
  • assert_equal(Matrix[[1]], (s1 / 1) * Matrix[[1]])
  • assert_raise(Matrix::ErrOperationNotDefined) { s1 / Vector[0] }
  • assert_equal(Matrix[[Rational(1,2)]], s1 / Matrix[[2]])
  • o = Object.new
  • def o.coerce(x)
  •  [1, 1]
    
  • end
  • assert_equal(1, s1 / o)
  • end
  • def test_scalar_pow
  • s1 = @m1.coerce(1).first
  • assert_equal(Matrix[[1]], (s1 ** 1) * Matrix[[1]])
  • assert_raise(Matrix::ErrOperationNotDefined) { s1 ** Vector[0] }
  • assert_raise(Matrix::ErrOperationNotImplemented) { s1 ** Matrix[[1]] }
  • o = Object.new
  • def o.coerce(x)
  •  [1, 1]
    
  • end
  • assert_equal(1, s1 ** o)
  • end
    end
    diff --git a/test/matrix/test_vector.rb b/test/matrix/test_vector.rb
    index 95a3969..9be54af 100644
    --- a/test/matrix/test_vector.rb
    +++ b/test/matrix/test_vector.rb
    @@ -46,4 +46,106 @@ class TestVector < Test::Unit::TestCase
    assert_equal @v1.hash, @v2.hash
    assert_equal @v1.hash, @v3.hash
    end
  • def test_aref
  • assert_equal(1, @v1[0])
  • assert_equal(2, @v1[1])
  • assert_equal(3, @v1[2])
  • assert_equal(3, @v1[-1])
  • assert_equal(nil, @v1[3])
  • end
  • def test_size
  • assert_equal(3, @v1.size)
  • end
  • def test_each2
  • a = []
  • @v1.each2(@v4) {|x, y| a << [x, y] }
  • assert_equal([[1,1.0],[2,2.0],[3,3.0]], a)
  • end
  • def test_collect
  • a = @v1.collect {|x| x + 1 }
  • assert_equal(Vector[2,3,4], a)
  • end
  • def test_collect2
  • a = @v1.collect2(@v4) {|x, y| x + y }
  • assert_equal([2.0,4.0,6.0], a)
  • end
  • def test_map2
  • a = @v1.map2(@v4) {|x, y| x + y }
  • assert_equal(Vector[2.0,4.0,6.0], a)
  • end
  • def test_compare_by
  • assert(@v1.compare_by([1,2,3], :==))
  • assert(@v1.compare_by([1,2,3], :equal?))
  • end
  • def test_mul
  • assert_equal(Vector[2,4,6], @v1 * 2)
  • assert_equal(Matrix[[1, 4, 9], [2, 8, 18], [3, 12, 27]], @v1 *
    Matrix[[1,4,9]])
  • assert_raise(Matrix::ErrOperationNotDefined) { @v1 * Vector[1,4,9] }
  • o = Object.new
  • def o.coerce(x)
  •  [1, 1]
    
  • end
  • assert_equal(1, Vector[1, 2, 3] * o)
  • end
  • def test_add
  • assert_equal(Vector[2,4,6], @v1 + @v1)
  • assert_equal(Matrix[[2],[6],[12]], @v1 + Matrix[[1],[4],[9]])
  • o = Object.new
  • def o.coerce(x)
  •  [1, 1]
    
  • end
  • assert_equal(2, Vector[1, 2, 3] + o)
  • end
  • def test_sub
  • assert_equal(Vector[0,0,0], @v1 - @v1)
  • assert_equal(Matrix[[0],[-2],[-6]], @v1 - Matrix[[1],[4],[9]])
  • o = Object.new
  • def o.coerce(x)
  •  [1, 1]
    
  • end
  • assert_equal(0, Vector[1, 2, 3] - o)
  • end
  • def test_inner_product
  • assert_equal(1+4+9, @v1.inner_product(@v1))
  • end
  • def test_r
  • assert_equal(5, Vector[3, 4].r)
  • end
  • def test_covector
  • assert_equal(Matrix[[1,2,3]], @v1.covector)
  • end
  • def test_elements_to_f
  • assert_equal(Vector[0.5,1.0,1.5], @v1.elements_to_f * Rational(1, 2))
  • end
  • def test_elements_to_i
  • assert_equal(Vector[0,1,1], (@v1.elements_to_f * Rational(1,
    2)).elements_to_i)
  • end
  • def test_elements_to_r
  • assert_equal(@v1.collect {|x| Rational(x, 2) }, @v1.elements_to_r
  • Rational(1, 2))
  • end
  • def test_to_s
  • assert_equal("Vector[1, 2, 3]", @v1.to_s)
  • end
  • def test_inspect
  • assert_equal("Vector[1, 2, 3]", @v1.inspect)
  • end

end

--
Yusuke ENDOH

=end

Actions #3

Updated by keiju (Keiju Ishitsuka) over 15 years ago

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

In [ruby-dev:40189] the message: "[ruby-dev:40189] Re: [Bug:trunk]
three bugs of Matrix::Scalar", on Jan/27 22:51(JST) Yusuke ENDOH
writes:

遠藤です。

いいと思いました。

はい.

ひとつだけ気になったこと。ErrOperationNotImplement よりは
ErrOperationNotImplemented の方がよくないでしょうか。

そうですね. 修正しました.
コミットしました.

これがコミットされたら、以下のテストをコミットしたいと思います。

あー. この件忘れていました...

  • def test_compare_by_row_vectors
  • assert(@m1.compare_by_row_vectors([[1, 2, 3], [4, 5, 6]]))
  • end

もともと, Matrix#compare_by_row_vectors って Matrix同士の比較のためな
ので, こう言ったことは想定していなかったんですよねぇ...

__
---------------------------------------------------->> 石塚 圭樹 <<---
---------------------------------->> e-mail: <<---

=end

Actions #4

Updated by matz (Yukihiro Matsumoto) over 15 years ago

=begin
まつもと ゆきひろです

In message "Re: [ruby-dev:40191] Re: [Bug:trunk] three bugs of Matrix::Scalar"
on Wed, 27 Jan 2010 23:35:01 +0900, (石塚圭樹) writes:

|>+ def test_compare_by_row_vectors
|>+ assert(@m1.compare_by_row_vectors([[1, 2, 3], [4, 5, 6]]))
|>+ end
|
|もともと, Matrix#compare_by_row_vectors って Matrix同士の比較のためな
|ので, こう言ったことは想定していなかったんですよねぇ...

それってcompare_by_row_vectorsは内部実装用で、テストの対象外っ
てことですか? それとも、引数はMatrixに限るってこと?

=end

Actions #5

Updated by keiju (Keiju Ishitsuka) over 15 years ago

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

In [ruby-dev:40224] the message: "[ruby-dev:40224] Re: [Bug:trunk]
three bugs of Matrix::Scalar", on Jan/29 01:49(JST) Yukihiro Matsumoto
writes:

まつもと ゆきひろです

|もともと, Matrix#compare_by_row_vectors って Matrix同士の比較のためな
|ので, こう言ったことは想定していなかったんですよねぇ...
それってcompare_by_row_vectorsは内部実装用で、テストの対象外っ
てことですか? それとも、引数はMatrixに限るってこと?

うーん. 歴史的には, 前者用途で == とかの内部のサブルーチン的な用途が
主で, Matirix同士の比較しか考えていませんでした.

それから, == とかが別実装になったんですが, 他にも用途があるかなと思っ
て別途独立させたのですが...

ただ, 正直言ってあまり考えてなくて, ほとんど昔のままの実装なので,
Matrix以外のクラスが来た場合にどうするべきか考えてなかったんですよね...

__
---------------------------------------------------->> 石塚 圭樹 <<---
---------------------------------->> e-mail: <<---

=end

Actions #6

Updated by matz (Yukihiro Matsumoto) over 15 years ago

=begin
まつもと ゆきひろです

In message "Re: [ruby-dev:40229] Re: [Bug:trunk] three bugs of Matrix::Scalar"
on Fri, 29 Jan 2010 04:56:48 +0900, (石塚圭樹) writes:

|うーん. 歴史的には, 前者用途で == とかの内部のサブルーチン的な用途が
|主で, Matirix同士の比較しか考えていませんでした.
|
|それから, == とかが別実装になったんですが, 他にも用途があるかなと思っ
|て別途独立させたのですが...
|
|ただ, 正直言ってあまり考えてなくて, ほとんど昔のままの実装なので,
|Matrix以外のクラスが来た場合にどうするべきか考えてなかったんですよね...

そういうことであれば、当面「内部実装である」と明記して、テス
ト対象外にした方がよいのではないかと思います。

=end

Actions #7

Updated by mame (Yusuke Endoh) over 15 years ago

=begin
遠藤です。

2010年1月29日7:36 Yukihiro Matsumoto :

|うーん. 歴史的には, 前者用途で == とかの内部のサブルーチン的な用途が
|主で, Matirix同士の比較しか考えていませんでした.
|
|それから, == とかが別実装になったんですが, 他にも用途があるかなと思っ
|て別途独立させたのですが...
|
|ただ, 正直言ってあまり考えてなくて, ほとんど昔のままの実装なので,
|Matrix以外のクラスが来た場合にどうするべきか考えてなかったんですよね...

そういうことであれば、当面「内部実装である」と明記して、テス
ト対象外にした方がよいのではないかと思います。

もしそうするなら、はっきりと private にしておいてください。

ただ、たとえ内部実装でも、実装に付属するテスト (test/matrix/*) では、
なるべくテスト対象にしたいと思います。カバレッジのためにも。
別に spec じゃないのでホワイトテストをしてもいいですよね。

--
Yusuke ENDOH

=end

Actions #8

Updated by keiju (Keiju Ishitsuka) over 15 years ago

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

In [ruby-dev:40231] the message: "[ruby-dev:40231] Re: [Bug:trunk]
three bugs of Matrix::Scalar", on Jan/29 08:37(JST) Yusuke ENDOH
writes:

遠藤です。

そういうことであれば、当面「内部実装である」と明記して、テス
ト対象外にした方がよいのではないかと思います。

もしそうするなら、はっきりと private にしておいてください。

ただ、たとえ内部実装でも、実装に付属するテスト (test/matrix/*) では、
なるべくテスト対象にしたいと思います。カバレッジのためにも。
別に spec じゃないのでホワイトテストをしてもいいですよね。

それでは, Matrix同士の比較にしてもらえますか?

__
---------------------------------------------------->> 石塚 圭樹 <<---
---------------------------------->> e-mail: <<---

=end

Actions #9

Updated by mame (Yusuke Endoh) over 15 years ago

=begin
遠藤です。

2010年1月29日13:44 石塚圭樹 :

それでは, Matrix同士の比較にしてもらえますか?

見てみたのですが、現在の実装では、compare_by_row_vectors は比較で
使われていない (というか、どこでも使われていない) 気がします。
なので、比較では compare_by_row_vectors のテストにはならなそうです。

あと、このチケットと関係ないですが、[ruby-core:27901] を見てもらえると
助かります > いしつかさん

--
Yusuke ENDOH

=end

Actions #10

Updated by keiju (Keiju Ishitsuka) over 15 years ago

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

In [ruby-dev:40236] the message: "[ruby-dev:40236] Re: [Bug:trunk]
three bugs of Matrix::Scalar", on Jan/29 17:33(JST) Yusuke ENDOH
writes:

遠藤です。

見てみたのですが、現在の実装では、compare_by_row_vectors は比較で
使われていない (というか、どこでも使われていない) 気がします。
なので、比較では compare_by_row_vectors のテストにはならなそうです。

ん?

def test_compare_by_row_vectors
assert(@m1.compare_by_row_vectors(Matrix[[1, 2, 3], [4, 5, 6]]))
end

と言う意味で言ったんですが?

あと、このチケットと関係ないですが、[ruby-core:27901] を見てもらえると
助かります > いしつかさん

これねぇ...

Integer#[], Integer#size

の名前を変えた方がよいんじゃない? って言いたいところですが...
どう見ても他のクラスの[], sizeと振る舞いが違いますしねぇ, duck type 的
にもイマイチな気がします.

それはともかく, NArrayのNVector などのVectorの別実装が実際にありますし,
Vector, Arrayに限定するのは, やはり duck type 的 にイマイチでしょう.

私としては, チェックしなくて良い気がしますが, どうしてもチェックしたい
なら, each2って Enumerable#zip &block と似ているので, to_aを持っている
かどうかで判断するというのはどうですかね?

__
---------------------------------------------------->> 石塚 圭樹 <<---
---------------------------------->> e-mail: <<---

=end

Actions #11

Updated by mame (Yusuke Endoh) over 15 years ago

=begin
遠藤です。

2010年1月29日19:24 石塚圭樹 :

見てみたのですが、現在の実装では、compare_by_row_vectors は比較で
使われていない (というか、どこでも使われていない) 気がします。
なので、比較では compare_by_row_vectors のテストにはならなそうです。

ん?

def test_compare_by_row_vectors
assert(@m1.compare_by_row_vectors(Matrix[[1, 2, 3], [4, 5, 6]]))
end

と言う意味で言ったんですが?

ああーなるほど。compare_by_row_vectors は Matrix#== の比較の内部実装として
存在する、という意味だと理解してました。そうしておきます。

いずれにしても、vectors という名前にはあわないですね。

あと、このチケットと関係ないですが、[ruby-core:27901] を見てもらえると
助かります > いしつかさん

これねぇ...

Integer#[], Integer#size

の名前を変えた方がよいんじゃない? って言いたいところですが...

Integer#[] はたまに便利ですが #size については完全に同意します。
無くてもいい、というか無いほうがいいとすら思います。

どう見ても他のクラスの[], sizeと振る舞いが違いますしねぇ, duck type 的
にもイマイチな気がします.

それはともかく, NArrayのNVector などのVectorの別実装が実際にありますし,
Vector, Arrayに限定するのは, やはり duck type 的 にイマイチでしょう.

別に「duck typing 的にそういうもの」といって reject してもらっても構わない
と思います。すでに rubyspec に載ってるので、見解を示してもらえると修正する
根拠になるので助かります。

--
Yusuke ENDOH

=end

Actions #12

Updated by mame (Yusuke Endoh) over 15 years ago

=begin
遠藤です。
何度もすみません。

2010年1月29日19:54 Yusuke ENDOH :

2010年1月29日19:24 石塚圭樹 :

見てみたのですが、現在の実装では、compare_by_row_vectors は比較で
使われていない (というか、どこでも使われていない) 気がします。
なので、比較では compare_by_row_vectors のテストにはならなそうです。

ん?

def test_compare_by_row_vectors
assert(@m1.compare_by_row_vectors(Matrix[[1, 2, 3], [4, 5, 6]]))
end

と言う意味で言ったんですが?

ああーなるほど。compare_by_row_vectors は Matrix#== の比較の内部実装として
存在する、という意味だと理解してました。そうしておきます。

やってみたら例外になりました……。

$ ./ruby -rmatrix -e
'Matrix[[1,2,3],[4,5,6]].compare_by_row_vectors(Matrix[[1, 2, 3], [4,
5, 6]])'
/home/mame/work/ruby-trunk-local/lib/ruby/1.9.1/matrix.rb:427:in
compare_by_row_vectors': undefined method size' for Matrix[[1, 2,
3], [4, 5, 6]]:Matrix (NoMethodError)
from -e:1:in `'

--
Yusuke ENDOH

=end

Actions #13

Updated by matz (Yukihiro Matsumoto) over 15 years ago

=begin
まつもと ゆきひろです

In message "Re: [ruby-dev:40237] Re: [Bug:trunk] three bugs of Matrix::Scalar"
on Fri, 29 Jan 2010 19:24:35 +0900, (石塚圭樹) writes:

| Integer#[], Integer#size
|
|の名前を変えた方がよいんじゃない? って言いたいところですが...
|どう見ても他のクラスの[], sizeと振る舞いが違いますしねぇ, duck type 的
|にもイマイチな気がします.

これらはduck typingという概念よりも古いですからねえ。今さら
変えられないとも思います。

さらにいえば、duck typing的というならば、型チェックなどしては
いけなくて、[ruby-core:27901]のようなエラーは許容すべきなんじゃ
ないかと思います。

=end

Actions #14

Updated by mame (Yusuke Endoh) over 15 years ago

=begin
遠藤です。

2010年1月31日0:51 Yukihiro Matsumoto :

| Integer#[], Integer#size
|
|の名前を変えた方がよいんじゃない? って言いたいところですが...
|どう見ても他のクラスの[], sizeと振る舞いが違いますしねぇ, duck type 的
|にもイマイチな気がします.

これらはduck typingという概念よりも古いですからねえ。今さら
変えられないとも思います。

さらにいえば、duck typing的というならば、型チェックなどしては
いけなくて、[ruby-core:27901]のようなエラーは許容すべきなんじゃ
ないかと思います。

いしつかさんもまつもとさんも反対ということで、勝手に reject させて
頂きました。

http://redmine.ruby-lang.org/issues/show/2495

もし問題があったら reopen してください。

--
Yusuke ENDOH

=end

Actions #15

Updated by keiju (Keiju Ishitsuka) over 15 years ago

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

In [ruby-dev:40240] the message: "[ruby-dev:40240] Re: [Bug:trunk]
three bugs of Matrix::Scalar", on Jan/29 21:44(JST) Yusuke ENDOH
writes:

遠藤です。
何度もすみません。

def test_compare_by_row_vectors
assert(@m1.compare_by_row_vectors(Matrix[[1, 2, 3], [4, 5, 6]]))

やってみたら例外になりました……。

$ ./ruby -rmatrix -e
'Matrix[[1,2,3],[4,5,6]].compare_by_row_vectors(Matrix[[1, 2, 3], [4,
5, 6]])'
/home/mame/work/ruby-trunk-local/lib/ruby/1.9.1/matrix.rb:427:in
compare_by_row_vectors': undefined method size' for Matrix[[1, 2,
3], [4, 5, 6]]:Matrix (NoMethodError)
from -e:1:in `'

申し訳ない.

引数は, 配列(の配列)を求めていました...

このままでは, あまり使い勝手が良くないので, trunkからはもう削除した方
が良いかなぁ...

__
---------------------------------------------------->> 石塚 圭樹 <<---
---------------------------------->> e-mail: <<---

=end

Actions #16

Updated by keiju (Keiju Ishitsuka) over 15 years ago

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

In [ruby-dev:40270] the message: "[ruby-dev:40270] Re: [Bug:trunk]
three bugs of Matrix::Scalar", on Jan/31 18:15(JST) Yusuke ENDOH
writes:

遠藤です。

いしつかさんもまつもとさんも反対ということで、勝手に reject させて
頂きました。

http://redmine.ruby-lang.org/issues/show/2495

もし問題があったら reopen してください。

了解です.
お手数お掛けしました.

__
---------------------------------------------------->> 石塚 圭樹 <<---
---------------------------------->> e-mail: <<---

=end

Actions #17

Updated by naruse (Yui NARUSE) over 15 years ago

  • Priority changed from 3 to Normal
  • ruby -v set to ruby 1.9.2dev (2009-11-16 trunk 25792) [i686-linux]

=begin

=end

Actions #18

Updated by mame (Yusuke Endoh) over 15 years ago

  • Status changed from Open to Closed

=begin
遠藤です。

本件は r26448 で修正済みですので close します。

--
Yusuke Endoh
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0