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:
parent
87d19c362d
commit
f9ca8e2d20
2 changed files with 54 additions and 26 deletions
|
@ -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(<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:
|
||||
* 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,:)'
|
||||
*
|
||||
* <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
|
||||
* (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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1722,14 +1722,56 @@ 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|
|
||||
[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
|
||||
|
||||
|
|
Loading…
Reference in a new issue