Add internal third party module Eigen3

I am glad to announce that after a few force-pushes, the pull request to add Eigen3 as an internal third party module is ready for review.
Kudos to @matt.mccormick @jcfr and @bpaniagua for the support :pick::balloon:!

  • Introduce Eigen3 as an internal ThirdParty module. It allows remote modules to use find_package(Eigen3) where Eigen3_DIR points to the internal ITK. This is convenient for modules bridging with third parties modules that are using Eigen, so they do not have to change the third party reference to the Eigen target Eigen3::Eigen . One instance of such a module is ITKTotalVariation, that aims to bring total variation regularization (denoising) bridging the third-party library proxTV

  • The first use of Eigen3 is in itkSymmetricEigenAnalysis.h.
    A flag m_UseEigenLibrary is added to allow using Eigen3 with a Eigen::Matrix<TValue, Dynamic, Dynamic> (where the size is unknown at compile time).

Also another class in the same header has been added: SymmetricEigenAnalysisFixedDimension , that allows usage of Eigen::Matrix<TValue, Dimension, Dimension> that performs optimized computations.

Current tests have been expanded to exercise the added features.

  • Performance test:
    Using this image, and this example --modifying the SymmetricEigenAnalysis there accordingly–
    with the command
for i in {1..10}; do ./BoneEnhancementExamples ~/Data/BoneEnhancement/001-CT.nii ~/Data/BoneEnhancement/out_preprocessed.nrrd ~/Data/BoneEnhancement/out_measure.nrrd 0 0 3 2 2 2; done


Eigen FixedDimension: 40.19
Old -const netlib-:   48.12
Eigen Dynamic:        57.10

Which is around 16% faster when using the fixed dimension.

  • Classes that have been modified to use the faster SymmetricEigenAnalysisFixedDimension:

Beyond the shown usage for computing eigenvalues, Eigen3 would allow ITK to reach and bridge with more existing algorithms.


@phcerdan congratulations on this monumental contribution! :building_construction:

This will enable us to gradually transition to Eigen from VNL.


Fantastic news! I just spotted this when updating my master branch.

Is there any plan for transitioning to Eigen throughout ITK? I know this has been discussed on-and-off for a long time. For my own code, it will be a big help if the underlying type of itk::VectorImage is an Eigen::ArrayXd instead of a vnl_vector, but I am aware that’s a pretty fundamental change.

If I can find time to help with this transition, I will gladly do so.


There is a 2-step plan:

  1. Encapsulate vnl_vector and friends behind ITK type aliases such as NumericVector or InternalVector or something similar. Make VNL an internal dependency not visible to users of ITK.
  2. Swap out Eigen in place of VNL. Possibly gradually, as time and resources allow.

I think it won’t be that hard to change the internal data, however it will span the whole library. But with the awesome test coverage of ITK, it shoudn’t be a problem.
Related with @dzenanz suggestion, the current name to access the vnl data is GetVnlVector, GetVnlMatrix, etc… which is unfortunate for this kind of internal refactoring.

Maybe 5.0 is a good opportunity to deprecate GetVnlVector, in favor of an equivalent new method: GetInternalVector or similar, so changes will be less painful for third parties in the future.

1 Like

As we come across small, bite-size tasks to facilitate the migration from VNL to Eigen, I think it will be helpful to create issues in GitHub. After we have a sufficient number of issues, we could collect them in a GitHub Project. :octopus: This should help facilitate forward progress! :owl:


Great idea. I’ve started “Watching” the github repo - but I may stop that as on something the size of ITK there tend to be a lot of notifications. Having this in a project I can keep an eye on would be fantastic.

1 Like

After we have enough issues collected, perhaps we should hold a hackathon to begin tackling them. :football: