diff --git a/ext/cvmat.cpp b/ext/cvmat.cpp
index 069c1d6..89e031b 100644
--- a/ext/cvmat.cpp
+++ b/ext/cvmat.cpp
@@ -281,7 +281,6 @@ void define_ruby_class()
rb_define_method(rb_klass, "svd", RUBY_METHOD_FUNC(rb_svd), -1);
rb_define_method(rb_klass, "svbksb", RUBY_METHOD_FUNC(rb_svbksb), -1);
rb_define_method(rb_klass, "eigenvv", RUBY_METHOD_FUNC(rb_eigenvv), -1);
- rb_define_method(rb_klass, "eigenvv!", RUBY_METHOD_FUNC(rb_eigenvv_bang), -1);
rb_define_method(rb_klass, "calc_covar_matrix", RUBY_METHOD_FUNC(rb_calc_covar_matrix), -1);
rb_define_method(rb_klass, "mahalonobis", RUBY_METHOD_FUNC(rb_mahalonobis), -1);
@@ -2331,21 +2330,6 @@ rb_svbksb(int argc, VALUE *argv, VALUE self)
rb_raise(rb_eNotImpError, "");
}
-/*
- * call-seq:
- * eigenvv([eps = 0.0]) -> [eigen_vectors(cvmat), eigen_values(cvmat)]
- *
- * Computes eigenvalues and eigenvectors of symmetric matrix.
- * self should be symmetric square matrix.
- *
- * see #eigenvv!
- */
-VALUE
-rb_eigenvv(int argc, VALUE *argv, VALUE self)
-{
- return rb_eigenvv_bang(argc, argv, copy(self));
-}
-
/*
* call-seq:
* eigenvv!([eps = 0.0]) -> [eigen_vectors(cvmat), eigen_values(cvmat)]
@@ -2355,21 +2339,23 @@ rb_eigenvv(int argc, VALUE *argv, VALUE self)
*
* self * eigen_vectors(i,:)' = eigen_values(i) * eigen_vectors(i,:)'
*
- * The contents of self is destroyed by this method.
- *
* Currently the function is slower than #svd yet less accurate, so if self is known to be positively-defined
* (e.g., it is a convariation matrix), it is recommanded to use #svd to find eigenvalues and eigenvectors of self,
* especially if eigenvectors are not required.
*/
VALUE
-rb_eigenvv_bang(int argc, VALUE *argv, VALUE self)
+rb_eigenvv(int argc, VALUE *argv, VALUE self)
{
- VALUE epsilon;
- double eps = rb_scan_args(argc, argv, "01", &epsilon) < 1 ? 0.0 : NUM2DBL(epsilon);
+ VALUE epsilon, lowindex, highindex;
+ rb_scan_args(argc, argv, "03", &epsilon, &lowindex, &highindex);
+ double eps = (NIL_P(epsilon)) ? 0.0 : NUM2DBL(epsilon);
+ int lowidx = (NIL_P(lowindex)) ? -1 : NUM2INT(lowindex);
+ int highidx = (NIL_P(highindex)) ? -1 : NUM2INT(highindex);
+
CvSize size = cvGetSize(CVARR(self));
int type = cvGetElemType(CVARR(self));
VALUE eigen_vectors = new_object(size, type), eigen_values = new_object(size.height, 1, type);
- cvEigenVV(CVARR(self), CVARR(eigen_vectors), CVARR(eigen_values), eps);
+ cvEigenVV(CVARR(self), CVARR(eigen_vectors), CVARR(eigen_values), eps, lowidx, highidx);
return rb_ary_new3(2, eigen_vectors, eigen_values);
}
diff --git a/test/test_cvmat.rb b/test/test_cvmat.rb
index 0b901ec..bd213fd 100755
--- a/test/test_cvmat.rb
+++ b/test/test_cvmat.rb
@@ -1722,15 +1722,57 @@ class TestCvMat < OpenCVTestCase
m0 = create_cvmat(3, 3, :cv32f, 1) { |j, i, c|
CvScalar.new(elems1[c])
}
- m1 = create_cvmat(3, 1, :cv32f, 1) { |j, i, c|
+ b = create_cvmat(3, 1, :cv32f, 1) { |j, i, c|
CvScalar.new(elems2[c])
}
- m2 = m0.solve(m1)
+
+ m1 = m0.solve(b)
+ m2 = m0.solve(b, :lu)
+ m3 = m0.solve(b, :svd)
+ m4 = m0.solve(b, :svd_sym)
+ m5 = m0.solve(b, :svd_symmetric)
expected = [2, -2, 1]
- assert_each_cvscalar(m2, 0.001) { |j, i, c|
- CvScalar.new(expected[c])
+ [m1, m2, m3, m4, m5].each { |m|
+ assert_equal(b.width, m.width)
+ assert_equal(m0.height, m.height)
+ assert_each_cvscalar(m, 0.001) { |j, i, c|
+ CvScalar.new(expected[c])
+ }
}
end
+
+ def test_svd
+ flunk('CvMat#svd is not implemented yet')
+ end
+
+ def test_svdksb
+ flunk('CvMat#svdksb is not implemented yet')
+ end
+
+ def test_eigenvv
+ elems = [6, -2, -3, 7]
+ m0 = create_cvmat(2, 2, :cv32f, 1) { |j, i, c|
+ CvScalar.new(elems[c])
+ }
+
+ v1 = m0.eigenvv
+ v2 = m0.eigenvv(10 ** -15)
+ v3 = m0.eigenvv(10 ** -15, 1, 1)
+
+ [v1, v2].each { |vec, val|
+ assert_in_delta(-0.615, vec[0, 0][0], 0.01)
+ assert_in_delta(0.788, vec[0, 1][0], 0.01)
+ assert_in_delta(0.788, vec[1, 0][0], 0.01)
+ assert_in_delta(0.615, vec[1, 1][0], 0.01)
+ assert_in_delta(8.562, val[0][0], 0.01)
+ assert_in_delta(4.438, val[1][0], 0.01)
+ }
+
+ vec3, val3 = v3
+ assert_in_delta(-0.615, vec3[0, 0][0], 0.01)
+ assert_in_delta(0.788, vec3[0, 1][0], 0.01)
+ assert_in_delta(8.562, val3[0][0], 0.01)
+ end
end