diff --git a/NEWS b/NEWS index 6d54696..d80696f 100644 --- a/NEWS +++ b/NEWS @@ -59,6 +59,8 @@ with all sufficient information, see the ChangeLog file. by deleting the specified row and column. * Matrix#cofactor(row, column) returns the (row, column) cofactor which is obtained by multiplying the first minor by (-1)**(row + column). + * Matrix#laplace_expansion(num, row_or_column) returns the laplace_expansion + along +num+ -th +row_or_column+. * Matrix#@+ and Matrix#@- . * Vector diff --git a/lib/matrix.rb b/lib/matrix.rb index 0bc7b7c..17900dd 100644 --- a/lib/matrix.rb +++ b/lib/matrix.rb @@ -61,6 +61,9 @@ end # * #minor(*param) # * #first_minor(row, column) # * #cofactor(row, column) +# * #laplace_expansion(num, row_or_column) +# * #cofactor_expansion(num, row_or_column) +# * #cofact_exp(num, row_or_column) # # Properties of a matrix: # * #diagonal? @@ -639,6 +642,31 @@ class Matrix det_of_minor * (-1) ** (row + column) end + # + # Returns the laplace_expansion along +num+ -th +row_or_column+ + # + # Matrix[[Vector[1, 0], Vector[0, 1]], [2, 3]].laplace_expansion(0, :row) + # => Vector[3, -2] + # + # Matrix[[7,6], [3,9]].laplace_expansion(1, :column) + # => 45 + # + def laplace_expansion(num, row_or_column) + Matrix.Raise ErrDimensionMismatch unless square? + raise RuntimeError, "laplace_expansion of empty matrix is not defined" if empty? + raise ArgumentError, "#{row_or_column} should be :row or :column" unless %i(row column).include?(row_or_column) + unless 0 <= num && num < row_count + raise ArgumentError, "invalid num (#{num.inspect} for 0..#{row_count - 1})" + end + + send(row_or_column, num).map.with_index { |e, k| + e * cofactor(*(row_or_column == :row ? [num, k] : [k,num])) + }.inject(:+) + end + alias_method :cofactor_expansion, :laplace_expansion + alias_method :cofact_exp, :laplace_expansion + + #-- # TESTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #++ diff --git a/test/matrix/test_matrix.rb b/test/matrix/test_matrix.rb index d6a420b..779a1ec 100644 --- a/test/matrix/test_matrix.rb +++ b/test/matrix/test_matrix.rb @@ -283,6 +283,21 @@ 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(0, :row)) + assert_equal(45, Matrix[[7,6], [3,9]].laplace_expansion(1, :row)) + assert_equal(0, Matrix[[0,0],[0,0]].laplace_expansion(0, :column)) + assert_equal(-7, Matrix[[0,0,1],[0,7,6],[1,3,9]].laplace_expansion(2, :column)) + + assert_equal(Vector[3, -2], Matrix[[Vector[1, 0], Vector[0, 1]], [2, 3]].laplace_expansion(0, :row)) + + assert_raise(ExceptionForMatrix::ErrDimensionMismatch) { @m1.laplace_expansion(1, :row) } + assert_raise(ArgumentError) { Matrix[[7,6], [3,9]].laplace_expansion(2, :row) } + assert_raise(ArgumentError) { Matrix[[0,0,1],[0,7,6],[1,3,9]].laplace_expansion(-1, :column) } + assert_raise(ArgumentError) { Matrix[[7,6], [3,9]].laplace_expansion(1, :foo) } + assert_raise(RuntimeError) { Matrix.empty(0, 0).laplace_expansion(0, :row) } + end + def test_regular? assert(Matrix[[1, 0], [0, 1]].regular?) assert(Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].regular?)