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

added CvMat#svd

This commit is contained in:
ser1zw 2011-09-18 18:22:21 +09:00
parent ca6b5daca1
commit 41bf713cd3
4 changed files with 130 additions and 13 deletions

View file

@ -2630,24 +2630,47 @@ rb_solve(int argc, VALUE *argv, VALUE self)
/*
* call-seq:
* svd(u = nil, v = nil</i>)
* svd(<i>l[flag=0]</i>)
*
* not implementated.
* Performs singular value decomposition of real floating-point matrix.
*/
VALUE
rb_svd(int argc, VALUE *argv, VALUE self)
{
rb_raise(rb_eNotImpError, "");
/*
VALUE u = Qnil, v = Qnil;
rb_scan_args(argc, argv, "02", &u, &v);
CvMat
*matU = NIL_P(u) ? NULL : CVARR(u),
*matV = NIL_P(v) ? NULL : CVARR(v);
cvSVD(CVARR(self), matU, matV);
return dest;
*/
VALUE _flag = Qnil;
int flag = 0;
if (rb_scan_args(argc, argv, "01", &_flag) > 0) {
flag = NUM2INT(_flag);
}
CvMat* self_ptr = CVMAT(self);
VALUE w = new_mat_kind_object(cvSize(self_ptr->cols, self_ptr->rows), self);
int rows = 0;
int cols = 0;
if (flag & CV_SVD_U_T) {
rows = MIN(self_ptr->rows, self_ptr->cols);
cols = self_ptr->rows;
}
else {
rows = self_ptr->rows;
cols = MIN(self_ptr->rows, self_ptr->cols);
}
VALUE u = new_mat_kind_object(cvSize(cols, rows), self);
if (flag & CV_SVD_V_T) {
rows = MIN(self_ptr->rows, self_ptr->cols);
cols = self_ptr->cols;
}
else {
rows = self_ptr->cols;
cols = MIN(self_ptr->rows, self_ptr->cols);
}
VALUE v = new_mat_kind_object(cvSize(cols, rows), self);
cvSVD(self_ptr, CVARR(w), CVARR(u), CVARR(v), flag);
return rb_ary_new3(3, w, u, v);
}
/*

View file

@ -278,6 +278,11 @@ define_ruby_module()
rb_define_const(rb_module, "CV_WARP_FILL_OUTLIERS", INT2FIX(CV_WARP_FILL_OUTLIERS));
rb_define_const(rb_module, "CV_WARP_INVERSE_MAP", INT2FIX(CV_WARP_INVERSE_MAP));
/* SVD optional flags */
rb_define_const(rb_module, "CV_SVD_MODIFY_A", INT2FIX(CV_SVD_MODIFY_A));
rb_define_const(rb_module, "CV_SVD_U_T", INT2FIX(CV_SVD_U_T));
rb_define_const(rb_module, "CV_SVD_V_T", INT2FIX(CV_SVD_V_T));
VALUE inversion_method = rb_hash_new();
/* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */
rb_define_const(rb_module, "INVERSION_METHOD", inversion_method);

View file

@ -2133,7 +2133,91 @@ class TestCvMat < OpenCVTestCase
end
def test_svd
flunk('FIXME: CvMat#svd is not implemented yet')
rows = 2
cols = 3
m0 = create_cvmat(rows, cols, :cv32f, 1) { |j, i, c|
CvScalar.new(c + 1)
}
[m0.svd, m0.clone.svd(CV_SVD_MODIFY_A)].each { |w, u, v|
expected = [0.38632, -0.92237,
0.92237, 0.38632]
assert_equal(rows, u.rows)
assert_equal(rows, u.cols)
expected.each_with_index { |x, i|
assert_in_delta(x, u[i][0], 0.0001)
}
assert_equal(rows, w.rows)
assert_equal(cols, w.cols)
expected = [9.50803, 0, 0,
0, 0.77287, 0]
expected.each_with_index { |x, i|
assert_in_delta(x, w[i][0], 0.0001)
}
assert_equal(cols, v.rows)
assert_equal(rows, v.cols)
expected = [0.42867, 0.80596,
0.56631, 0.11238,
0.70395, -0.58120]
expected.each_with_index { |x, i|
assert_in_delta(x, v[i][0], 0.0001)
}
}
w, ut, v = m0.svd(CV_SVD_U_T)
expected = [0.38632, 0.92237,
-0.92237, 0.38632]
assert_equal(rows, ut.rows)
assert_equal(rows, ut.cols)
expected.each_with_index { |x, i|
assert_in_delta(x, ut[i][0], 0.0001)
}
assert_equal(rows, w.rows)
assert_equal(cols, w.cols)
expected = [9.50803, 0, 0,
0, 0.77287, 0]
expected.each_with_index { |x, i|
assert_in_delta(x, w[i][0], 0.0001)
}
assert_equal(cols, v.rows)
assert_equal(rows, v.cols)
expected = [0.42867, 0.80596,
0.56631, 0.11238,
0.70395, -0.58120]
expected.each_with_index { |x, i|
assert_in_delta(x, v[i][0], 0.0001)
}
w, u, vt = m0.svd(CV_SVD_V_T)
expected = [0.38632, -0.92237,
0.92237, 0.38632]
assert_equal(rows, u.rows)
assert_equal(rows, u.cols)
expected.each_with_index { |x, i|
assert_in_delta(x, u[i][0], 0.0001)
}
assert_equal(rows, w.rows)
assert_equal(cols, w.cols)
expected = [9.50803, 0, 0,
0, 0.77287, 0]
expected.each_with_index { |x, i|
assert_in_delta(x, w[i][0], 0.0001)
}
assert_equal(rows, vt.rows)
assert_equal(cols, vt.cols)
expected = [0.42867, 0.56631, 0.70395,
0.80596, 0.11238, -0.58120]
expected.each_with_index { |x, i|
assert_in_delta(x, vt[i][0], 0.0001)
}
end
def test_svdksb

View file

@ -119,6 +119,11 @@ class TestOpenCV < OpenCVTestCase
# Warp affine optional flags
assert_equal(8, CV_WARP_FILL_OUTLIERS)
assert_equal(16, CV_WARP_INVERSE_MAP)
# SVD operation flags
assert_equal(1, CV_SVD_MODIFY_A)
assert_equal(2, CV_SVD_U_T)
assert_equal(4, CV_SVD_V_T)
end
def test_symbols