MAST
lapack_zggevx_interface.h
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 #ifndef __mast__lapack_zggevx_interface_h__
21 #define __mast__lapack_zggevx_interface_h__
22 
23 
24 // MAST includes
25 #include "base/mast_data_types.h"
27 
28 
29 extern "C" {
30  /*
31  * =====================================================================
32  * Purpose
33  * =======
34  *
35  * ZGGEVX computes for a pair of N-by-N complex nonsymmetric matrices
36  * (A,B) the generalized eigenvalues, and optionally, the left and/or
37  * right generalized eigenvectors.
38  *
39  * Optionally, it also computes a balancing transformation to improve
40  * the conditioning of the eigenvalues and eigenvectors (ILO, IHI,
41  * LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for
42  * the eigenvalues (RCONDE), and reciprocal condition numbers for the
43  * right eigenvectors (RCONDV).
44  *
45  * A generalized eigenvalue for a pair of matrices (A,B) is a scalar
46  * lambda or a ratio alpha/beta = lambda, such that A - lambda*B is
47  * singular. It is usually represented as the pair (alpha,beta), as
48  * there is a reasonable interpretation for beta=0, and even for both
49  * being zero.
50  *
51  * The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
52  * of (A,B) satisfies
53  * A * v(j) = lambda(j) * B * v(j) .
54  * The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
55  * of (A,B) satisfies
56  * u(j)**H * A = lambda(j) * u(j)**H * B.
57  * where u(j)**H is the conjugate-transpose of u(j).
58  *
59  *
60  * Arguments
61  * =========
62  *
63  * BALANC (input) CHARACTER*1
64  * Specifies the balance option to be performed:
65  * = 'N': do not diagonally scale or permute;
66  * = 'P': permute only;
67  * = 'S': scale only;
68  * = 'B': both permute and scale.
69  * Computed reciprocal condition numbers will be for the
70  * matrices after permuting and/or balancing. Permuting does
71  * not change condition numbers (in exact arithmetic), but
72  * balancing does.
73  *
74  * JOBVL (input) CHARACTER*1
75  * = 'N': do not compute the left generalized eigenvectors;
76  * = 'V': compute the left generalized eigenvectors.
77  *
78  * JOBVR (input) CHARACTER*1
79  * = 'N': do not compute the right generalized eigenvectors;
80  * = 'V': compute the right generalized eigenvectors.
81  *
82  * SENSE (input) CHARACTER*1
83  * Determines which reciprocal condition numbers are computed.
84  * = 'N': none are computed;
85  * = 'E': computed for eigenvalues only;
86  * = 'V': computed for eigenvectors only;
87  * = 'B': computed for eigenvalues and eigenvectors.
88  *
89  * N (input) INTEGER
90  * The order of the matrices A, B, VL, and VR. N >= 0.
91  *
92  * A (input/output) COMPLEX*16 array, dimension (LDA, N)
93  * On entry, the matrix A in the pair (A,B).
94  * On exit, A has been overwritten. If JOBVL='V' or JOBVR='V'
95  * or both, then A contains the first part of the complex Schur
96  * form of the "balanced" versions of the input A and B.
97  *
98  * LDA (input) INTEGER
99  * The leading dimension of A. LDA >= max(1,N).
100  *
101  * B (input/output) COMPLEX*16 array, dimension (LDB, N)
102  * On entry, the matrix B in the pair (A,B).
103  * On exit, B has been overwritten. If JOBVL='V' or JOBVR='V'
104  * or both, then B contains the second part of the complex
105  * Schur form of the "balanced" versions of the input A and B.
106  *
107  * LDB (input) INTEGER
108  * The leading dimension of B. LDB >= max(1,N).
109  *
110  * ALPHA (output) COMPLEX*16 array, dimension (N)
111  * BETA (output) COMPLEX*16 array, dimension (N)
112  * On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the generalized
113  * eigenvalues.
114  *
115  * Note: the quotient ALPHA(j)/BETA(j) ) may easily over- or
116  * underflow, and BETA(j) may even be zero. Thus, the user
117  * should avoid naively computing the ratio ALPHA/BETA.
118  * However, ALPHA will be always less than and usually
119  * comparable with norm(A) in magnitude, and BETA always less
120  * than and usually comparable with norm(B).
121  *
122  * VL (output) COMPLEX*16 array, dimension (LDVL,N)
123  * If JOBVL = 'V', the left generalized eigenvectors u(j) are
124  * stored one after another in the columns of VL, in the same
125  * order as their eigenvalues.
126  * Each eigenvector will be scaled so the largest component
127  * will have abs(real part) + abs(imag. part) = 1.
128  * Not referenced if JOBVL = 'N'.
129  *
130  * LDVL (input) INTEGER
131  * The leading dimension of the matrix VL. LDVL >= 1, and
132  * if JOBVL = 'V', LDVL >= N.
133  *
134  * VR (output) COMPLEX*16 array, dimension (LDVR,N)
135  * If JOBVR = 'V', the right generalized eigenvectors v(j) are
136  * stored one after another in the columns of VR, in the same
137  * order as their eigenvalues.
138  * Each eigenvector will be scaled so the largest component
139  * will have abs(real part) + abs(imag. part) = 1.
140  * Not referenced if JOBVR = 'N'.
141  *
142  * LDVR (input) INTEGER
143  * The leading dimension of the matrix VR. LDVR >= 1, and
144  * if JOBVR = 'V', LDVR >= N.
145  *
146  * ILO (output) INTEGER
147  * IHI (output) INTEGER
148  * ILO and IHI are integer values such that on exit
149  * A(i,j) = 0 and B(i,j) = 0 if i > j and
150  * j = 1,...,ILO-1 or i = IHI+1,...,N.
151  * If BALANC = 'N' or 'S', ILO = 1 and IHI = N.
152  *
153  * LSCALE (output) DOUBLE PRECISION array, dimension (N)
154  * Details of the permutations and scaling factors applied
155  * to the left side of A and B. If PL(j) is the index of the
156  * row interchanged with row j, and DL(j) is the scaling
157  * factor applied to row j, then
158  * LSCALE(j) = PL(j) for j = 1,...,ILO-1
159  * = DL(j) for j = ILO,...,IHI
160  * = PL(j) for j = IHI+1,...,N.
161  * The order in which the interchanges are made is N to IHI+1,
162  * then 1 to ILO-1.
163  *
164  * RSCALE (output) DOUBLE PRECISION array, dimension (N)
165  * Details of the permutations and scaling factors applied
166  * to the right side of A and B. If PR(j) is the index of the
167  * column interchanged with column j, and DR(j) is the scaling
168  * factor applied to column j, then
169  * RSCALE(j) = PR(j) for j = 1,...,ILO-1
170  * = DR(j) for j = ILO,...,IHI
171  * = PR(j) for j = IHI+1,...,N
172  * The order in which the interchanges are made is N to IHI+1,
173  * then 1 to ILO-1.
174  *
175  * ABNRM (output) DOUBLE PRECISION
176  * The one-norm of the balanced matrix A.
177  *
178  * BBNRM (output) DOUBLE PRECISION
179  * The one-norm of the balanced matrix B.
180  *
181  * RCONDE (output) DOUBLE PRECISION array, dimension (N)
182  * If SENSE = 'E' or 'B', the reciprocal condition numbers of
183  * the eigenvalues, stored in consecutive elements of the array.
184  * If SENSE = 'N' or 'V', RCONDE is not referenced.
185  *
186  * RCONDV (output) DOUBLE PRECISION array, dimension (N)
187  * If JOB = 'V' or 'B', the estimated reciprocal condition
188  * numbers of the eigenvectors, stored in consecutive elements
189  * of the array. If the eigenvalues cannot be reordered to
190  * compute RCONDV(j), RCONDV(j) is set to 0; this can only occur
191  * when the true value would be very small anyway.
192  * If SENSE = 'N' or 'E', RCONDV is not referenced.
193  *
194  * WORK (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
195  * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
196  *
197  * LWORK (input) INTEGER
198  * The dimension of the array WORK. LWORK >= max(1,2*N).
199  * If SENSE = 'E', LWORK >= max(1,4*N).
200  * If SENSE = 'V' or 'B', LWORK >= max(1,2*N*N+2*N).
201  *
202  * If LWORK = -1, then a workspace query is assumed; the routine
203  * only calculates the optimal size of the WORK array, returns
204  * this value as the first entry of the WORK array, and no error
205  * message related to LWORK is issued by XERBLA.
206  *
207  * RWORK (workspace) REAL array, dimension (lrwork)
208  * lrwork must be at least max(1,6*N) if BALANC = 'S' or 'B',
209  * and at least max(1,2*N) otherwise.
210  * Real workspace.
211  *
212  * IWORK (workspace) INTEGER array, dimension (N+2)
213  * If SENSE = 'E', IWORK is not referenced.
214  *
215  * BWORK (workspace) LOGICAL array, dimension (N)
216  * If SENSE = 'N', BWORK is not referenced.
217  *
218  * INFO (output) INTEGER
219  * = 0: successful exit
220  * < 0: if INFO = -i, the i-th argument had an illegal value.
221  * = 1,...,N:
222  * The QZ iteration failed. No eigenvectors have been
223  * calculated, but ALPHA(j) and BETA(j) should be correct
224  * for j=INFO+1,...,N.
225  * > N: =N+1: other than QZ iteration failed in ZHGEQZ.
226  * =N+2: error return from ZTGEVC.
227  *
228  * Further Details
229  * ===============
230  *
231  * Balancing a matrix pair (A,B) includes, first, permuting rows and
232  * columns to isolate eigenvalues, second, applying diagonal similarity
233  * transformation to the rows and columns to make the rows and columns
234  * as close in norm as possible. The computed reciprocal condition
235  * numbers correspond to the balanced matrix. Permuting rows and columns
236  * will not change the condition numbers (in exact arithmetic) but
237  * diagonal scaling will. For further explanation of balancing, see
238  * section 4.11.1.2 of LAPACK Users' Guide.
239  *
240  * An approximate error bound on the chordal distance between the i-th
241  * computed generalized eigenvalue w and the corresponding exact
242  * eigenvalue lambda is
243  *
244  * chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I)
245  *
246  * An approximate error bound for the angle between the i-th computed
247  * eigenvector VL(i) or VR(i) is given by
248  *
249  * EPS * norm(ABNRM, BBNRM) / DIF(i).
250  *
251  * For further explanation of the reciprocal condition numbers RCONDE
252  * and RCONDV, see section 4.11 of LAPACK User's Guide.
253  *
254  * =====================================================================
255  */
256  extern int zggevx_(char* balanc,
257  char* jobvl,
258  char* jobvr,
259  char* sens,
260  int* n,
261  std::complex<double>* a,
262  int* lda,
263  std::complex<double>* b,
264  int* ldb,
265  std::complex<double>* alpha,
266  std::complex<double>* beta,
267  std::complex<double>* vl,
268  int* ldvl,
269  std::complex<double>* vr,
270  int* ldvr,
271  int* ilo,
272  int* ihi,
273  double* lscale,
274  double* rscale,
275  double* abnrm,
276  double* bbnrm,
277  double* rconde,
278  double* rcondv,
279  std::complex<double>* work,
280  int* lwork,
281  double* rwork,
282  int* iwork,
283  bool* bwork,
284  int* info);
285 
286 }
287 
288 
289 namespace MAST {
290 
292  public MAST::LAPACK_ZGGEV_Base {
293 
294  public:
295 
298  { }
299 
304  virtual void compute(const ComplexMatrixX& A,
305  const ComplexMatrixX& B,
306  bool computeEigenvectors = true);
307 
308  };
309 }
310 
311 
312 
313 #endif // __mast__lapack_zggevx_interface_h__
int zggevx_(char *balanc, char *jobvl, char *jobvr, char *sens, int *n, std::complex< double > *a, int *lda, std::complex< double > *b, int *ldb, std::complex< double > *alpha, std::complex< double > *beta, std::complex< double > *vl, int *ldvl, std::complex< double > *vr, int *ldvr, int *ilo, int *ihi, double *lscale, double *rscale, double *abnrm, double *bbnrm, double *rconde, double *rcondv, std::complex< double > *work, int *lwork, double *rwork, int *iwork, bool *bwork, int *info)
virtual void compute(const ComplexMatrixX &A, const ComplexMatrixX &B, bool computeEigenvectors=true)
computes the eigensolution for .
const ComplexMatrixX & B() const
Matrix< Complex, Dynamic, Dynamic > ComplexMatrixX
const ComplexMatrixX & A() const