MAST
lapack_dggev_interface.cpp
Go to the documentation of this file.
1 /*
2  * MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit
3  * Copyright (C) 2013-2019 Manav Bhatia
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 
21 // MAST includes
23 
24 
25 void
27  const RealMatrixX &B,
28  bool computeEigenvectors) {
29 
30  libmesh_assert(A.cols() == A.rows() &&
31  B.cols() == A.rows() &&
32  B.cols() == B.rows());
33 
34  _A = A;
35  _B = B;
36 
38  Amat = A,
39  Bmat = B;
40 
41  int n = (int)A.cols();
42 
43  char L='N',R='N';
44 
45  if (computeEigenvectors) {
46 
47  L = 'V'; R = 'V';
48  VL.setZero(n, n);
49  VR.setZero(n, n);
50  }
51 
52  int
53  lwork=16*n;
54 
55  info_val=-1;
56 
57  alpha.setZero(n);
58  beta.setZero(n);
59 
61  work,
62  aval_r,
63  aval_i,
64  bval;
65 
67  vecl,
68  vecr;
69 
70  work.setZero(lwork);
71  aval_r.setZero(n);
72  aval_i.setZero(n);
73  bval.setZero(n);
74  vecl.setZero(n,n);
75  vecr.setZero(n,n);
76 
77  Real
78  *a_vals = Amat.data(),
79  *b_vals = Bmat.data(),
80  *alpha_r_v = aval_r.data(),
81  *alpha_i_v = aval_i.data(),
82  *beta_v = bval.data(),
83  *vecl_v = vecl.data(),
84  *vecr_v = vecr.data(),
85  *work_v = work.data();
86 
87 
88  dggev_(&L, &R, &n,
89  &(a_vals[0]), &n,
90  &(b_vals[0]), &n,
91  &(alpha_r_v[0]), &(alpha_i_v[0]), &(beta_v[0]),
92  &(vecl_v[0]), &n, &(vecr_v[0]), &n,
93  &(work_v[0]), &lwork,
94  &info_val);
95 
96  // now sort the eigenvalues for complex conjugates
97  unsigned int n_located = 0;
98  while (n_located < n) {
99 
100  // if the imaginary part of the eigenvalue is non-zero, it is a
101  // complex conjugate
102  if (aval_i(n_located) != 0.) { // complex conjugate
103 
104  alpha( n_located) = std::complex<double>(aval_r(n_located), aval_i(n_located));
105  alpha(1+n_located) = std::complex<double>(aval_r(n_located), -aval_i(n_located));
106  beta ( n_located) = bval(n_located);
107  beta (1+n_located) = bval(n_located);
108 
109  // copy the eigenvectors if they were requested
110  if (computeEigenvectors) {
111 
112  std::complex<double> iota = std::complex<double>(0, 1.);
113 
114  VL.col( n_located) = (vecl.col( n_located).cast<Complex>() +
115  vecl.col(1+n_located).cast<Complex>() * iota);
116  VL.col(1+n_located) = (vecl.col( n_located).cast<Complex>() -
117  vecl.col(1+n_located).cast<Complex>() * iota);
118  VR.col( n_located) = (vecr.col( n_located).cast<Complex>() +
119  vecr.col(1+n_located).cast<Complex>() * iota);
120  VR.col(1+n_located) = (vecr.col( n_located).cast<Complex>() -
121  vecr.col(1+n_located).cast<Complex>() * iota);
122  }
123 
124  // two complex conjugate roots were found
125  n_located +=2;
126  }
127  else {
128 
129  alpha( n_located) = std::complex<double>(aval_r(n_located), 0.);
130  beta ( n_located) = bval(n_located);
131 
132  // copy the eigenvectors if they were requested
133  if (computeEigenvectors) {
134 
135  VL.col(n_located) = vecl.col(n_located).cast<Complex>();
136  VR.col(n_located) = vecr.col(n_located).cast<Complex>();
137  }
138 
139  // only one real root was found
140  n_located++;
141  }
142  }
143 
144  if (info_val != 0)
145  libMesh::out
146  << "Warning!! DGGEV returned with nonzero info = "
147  << info_val << std::endl;
148 }
149 
150 
libMesh::Real Real
libMesh::Complex Complex
const RealMatrixX & B() const
Matrix< Real, Dynamic, Dynamic > RealMatrixX
Matrix< Real, Dynamic, 1 > RealVectorX
const RealMatrixX & A() const
void compute(const RealMatrixX &A, const RealMatrixX &B, bool computeEigenvectors=true)
computes the eigensolution for .
int dggev_(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *b, int *ldb, double *alpha_r, double *alpha_i, double *beta, double *vl, int *ldvl, double *vr, int *ldvr, double *work, int *lwork, int *info)