What does this specific use of the () operator mean?

I have this expression:

M(:,[[3,6,9,12]]) =  M(:,[3,6,9,12]) .* (U * ones(1,4));

      

I have checked in the Matlab docs but there are no such examples. Trying to translate it to OpenCV C ++. This is my code:

  cv::Mat temp(M.rows, 4, CV_64F);
  M.col(2).copyTo(temp(cv::Rect(0,0,1,M.rows)));
  M.col(5).copyTo(temp(cv::Rect(1,0,1,M.rows)));
  M.col(8).copyTo(temp(cv::Rect(2,0,1,M.rows)));
  M.col(11).copyTo(temp(cv::Rect(3,0,1,M.rows)));
  temp = temp.mul(U * cv::Mat::ones(1,4,CV_64F));
  temp.col(0).copyTo(M(cv::Rect(2,0,1,M.rows)));
  temp.col(1).copyTo(M(cv::Rect(5,0,1,M.rows)));
  temp.col(2).copyTo(M(cv::Rect(8,0,1,M.rows)));
  temp.col(3).copyTo(M(cv::Rect(11,0,1,M.rows)));

      

Is it correct? As far as I know, I cannot change these columns directly in OpenCV, perhaps it would be possible with Eigen. Also don't understand the double parenthesis on the left side of the assignment.

+3


source to share


2 answers


In Matlab, the code you give is well vectorized because it is the only way to get good performance without using Mex. However, in C ++, you're better off extending it into loops for

for readability and performance.

for(int i=0; i<M.rows; ++i) {
    for(int j=2; j<12; j+=3) {    // start from 2 due to 0-based indexing
        M.at<double>(i,j) *= U.at<double>(i);
    }
}

      



Note the use of an operator *=

that is not available in Matlab.

Oh, and it is [[3,6,9,12]]

equivalent to [3,6,9,12]

(and 3:3:12

).

+3


source


Opencv

You can write a statement concisely in OpenCV, in a somewhat vectorized form:

for (int i=2; i<12; i+=3) {
    Mat(M.col(i).mul(U)).copyTo(M.col(i));
}

      


MATLAB

For what it's worth, MATLAB code can also be written using translation:



M(:,[3 6 9 12]) = bsxfun(@times, M(:,[3 6 9 12]), U);

      

This avoids replicating the vector U

in memory. This is the same as:

for i=3:3:12
    M(:,i) = M(:,i) .* U;
end

      

which resembles the above C ++ code.

Unfortunately, MATLAB has gained a bad reputation over the years for being slow with loops, and that everyone should always prefer fully vectorized code over loops. But this is no longer so true in all cases, starting with the improvements made in the JIT.

In fact, the last for loop is very fast, even slightly faster than bsxfun

either or the original code!

+1


source







All Articles