Given two 3xK matrices I wish to compute the squared average of column by column dot products. This can be accomplished with a simple loop:
Eigen::Matrix<float,3,Eigen::Dynamic> L(3,K);
Eigen::Matrix<float,3,Eigen::Dynamic> P(3,K);
float distance = 0;
for (int q = 0; q < K; q++){
const Eigen::Vector3f& line = L.col(q);
const Eigen::Vector3f& point = P.col(q);
const float d = line.dot(point);
distance += d*d;
}
const float residual2 = distance / K;
which outperforms (g++ -O3 -DNDEBUG) the fancier reduction techniques, e.g.:
const float residual2 = (L.array() * P.array()).colwise().sum().square().mean();
const float residual2 = L.cwiseProduct(P).array().colwise().sum().array().square().mean();
const float residual2 = (L.transpose() * P).diagonal().array().square().mean();
Perhaps there is something I am missing here. Shouldn't the reductions be faster?
Edit: Using K = 20. I perform each of the above 100*632*631 times with the loop version taking about 1200 msec while the others would take around 2000 msec. 3.2 GHz Intel Core i5, MacOS, clang++ -O3
Edit2: Created a small test program. Adding -NDEBUG for compiling made a huge difference (I thought you got this for free with -O3). The loop version is significantly faster than
the reductions:
./eigentest
CASE 1: 12 milliseconds
solution = 1482.5
CASE 2: 835 milliseconds
solution = 1482.5
CASE 3: 849 milliseconds
solution = 1482.5
CASE 4: 843 milliseconds
solution = 1482.5
Edit3: I think the test above is crap since the compiler unrolled the loop.... sigh... I'll get back to this soon...