Eigen (C++ library)

From David's Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
\( \newcommand{\P}[]{\unicode{xB6}} \newcommand{\AA}[]{\unicode{x212B}} \newcommand{\empty}[]{\emptyset} \newcommand{\O}[]{\emptyset} \newcommand{\Alpha}[]{Α} \newcommand{\Beta}[]{Β} \newcommand{\Epsilon}[]{Ε} \newcommand{\Iota}[]{Ι} \newcommand{\Kappa}[]{Κ} \newcommand{\Rho}[]{Ρ} \newcommand{\Tau}[]{Τ} \newcommand{\Zeta}[]{Ζ} \newcommand{\Mu}[]{\unicode{x039C}} \newcommand{\Chi}[]{Χ} \newcommand{\Eta}[]{\unicode{x0397}} \newcommand{\Nu}[]{\unicode{x039D}} \newcommand{\Omicron}[]{\unicode{x039F}} \DeclareMathOperator{\sgn}{sgn} \def\oiint{\mathop{\vcenter{\mathchoice{\huge\unicode{x222F}\,}{\unicode{x222F}}{\unicode{x222F}}{\unicode{x222F}}}\,}\nolimits} \def\oiiint{\mathop{\vcenter{\mathchoice{\huge\unicode{x2230}\,}{\unicode{x2230}}{\unicode{x2230}}{\unicode{x2230}}}\,}\nolimits} \)

Eigen is a template header-only C++ linear algebra library. You can think of it as as numpy for C++.

Website

Usage

Compilation

Reference
For optimal performance, I recommend using the following flags when compiling.

GCC

  • -march=native and -mtune=native if running only locally or -march=skylake if distributing to relatively modern (since ~2015) cpus.
    • Otherwise, at a minimum
    • -mfma Enable fused multiply add
    • -mavx2 Enable avx2 vector instructions
  • -DEIGEN_NO_DEBUG Set preprocessor define for eigen optimizations
  • -fopenmp OpenMP parallel execution
  • -O3 to enable optimizations

Data to Eigen

You can use Eigen::Map to create an eigen view for your existing data. This works with aligned or unaligned data, row-order or column-order, and different strides.
See Eigen: Interfacing with raw buffers for an example.

Math

SVD

Eigen comes with a few SVD implementations in its SVD Module.
If you only need low-rank approximations then you may be interested in randomized SVD.
This can be 10-20x faster when calculating low-rank approximations on large matrices.
Github Implementation
Finding structure with randomness paper
Facebook Blog post

Unsupported

FFT

https://eigen.tuxfamily.org/dox/unsupported/group__FFT__Module.html
https://gitlab.com/libeigen/eigen/-/blob/master/unsupported/Eigen/FFT?ref_type=heads
https://eigen.tuxfamily.org/index.php?title=EigenFFT


This uses either kissfft (default), FFTW (GPL), Intel oneMKL, or pocketFFT under the hood. There is very little documentation on this so it's easier to just read the code:

// Initialize standard FFT.
Eigen::FFT<double> fft;

// Initialize RFFT
Eigen::FFT<double> fft(Eigen::FFT<double>::impl_type(), Eigen::FFT<double>::HalfSpectrum);

// Do the actual FFT or RFFT.
std::vector<double> my_data = {1.0, 2.0, 3.0, 4.0};
std::vector<std::complex<double>> fft_result;
fft.fwd(fft_result, my_data);

// Inverse
fft.inv(my_data, fft_result);

Notes

  • Alternative backend implementations can be set with EIGEN_FFTW_DEFAULT, EIGEN_MKL_DEFAULT, EIGEN_POCKETFFT_DEFAULT
  • fwd2 and inv2 is available on the non-default backends.