BELFEM 0.9.0
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
fn_AR_eigen.hpp
Go to the documentation of this file.
1/*
2 * BELFEM -- The Berkeley Lab Finite Element Framework
3 * Copyright (c) 2026, The Regents of the University of California,
4 * through Lawrence Berkeley National Laboratory (subject to receipt of any required
5 * approvals from the U.S. Dept. of Energy). All rights reserved.
6 *
7 * Developers: Christian Messe, Gregory Giard
8 *
9 * See the top-level LICENSE file for the complete license and disclaimer.
10 */
11
12#ifndef BELFEM_FN_AR_EIGEN_HPP
13#define BELFEM_FN_AR_EIGEN_HPP
14#include "typedefs.hpp"
15#include "assert.hpp"
16#include "cl_AR_Vector.hpp"
17#include "cl_AR_Matrix.hpp"
18
19namespace belfem
20{
21//------------------------------------------------------------------------------
22
23 inline int_t
24 eigen( const Matrix< real > & aMatrix,
25 Vector< real > & aValues,
26 const bool aAbortOnComplex = true )
27 {
28 BELFEM_ASSERT( aMatrix.n_cols() == aMatrix.n_rows(),
29 "Matrix must be quadratic");
30
31 arma::cx_vec tValues ;
32
33 arma::eig_gen( tValues, aMatrix.matrix_data() );
34
35 size_t tN = aMatrix.n_cols() ;
36 aValues.set_size( aMatrix.n_cols() );
37
38 int_t tNumComplex = 0 ;
39
40 for( size_t k=0; k<tN; ++k )
41 {
42 if( std::abs( std::imag( tValues( k ) ) ) > BELFEM_EPSILON )
43 {
44 BELFEM_ERROR( ! aAbortOnComplex,
45 "eigen(): eigenvalue %u of this matrix is complex ( %g %+g i ), and a real "
46 "Vector cannot hold it. Use eigen_sym() if the matrix is symmetric, or pass "
47 "aAbortOnComplex = false to receive a count and NaN entries instead.",
48 ( unsigned int ) k,
49 ( double ) std::real( tValues( k ) ),
50 ( double ) std::imag( tValues( k ) ) );
51
52 aValues( k ) = BELFEM_QUIET_NAN ;
53 ++tNumComplex ;
54 }
55 else
56 {
57 aValues( k ) = std::real( tValues( k ) );
58 }
59 }
60
61 return tNumComplex ;
62 }
63
64//------------------------------------------------------------------------------
65
66 inline void
67 eigen_sym( const Matrix< real > & aMatrix,
68 Vector< real > & aValues )
69 {
70 BELFEM_ASSERT( aMatrix.n_cols() == aMatrix.n_rows(),
71 "Matrix must be quadratic");
72
73 // arma::eig_sym writes into an arma::Col, but Vector< T > is backed by an
74 // arma::Mat, so the eigenvalues are collected in a local and copied out
75 arma::Col< real > tValues ;
76
77 BELFEM_ERROR( arma::eig_sym( tValues, aMatrix.matrix_data() ),
78 "eigen_sym(): the symmetric eigenvalue decomposition did not converge" );
79
80 size_t tN = aMatrix.n_cols() ;
81 aValues.set_size( tN );
82
83 for( size_t k=0; k<tN; ++k )
84 {
85 aValues( k ) = tValues( k );
86 }
87 }
88
89//------------------------------------------------------------------------------
90}
91
92#endif //BELFEM_FN_AR_EIGEN_HPP
#define BELFEM_ERROR(aCheck,...)
Definition assert.hpp:264
#define BELFEM_ASSERT(aCheck,...)
Definition assert.hpp:244
MatrixType & matrix_data()
Definition cl_AR_Matrix.hpp:157
size_t n_rows() const
Definition cl_AR_Matrix.hpp:205
size_t n_cols() const
Definition cl_AR_Matrix.hpp:213
void set_size(const size_t aNumRows)
change the size of the vector
Definition cl_AR_Vector.hpp:237
int_t eigen(const Matrix< real > &aMatrix, Vector< real > &aValues, const bool aAbortOnComplex=true)
Eigenvalues of a general (not necessarily symmetric) square matrix.
Definition fn_AR_eigen.hpp:24
void eigen_sym(const Matrix< real > &aMatrix, Vector< real > &aValues)
Eigenvalues of a symmetric matrix.
Definition fn_AR_eigen.hpp:67
USER GUIDES:
Definition cl_Capacitor.cpp:16
constexpr real BELFEM_EPSILON
Definition typedefs.hpp:90
int32_t int_t
Definition typedefs.hpp:51
#define BELFEM_QUIET_NAN
Definition typedefs.hpp:87