Mercurial > hg > octave-lyh
comparison src/DLD-FUNCTIONS/qz.cc @ 10311:a217e1d74353
untabify qz.cc
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 11 Feb 2010 11:57:36 -0500 |
parents | 4e4270ab70d6 |
children | 12884915a8e4 |
comparison
equal
deleted
inserted
replaced
10310:cd14d826025f | 10311:a217e1d74353 |
---|---|
65 | 65 |
66 extern "C" | 66 extern "C" |
67 { | 67 { |
68 F77_RET_T | 68 F77_RET_T |
69 F77_FUNC (dggbal, DGGBAL) (F77_CONST_CHAR_ARG_DECL, | 69 F77_FUNC (dggbal, DGGBAL) (F77_CONST_CHAR_ARG_DECL, |
70 const octave_idx_type& N, double* A, const octave_idx_type& LDA, | 70 const octave_idx_type& N, double* A, |
71 double* B, const octave_idx_type& LDB, octave_idx_type& ILO, | 71 const octave_idx_type& LDA, double* B, |
72 octave_idx_type& IHI, double* LSCALE, double* RSCALE, | 72 const octave_idx_type& LDB, octave_idx_type& ILO, |
73 double* WORK, octave_idx_type& INFO | 73 octave_idx_type& IHI, double* LSCALE, |
74 double* RSCALE, double* WORK, | |
75 octave_idx_type& INFO | |
74 F77_CHAR_ARG_LEN_DECL); | 76 F77_CHAR_ARG_LEN_DECL); |
75 | 77 |
76 F77_RET_T | 78 F77_RET_T |
77 F77_FUNC (zggbal, ZGGBAL) (F77_CONST_CHAR_ARG_DECL, | 79 F77_FUNC (zggbal, ZGGBAL) (F77_CONST_CHAR_ARG_DECL, |
78 const octave_idx_type& N, Complex* A, const octave_idx_type& LDA, | 80 const octave_idx_type& N, Complex* A, |
79 Complex* B, const octave_idx_type& LDB, octave_idx_type& ILO, | 81 const octave_idx_type& LDA, Complex* B, |
80 octave_idx_type& IHI, double* LSCALE, double* RSCALE, | 82 const octave_idx_type& LDB, octave_idx_type& ILO, |
81 double* WORK, octave_idx_type& INFO | 83 octave_idx_type& IHI, double* LSCALE, |
82 F77_CHAR_ARG_LEN_DECL); | 84 double* RSCALE, double* WORK, |
85 octave_idx_type& INFO | |
86 F77_CHAR_ARG_LEN_DECL); | |
83 | 87 |
84 F77_RET_T | 88 F77_RET_T |
85 F77_FUNC (dggbak, DGGBAK) (F77_CONST_CHAR_ARG_DECL, | 89 F77_FUNC (dggbak, DGGBAK) (F77_CONST_CHAR_ARG_DECL, |
86 F77_CONST_CHAR_ARG_DECL, | 90 F77_CONST_CHAR_ARG_DECL, |
87 const octave_idx_type& N, const octave_idx_type& ILO, | 91 const octave_idx_type& N, |
88 const octave_idx_type& IHI, const double* LSCALE, | 92 const octave_idx_type& ILO, |
89 const double* RSCALE, octave_idx_type& M, double* V, | 93 const octave_idx_type& IHI, |
94 const double* LSCALE, const double* RSCALE, | |
95 octave_idx_type& M, double* V, | |
90 const octave_idx_type& LDV, octave_idx_type& INFO | 96 const octave_idx_type& LDV, octave_idx_type& INFO |
91 F77_CHAR_ARG_LEN_DECL | 97 F77_CHAR_ARG_LEN_DECL |
92 F77_CHAR_ARG_LEN_DECL); | 98 F77_CHAR_ARG_LEN_DECL); |
93 | 99 |
94 F77_RET_T | 100 F77_RET_T |
95 F77_FUNC (zggbak, ZGGBAK) (F77_CONST_CHAR_ARG_DECL, | 101 F77_FUNC (zggbak, ZGGBAK) (F77_CONST_CHAR_ARG_DECL, |
96 F77_CONST_CHAR_ARG_DECL, | 102 F77_CONST_CHAR_ARG_DECL, |
97 const octave_idx_type& N, const octave_idx_type& ILO, | 103 const octave_idx_type& N, |
98 const octave_idx_type& IHI, const double* LSCALE, | 104 const octave_idx_type& ILO, |
99 const double* RSCALE, octave_idx_type& M, Complex* V, | 105 const octave_idx_type& IHI, |
106 const double* LSCALE, const double* RSCALE, | |
107 octave_idx_type& M, Complex* V, | |
100 const octave_idx_type& LDV, octave_idx_type& INFO | 108 const octave_idx_type& LDV, octave_idx_type& INFO |
101 F77_CHAR_ARG_LEN_DECL | 109 F77_CHAR_ARG_LEN_DECL |
102 F77_CHAR_ARG_LEN_DECL); | 110 F77_CHAR_ARG_LEN_DECL); |
103 | 111 |
104 F77_RET_T | 112 F77_RET_T |
105 F77_FUNC (dgghrd, DGGHRD) (F77_CONST_CHAR_ARG_DECL, | 113 F77_FUNC (dgghrd, DGGHRD) (F77_CONST_CHAR_ARG_DECL, |
106 F77_CONST_CHAR_ARG_DECL, | 114 F77_CONST_CHAR_ARG_DECL, |
107 const octave_idx_type& N, const octave_idx_type& ILO, | 115 const octave_idx_type& N, |
116 const octave_idx_type& ILO, | |
108 const octave_idx_type& IHI, double* A, | 117 const octave_idx_type& IHI, double* A, |
109 const octave_idx_type& LDA, double* B, | 118 const octave_idx_type& LDA, double* B, |
110 const octave_idx_type& LDB, double* Q, | 119 const octave_idx_type& LDB, double* Q, |
111 const octave_idx_type& LDQ, double* Z, | 120 const octave_idx_type& LDQ, double* Z, |
112 const octave_idx_type& LDZ, octave_idx_type& INFO | 121 const octave_idx_type& LDZ, octave_idx_type& INFO |
114 F77_CHAR_ARG_LEN_DECL); | 123 F77_CHAR_ARG_LEN_DECL); |
115 | 124 |
116 F77_RET_T | 125 F77_RET_T |
117 F77_FUNC (zgghrd, ZGGHRD) (F77_CONST_CHAR_ARG_DECL, | 126 F77_FUNC (zgghrd, ZGGHRD) (F77_CONST_CHAR_ARG_DECL, |
118 F77_CONST_CHAR_ARG_DECL, | 127 F77_CONST_CHAR_ARG_DECL, |
119 const octave_idx_type& N, const octave_idx_type& ILO, | 128 const octave_idx_type& N, |
129 const octave_idx_type& ILO, | |
120 const octave_idx_type& IHI, Complex* A, | 130 const octave_idx_type& IHI, Complex* A, |
121 const octave_idx_type& LDA, Complex* B, | 131 const octave_idx_type& LDA, Complex* B, |
122 const octave_idx_type& LDB, Complex* Q, | 132 const octave_idx_type& LDB, Complex* Q, |
123 const octave_idx_type& LDQ, Complex* Z, | 133 const octave_idx_type& LDQ, Complex* Z, |
124 const octave_idx_type& LDZ, octave_idx_type& INFO | 134 const octave_idx_type& LDZ, octave_idx_type& INFO |
127 | 137 |
128 F77_RET_T | 138 F77_RET_T |
129 F77_FUNC (dhgeqz, DHGEQZ) (F77_CONST_CHAR_ARG_DECL, | 139 F77_FUNC (dhgeqz, DHGEQZ) (F77_CONST_CHAR_ARG_DECL, |
130 F77_CONST_CHAR_ARG_DECL, | 140 F77_CONST_CHAR_ARG_DECL, |
131 F77_CONST_CHAR_ARG_DECL, | 141 F77_CONST_CHAR_ARG_DECL, |
132 const octave_idx_type& N, const octave_idx_type& ILO, const octave_idx_type& IHI, | 142 const octave_idx_type& N, |
143 const octave_idx_type& ILO, | |
144 const octave_idx_type& IHI, | |
133 double* A, const octave_idx_type& LDA, double* B, | 145 double* A, const octave_idx_type& LDA, double* B, |
134 const octave_idx_type& LDB, double* ALPHAR, | 146 const octave_idx_type& LDB, double* ALPHAR, |
135 double* ALPHAI, double* BETA, double* Q, | 147 double* ALPHAI, double* BETA, double* Q, |
136 const octave_idx_type& LDQ, double* Z, | 148 const octave_idx_type& LDQ, double* Z, |
137 const octave_idx_type& LDZ, double* WORK, | 149 const octave_idx_type& LDZ, double* WORK, |
138 const octave_idx_type& LWORK, octave_idx_type& INFO | 150 const octave_idx_type& LWORK, |
151 octave_idx_type& INFO | |
139 F77_CHAR_ARG_LEN_DECL | 152 F77_CHAR_ARG_LEN_DECL |
140 F77_CHAR_ARG_LEN_DECL | 153 F77_CHAR_ARG_LEN_DECL |
141 F77_CHAR_ARG_LEN_DECL); | 154 F77_CHAR_ARG_LEN_DECL); |
142 | 155 |
143 F77_RET_T | 156 F77_RET_T |
144 F77_FUNC (zhgeqz, ZHGEQZ) (F77_CONST_CHAR_ARG_DECL, | 157 F77_FUNC (zhgeqz, ZHGEQZ) (F77_CONST_CHAR_ARG_DECL, |
145 F77_CONST_CHAR_ARG_DECL, | 158 F77_CONST_CHAR_ARG_DECL, |
146 F77_CONST_CHAR_ARG_DECL, | 159 F77_CONST_CHAR_ARG_DECL, |
147 const octave_idx_type& N, const octave_idx_type& ILO, const octave_idx_type& IHI, | 160 const octave_idx_type& N, |
148 Complex* A, const octave_idx_type& LDA, Complex* B, | 161 const octave_idx_type& ILO, |
149 const octave_idx_type& LDB, Complex* ALPHA, Complex* BETA, Complex* CQ, const octave_idx_type& LDQ, | 162 const octave_idx_type& IHI, |
150 Complex* CZ, const octave_idx_type& LDZ, | 163 Complex* A, const octave_idx_type& LDA, |
151 Complex* WORK, | 164 Complex* B, const octave_idx_type& LDB, |
152 const octave_idx_type& LWORK, double* RWORK, | 165 Complex* ALPHA, Complex* BETA, Complex* CQ, |
153 octave_idx_type& INFO | 166 const octave_idx_type& LDQ, |
167 Complex* CZ, const octave_idx_type& LDZ, | |
168 Complex* WORK, const octave_idx_type& LWORK, | |
169 double* RWORK, octave_idx_type& INFO | |
154 F77_CHAR_ARG_LEN_DECL | 170 F77_CHAR_ARG_LEN_DECL |
155 F77_CHAR_ARG_LEN_DECL | 171 F77_CHAR_ARG_LEN_DECL |
156 F77_CHAR_ARG_LEN_DECL); | 172 F77_CHAR_ARG_LEN_DECL); |
157 | 173 |
158 F77_RET_T | 174 F77_RET_T |
159 F77_FUNC (dlag2, DLAG2) (const double* A, const octave_idx_type& LDA, const double* B, | 175 F77_FUNC (dlag2, DLAG2) (const double* A, const octave_idx_type& LDA, |
160 const octave_idx_type& LDB, const double& SAFMIN, | 176 const double* B, const octave_idx_type& LDB, |
161 double& SCALE1, double& SCALE2, | 177 const double& SAFMIN, double& SCALE1, |
162 double& WR1, double& WR2, double& WI); | 178 double& SCALE2, double& WR1, double& WR2, |
179 double& WI); | |
163 | 180 |
164 // Van Dooren's code (netlib.org: toms/590) for reordering | 181 // Van Dooren's code (netlib.org: toms/590) for reordering |
165 // GEP. Only processes Z, not Q. | 182 // GEP. Only processes Z, not Q. |
166 F77_RET_T | 183 F77_RET_T |
167 F77_FUNC (dsubsp, DSUBSP) (const octave_idx_type& NMAX, const octave_idx_type& N, double* A, | 184 F77_FUNC (dsubsp, DSUBSP) (const octave_idx_type& NMAX, |
185 const octave_idx_type& N, double* A, | |
168 double* B, double* Z, sort_function, | 186 double* B, double* Z, sort_function, |
169 const double& EPS, octave_idx_type& NDIM, octave_idx_type& FAIL, | 187 const double& EPS, octave_idx_type& NDIM, |
170 octave_idx_type* IND); | 188 octave_idx_type& FAIL, octave_idx_type* IND); |
171 | 189 |
172 // documentation for DTGEVC incorrectly states that VR, VL are | 190 // Documentation for DTGEVC incorrectly states that VR, VL are |
173 // complex*16; they are declared in DTGEVC as double precision | 191 // complex*16; they are declared in DTGEVC as double precision |
174 // (probably a cut and paste problem fro ZTGEVC) | 192 // (probably a cut and paste problem fro ZTGEVC). |
175 F77_RET_T | 193 F77_RET_T |
176 F77_FUNC (dtgevc, DTGEVC) (F77_CONST_CHAR_ARG_DECL, | 194 F77_FUNC (dtgevc, DTGEVC) (F77_CONST_CHAR_ARG_DECL, |
177 F77_CONST_CHAR_ARG_DECL, | 195 F77_CONST_CHAR_ARG_DECL, |
178 octave_idx_type* SELECT, const octave_idx_type& N, double* A, | 196 octave_idx_type* SELECT, |
197 const octave_idx_type& N, double* A, | |
179 const octave_idx_type& LDA, double* B, | 198 const octave_idx_type& LDA, double* B, |
180 const octave_idx_type& LDB, double* VL, | 199 const octave_idx_type& LDB, double* VL, |
181 const octave_idx_type& LDVL, double* VR, | 200 const octave_idx_type& LDVL, double* VR, |
182 const octave_idx_type& LDVR, const octave_idx_type& MM, | 201 const octave_idx_type& LDVR, |
183 octave_idx_type& M, double* WORK, octave_idx_type& INFO | 202 const octave_idx_type& MM, octave_idx_type& M, |
203 double* WORK, octave_idx_type& INFO | |
184 F77_CHAR_ARG_LEN_DECL | 204 F77_CHAR_ARG_LEN_DECL |
185 F77_CHAR_ARG_LEN_DECL); | 205 F77_CHAR_ARG_LEN_DECL); |
186 | 206 |
187 F77_RET_T | 207 F77_RET_T |
188 F77_FUNC (ztgevc, ZTGEVC) (F77_CONST_CHAR_ARG_DECL, | 208 F77_FUNC (ztgevc, ZTGEVC) (F77_CONST_CHAR_ARG_DECL, |
189 F77_CONST_CHAR_ARG_DECL, | 209 F77_CONST_CHAR_ARG_DECL, |
190 octave_idx_type* SELECT, const octave_idx_type& N,const Complex* A, | 210 octave_idx_type* SELECT, |
211 const octave_idx_type& N, const Complex* A, | |
191 const octave_idx_type& LDA,const Complex* B, | 212 const octave_idx_type& LDA,const Complex* B, |
192 const octave_idx_type& LDB, Complex* xVL, | 213 const octave_idx_type& LDB, Complex* xVL, |
193 const octave_idx_type& LDVL, Complex* xVR, | 214 const octave_idx_type& LDVL, Complex* xVR, |
194 const octave_idx_type& LDVR, const octave_idx_type& MM, | 215 const octave_idx_type& LDVR, |
195 octave_idx_type& M, Complex* CWORK, double* RWORK, octave_idx_type& INFO | 216 const octave_idx_type& MM, octave_idx_type& M, |
217 Complex* CWORK, double* RWORK, | |
218 octave_idx_type& INFO | |
196 F77_CHAR_ARG_LEN_DECL | 219 F77_CHAR_ARG_LEN_DECL |
197 F77_CHAR_ARG_LEN_DECL); | 220 F77_CHAR_ARG_LEN_DECL); |
198 | 221 |
199 F77_RET_T | 222 F77_RET_T |
200 F77_FUNC (xdlamch, XDLAMCH) (F77_CONST_CHAR_ARG_DECL, | 223 F77_FUNC (xdlamch, XDLAMCH) (F77_CONST_CHAR_ARG_DECL, |
201 double& retval | 224 double& retval |
202 F77_CHAR_ARG_LEN_DECL); | 225 F77_CHAR_ARG_LEN_DECL); |
203 | 226 |
204 F77_RET_T | 227 F77_RET_T |
205 F77_FUNC (xdlange, XDLANGE) (F77_CONST_CHAR_ARG_DECL, | 228 F77_FUNC (xdlange, XDLANGE) (F77_CONST_CHAR_ARG_DECL, |
206 const octave_idx_type&, const octave_idx_type&, const double*, | 229 const octave_idx_type&, |
230 const octave_idx_type&, const double*, | |
207 const octave_idx_type&, double*, double& | 231 const octave_idx_type&, double*, double& |
208 F77_CHAR_ARG_LEN_DECL); | 232 F77_CHAR_ARG_LEN_DECL); |
209 } | 233 } |
210 | 234 |
211 // fcrhp, fin, fout, folhp: | 235 // fcrhp, fin, fout, folhp: |
219 static octave_idx_type | 243 static octave_idx_type |
220 fcrhp (const octave_idx_type& lsize, const double& alpha, | 244 fcrhp (const octave_idx_type& lsize, const double& alpha, |
221 const double& beta, const double& s, const double&) | 245 const double& beta, const double& s, const double&) |
222 { | 246 { |
223 if (lsize == 1) | 247 if (lsize == 1) |
224 return (alpha*beta >= 0 ? 1 : -1); | 248 return (alpha * beta >= 0 ? 1 : -1); |
225 else | 249 else |
226 return (s >= 0 ? 1 : -1); | 250 return (s >= 0 ? 1 : -1); |
227 } | 251 } |
228 | 252 |
229 static octave_idx_type | 253 static octave_idx_type |
247 static octave_idx_type | 271 static octave_idx_type |
248 folhp (const octave_idx_type& lsize, const double& alpha, | 272 folhp (const octave_idx_type& lsize, const double& alpha, |
249 const double& beta, const double& s, const double&) | 273 const double& beta, const double& s, const double&) |
250 { | 274 { |
251 if (lsize == 1) | 275 if (lsize == 1) |
252 return (alpha*beta < 0 ? 1 : -1); | 276 return (alpha * beta < 0 ? 1 : -1); |
253 else | 277 else |
254 return (s < 0 ? 1 : -1); | 278 return (s < 0 ? 1 : -1); |
255 } | 279 } |
256 | 280 |
257 static octave_idx_type | 281 static octave_idx_type |
291 @end tex\n\ | 315 @end tex\n\ |
292 @ifnottex\n\ | 316 @ifnottex\n\ |
293 @example\n\ | 317 @example\n\ |
294 @group\n\ | 318 @group\n\ |
295 \n\ | 319 \n\ |
296 A*V = B*V*diag(lambda)\n\ | 320 A * V = B * V * diag (lambda)\n\ |
297 W'*A = diag(lambda)*W'*B\n\ | 321 W' * A = diag (lambda) * W' * B\n\ |
298 AA = Q*A*Z, BB = Q*B*Z\n\ | 322 AA = Q * A * Z, BB = Q * B * Z\n\ |
299 \n\ | 323 \n\ |
300 @end group\n\ | 324 @end group\n\ |
301 @end example\n\ | 325 @end example\n\ |
302 @end ifnottex\n\ | 326 @end ifnottex\n\ |
303 with @var{Q} and @var{Z} orthogonal (unitary)= @var{I}\n\ | 327 with @var{Q} and @var{Z} orthogonal (unitary)= @var{I}\n\ |
359 | 383 |
360 #ifdef DEBUG | 384 #ifdef DEBUG |
361 std::cout << "qz: determine ordering option" << std::endl; | 385 std::cout << "qz: determine ordering option" << std::endl; |
362 #endif | 386 #endif |
363 | 387 |
364 // Determine ordering option | 388 // Determine ordering option. |
365 volatile char ord_job = 0; | 389 volatile char ord_job = 0; |
366 static double safmin; | 390 static double safmin; |
367 | 391 |
368 if (nargin == 2) | 392 if (nargin == 2) |
369 ord_job = 'N'; | 393 ord_job = 'N'; |
396 #ifdef DEBUG_EIG | 420 #ifdef DEBUG_EIG |
397 std::cout << "qz: initial value of safmin=" << setiosflags (std::ios::scientific) | 421 std::cout << "qz: initial value of safmin=" << setiosflags (std::ios::scientific) |
398 << safmin << std::endl; | 422 << safmin << std::endl; |
399 #endif | 423 #endif |
400 | 424 |
401 // some machines (e.g., DEC alpha) get safmin = 0; | 425 // Some machines (e.g., DEC alpha) get safmin = 0; |
402 // for these, use eps instead to avoid problems in dlag2 | 426 // for these, use eps instead to avoid problems in dlag2. |
403 if (safmin == 0) | 427 if (safmin == 0) |
404 { | 428 { |
405 #ifdef DEBUG_EIG | 429 #ifdef DEBUG_EIG |
406 std::cout << "qz: DANGER WILL ROBINSON: safmin is 0!" << std::endl; | 430 std::cout << "qz: DANGER WILL ROBINSON: safmin is 0!" << std::endl; |
407 #endif | 431 #endif |
419 | 443 |
420 #ifdef DEBUG | 444 #ifdef DEBUG |
421 std::cout << "qz: check argument 1" << std::endl; | 445 std::cout << "qz: check argument 1" << std::endl; |
422 #endif | 446 #endif |
423 | 447 |
424 // Argument 1: check if it's o.k. dimensioned | 448 // Argument 1: check if it's o.k. dimensioned. |
425 octave_idx_type nn = args(0).rows (); | 449 octave_idx_type nn = args(0).rows (); |
426 | 450 |
427 #ifdef DEBUG | 451 #ifdef DEBUG |
428 std::cout << "argument 1 dimensions: (" << nn << "," << args(0).columns () << ")" | 452 std::cout << "argument 1 dimensions: (" << nn << "," << args(0).columns () << ")" |
429 << std::endl; | 453 << std::endl; |
445 { | 469 { |
446 gripe_square_matrix_required ("qz"); | 470 gripe_square_matrix_required ("qz"); |
447 return retval; | 471 return retval; |
448 } | 472 } |
449 | 473 |
450 // Argument 1: dimensions look good; get the value | 474 // Argument 1: dimensions look good; get the value. |
451 Matrix aa; | 475 Matrix aa; |
452 ComplexMatrix caa; | 476 ComplexMatrix caa; |
453 | 477 |
454 if (args(0).is_complex_type ()) | 478 if (args(0).is_complex_type ()) |
455 caa = args(0).complex_matrix_value (); | 479 caa = args(0).complex_matrix_value (); |
461 | 485 |
462 #ifdef DEBUG | 486 #ifdef DEBUG |
463 std::cout << "qz: check argument 2" << std::endl; | 487 std::cout << "qz: check argument 2" << std::endl; |
464 #endif | 488 #endif |
465 | 489 |
466 // Extract argument 2 (bb, or cbb if complex) | 490 // Extract argument 2 (bb, or cbb if complex). |
467 if ((nn != args(1).columns ()) || (nn != args(1).rows ())) | 491 if ((nn != args(1).columns ()) || (nn != args(1).rows ())) |
468 { | 492 { |
469 gripe_nonconformant (); | 493 gripe_nonconformant (); |
470 return retval; | 494 return retval; |
471 } | 495 } |
480 | 504 |
481 if (error_state) | 505 if (error_state) |
482 return retval; | 506 return retval; |
483 | 507 |
484 // Both matrices loaded, now let's check what kind of arithmetic: | 508 // Both matrices loaded, now let's check what kind of arithmetic: |
485 //declared static to avoid compiler warnings about long jumps, vforks. | 509 // declared volatile to avoid compiler warnings about long jumps, |
486 | 510 // vforks. |
487 int complex_case | 511 |
512 volatile int complex_case | |
488 = (args(0).is_complex_type () || args(1).is_complex_type ()); | 513 = (args(0).is_complex_type () || args(1).is_complex_type ()); |
489 // static complex_case causing random segfault, so it is removed | 514 |
490 if (nargin == 3 && complex_case) | 515 if (nargin == 3 && complex_case) |
491 { | 516 { |
492 error ("qz: cannot re-order complex qz decomposition."); | 517 error ("qz: cannot re-order complex qz decomposition."); |
493 return retval; | 518 return retval; |
494 } | 519 } |
495 | 520 |
496 // first, declare variables used in both the real and complex case | 521 // First, declare variables used in both the real and complex case. |
497 Matrix QQ(nn,nn), ZZ(nn,nn), VR(nn,nn), VL(nn,nn); | 522 Matrix QQ(nn,nn), ZZ(nn,nn), VR(nn,nn), VL(nn,nn); |
498 RowVector alphar(nn), alphai(nn), betar(nn); | 523 RowVector alphar(nn), alphai(nn), betar(nn); |
499 ComplexRowVector xalpha(nn), xbeta(nn); | 524 ComplexRowVector xalpha(nn), xbeta(nn); |
500 ComplexMatrix CQ(nn,nn), CZ(nn,nn), CVR(nn,nn), CVL(nn,nn); | 525 ComplexMatrix CQ(nn,nn), CZ(nn,nn), CVR(nn,nn), CVL(nn,nn); |
501 octave_idx_type ilo, ihi, info; | 526 octave_idx_type ilo, ihi, info; |
502 char compq = (nargout >= 3 ? 'V' : 'N'); | 527 char compq = (nargout >= 3 ? 'V' : 'N'); |
503 char compz = (nargout >= 4 ? 'V' : 'N'); | 528 char compz = (nargout >= 4 ? 'V' : 'N'); |
504 | 529 |
505 // initialize Q, Z to identity if we need either of them | 530 // Initialize Q, Z to identity if we need either of them. |
506 if (compq == 'V' || compz == 'V') | 531 if (compq == 'V' || compz == 'V') |
507 for (octave_idx_type ii = 0; ii < nn; ii++) | 532 for (octave_idx_type ii = 0; ii < nn; ii++) |
508 for (octave_idx_type jj = 0; jj < nn; jj++) | 533 for (octave_idx_type jj = 0; jj < nn; jj++) |
509 { | 534 { |
510 OCTAVE_QUIT; | 535 OCTAVE_QUIT; |
511 QQ(ii,jj) = ZZ(ii,jj) = (ii == jj ? 1.0 : 0.0); | 536 QQ(ii,jj) = ZZ(ii,jj) = (ii == jj ? 1.0 : 0.0); |
512 } | 537 } |
513 | 538 |
514 // always perform permutation balancing | 539 // Always perform permutation balancing. |
515 const char bal_job = 'P'; | 540 const char bal_job = 'P'; |
516 RowVector lscale(nn), rscale(nn), work(6*nn), rwork(nn); | 541 RowVector lscale (nn), rscale (nn), work (6 * nn), rwork (nn); |
517 | 542 |
518 if (complex_case) | 543 if (complex_case) |
519 { | 544 { |
520 #ifdef DEBUG | 545 #ifdef DEBUG |
521 if (compq == 'V') | 546 if (compq == 'V') |
522 std::cout << "qz: performing balancing; CQ=" << std::endl << CQ << std::endl; | 547 std::cout << "qz: performing balancing; CQ=" << std::endl << CQ << std::endl; |
523 #endif | 548 #endif |
524 if (args(0).is_real_type ()) | 549 if (args(0).is_real_type ()) |
525 caa = ComplexMatrix (aa); | 550 caa = ComplexMatrix (aa); |
526 | 551 |
527 if (args(1).is_real_type ()) | 552 if (args(1).is_real_type ()) |
528 cbb = ComplexMatrix (bb); | 553 cbb = ComplexMatrix (bb); |
529 | 554 |
530 if (compq == 'V') | 555 if (compq == 'V') |
531 CQ = ComplexMatrix (QQ); | 556 CQ = ComplexMatrix (QQ); |
532 | 557 |
533 if (compz == 'V') | 558 if (compz == 'V') |
534 CZ = ComplexMatrix (ZZ); | 559 CZ = ComplexMatrix (ZZ); |
535 | 560 |
536 F77_XFCN (zggbal, ZGGBAL, | 561 F77_XFCN (zggbal, ZGGBAL, |
537 (F77_CONST_CHAR_ARG2 (&bal_job, 1), | 562 (F77_CONST_CHAR_ARG2 (&bal_job, 1), |
538 nn, caa.fortran_vec (), nn, cbb.fortran_vec (), | 563 nn, caa.fortran_vec (), nn, cbb.fortran_vec (), |
539 nn, ilo, ihi, lscale.fortran_vec (), | 564 nn, ilo, ihi, lscale.fortran_vec (), |
540 rscale.fortran_vec (), work.fortran_vec (), info | 565 rscale.fortran_vec (), work.fortran_vec (), info |
541 F77_CHAR_ARG_LEN (1))); | 566 F77_CHAR_ARG_LEN (1))); |
542 } | 567 } |
543 else | 568 else |
544 { | 569 { |
545 #ifdef DEBUG | 570 #ifdef DEBUG |
546 if (compq == 'V') | 571 if (compq == 'V') |
554 rscale.fortran_vec (), work.fortran_vec (), info | 579 rscale.fortran_vec (), work.fortran_vec (), info |
555 F77_CHAR_ARG_LEN (1))); | 580 F77_CHAR_ARG_LEN (1))); |
556 } | 581 } |
557 | 582 |
558 // Since we just want the balancing matrices, we can use dggbal | 583 // Since we just want the balancing matrices, we can use dggbal |
559 // for both the real and complex cases; | 584 // for both the real and complex cases; left first |
560 // left first | 585 |
561 | 586 #if 0 |
562 /* if (compq == 'V') | 587 if (compq == 'V') |
563 { | 588 { |
564 F77_XFCN (dggbak, DGGBAK, | 589 F77_XFCN (dggbak, DGGBAK, |
565 (F77_CONST_CHAR_ARG2 (&bal_job, 1), | 590 (F77_CONST_CHAR_ARG2 (&bal_job, 1), |
566 F77_CONST_CHAR_ARG2 ("L", 1), | 591 F77_CONST_CHAR_ARG2 ("L", 1), |
567 nn, ilo, ihi, lscale.data (), rscale.data (), | 592 nn, ilo, ihi, lscale.data (), rscale.data (), |
588 | 613 |
589 #ifdef DEBUG | 614 #ifdef DEBUG |
590 if (compz == 'V') | 615 if (compz == 'V') |
591 std::cout << "qz: balancing done; ZZ=" << std::endl << ZZ << std::endl; | 616 std::cout << "qz: balancing done; ZZ=" << std::endl << ZZ << std::endl; |
592 #endif | 617 #endif |
593 } */ | 618 } |
619 #endif | |
594 | 620 |
595 static char qz_job; | 621 static char qz_job; |
596 qz_job = (nargout < 2 ? 'E' : 'S'); | 622 qz_job = (nargout < 2 ? 'E' : 'S'); |
597 | 623 |
598 if (complex_case) | 624 if (complex_case) |
599 { | 625 { |
600 // complex case | 626 // Complex case. |
601 ComplexQR cbqr (cbb); // declare cbqr as the QR decomposition of cbb | 627 |
602 cbb = cbqr.R (); // the R matrix of QR decomposition for cbb | 628 // The QR decomposition of cbb. |
603 caa = (cbqr.Q ().hermitian ())*caa; // (Q*)caa for following work | 629 ComplexQR cbqr (cbb); |
604 //if (compq == 'V') | 630 // The R matrix of QR decomposition for cbb. |
605 CQ = CQ*cbqr.Q (); | 631 cbb = cbqr.R (); |
632 // (Q*)caa for following work. | |
633 caa = (cbqr.Q ().hermitian ()) * caa; | |
634 CQ = CQ * cbqr.Q (); | |
635 | |
606 F77_XFCN (zgghrd, ZGGHRD, | 636 F77_XFCN (zgghrd, ZGGHRD, |
607 (F77_CONST_CHAR_ARG2 (&compq, 1), | 637 (F77_CONST_CHAR_ARG2 (&compq, 1), |
608 F77_CONST_CHAR_ARG2 (&compz, 1), | 638 F77_CONST_CHAR_ARG2 (&compz, 1), |
609 nn, ilo, ihi, caa.fortran_vec (), | 639 nn, ilo, ihi, caa.fortran_vec (), |
610 nn, cbb.fortran_vec (), nn, CQ.fortran_vec (), nn, | 640 nn, cbb.fortran_vec (), nn, CQ.fortran_vec (), nn, |
611 CZ.fortran_vec (), nn, info | 641 CZ.fortran_vec (), nn, info |
612 F77_CHAR_ARG_LEN (1) | 642 F77_CHAR_ARG_LEN (1) |
613 F77_CHAR_ARG_LEN (1))); | 643 F77_CHAR_ARG_LEN (1))); |
614 ComplexRowVector cwork(1*nn); | 644 |
645 ComplexRowVector cwork (1 * nn); | |
646 | |
615 F77_XFCN (zhgeqz, ZHGEQZ, | 647 F77_XFCN (zhgeqz, ZHGEQZ, |
616 (F77_CONST_CHAR_ARG2 (&qz_job, 1), | 648 (F77_CONST_CHAR_ARG2 (&qz_job, 1), |
617 F77_CONST_CHAR_ARG2 (&compq, 1), | 649 F77_CONST_CHAR_ARG2 (&compq, 1), |
618 F77_CONST_CHAR_ARG2 (&compz, 1), | 650 F77_CONST_CHAR_ARG2 (&compz, 1), |
619 nn, ilo, ihi, | 651 nn, ilo, ihi, |
627 F77_CHAR_ARG_LEN (1) | 659 F77_CHAR_ARG_LEN (1) |
628 F77_CHAR_ARG_LEN (1))); | 660 F77_CHAR_ARG_LEN (1))); |
629 | 661 |
630 if (compq == 'V') | 662 if (compq == 'V') |
631 { | 663 { |
632 // Left eigenvector | 664 // Left eigenvector. |
633 F77_XFCN (zggbak, ZGGBAK, | 665 F77_XFCN (zggbak, ZGGBAK, |
634 (F77_CONST_CHAR_ARG2 (&bal_job, 1), | 666 (F77_CONST_CHAR_ARG2 (&bal_job, 1), |
635 F77_CONST_CHAR_ARG2 ("L", 1), | 667 F77_CONST_CHAR_ARG2 ("L", 1), |
636 nn, ilo, ihi, lscale.data (), rscale.data (), | 668 nn, ilo, ihi, lscale.data (), rscale.data (), |
637 nn, CQ.fortran_vec (), nn, info | 669 nn, CQ.fortran_vec (), nn, info |
638 F77_CHAR_ARG_LEN (1) | 670 F77_CHAR_ARG_LEN (1) |
639 F77_CHAR_ARG_LEN (1))); | 671 F77_CHAR_ARG_LEN (1))); |
640 } | 672 } |
641 | 673 |
642 // then right | 674 // Right eigenvector. |
643 if (compz == 'V') | 675 if (compz == 'V') |
644 { | 676 { |
645 F77_XFCN (zggbak, ZGGBAK, | 677 F77_XFCN (zggbak, ZGGBAK, |
646 (F77_CONST_CHAR_ARG2 (&bal_job, 1), | 678 (F77_CONST_CHAR_ARG2 (&bal_job, 1), |
647 F77_CONST_CHAR_ARG2 ("R", 1), | 679 F77_CONST_CHAR_ARG2 ("R", 1), |
650 F77_CHAR_ARG_LEN (1) | 682 F77_CHAR_ARG_LEN (1) |
651 F77_CHAR_ARG_LEN (1))); | 683 F77_CHAR_ARG_LEN (1))); |
652 } | 684 } |
653 | 685 |
654 } | 686 } |
655 else // real matrices case | 687 else |
656 { | 688 { |
657 #ifdef DEBUG | 689 #ifdef DEBUG |
658 std::cout << "qz: peforming qr decomposition of bb" << std::endl; | 690 std::cout << "qz: peforming qr decomposition of bb" << std::endl; |
659 #endif | 691 #endif |
660 | 692 |
661 // compute the QR factorization of bb | 693 // Compute the QR factorization of bb. |
662 QR bqr (bb); | 694 QR bqr (bb); |
663 | 695 |
664 #ifdef DEBUG | 696 #ifdef DEBUG |
665 std::cout << "qz: qr (bb) done; now peforming qz decomposition" << std::endl; | 697 std::cout << "qz: qr (bb) done; now peforming qz decomposition" << std::endl; |
666 #endif | 698 #endif |
669 | 701 |
670 #ifdef DEBUG | 702 #ifdef DEBUG |
671 std::cout << "qz: extracted bb" << std::endl; | 703 std::cout << "qz: extracted bb" << std::endl; |
672 #endif | 704 #endif |
673 | 705 |
674 aa = (bqr.Q ()).transpose ()*aa; | 706 aa = (bqr.Q ()).transpose () * aa; |
675 | 707 |
676 #ifdef DEBUG | 708 #ifdef DEBUG |
677 std::cout << "qz: updated aa " << std::endl; | 709 std::cout << "qz: updated aa " << std::endl; |
678 std::cout << "bqr.Q () = " << std::endl << bqr.Q () << std::endl; | 710 std::cout << "bqr.Q () = " << std::endl << bqr.Q () << std::endl; |
679 | 711 |
680 if (compq == 'V') | 712 if (compq == 'V') |
681 std::cout << "QQ =" << QQ << std::endl; | 713 std::cout << "QQ =" << QQ << std::endl; |
682 #endif | 714 #endif |
683 | 715 |
684 if (compq == 'V') | 716 if (compq == 'V') |
685 QQ = QQ*bqr.Q (); | 717 QQ = QQ * bqr.Q (); |
686 | 718 |
687 #ifdef DEBUG | 719 #ifdef DEBUG |
688 std::cout << "qz: precursors done..." << std::endl; | 720 std::cout << "qz: precursors done..." << std::endl; |
689 #endif | 721 #endif |
690 | 722 |
691 #ifdef DEBUG | 723 #ifdef DEBUG |
692 std::cout << "qz: compq = " << compq << ", compz = " << compz << std::endl; | 724 std::cout << "qz: compq = " << compq << ", compz = " << compz << std::endl; |
693 #endif | 725 #endif |
694 | 726 |
695 // reduce to generalized hessenberg form | 727 // Reduce to generalized hessenberg form. |
696 F77_XFCN (dgghrd, DGGHRD, | 728 F77_XFCN (dgghrd, DGGHRD, |
697 (F77_CONST_CHAR_ARG2 (&compq, 1), | 729 (F77_CONST_CHAR_ARG2 (&compq, 1), |
698 F77_CONST_CHAR_ARG2 (&compz, 1), | 730 F77_CONST_CHAR_ARG2 (&compz, 1), |
699 nn, ilo, ihi, aa.fortran_vec (), | 731 nn, ilo, ihi, aa.fortran_vec (), |
700 nn, bb.fortran_vec (), nn, QQ.fortran_vec (), nn, | 732 nn, bb.fortran_vec (), nn, QQ.fortran_vec (), nn, |
701 ZZ.fortran_vec (), nn, info | 733 ZZ.fortran_vec (), nn, info |
702 F77_CHAR_ARG_LEN (1) | 734 F77_CHAR_ARG_LEN (1) |
703 F77_CHAR_ARG_LEN (1))); | 735 F77_CHAR_ARG_LEN (1))); |
704 | 736 |
705 // check if just computing generalized eigenvalues or if we're | 737 // Check if just computing generalized eigenvalues or if we're |
706 // actually computing the decomposition | 738 // actually computing the decomposition. |
707 | 739 |
708 // reduce to generalized Schur form | 740 // Reduce to generalized Schur form. |
709 F77_XFCN (dhgeqz, DHGEQZ, | 741 F77_XFCN (dhgeqz, DHGEQZ, |
710 (F77_CONST_CHAR_ARG2 (&qz_job, 1), | 742 (F77_CONST_CHAR_ARG2 (&qz_job, 1), |
711 F77_CONST_CHAR_ARG2 (&compq, 1), | 743 F77_CONST_CHAR_ARG2 (&compq, 1), |
712 F77_CONST_CHAR_ARG2 (&compz, 1), | 744 F77_CONST_CHAR_ARG2 (&compz, 1), |
713 nn, ilo, ihi, aa.fortran_vec (), nn, bb.fortran_vec (), | 745 nn, ilo, ihi, aa.fortran_vec (), nn, bb.fortran_vec (), |
715 betar.fortran_vec (), QQ.fortran_vec (), nn, | 747 betar.fortran_vec (), QQ.fortran_vec (), nn, |
716 ZZ.fortran_vec (), nn, work.fortran_vec (), nn, info | 748 ZZ.fortran_vec (), nn, work.fortran_vec (), nn, info |
717 F77_CHAR_ARG_LEN (1) | 749 F77_CHAR_ARG_LEN (1) |
718 F77_CHAR_ARG_LEN (1) | 750 F77_CHAR_ARG_LEN (1) |
719 F77_CHAR_ARG_LEN (1))); | 751 F77_CHAR_ARG_LEN (1))); |
752 | |
720 if (compq == 'V') | 753 if (compq == 'V') |
721 { | 754 { |
722 F77_XFCN (dggbak, DGGBAK, | 755 F77_XFCN (dggbak, DGGBAK, |
723 (F77_CONST_CHAR_ARG2 (&bal_job, 1), | 756 (F77_CONST_CHAR_ARG2 (&bal_job, 1), |
724 F77_CONST_CHAR_ARG2 ("L", 1), | 757 F77_CONST_CHAR_ARG2 ("L", 1), |
725 nn, ilo, ihi, lscale.data (), rscale.data (), | 758 nn, ilo, ihi, lscale.data (), rscale.data (), |
726 nn, QQ.fortran_vec (), nn, info | 759 nn, QQ.fortran_vec (), nn, info |
727 F77_CHAR_ARG_LEN (1) | 760 F77_CHAR_ARG_LEN (1) |
728 F77_CHAR_ARG_LEN (1))); | 761 F77_CHAR_ARG_LEN (1))); |
729 | 762 |
730 #ifdef DEBUG | 763 #ifdef DEBUG |
731 if (compq == 'V') | 764 if (compq == 'V') |
732 std::cout << "qz: balancing done; QQ=" << std::endl << QQ << std::endl; | 765 std::cout << "qz: balancing done; QQ=" << std::endl << QQ << std::endl; |
733 #endif | 766 #endif |
734 } | 767 } |
735 | 768 |
736 // then right | 769 // then right |
737 if (compz == 'V') | 770 if (compz == 'V') |
738 { | 771 { |
739 F77_XFCN (dggbak, DGGBAK, | 772 F77_XFCN (dggbak, DGGBAK, |
740 (F77_CONST_CHAR_ARG2 (&bal_job, 1), | 773 (F77_CONST_CHAR_ARG2 (&bal_job, 1), |
741 F77_CONST_CHAR_ARG2 ("R", 1), | 774 F77_CONST_CHAR_ARG2 ("R", 1), |
742 nn, ilo, ihi, lscale.data (), rscale.data (), | 775 nn, ilo, ihi, lscale.data (), rscale.data (), |
743 nn, ZZ.fortran_vec (), nn, info | 776 nn, ZZ.fortran_vec (), nn, info |
744 F77_CHAR_ARG_LEN (1) | 777 F77_CHAR_ARG_LEN (1) |
745 F77_CHAR_ARG_LEN (1))); | 778 F77_CHAR_ARG_LEN (1))); |
746 | 779 |
747 #ifdef DEBUG | 780 #ifdef DEBUG |
748 if (compz == 'V') | 781 if (compz == 'V') |
749 std::cout << "qz: balancing done; ZZ=" << std::endl << ZZ << std::endl; | 782 std::cout << "qz: balancing done; ZZ=" << std::endl << ZZ << std::endl; |
750 #endif | 783 #endif |
751 } | 784 } |
752 | 785 |
753 } | 786 } |
754 | 787 |
755 // order the QZ decomposition? | 788 // Order the QZ decomposition? |
756 if (! (ord_job == 'N' || ord_job == 'n')) | 789 if (! (ord_job == 'N' || ord_job == 'n')) |
757 { | 790 { |
758 if (complex_case) | 791 if (complex_case) |
759 { | 792 { |
760 // probably not needed, but better be safe | 793 // Probably not needed, but better be safe. |
761 error ("qz: cannot re-order complex qz decomposition."); | 794 error ("qz: cannot re-order complex qz decomposition."); |
762 return retval; | 795 return retval; |
763 } | 796 } |
764 else | 797 else |
765 { | 798 { |
766 #ifdef DEBUG_SORT | 799 #ifdef DEBUG_SORT |
767 std::cout << "qz: ordering eigenvalues: ord_job = " | 800 std::cout << "qz: ordering eigenvalues: ord_job = " |
768 << ord_job << std::endl; | 801 << ord_job << std::endl; |
769 #endif | 802 #endif |
770 | 803 |
771 // declared static to avoid vfork/long jump compiler complaints | 804 // Declared static to avoid vfork/long jump compiler complaints. |
772 static sort_function sort_test; | 805 static sort_function sort_test; |
773 sort_test = 0; | 806 sort_test = 0; |
774 | 807 |
775 switch (ord_job) | 808 switch (ord_job) |
776 { | 809 { |
791 case '-': | 824 case '-': |
792 sort_test = &folhp; | 825 sort_test = &folhp; |
793 break; | 826 break; |
794 | 827 |
795 default: | 828 default: |
796 // invalid order option (should never happen, since we | 829 // Invalid order option (should never happen, since we |
797 // checked the options at the top). | 830 // checked the options at the top). |
798 panic_impossible (); | 831 panic_impossible (); |
799 break; | 832 break; |
800 } | 833 } |
801 | 834 |
805 F77_XFCN (xdlange, XDLANGE, | 838 F77_XFCN (xdlange, XDLANGE, |
806 (F77_CONST_CHAR_ARG2 ("I", 1), | 839 (F77_CONST_CHAR_ARG2 ("I", 1), |
807 nn, nn, aa.data (), nn, work.fortran_vec (), inf_norm | 840 nn, nn, aa.data (), nn, work.fortran_vec (), inf_norm |
808 F77_CHAR_ARG_LEN (1))); | 841 F77_CHAR_ARG_LEN (1))); |
809 | 842 |
810 double eps = DBL_EPSILON*inf_norm*nn; | 843 double eps = DBL_EPSILON * inf_norm * nn; |
811 | 844 |
812 #ifdef DEBUG_SORT | 845 #ifdef DEBUG_SORT |
813 std::cout << "qz: calling dsubsp: aa=" << std::endl; | 846 std::cout << "qz: calling dsubsp: aa=" << std::endl; |
814 octave_print_internal (std::cout, aa, 0); | 847 octave_print_internal (std::cout, aa, 0); |
815 std::cout << std::endl << "bb=" << std::endl; | 848 std::cout << std::endl << "bb=" << std::endl; |
847 octave_print_internal (std::cout, ZZ, 0); | 880 octave_print_internal (std::cout, ZZ, 0); |
848 } | 881 } |
849 std::cout << std::endl; | 882 std::cout << std::endl; |
850 #endif | 883 #endif |
851 | 884 |
852 // manually update alphar, alphai, betar | 885 // Manually update alphar, alphai, betar. |
853 static int jj; | 886 static int jj; |
854 | 887 |
855 jj=0; | 888 jj = 0; |
856 while (jj < nn) | 889 while (jj < nn) |
857 { | 890 { |
858 #ifdef DEBUG_EIG | 891 #ifdef DEBUG_EIG |
859 std::cout << "computing gen eig #" << jj << std::endl; | 892 std::cout << "computing gen eig #" << jj << std::endl; |
860 #endif | 893 #endif |
861 | 894 |
862 static int zcnt; // number of zeros in this block | 895 // Number of zeros in this block. |
896 static int zcnt; | |
863 | 897 |
864 if (jj == (nn-1)) | 898 if (jj == (nn-1)) |
865 zcnt = 1; | 899 zcnt = 1; |
866 else if (aa(jj+1,jj) == 0) | 900 else if (aa(jj+1,jj) == 0) |
867 zcnt = 1; | 901 zcnt = 1; |
868 else zcnt = 2; | 902 else zcnt = 2; |
869 | 903 |
870 if (zcnt == 1) // real zero | 904 if (zcnt == 1) |
871 { | 905 { |
906 // Real zero. | |
872 #ifdef DEBUG_EIG | 907 #ifdef DEBUG_EIG |
873 std::cout << " single gen eig:" << std::endl; | 908 std::cout << " single gen eig:" << std::endl; |
874 std::cout << " alphar(" << jj << ") = " << aa(jj,jj) << std::endl; | 909 std::cout << " alphar(" << jj << ") = " << aa(jj,jj) << std::endl; |
875 std::cout << " betar( " << jj << ") = " << bb(jj,jj) << std::endl; | 910 std::cout << " betar( " << jj << ") = " << bb(jj,jj) << std::endl; |
876 std::cout << " alphai(" << jj << ") = 0" << std::endl; | 911 std::cout << " alphai(" << jj << ") = 0" << std::endl; |
880 alphai(jj) = 0; | 915 alphai(jj) = 0; |
881 betar(jj) = bb(jj,jj); | 916 betar(jj) = bb(jj,jj); |
882 } | 917 } |
883 else | 918 else |
884 { | 919 { |
885 // complex conjugate pair | 920 // Complex conjugate pair. |
886 #ifdef DEBUG_EIG | 921 #ifdef DEBUG_EIG |
887 std::cout << "qz: calling dlag2:" << std::endl; | 922 std::cout << "qz: calling dlag2:" << std::endl; |
888 std::cout << "safmin=" | 923 std::cout << "safmin=" |
889 << setiosflags (std::ios::scientific) << safmin << std::endl; | 924 << setiosflags (std::ios::scientific) << safmin << std::endl; |
890 | 925 |
902 | 937 |
903 // FIXME -- probably should be using | 938 // FIXME -- probably should be using |
904 // fortran_vec instead of &aa(jj,jj) here. | 939 // fortran_vec instead of &aa(jj,jj) here. |
905 | 940 |
906 double scale1, scale2, wr1, wr2, wi; | 941 double scale1, scale2, wr1, wr2, wi; |
907 const double *aa_ptr = aa.data () + jj*nn+jj; | 942 const double *aa_ptr = aa.data () + jj * nn + jj; |
908 const double *bb_ptr = bb.data () + jj*nn+jj; | 943 const double *bb_ptr = bb.data () + jj * nn + jj; |
909 F77_XFCN (dlag2, DLAG2, | 944 F77_XFCN (dlag2, DLAG2, |
910 (aa_ptr, nn, bb_ptr, nn, safmin, | 945 (aa_ptr, nn, bb_ptr, nn, safmin, |
911 scale1, scale2, wr1, wr2, wi)); | 946 scale1, scale2, wr1, wr2, wi)); |
912 | 947 |
913 #ifdef DEBUG_EIG | 948 #ifdef DEBUG_EIG |
915 << "\tscale2=" << scale2 << std::endl | 950 << "\tscale2=" << scale2 << std::endl |
916 << "\twr1=" << wr1 << "\twr2=" << wr2 | 951 << "\twr1=" << wr1 << "\twr2=" << wr2 |
917 << "\twi=" << wi << std::endl; | 952 << "\twi=" << wi << std::endl; |
918 #endif | 953 #endif |
919 | 954 |
920 // just to be safe, check if it's a real pair | 955 // Just to be safe, check if it's a real pair. |
921 if (wi == 0) | 956 if (wi == 0) |
922 { | 957 { |
923 alphar(jj) = wr1; | 958 alphar(jj) = wr1; |
924 alphai(jj) = 0; | 959 alphai(jj) = 0; |
925 betar(jj) = scale1; | 960 betar(jj) = scale1; |
927 alphai(jj+1) = 0; | 962 alphai(jj+1) = 0; |
928 betar(jj+1) = scale2; | 963 betar(jj+1) = scale2; |
929 } | 964 } |
930 else | 965 else |
931 { | 966 { |
932 alphar(jj) = alphar(jj+1)=wr1; | 967 alphar(jj) = alphar(jj+1) = wr1; |
933 alphai(jj) = -(alphai(jj+1) = wi); | 968 alphai(jj) = -(alphai(jj+1) = wi); |
934 betar(jj) = betar(jj+1) = scale1; | 969 betar(jj) = betar(jj+1) = scale1; |
935 } | 970 } |
936 } | 971 } |
937 | 972 |
938 // advance past this block | 973 // Advance past this block. |
939 jj += zcnt; | 974 jj += zcnt; |
940 } | 975 } |
941 | 976 |
942 #ifdef DEBUG_SORT | 977 #ifdef DEBUG_SORT |
943 std::cout << "qz: back from dsubsp: aa=" << std::endl; | 978 std::cout << "qz: back from dsubsp: aa=" << std::endl; |
961 std::cout << std::endl; | 996 std::cout << std::endl; |
962 #endif | 997 #endif |
963 } | 998 } |
964 } | 999 } |
965 | 1000 |
966 // compute generalized eigenvalues? | 1001 // Compute generalized eigenvalues? |
967 ComplexColumnVector gev; | 1002 ComplexColumnVector gev; |
968 | 1003 |
969 if (nargout < 2 || nargout == 7 || (nargin == 3 && nargout == 4)) | 1004 if (nargout < 2 || nargout == 7 || (nargin == 3 && nargout == 4)) |
970 { | 1005 { |
971 if (complex_case) | 1006 if (complex_case) |
972 { | 1007 { |
973 int cnt = 0; | 1008 int cnt = 0; |
974 | 1009 |
975 for (int ii = 0; ii < nn; ii++) | 1010 for (int ii = 0; ii < nn; ii++) |
976 // if (cbetar(ii) != 0) | 1011 cnt++; |
977 cnt++; | 1012 |
978 | 1013 ComplexColumnVector tmp (cnt); |
979 ComplexColumnVector tmp(cnt); | 1014 |
980 | 1015 cnt = 0; |
981 cnt = 0; | 1016 for (int ii = 0; ii < nn; ii++) |
982 for (int ii = 0; ii < nn; ii++) | 1017 tmp(cnt++) = xalpha(ii) / xbeta(ii); |
983 // if (cbetar(ii) != 0) | 1018 |
984 tmp(cnt++) = xalpha(ii)/xbeta(ii); | 1019 gev = tmp; |
985 gev = tmp; | |
986 } | 1020 } |
987 else | 1021 else |
988 { | 1022 { |
989 #ifdef DEBUG | 1023 #ifdef DEBUG |
990 std::cout << "qz: computing generalized eigenvalues" << std::endl; | 1024 std::cout << "qz: computing generalized eigenvalues" << std::endl; |
991 #endif | 1025 #endif |
992 | 1026 |
993 // return finite generalized eigenvalues | 1027 // Return finite generalized eigenvalues. |
994 int cnt = 0; | 1028 int cnt = 0; |
995 | 1029 |
996 for (int ii = 0; ii < nn; ii++) | 1030 for (int ii = 0; ii < nn; ii++) |
997 if (betar(ii) != 0) | 1031 if (betar(ii) != 0) |
998 cnt++; | 1032 cnt++; |
999 | 1033 |
1000 ComplexColumnVector tmp(cnt); | 1034 ComplexColumnVector tmp (cnt); |
1001 | 1035 |
1002 cnt = 0; | 1036 cnt = 0; |
1003 for (int ii = 0; ii < nn; ii++) | 1037 for (int ii = 0; ii < nn; ii++) |
1004 if (betar(ii) != 0) | 1038 if (betar(ii) != 0) |
1005 tmp(cnt++) = Complex(alphar(ii), alphai(ii))/betar(ii); | 1039 tmp(cnt++) = Complex(alphar(ii), alphai(ii))/betar(ii); |
1040 | |
1006 gev = tmp; | 1041 gev = tmp; |
1007 } | 1042 } |
1008 } | 1043 } |
1009 | 1044 |
1010 // right, left eigenvector matrices | 1045 // Right, left eigenvector matrices. |
1011 if (nargout >= 5) | 1046 if (nargout >= 5) |
1012 { | 1047 { |
1013 char side = (nargout == 5 ? 'R' : 'B'); // which side to compute? | 1048 // Which side to compute? |
1014 char howmny = 'B'; // compute all of them and backtransform | 1049 char side = (nargout == 5 ? 'R' : 'B'); |
1015 octave_idx_type *select = 0; // dummy pointer; select is not used. | 1050 // Compute all of them and backtransform |
1051 char howmny = 'B'; | |
1052 // Dummy pointer; select is not used. | |
1053 octave_idx_type *select = 0; | |
1016 | 1054 |
1017 if (complex_case) | 1055 if (complex_case) |
1018 { | 1056 { |
1057 CVL = CQ; | |
1058 CVR = CZ; | |
1059 ComplexRowVector cwork2 (2 * nn); | |
1060 RowVector rwork2 (8 * nn); | |
1019 octave_idx_type m; | 1061 octave_idx_type m; |
1020 CVL=CQ; | 1062 |
1021 CVR=CZ; | 1063 F77_XFCN (ztgevc, ZTGEVC, |
1022 ComplexRowVector cwork2(2*nn); | 1064 (F77_CONST_CHAR_ARG2 (&side, 1), |
1023 RowVector rwork2(8*nn); | 1065 F77_CONST_CHAR_ARG2 (&howmny, 1), |
1024 | 1066 select, nn, caa.fortran_vec (), nn, cbb.fortran_vec (), |
1025 //octave_idx_type n=nn; | 1067 nn, CVL.fortran_vec (), nn, CVR.fortran_vec (), nn, nn, |
1026 F77_XFCN (ztgevc, ZTGEVC, | 1068 m, cwork2.fortran_vec (), rwork2.fortran_vec (), info |
1027 (F77_CONST_CHAR_ARG2 (&side, 1), | 1069 F77_CHAR_ARG_LEN (1) |
1028 F77_CONST_CHAR_ARG2 (&howmny, 1), | 1070 F77_CHAR_ARG_LEN (1))); |
1029 select, nn, caa.fortran_vec (), nn, cbb.fortran_vec (), | |
1030 nn, CVL.fortran_vec (), nn, CVR.fortran_vec (), nn, nn, | |
1031 m, cwork2.fortran_vec (), rwork2.fortran_vec (), info | |
1032 F77_CHAR_ARG_LEN (1) | |
1033 F77_CHAR_ARG_LEN (1))); | |
1034 } | 1071 } |
1035 else | 1072 else |
1036 { | 1073 { |
1037 #ifdef DEBUG | 1074 #ifdef DEBUG |
1038 std::cout << "qz: computing generalized eigenvectors" << std::endl; | 1075 std::cout << "qz: computing generalized eigenvectors" << std::endl; |
1039 #endif | 1076 #endif |
1040 | 1077 |
1041 VL = QQ; | 1078 VL = QQ; |
1042 VR = ZZ; | 1079 VR = ZZ; |
1043 octave_idx_type m; | 1080 octave_idx_type m; |
1081 | |
1044 F77_XFCN (dtgevc, DTGEVC, | 1082 F77_XFCN (dtgevc, DTGEVC, |
1045 (F77_CONST_CHAR_ARG2 (&side, 1), | 1083 (F77_CONST_CHAR_ARG2 (&side, 1), |
1046 F77_CONST_CHAR_ARG2 (&howmny, 1), | 1084 F77_CONST_CHAR_ARG2 (&howmny, 1), |
1047 select, nn, aa.fortran_vec (), nn, bb.fortran_vec (), | 1085 select, nn, aa.fortran_vec (), nn, bb.fortran_vec (), |
1048 nn, VL.fortran_vec (), nn, VR.fortran_vec (), nn, nn, | 1086 nn, VL.fortran_vec (), nn, VR.fortran_vec (), nn, nn, |
1049 m, work.fortran_vec (), info | 1087 m, work.fortran_vec (), info |
1050 F77_CHAR_ARG_LEN (1) | 1088 F77_CHAR_ARG_LEN (1) |
1051 F77_CHAR_ARG_LEN (1))); | 1089 F77_CHAR_ARG_LEN (1))); |
1052 | 1090 |
1053 // now construct the complex form of VV, WW | 1091 // Now construct the complex form of VV, WW. |
1054 int jj = 0; | 1092 int jj = 0; |
1055 | 1093 |
1056 while (jj < nn) | 1094 while (jj < nn) |
1057 { | 1095 { |
1058 OCTAVE_QUIT; | 1096 OCTAVE_QUIT; |
1059 | 1097 |
1060 // see if real or complex eigenvalue | 1098 // See if real or complex eigenvalue. |
1061 int cinc = 2; // column increment; assume complex eigenvalue | 1099 |
1100 // Column increment; assume complex eigenvalue. | |
1101 int cinc = 2; | |
1062 | 1102 |
1063 if (jj == (nn-1)) | 1103 if (jj == (nn-1)) |
1064 cinc = 1; // single column | 1104 // Single column. |
1105 cinc = 1; | |
1065 else if (aa(jj+1,jj) == 0) | 1106 else if (aa(jj+1,jj) == 0) |
1066 cinc = 1; | 1107 cinc = 1; |
1067 | 1108 |
1068 // now copy the eigenvector (s) to CVR, CVL | 1109 // Now copy the eigenvector (s) to CVR, CVL. |
1069 if (cinc == 1) | 1110 if (cinc == 1) |
1070 { | 1111 { |
1071 for (int ii = 0; ii < nn; ii++) | 1112 for (int ii = 0; ii < nn; ii++) |
1072 CVR(ii,jj) = VR(ii,jj); | 1113 CVR(ii,jj) = VR(ii,jj); |
1073 | 1114 |
1075 for (int ii = 0; ii < nn; ii++) | 1116 for (int ii = 0; ii < nn; ii++) |
1076 CVL(ii,jj) = VL(ii,jj); | 1117 CVL(ii,jj) = VL(ii,jj); |
1077 } | 1118 } |
1078 else | 1119 else |
1079 { | 1120 { |
1080 // double column; complex vector | 1121 // Double column; complex vector. |
1081 | 1122 |
1082 for (int ii = 0; ii < nn; ii++) | 1123 for (int ii = 0; ii < nn; ii++) |
1083 { | 1124 { |
1084 CVR(ii,jj) = Complex (VR(ii,jj), VR(ii,jj+1)); | 1125 CVR(ii,jj) = Complex (VR(ii,jj), VR(ii,jj+1)); |
1085 CVR(ii,jj+1) = Complex (VR(ii,jj), -VR(ii,jj+1)); | 1126 CVR(ii,jj+1) = Complex (VR(ii,jj), -VR(ii,jj+1)); |
1091 CVL(ii,jj) = Complex (VL(ii,jj), VL(ii,jj+1)); | 1132 CVL(ii,jj) = Complex (VL(ii,jj), VL(ii,jj+1)); |
1092 CVL(ii,jj+1) = Complex (VL(ii,jj), -VL(ii,jj+1)); | 1133 CVL(ii,jj+1) = Complex (VL(ii,jj), -VL(ii,jj+1)); |
1093 } | 1134 } |
1094 } | 1135 } |
1095 | 1136 |
1096 // advance to next eigenvectors (if any) | 1137 // Advance to next eigenvectors (if any). |
1097 jj += cinc; | 1138 jj += cinc; |
1098 } | 1139 } |
1099 } | 1140 } |
1100 } | 1141 } |
1101 | 1142 |
1102 switch (nargout) | 1143 switch (nargout) |
1103 { | 1144 { |
1104 case 7: | 1145 case 7: |
1105 retval(6) = gev; | 1146 retval(6) = gev; |
1106 | 1147 |
1107 case 6: // return eigenvectors | 1148 case 6: |
1149 // Return eigenvectors. | |
1108 retval(5) = CVL; | 1150 retval(5) = CVL; |
1109 | 1151 |
1110 case 5: // return eigenvectors | 1152 case 5: |
1153 // Return eigenvectors. | |
1111 retval(4) = CVR; | 1154 retval(4) = CVR; |
1112 | 1155 |
1113 case 4: | 1156 case 4: |
1114 if (nargin == 3) | 1157 if (nargin == 3) |
1115 { | 1158 { |
1119 std::cout << std::endl; | 1162 std::cout << std::endl; |
1120 #endif | 1163 #endif |
1121 retval(3) = gev; | 1164 retval(3) = gev; |
1122 } | 1165 } |
1123 else | 1166 else |
1124 {if (complex_case) | 1167 { |
1125 retval(3) = CZ; | 1168 if (complex_case) |
1126 else | 1169 retval(3) = CZ; |
1127 retval(3) = ZZ; | 1170 else |
1128 } | 1171 retval(3) = ZZ; |
1172 } | |
1129 | 1173 |
1130 case 3: | 1174 case 3: |
1131 if (nargin == 3) | 1175 if (nargin == 3) |
1132 retval(2) = CZ; | 1176 retval(2) = CZ; |
1133 else | 1177 else |
1134 {if (complex_case) | 1178 { |
1135 retval(2) = CQ.hermitian(); // compabible with MATLAB output | 1179 if (complex_case) |
1136 else | 1180 retval(2) = CQ.hermitian (); |
1137 retval(2) = QQ.transpose(); | 1181 else |
1138 } | 1182 retval(2) = QQ.transpose (); |
1183 } | |
1184 | |
1139 case 2: | 1185 case 2: |
1140 {if (complex_case) | |
1141 { | 1186 { |
1142 #ifdef DEBUG | 1187 if (complex_case) |
1143 std::cout << "qz: retval (1) = cbb = " << std::endl; | 1188 { |
1144 octave_print_internal (std::cout, cbb, 0); | 1189 #ifdef DEBUG |
1145 std::cout << std::endl << "qz: retval(0) = caa = " <<std::endl; | 1190 std::cout << "qz: retval (1) = cbb = " << std::endl; |
1146 octave_print_internal (std::cout, caa, 0); | 1191 octave_print_internal (std::cout, cbb, 0); |
1147 std::cout << std::endl; | 1192 std::cout << std::endl << "qz: retval(0) = caa = " <<std::endl; |
1148 #endif | 1193 octave_print_internal (std::cout, caa, 0); |
1149 retval(1) = cbb; | 1194 std::cout << std::endl; |
1150 retval(0) = caa; | 1195 #endif |
1151 } | 1196 retval(1) = cbb; |
1197 retval(0) = caa; | |
1198 } | |
1152 else | 1199 else |
1153 { // real case | 1200 { |
1154 #ifdef DEBUG | 1201 #ifdef DEBUG |
1155 std::cout << "qz: retval (1) = bb = " << std::endl; | 1202 std::cout << "qz: retval (1) = bb = " << std::endl; |
1156 octave_print_internal (std::cout, bb, 0); | 1203 octave_print_internal (std::cout, bb, 0); |
1157 std::cout << std::endl << "qz: retval(0) = aa = " <<std::endl; | 1204 std::cout << std::endl << "qz: retval(0) = aa = " <<std::endl; |
1158 octave_print_internal (std::cout, aa, 0); | 1205 octave_print_internal (std::cout, aa, 0); |
1159 std::cout << std::endl; | 1206 std::cout << std::endl; |
1160 #endif | 1207 #endif |
1161 retval(1) = bb; | 1208 retval(1) = bb; |
1162 retval(0) = aa; | 1209 retval(0) = aa; |
1163 } | 1210 } |
1164 break;} | 1211 } |
1212 break; | |
1165 | 1213 |
1166 | 1214 |
1167 case 1: | 1215 case 1: |
1168 case 0: | 1216 case 0: |
1169 #ifdef DEBUG | 1217 #ifdef DEBUG |