16 template <
typename _Type>
23 template <
typename _Type>
27 template <
typename _Type>
30 m_tagged_indices.clear();
32 if(m_calc_eigenvectors) {
33 eigensolve_lapack_with_vectors();
35 eigensolve_lapack_without_vectors();
44 problem =
"The DenseLinearEigenSystem::eigensolve_lapack_without_vectors method has been called\n";
45 problem +=
"but the compiler option -DLAPACK was not provided when\n";
46 problem +=
"the library was built.";
50 std::size_t N = m_pA -> nrows();
55 if((N % 2 == 0) && (N > 127)) {
59 if((m_pA -> nrows() != m_pB -> nrows()) ||
60 (m_pA -> ncols() != m_pB -> ncols())) {
61 std::string problem(
"The DenseLinearEigenSystem::eigensolve_lapack_without_vectors method has detected a failure \n");
62 throw ExceptionGeom(problem, m_pA -> nrows(), m_pA -> ncols(),
63 m_pB -> nrows(), m_pB -> ncols());
66 FortranData Af(*m_pA,
true, padding);
67 FortranData Bf(*m_pB,
true, padding);
69 DenseVector<double> alpha_r(N, 0.0);
70 DenseVector<double> alpha_i(N, 0.0);
71 DenseVector<double> beta(N, 0.0);
73 DenseVector<double> vec_left(1, 0.0);
74 DenseVector<double> vec_right(1, 0.0);
76 DenseVector<double> work(1, 0.0);
79 LAPACK_DGGEV((
char*)
"N", (
char*)
"N", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha_r[ 0 ], &alpha_i[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], 1, &work[ 0 ], -1, info);
80 int required_workspace = (int) work[ 0 ];
83 std::cout <<
" [DEBUG] DenseLinearEigenSystem::eigensolve_lapack_without_vectors is requesting \n";
84 std::cout <<
" [DEBUG] a workspace vector of size " << required_workspace <<
"\n";
87 work.resize(required_workspace);
89 LAPACK_DGGEV((
char*)
"N", (
char*)
"N", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha_r[ 0 ], &alpha_i[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], 1, &work[ 0 ], required_workspace, info);
91 std::string problem(
"The DenseLinearEigenSystem::eigensolve_lapack_without_vectors method has detected a failure. \n");
92 throw ExceptionExternal(problem, info);
95 m_eigenvalues_alpha = DenseVector<D_complex>(N, 0.0);
96 for(std::size_t i = 0; i < N; ++i) {
98 m_eigenvalues_alpha[ i ] = alpha_r[ i ] + alpha_i[ i ] *
eye;
101 m_eigenvalues_beta = beta;
107 void DenseLinearEigenSystem< std::complex<double> >::eigensolve_lapack_without_vectors() {
110 problem =
"The DenseLinearEigenSystem::eigensolve_lapack_without_vectors method has been called\n";
111 problem +=
"but the compiler option -DLAPACK was not provided when\n";
112 problem +=
"the library was built.";
113 throw ExceptionExternal(problem);
116 std::size_t N = m_pA -> nrows();
121 if((N % 2 == 0) && (N > 127)) {
125 if((m_pA -> nrows() != m_pB -> nrows()) ||
126 (m_pA -> ncols() != m_pB -> ncols())) {
127 std::string problem(
"The DenseLinearEigenSystem::eigensolve_lapack_without_vectors method has detected a failure. \n");
128 throw ExceptionGeom(problem, m_pA -> nrows(), m_pA -> ncols(),
129 m_pB -> nrows(), m_pB -> ncols());
133 FortranData Af(*m_pA,
true, padding);
134 FortranData Bf(*m_pB,
true, padding);
136 DenseVector<double>
alpha(2 * N, 0.0);
137 DenseVector<double> beta(2 * N, 0.0);
139 DenseVector<double> vec_left(2, 0.0);
140 DenseVector<double> vec_right(2, 0.0);
143 DenseVector<double> work(2, 0.0);
144 DenseVector<double> rwork(8 * N, 0.0);
147 LAPACK_ZGGEV((
char*)
"N", (
char*)
"N", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], 1, &work[ 0 ], -1, &rwork[ 0 ], info);
148 int required_workspace = int(work[ 0 ]);
151 std::cout <<
"[DEBUG] DenseLinearEigenSystem::eigensolve_lapack_without_vectors is requesting \n";
152 std::cout <<
"[DEBUG] a workspace vector of size " << required_workspace <<
"\n";
155 work.resize(2 * required_workspace);
157 LAPACK_ZGGEV((
char*)
"N", (
char*)
"N", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], 1, &work[ 0 ], required_workspace, &rwork[ 0 ], info);
160 std::string problem(
"The DenseLinearEigenSystem::eigensolve_lapack_without_vectors method has detected a failure \n");
161 throw ExceptionExternal(problem, info);
164 m_eigenvalues_alpha = DenseVector<D_complex>(N, 0.0);
165 m_eigenvalues_beta = DenseVector<D_complex>(N, 0.0);
168 for(std::size_t i = 0; i < N; ++i) {
169 m_eigenvalues_alpha[ i ] =
alpha[ 2 * i ] +
alpha[ 2 * i + 1 ] *
eye;
170 m_eigenvalues_beta[ i ] = beta[ 2 * i ] + beta[ 2 * i + 1 ] *
eye;
178 void DenseLinearEigenSystem< double >::eigensolve_lapack_with_vectors() {
181 problem =
"The DenseLinearEigenSystem::eigensolve_lapack_with_vectors method has been called\n";
182 problem +=
"but the compiler option -DLAPACK was not provided when\n";
183 problem +=
"the library was built.";
184 throw ExceptionExternal(problem);
187 std::size_t N = m_pA -> nrows();
192 if((N % 2 == 0) && (N > 127)) {
196 if((m_pA -> nrows() != m_pB -> nrows()) ||
197 (m_pA -> ncols() != m_pB -> ncols())) {
198 std::string problem(
"The DenseLinearEigenSystem::eigensolve_lapack_with_vectors method has detected a failure. \n");
199 throw ExceptionGeom(problem, m_pA -> nrows(), m_pA -> ncols(),
200 m_pB -> nrows(), m_pB -> ncols());
205 FortranData Af(*m_pA,
true, padding);
206 FortranData Bf(*m_pB,
true, padding);
208 DenseVector<double> alpha_r(N, 0.0);
209 DenseVector<double> alpha_i(N, 0.0);
210 DenseVector<double> beta(N, 0.0);
212 DenseVector<double> vec_left(1, 0.0);
213 DenseVector<double> vec_right(N * N, 0.0);
215 DenseVector<double> work(1, 0.0);
219 LAPACK_DGGEV((
char*)
"N", (
char*)
"V", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha_r[ 0 ], &alpha_i[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], N, &work[ 0 ], -1, info);
220 int required_workspace = 4 * int(work[ 0 ]);
223 std::cout <<
"[DEBUG] DenseLinearEigenSystem::eigensolve_lapack_with_vectors is requesting \n";
224 std::cout <<
"[DEBUG] a workspace vector of size " << required_workspace <<
"\n";
227 work.resize(required_workspace);
229 LAPACK_DGGEV((
char*)
"N", (
char*)
"V", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha_r[ 0 ], &alpha_i[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], N, &work[ 0 ], required_workspace, info);
231 std::string problem(
"The DenseLinearEigenSystem::eigensolve_lapack_with_vectors method has detected a failure.\n");
232 throw ExceptionExternal(problem, info);
235 m_eigenvalues_alpha = DenseVector<D_complex>(N, 0.0);
237 m_all_eigenvectors = DenseMatrix<D_complex>(N, N, 0.0);
239 for(std::size_t i = 0; i < N; ++i) {
242 m_eigenvalues_alpha[ i ] = alpha_r[ i ] + alpha_i[ i ] *
eye;
243 if(std::abs(alpha_i[ i ]) > 0.0) {
245 for(std::size_t k = 0; k < N; ++k) {
246 m_all_eigenvectors[ i ][ k ] = vec_right[ i * N + k ] +
eye * vec_right[(i + 1) * N + k ];
248 m_all_eigenvectors[ i + 1 ][ k ] = vec_right[ i * N + k ] -
eye * vec_right[(i + 1) * N + k ];
252 for(std::size_t k = 0; k < N; ++k) {
253 m_all_eigenvectors(i, k) = vec_right[ i * N + k ];
258 m_eigenvalues_beta = beta;
264 void DenseLinearEigenSystem< std::complex<double> >::eigensolve_lapack_with_vectors() {
267 problem =
"The DenseLinearEigenSystem::eigensolve_lapack_with_vectors method has been called\n";
268 problem +=
"but the compiler option -DLAPACK was not provided when\n";
269 problem +=
"the library was built.";
270 throw ExceptionExternal(problem);
273 std::size_t N = m_pA -> nrows();
278 if((N % 2 == 0) && (N > 127)) {
282 if((m_pA -> nrows() != m_pB -> nrows()) ||
283 (m_pA -> ncols() != m_pB -> ncols())) {
284 std::string problem(
"The DenseLinearEigenSystem::eigensolve_lapack_with_vectors method has detected a failure. \n");
285 throw ExceptionGeom(problem, m_pA -> nrows(), m_pA -> ncols(),
286 m_pB -> nrows(), m_pB -> ncols());
290 FortranData Af(*m_pA,
true, padding);
291 FortranData Bf(*m_pB,
true, padding);
293 DenseVector<double>
alpha(2 * N, 0.0);
294 DenseVector<double> beta(2 * N, 0.0);
296 DenseVector<double> vec_left(2, 0.0);
297 DenseVector<double> vec_right(2 * N * N, 0.0);
299 DenseVector<double> work(2, 0.0);
300 DenseVector<double> rwork(8 * N, 0.0);
303 LAPACK_ZGGEV((
char*)
"N", (
char*)
"V", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], N, &work[ 0 ], -1, &rwork[ 0 ], info);
304 int required_workspace = int(work[ 0 ]);
307 std::cout <<
"[DEBUG] DenseLinearEigenSystem::eigensolve_lapack_with_vectors is requesting \n";
308 std::cout <<
"[DEBUG] a workspace vector of size " << required_workspace <<
"\n";
311 work.resize(2 * required_workspace);
313 LAPACK_ZGGEV((
char*)
"N", (
char*)
"V", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], N, &work[ 0 ], required_workspace, &rwork[ 0 ], info);
315 std::string problem(
"The DenseLinearEigenSystem::eigensolve_lapack_with_vectors method has detected a failure.\n");
316 throw ExceptionExternal(problem, info);
319 m_eigenvalues_alpha = DenseVector<D_complex>(N, 0.0);
320 m_eigenvalues_beta = DenseVector<D_complex>(N, 0.0);
322 m_all_eigenvectors = DenseMatrix<D_complex>(N, N, 0.0);
324 for(std::size_t i = 0; i < N; ++i) {
326 m_eigenvalues_alpha[ i ] =
alpha[ 2 * i ] +
alpha[ 2 * i + 1 ] *
eye;
327 m_eigenvalues_beta[ i ] = beta[ 2 * i ] + beta[ 2 * i + 1 ] *
eye;
328 for(std::size_t j = 0; j < N; ++j) {
329 m_all_eigenvectors(i, j) = vec_right[ 2 * i * N + 2 * j ] + vec_right[ 2 * i * N + 2 * j + 1 ] *
eye;
336 template <
typename _Type>
338 if(m_tagged_indices.size() == 0) {
340 problem =
"In DenseLinearEigenSystem.get_tagged_eigenvalues() : there are\n";
341 problem +=
"no eigenvalues that have been tagged. This set is empty.\n";
347 for(
iter p = m_tagged_indices.begin();
p != m_tagged_indices.end(); ++
p) {
352 evals.
push_back(m_eigenvalues_alpha[ j ] / m_eigenvalues_beta[ j ]);
358 template <
typename _Type>
360 if(m_tagged_indices.size() == 0) {
362 problem =
"In DenseLinearEigenSystem.get_tagged_eigenvectors() : there are\n";
363 problem +=
"no eigenvalues that have been tagged. This set is empty.\n";
367 std::size_t N = m_eigenvalues_alpha.size();
372 for(
iter p = m_tagged_indices.begin();
p != m_tagged_indices.end(); ++
p) {
376 evecs[ row ] = m_all_eigenvectors[ j ];
385 template <
typename _Type>
388 for(std::size_t i = 0; i < m_eigenvalues_alpha.size(); ++i) {
390 if(std::abs(m_eigenvalues_alpha[ i ] - m_shift * m_eigenvalues_beta[ i ]) <
391 std::abs(radius * m_eigenvalues_beta[ i ])) {
394 m_tagged_indices.insert(m_tagged_indices.end(), i);
397 m_tagged_indices.erase(i);
403 template <
typename _Type>
405 double real_value = m_shift.real();
407 for(std::size_t i = 0; i < m_eigenvalues_alpha.size(); ++i) {
409 if((m_eigenvalues_alpha[ i ] * std::conj(m_eigenvalues_beta[ i ])).real() >
410 std::pow(std::abs(m_eigenvalues_beta[ i ]), 2) * real_value) {
413 m_tagged_indices.insert(m_tagged_indices.end(), i);
416 m_tagged_indices.erase(i);
422 template <
typename _Type>
424 double real_value = m_shift.real();
426 for(std::size_t i = 0; i < m_eigenvalues_alpha.size(); ++i) {
428 if((m_eigenvalues_alpha[ i ] * std::conj(m_eigenvalues_beta[ i ])).real() <
429 std::pow(std::abs(m_eigenvalues_beta[ i ]), 2) * real_value) {
432 m_tagged_indices.insert(m_tagged_indices.end(), i);
435 m_tagged_indices.erase(i);
441 template <
typename _Type>
443 double imag_value = m_shift.imag();
445 for(std::size_t i = 0; i < m_eigenvalues_alpha.size(); ++i) {
447 if((m_eigenvalues_alpha[ i ] * std::conj(m_eigenvalues_beta[ i ])).imag() >
448 std::pow(std::abs(m_eigenvalues_beta[ i ]), 2) * imag_value) {
451 m_tagged_indices.insert(m_tagged_indices.end(), i);
454 m_tagged_indices.erase(i);
460 template <
typename _Type>
462 double imag_value = m_shift.imag();
464 for(std::size_t i = 0; i < m_eigenvalues_alpha.size(); ++i) {
466 if((m_eigenvalues_alpha[ i ] * std::conj(m_eigenvalues_beta[ i ])).imag() <
467 std::pow(std::abs(m_eigenvalues_beta[ i ]), 2) * imag_value) {
470 m_tagged_indices.insert(m_tagged_indices.end(), i);
473 m_tagged_indices.erase(i);
Specification of the dense linear eigensystem class.
The collection of CppNoddy exceptions.
Some interface definitions for calling external fortran routines in LAPACK.
A linear Nth-order generalised eigensystem class.
void tag_eigenvalues_right(const int &val)
Tag those eigenvalues that are to the right of a specified point.
void tag_eigenvalues_disc(const int &val, const double &radius)
Tag those eigenvalues that are within a disc centred at a point in the complex plane.
DenseVector< D_complex > get_tagged_eigenvalues() const
Get the the tagged eigenvalues.
void eigensolve()
Solve the matrix linear eigensystem.
void tag_eigenvalues_lower(const int &val)
Tag those eigenvalues that are in the lower half-plane below a specified point.
void tag_eigenvalues_left(const int &val)
Tag those eigenvalues that are to the left of a specified point.
DenseLinearEigenSystem(DenseMatrix< _Type > *Aptr, DenseMatrix< _Type > *Bptr)
Constructor for a linear system object.
void tag_eigenvalues_upper(const int &val)
Tag those eigenvalues that are in the upper half-plane above a specified point.
DenseMatrix< D_complex > get_tagged_eigenvectors() const
Get the the tagged eigenvectors.
~DenseLinearEigenSystem()
Destructor for a linear system object.
A matrix class that constructs a DENSE matrix as a row major std::vector of DenseVectors.
An DenseVector class – a dense vector object.
void push_back(const _Type &fill)
A pass-thru definition of push_back.
An exception to indicate that an error has been detected in an external (LAPACK) routine.
A generic runtime exception.
A linear Nth-order generalised eigensystem base class.
std::set< unsigned, std::less< unsigned > >::iterator iter
const D_complex eye(0., 1.0)
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...
std::complex< double > D_complex
A complex double precision number using std::complex.