Skip to content
Snippets Groups Projects

compute Eigenvalues and -vectors in 1-3d without LAPACK

Merged Lukas Renelt requested to merge feature/3d-eigenvalues+vectors into master

When dealing with small matrices calling LAPACK to calculate Eigenvalues and Eigenvectors can be quite slow. 1d- and 2d-specializations are quite straightforward, for the 3d-specialization I´m using the approach presented in https://www.geometrictools.com/Documentation/RobustEigenSymmetric3x3.pdf.

Edited by Christian Engwer

Merge request reports

Pipeline #24942 failed

Pipeline failed for 53ea620e on feature/3d-eigenvalues+vectors

Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • added feature label

  • @christi The main work should be done here, however, there are still two design choices to be made: I implemented the new Eigenvector functions with the signature

    eigenValuesVectors(const FieldMatrix<K, dim, dim>& matrix,
                      FieldVector<K, dim>& eigenValues,
                      FieldVector<FieldVector<K, dim>, dim>& eigenVectors)

    while the existing Lapack-binding has the signature

    eigenValuesVectorsLapack(const FieldMatrix<K, dim, dim>& matrix,
                            FieldVector<K, dim>& eigenValues,
                            FieldMatrix<K, dim, dim>& eigenVectors,
                            const char& jobz)

    First, I propose to adopt the jobz-tag (which controls whether to only calculate eigenvalues or eigenvalues and eigenvectors) and get rid of the eigenValues-function. Second, I feel that FieldVector<FieldVector<K, dim>, dim> is the more natural type for a set of eigenvectors, so I´d like to change the return type in the Lapack-binding. Both of those changes would most likely lead to subsequent changes in dependend code. How do you feel about this?

  • Second, I feel that FieldVector<FieldVector<K, dim>, dim> is the more natural type for a set of eigenvectors, so I´d like to change the return type in the Lapack-binding. Both of those changes would most likely lead to subsequent changes in dependend code. How do you feel about this?

    I'd stick to the current interface. It is not uncommon that you want to use the eigenvector basis to map an operator or a vector. In this case FieldMatrix is the right type. If you want to access individual eigenevectors, you can still do so in the current interface, as FieldMatrix::operator[] returns a FieldVector.

  • Lukas Renelt added 1 commit

    added 1 commit

    • c35c18f4 - resolve signature difference with lapack-binding

    Compare with previous version

  • Okay, I wasnt aware of the operator[] functionality - then there is no need to change anything. What about my other question?

  • What about my other question?

    I'm undecided and have to think about it.

    An additional parameter sounds good, but I don't like the char argument

  • Just a small side note: Please don't use FieldVector<FieldVector<...>> at all. Since FieldVector<...> is intended to contain entries from a field we dropped all occurrences long ago. If this should represent a linear operator or tensor, use FieldMatrix<...>, it it's just a statically sized collection of vectors then use std::array<FieldVector<...>>.

  • Lukas Renelt added 2 commits

    added 2 commits

    • f1a47aa5 - [temp] reenable tests for dim>3
    • 08fda1d6 - restructure interface and update tests

    Compare with previous version

  • There are currently two issues with this MR:

    1. if constexpr only works for newer compilers, so you have to switch to the updated .gitlab-ci.yml (easiest is to rebase on current master)
    2. you removed the eigenValues functions. We still need them for backwards compatibility and can think about deprecating them...
  • Christian Engwer mentioned in merge request !724 (closed)

    mentioned in merge request !724 (closed)

  • Lukas Renelt added 23 commits

    added 23 commits

    Compare with previous version

  • Lukas Renelt added 2 commits

    added 2 commits

    • b958a4c0 - re-add eigenValues for compatibility
    • f0cbbe33 - deprecate 'eigenValues()'

    Compare with previous version

  • adressing 2.: Yes, I'm still thinking about how to solve this best. I'm also not happy with the ComputationJob-tag yet - in practice this can get really long (Dune::FMatrixHelp::eigenValuesVectors<Dune::FMatrixHelp::ComputationJob::EigenvaluesEigenvectors>(...)).

  • How about the following...

    • we keep the two interfaces fr eigenvalues and eigenvalues+vectors
    • these forward then to the same implementation using a particular tag
  • Thats probably the easiest solution. I was also thinking about keeping eigenValues and somehow making ComputationJob::EigenvaluesEigenvectors the "default-tag" for eigenValuesVectors- passing a tag called EigenvaluesEigenvectors to a function eigenValuesVectors (which is expected to compute exactly that) is also kind of counterintuitive...

  • Lukas Renelt added 1 commit

    added 1 commit

    • d4d36dc5 - simplify interface: hide ComputationTag internally

    Compare with previous version

  • Christian Engwer
    Christian Engwer @christi started a thread on commit d4d36dc5
38 38 const long int* ldvl, double* vr, const long int* ldvr, double* work,
39 39 const long int* lwork, long int* info);
40 40
41 namespace Impl {
42 enum Jobs { OnlyEigenvalues, EigenvaluesEigenvectors };
43 constexpr std::array<char,2> LapackTags = {'n', 'v'};
  • Christian Engwer
    Christian Engwer @christi started a thread on commit d4d36dc5
  • 38 38 const long int* ldvl, double* vr, const long int* ldvr, double* work,
    39 39 const long int* lwork, long int* info);
    40 40
    41 namespace Impl {
    42 enum Jobs { OnlyEigenvalues, EigenvaluesEigenvectors };
  • Christian Engwer
    Christian Engwer @christi started a thread on commit d4d36dc5
  • 362 }
    363 }
    324 364 }
    365 //The preconditioning scaled the matrix, which scales the eigenvalues. Revert the scaling.
    366 eigenValues *= maxAbsElement;
    325 367 }
    326 }
    327 368
    369 // forwarding to LAPACK with corresponding tag
    370 template <Jobs Tag, int dim, typename K>
    371 static void eigenValuesVectorsLapackImpl(const FieldMatrix<K, dim, dim>& matrix,
    372 FieldVector<K, dim>& eigenValues,
    373 FieldMatrix<K, dim, dim>& eigenVectors)
    374 {
    375 {
    376 const char jobz = LapackTags[Tag];
  • Christian Engwer mentioned in merge request !727 (closed)

    mentioned in merge request !727 (closed)

  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Please register or sign in to reply
    Loading