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.
source to share
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
).
source to share
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!
source to share