0

I am writing smoothing spline in C++ using opencv.

I need to use sparse matrix (like in MATLAB), i.e. large matrix which consists of zeros and a few non-zero diagonals. I use Mat matrices for this purpose, because I want to be able to multiply them, transpose them, etc.

Is there exist some elegant way to initialize such matrix, without processing it element after element?

There is a function called Mat::diag, but this creates a column matrix, it is not what I need. Is it possible to convert this to normal matrix? The most similar thing to what I need is Mat::eye, but I need to initialize more than one diagonal, in addition, I have different numbers in same diagonal, so I cannot use Mat::eye.

Thank you!

smyslov
  • 1,279
  • 1
  • 8
  • 29
Maria
  • 63
  • 1
  • 6
  • What do you mean with _more than one diagonal_? Do you have the _different numbers in same diagonal_ stored in a vector or something? Could you edit adding how final matrix should look? – Miki Jul 15 '15 at 13:50
  • For example, matrix 3X3 has one "general" diagonal of length 3, two diagolals of length 2 each one - above and below the main diagonal, etc. And, yes, I may have different numbers in same diagonal. – Maria Jul 15 '15 at 13:52
  • well, you can set different "diagonals" creating "small" submatrices using Mat::eye to generate each one, and then sum each diagonal matrix on a zero initialized matrix with the actual size. If you need to set also different values, you need to set them manually. You can always wrap this all in a single function. If you provide the data structures (vector or whatever) that contain your data, and the final result you are expecting, it'll be much easier to provide a solution – Miki Jul 15 '15 at 14:02
  • 3
    Since tou mentioned matlab, do you know how to do it in Matlab? If so, provide an example that will be easily ported to OpenCV. – Miki Jul 15 '15 at 14:03
  • opencv has a sparse matrix class too. But not sure whether it has multuiplications etc implemented – Micka Jul 15 '15 at 15:59

2 Answers2

1

I solved myself: :)

Mat B = Mat::zeros(3, 3, CV_8UC1);
Mat C = B.diag(0);
C.at<unsigned char>(0) = 64;
C.at<unsigned char>(1) = 64;
C.at<unsigned char>(2) = 64;

Mat::diag is dynamic, so it works.

Maria
  • 63
  • 1
  • 6
0

You can initialize with Mat::eye and multiply by a 1 by N dimensional matrix containing the diagonal values you want. (Or just set them manually.) If your matrix is large enough that these operations take a significant amount of time you should not be using Mat which is not optimized for sparse matrices.

If your matrices are large enough that the above operations are slow, look here.

Community
  • 1
  • 1
Chris K
  • 1,703
  • 1
  • 14
  • 26