summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--NEWS2
-rw-r--r--lib/matrix.rb17
-rw-r--r--test/matrix/test_matrix.rb11
4 files changed, 37 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 134ea99124..031d8ac0bd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Mon Apr 7 02:39:48 2014 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
+
+ * lib/matrix.rb: Add Matrix#cofactor [fix GH-568]
+ Add first_minor [fix GH-568]
+ Handle empty diagonal matrix case [fix GH-576]
+ Patches by gogotanaka
+
Sun Apr 6 08:52:50 2014 Bugra Barin <bugrabarin@hotmail.com>
* dln.c (dln_load): use wchar version to load a library in
diff --git a/NEWS b/NEWS
index 4e344227bb..acf414caa2 100644
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,8 @@ with all sufficient information, see the ChangeLog file.
* New methods:
* Matrix#first_minor(row, column) returns the submatrix obtained
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).
=== Core classes compatibility issues (excluding feature bug fixes)
diff --git a/lib/matrix.rb b/lib/matrix.rb
index 7502e6ef8b..1a7519f408 100644
--- a/lib/matrix.rb
+++ b/lib/matrix.rb
@@ -59,6 +59,7 @@ end
# * #find_index
# * #minor(*param)
# * #first_minor(row, column)
+# * #cofactor(row, column)
#
# Properties of a matrix:
# * #diagonal?
@@ -545,6 +546,7 @@ class Matrix
nil
end
alias_method :find_index, :index
+
#
# Returns a section of the matrix. The parameters are either:
# * start_row, nrows, start_col, ncols; OR
@@ -619,6 +621,21 @@ class Matrix
new_matrix arrays, column_count - 1
end
+ #
+ # Returns the (row, column) cofactor which is obtained by multiplying
+ # the first minor by (-1)**(row + column).
+ #
+ # Matrix.diagonal(9, 5, -3, 4).cofactor(1, 1)
+ # => -108
+ #
+ def cofactor(row, column)
+ raise RuntimeError, "cofactor of empty matrix is not defined" if empty?
+ Matrix.Raise ErrDimensionMismatch unless square?
+
+ det_of_minor = first_minor(row, column).determinant
+ det_of_minor * (-1) ** (row + column)
+ end
+
#--
# TESTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#++
diff --git a/test/matrix/test_matrix.rb b/test/matrix/test_matrix.rb
index 2412f00822..e38db709a6 100644
--- a/test/matrix/test_matrix.rb
+++ b/test/matrix/test_matrix.rb
@@ -262,6 +262,17 @@ class TestMatrix < Test::Unit::TestCase
assert_raise(ArgumentError) { @m1.first_minor(-1, 4) }
end
+ def test_cofactor
+ assert_equal(1, Matrix[[1]].cofactor(0, 0))
+ assert_equal(9, Matrix[[7,6],[3,9]].cofactor(0, 0))
+ assert_equal(0, Matrix[[0,0],[0,0]].cofactor(0, 0))
+ assert_equal(3, Matrix[[0,0,1],[0,7,6],[1,3,9]].cofactor(1, 0))
+ assert_equal(-21, Matrix[[7,0,1,0,12],[8,1,1,9,1],[4,0,0,-7,17],[-1,0,0,-4,8],[10,1,1,8,6]].cofactor(2, 3))
+ assert_raise(RuntimeError) { Matrix.empty(0, 0).cofactor(0, 0) }
+ assert_raise(ArgumentError) { Matrix[[0,0],[0,0]].cofactor(-1, 4) }
+ assert_raise(ExceptionForMatrix::ErrDimensionMismatch) { Matrix[[2,0,1],[0,-2,2]].cofactor(0, 0) }
+ end
+
def test_regular?
assert(Matrix[[1, 0], [0, 1]].regular?)
assert(Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].regular?)