Search code examples
c++eigen

Can I use Eigen-defined variable with the function adjacent_difference?


All, thanks in advance for any comments and advice!

I defined a double array with the Eigen-library of C++, then I want to use the adjacent_difference of the Numeric-library of C++, I found that I could not use that function for a variable defined under the Eigen-library.

Is it a conflict between the two libraries? Basically, I want to use the LinSpaced-function of the Eigen-library and adjacent_difference-function of Numeric library. Of course, I prefer to keep the Eigen-library in the code.

//not use Eigen defined variables
double a[] = { 1,3,4,7 }, b[4];
adjacent_difference(a,a+4,b);
for (int i = 0; i < 4; i++)
    cout << b[i] << endl;

//use Eigen defined variables
ArrayXd a1(4), b1(4);
a1 << 1, 3, 4, 7;
adjacent_difference(a1, a1 + 4, b1);
for (int i = 0; i < 4; i++)
    cout << b1[i] << endl;

The error message shows that "no instance of overloaded function matches the argument list".


Solution

  • First of all, you can easily calculate adjacent differences with built-in functionality of Eigen, e.g.:

    void adjacent_diff_eigen(Eigen::ArrayXf const& A, Eigen::ArrayXf& B)
    {
        Eigen::Index n = A.size();
        B.resize(n);
        if(n == 0) return;
        B[0] = A[0];
        B.tail(n-1) = A.tail(n-1) - A.head(n-1);
    }
    

    In contrast to the std approach, this should also get vectorized (unless unaligned vectorization is disabled).

    Furthermore, with the development branch of Eigen you can also use std-like iterators like so:

    void adjacent_diff_std(Eigen::ArrayXf const& A, Eigen::ArrayXf& B)
    {
        B.resizeLike(A);
        std::adjacent_difference(A.begin(), A.end(), B.begin());
    }
    

    For older Eigen versions, you can workaround by directly accessing the data:

        std::adjacent_difference(A.data(), A.data()+A.size(), B.data());
    

    Live-Demo at godbolt: https://godbolt.org/z/qbkagM