From 56d5728589f9cfea6e1d923d5faab8f1b982d29d Mon Sep 17 00:00:00 2001 From: marcandre Date: Tue, 7 Oct 2014 19:30:48 +0000 Subject: * lib/matrix.rb: Add Matrix#laplace_expansion. patch by gogo tanaka [#10073] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47835 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ NEWS | 2 ++ lib/matrix.rb | 33 +++++++++++++++++++++++++++++++++ test/matrix/test_matrix.rb | 18 ++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6c069a0d55..a860bf88df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Oct 8 04:30:29 2014 Marc-Andre Lafortune + + * lib/matrix.rb: Add Matrix#laplace_expansion. + patch by gogo tanaka [#10073] + Wed Oct 8 04:29:21 2014 Marc-Andre Lafortune * lib/matrix.rb: Add Vector.basis. diff --git a/NEWS b/NEWS index 8222050f93..021c1f9cb4 100644 --- a/NEWS +++ b/NEWS @@ -84,6 +84,8 @@ with all sufficient information, see the ChangeLog file. which is obtained by multiplying the first minor by (-1)**(row + column). * hstack and vstack are new instance and class methods to stack matrices horizontally and vertically. + * Matrix#laplace_expansion(row_or_column: num) returns the laplace_expansion + along the +num+ -th row or column. * Vector.basis(size:, index:) returns the specified basis vector * Method diff --git a/lib/matrix.rb b/lib/matrix.rb index 054c197b52..b56b12819a 100644 --- a/lib/matrix.rb +++ b/lib/matrix.rb @@ -62,6 +62,8 @@ end # * #minor(*param) # * #first_minor(row, column) # * #cofactor(row, column) +# * #laplace_expansion(row_or_column: num) +# * #cofactor_expansion(row_or_column: num) # # Properties of a matrix: # * #diagonal? @@ -685,6 +687,37 @@ class Matrix det_of_minor * (-1) ** (row + column) end + # + # Returns the Laplace expansion along given row or column. + # + # Matrix[[7,6], [3,9]].laplace_expansion(column: 1) + # => 45 + # + # Matrix[[Vector[1, 0], Vector[0, 1]], [2, 3]].laplace_expansion(row: 0) + # => Vector[3, -2] + # + # + def laplace_expansion(row: nil, column: nil) + num = row || column + + if !num || (row && column) + raise ArgumentError, "exactly one the row or column arguments must be specified" + end + + Matrix.Raise ErrDimensionMismatch unless square? + raise RuntimeError, "laplace_expansion of empty matrix is not defined" if empty? + + unless 0 <= num && num < row_count + raise ArgumentError, "invalid num (#{num.inspect} for 0..#{row_count - 1})" + end + + send(row ? :row : :column, num).map.with_index { |e, k| + e * cofactor(*(row ? [num, k] : [k,num])) + }.inject(:+) + end + alias_method :cofactor_expansion, :laplace_expansion + + #-- # TESTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #++ diff --git a/test/matrix/test_matrix.rb b/test/matrix/test_matrix.rb index eb62a326b6..2d99cead42 100644 --- a/test/matrix/test_matrix.rb +++ b/test/matrix/test_matrix.rb @@ -293,6 +293,24 @@ class TestMatrix < Test::Unit::TestCase assert_raise(ExceptionForMatrix::ErrDimensionMismatch) { Matrix[[2,0,1],[0,-2,2]].cofactor(0, 0) } end + def test_laplace_expansion + assert_equal(1, Matrix[[1]].laplace_expansion(row: 0)) + assert_equal(45, Matrix[[7,6], [3,9]].laplace_expansion(row: 1)) + assert_equal(0, Matrix[[0,0],[0,0]].laplace_expansion(column: 0)) + assert_equal(-7, Matrix[[0,0,1],[0,7,6],[1,3,9]].laplace_expansion(column: 2)) + + assert_equal(Vector[3, -2], Matrix[[Vector[1, 0], Vector[0, 1]], [2, 3]].laplace_expansion(row: 0)) + + assert_raise(ExceptionForMatrix::ErrDimensionMismatch) { @m1.laplace_expansion(row: 1) } + assert_raise(ArgumentError) { Matrix[[7,6], [3,9]].laplace_expansion() } + assert_raise(ArgumentError) { Matrix[[7,6], [3,9]].laplace_expansion(foo: 1) } + assert_raise(ArgumentError) { Matrix[[7,6], [3,9]].laplace_expansion(row: 1, column: 1) } + assert_raise(ArgumentError) { Matrix[[7,6], [3,9]].laplace_expansion(row: 2) } + assert_raise(ArgumentError) { Matrix[[0,0,1],[0,7,6],[1,3,9]].laplace_expansion(column: -1) } + + assert_raise(RuntimeError) { Matrix.empty(0, 0).laplace_expansion(row: 0) } + end + def test_regular? assert(Matrix[[1, 0], [0, 1]].regular?) assert(Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].regular?) -- cgit v1.2.3