1
0
Fork 0
mirror of https://github.com/ruby-opencv/ruby-opencv synced 2023-03-27 23:22:12 -04:00

fixed CvMat#eigenvv, removed CvMat#eigenvv!, and added some tests

This commit is contained in:
ser1zw 2011-01-09 03:05:52 +09:00
parent 87d19c362d
commit f9ca8e2d20
2 changed files with 54 additions and 26 deletions

View file

@ -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, "svd", RUBY_METHOD_FUNC(rb_svd), -1);
rb_define_method(rb_klass, "svbksb", RUBY_METHOD_FUNC(rb_svbksb), -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), -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, "calc_covar_matrix", RUBY_METHOD_FUNC(rb_calc_covar_matrix), -1);
rb_define_method(rb_klass, "mahalonobis", RUBY_METHOD_FUNC(rb_mahalonobis), -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, ""); rb_raise(rb_eNotImpError, "");
} }
/*
* call-seq:
* eigenvv(<i>[eps = 0.0]</i>) -> [eigen_vectors(cvmat), eigen_values(cvmat)]
*
* Computes eigenvalues and eigenvectors of symmetric matrix.
* <i>self</i> 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: * call-seq:
* eigenvv!(<i>[eps = 0.0]</i>) -> [eigen_vectors(cvmat), eigen_values(cvmat)] * eigenvv!(<i>[eps = 0.0]</i>) -> [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,:)' * self * eigen_vectors(i,:)' = eigen_values(i) * eigen_vectors(i,:)'
* *
* <b>The contents of <i>self</i> is destroyed by this method</b>.
*
* Currently the function is slower than #svd yet less accurate, so if <i>self</i> is known to be positively-defined * Currently the function is slower than #svd yet less accurate, so if <i>self</i> 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 <i>self</i>, * (e.g., it is a convariation matrix), it is recommanded to use #svd to find eigenvalues and eigenvectors of <i>self</i>,
* especially if eigenvectors are not required. * especially if eigenvectors are not required.
*/ */
VALUE VALUE
rb_eigenvv_bang(int argc, VALUE *argv, VALUE self) rb_eigenvv(int argc, VALUE *argv, VALUE self)
{ {
VALUE epsilon; VALUE epsilon, lowindex, highindex;
double eps = rb_scan_args(argc, argv, "01", &epsilon) < 1 ? 0.0 : NUM2DBL(epsilon); 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)); CvSize size = cvGetSize(CVARR(self));
int type = cvGetElemType(CVARR(self)); int type = cvGetElemType(CVARR(self));
VALUE eigen_vectors = new_object(size, type), eigen_values = new_object(size.height, 1, type); 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); return rb_ary_new3(2, eigen_vectors, eigen_values);
} }

View file

@ -1722,15 +1722,57 @@ class TestCvMat < OpenCVTestCase
m0 = create_cvmat(3, 3, :cv32f, 1) { |j, i, c| m0 = create_cvmat(3, 3, :cv32f, 1) { |j, i, c|
CvScalar.new(elems1[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]) 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] expected = [2, -2, 1]
assert_each_cvscalar(m2, 0.001) { |j, i, c| [m1, m2, m3, m4, m5].each { |m|
CvScalar.new(expected[c]) 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 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 end