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:
parent
ca6b5daca1
commit
41bf713cd3
4 changed files with 130 additions and 13 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue