Matrix product is repeatedly evaluated when iterating over the product expression

Submitted by tar..@..ok.com

Assigned to Nobody

Link to original bugzilla bug (#1585)
Version: 3.3 (current stable)

Description

Here is the code that causes the problem.

#include <chrono>
#include <Eigen/Eigen>
#include <iostream>

template <typename Derived>
void my_print_mat1(const MatrixBase<Derived>& v_) {
volatile double dummy_output;
const Derived& v = v_.derived();
auto tstart = Clock::now();

auto size = v.size();  

for (auto i = 0; i < size; ++i) {  
    dummy_output = v(i);  
}  

std::chrono::duration&lt;double&gt; time = Clock::now() - tstart;  
std::cout << "my_print_mat1: " << time.count() << '\n';  

}

void my_print_mat2(const Ref<const Vec>& v) {
volatile double dummy_output;
auto tstart = Clock::now();

auto size = v.size();  

for (auto i = 0; i < size; ++i) {  
    dummy_output = v(i);  
}  

std::chrono::duration&lt;double&gt; time = Clock::now() - tstart;  

std::cout << "my_print_mat2: " << time.count() << '\n';  

}

int main() {
constexpr int size = 1000;
Mat mat = Mat::Random(size, size);
Vec vec = Vec::Random(size);
my_print_mat1(mat * vec);
my_print_mat2(mat * vec);
}

On my PC, the output is:
my_print_mat1: 0.97757
my_print_mat2: 2.3e-06

It appears that, in function "my_print_mat1", matrix-vector product is evaluated every time when the i-th component of v is accessed.

However, according to the documentation, my_print_mat1 is the recommended way to write functions that take Eigen types as parameters. (https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html)

And in this topic (https://eigen.tuxfamily.org/dox/TopicLazyEvaluation.html), I am told that matrix product expression will be evaluated in to a temporary variable. "Again, the most important example of such an expression is the matrix product expression." The code example above seems to contradict what the documatation claimed.

When I write a function that takes Eigen types as parameters, how could I get all the good of avoiding a temporary while making sure that costly expressions (like matrix product) are not repeatedly evaluated when iterating through a vector?

Note: In my project, the function is not as simple as printing a vector. And the iteration through every component of a vector is unavoidable.

Blocking

#558 (closed) #814 (closed)

Edited by Eigen Bugzilla