Search code examples
c++eigen

Fast 1D Convolution with Eigen C++?


Suppose I have two data arrays:

double data[4096] = { .... };
double b[3] = {.25, .5, .25};

I would like a fast and portable implementation of convolution. To use NumPy syntax

result = numpy.convolve(data, b, "same")

Kernel size is small, 3 or 5 and I may have to convolve with a kernel with zeros (giving scope maybe for further optimisations).

double b[5] = {.25, .0, .5, .0, .25};

I have a feeling Eigen C++ has optimised code for this, but I can't figure out how to use it. Alternatively, are there other libraries with a portable implementation of convolution, ideally optimised for common platforms?


Solution

  • Armadillo should have you covered.

    An Eigen implementation may look like this:

    Eigen::VectorXd convolve(const Eigen::Ref<const Eigen::VectorXd>& in,
          const Eigen::Vector3d& weights)
    {
        const Eigen::Index innersize = in.size() - 2;
        Eigen::VectorXd out(in.size());
        out.segment(1, innersize) =
              in.head(innersize) * weights.x() +
              in.segment(1, innersize) * weights.y() +
              in.tail(innersize) * weights.z();
        // Treat borders separately
        return out;
    }
    

    Unroll similarly for 5 weights.