Mercurial > jwe > octave
comparison liboctave/numeric/fEIG.cc @ 21136:7cac4e7458f2
maint: clean up code around calls to current_liboctave_error_handler.
Remove statements after call to handler that are no longer reachable.
Place input validation first and immediately call handler if necessary.
Change if/error_handler/else to if/error_handler and re-indent code.
* Array-util.cc, Array.cc, CColVector.cc, CDiagMatrix.cc, CMatrix.cc,
CNDArray.cc, CRowVector.cc, CSparse.cc, DiagArray2.cc, MArray.cc,
PermMatrix.cc, Sparse.cc, Sparse.h, chMatrix.cc, chNDArray.cc, dColVector.cc,
dDiagMatrix.cc, dMatrix.cc, dNDArray.cc, dRowVector.cc, dSparse.cc,
fCColVector.cc, fCDiagMatrix.cc, fCMatrix.cc, fCNDArray.cc, fCRowVector.cc,
fColVector.cc, fDiagMatrix.cc, fMatrix.cc, fNDArray.cc, fRowVector.cc,
idx-vector.cc, CmplxAEPBAL.cc, CmplxCHOL.cc, CmplxGEPBAL.cc, CmplxHESS.cc,
CmplxLU.cc, CmplxQR.cc, CmplxSCHUR.cc, CmplxSVD.cc, DASPK.cc, EIG.cc, LSODE.cc,
Quad.cc, SparseCmplxCHOL.cc, SparseCmplxLU.cc, SparseCmplxQR.cc, SparseQR.cc,
SparsedbleCHOL.cc, SparsedbleLU.cc, base-lu.cc, bsxfun-defs.cc, dbleAEPBAL.cc,
dbleCHOL.cc, dbleGEPBAL.cc, dbleHESS.cc, dbleLU.cc, dbleQR.cc, dbleSCHUR.cc,
dbleSVD.cc, eigs-base.cc, fCmplxAEPBAL.cc, fCmplxCHOL.cc, fCmplxLU.cc,
fCmplxQR.cc, fCmplxSCHUR.cc, fEIG.cc, floatAEPBAL.cc, floatCHOL.cc,
floatGEPBAL.cc, floatHESS.cc, floatLU.cc, floatQR.cc, floatSCHUR.cc,
floatSVD.cc, lo-specfun.cc, oct-fftw.cc, oct-rand.cc, oct-spparms.cc,
sparse-base-chol.cc, sparse-dmsolve.cc, file-ops.cc, lo-sysdep.cc,
mach-info.cc, oct-env.cc, oct-syscalls.cc, cmd-edit.cc, cmd-hist.cc,
data-conv.cc, lo-ieee.cc, lo-regexp.cc, oct-base64.cc, oct-shlib.cc,
pathsearch.cc, singleton-cleanup.cc, sparse-util.cc, unwind-prot.cc:
Remove statements after call to handler that are no longer reachable.
Place input validation first and immediately call handler if necessary.
Change if/error_handler/else to if/error_handler and re-indent code.
author | Rik <rik@octave.org> |
---|---|
date | Sat, 23 Jan 2016 13:52:03 -0800 |
parents | ff904ae0285b |
children | f7121e111991 |
comparison
equal
deleted
inserted
replaced
21135:95da3bc8a281 | 21136:7cac4e7458f2 |
---|---|
135 | 135 |
136 octave_idx_type | 136 octave_idx_type |
137 FloatEIG::init (const FloatMatrix& a, bool calc_ev) | 137 FloatEIG::init (const FloatMatrix& a, bool calc_ev) |
138 { | 138 { |
139 if (a.any_element_is_inf_or_nan ()) | 139 if (a.any_element_is_inf_or_nan ()) |
140 { | 140 (*current_liboctave_error_handler) |
141 (*current_liboctave_error_handler) | 141 ("EIG: matrix contains Inf or NaN values"); |
142 ("EIG: matrix contains Inf or NaN values"); | |
143 return -1; | |
144 } | |
145 | 142 |
146 if (a.is_symmetric ()) | 143 if (a.is_symmetric ()) |
147 return symmetric_init (a, calc_ev); | 144 return symmetric_init (a, calc_ev); |
148 | 145 |
149 octave_idx_type n = a.rows (); | 146 octave_idx_type n = a.rows (); |
150 | 147 |
151 if (n != a.cols ()) | 148 if (n != a.cols ()) |
152 { | 149 (*current_liboctave_error_handler) ("EIG requires square matrix"); |
153 (*current_liboctave_error_handler) ("EIG requires square matrix"); | |
154 return -1; | |
155 } | |
156 | 150 |
157 octave_idx_type info = 0; | 151 octave_idx_type info = 0; |
158 | 152 |
159 FloatMatrix atmp = a; | 153 FloatMatrix atmp = a; |
160 float *tmp_data = atmp.fortran_vec (); | 154 float *tmp_data = atmp.fortran_vec (); |
180 n, tmp_data, n, pwr, pwi, dummy, | 174 n, tmp_data, n, pwr, pwi, dummy, |
181 idummy, pvr, n, &dummy_work, lwork, info | 175 idummy, pvr, n, &dummy_work, lwork, info |
182 F77_CHAR_ARG_LEN (1) | 176 F77_CHAR_ARG_LEN (1) |
183 F77_CHAR_ARG_LEN (1))); | 177 F77_CHAR_ARG_LEN (1))); |
184 | 178 |
185 if (info == 0) | 179 if (info != 0) |
180 (*current_liboctave_error_handler) ("sgeev workspace query failed"); | |
181 | |
182 lwork = static_cast<octave_idx_type> (dummy_work); | |
183 Array<float> work (dim_vector (lwork, 1)); | |
184 float *pwork = work.fortran_vec (); | |
185 | |
186 F77_XFCN (sgeev, SGEEV, (F77_CONST_CHAR_ARG2 ("N", 1), | |
187 F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
188 n, tmp_data, n, pwr, pwi, dummy, | |
189 idummy, pvr, n, pwork, lwork, info | |
190 F77_CHAR_ARG_LEN (1) | |
191 F77_CHAR_ARG_LEN (1))); | |
192 | |
193 if (info < 0) | |
194 (*current_liboctave_error_handler) ("unrecoverable error in sgeev"); | |
195 | |
196 if (info > 0) | |
197 (*current_liboctave_error_handler) ("sgeev failed to converge"); | |
198 | |
199 lambda.resize (n); | |
200 v.resize (nvr, nvr); | |
201 | |
202 for (octave_idx_type j = 0; j < n; j++) | |
186 { | 203 { |
187 lwork = static_cast<octave_idx_type> (dummy_work); | 204 if (wi.elem (j) == 0.0) |
188 Array<float> work (dim_vector (lwork, 1)); | |
189 float *pwork = work.fortran_vec (); | |
190 | |
191 F77_XFCN (sgeev, SGEEV, (F77_CONST_CHAR_ARG2 ("N", 1), | |
192 F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
193 n, tmp_data, n, pwr, pwi, dummy, | |
194 idummy, pvr, n, pwork, lwork, info | |
195 F77_CHAR_ARG_LEN (1) | |
196 F77_CHAR_ARG_LEN (1))); | |
197 | |
198 if (info < 0) | |
199 { | 205 { |
200 (*current_liboctave_error_handler) ("unrecoverable error in sgeev"); | 206 lambda.elem (j) = FloatComplex (wr.elem (j)); |
201 return info; | 207 for (octave_idx_type i = 0; i < nvr; i++) |
208 v.elem (i, j) = vr.elem (i, j); | |
202 } | 209 } |
203 | 210 else |
204 if (info > 0) | |
205 { | 211 { |
206 (*current_liboctave_error_handler) ("sgeev failed to converge"); | 212 if (j+1 >= n) |
207 return info; | 213 (*current_liboctave_error_handler) ("EIG: internal error"); |
208 } | 214 |
209 | 215 lambda.elem (j) = FloatComplex (wr.elem (j), wi.elem (j)); |
210 lambda.resize (n); | 216 lambda.elem (j+1) = FloatComplex (wr.elem (j+1), wi.elem (j+1)); |
211 v.resize (nvr, nvr); | 217 |
212 | 218 for (octave_idx_type i = 0; i < nvr; i++) |
213 for (octave_idx_type j = 0; j < n; j++) | |
214 { | |
215 if (wi.elem (j) == 0.0) | |
216 { | 219 { |
217 lambda.elem (j) = FloatComplex (wr.elem (j)); | 220 float real_part = vr.elem (i, j); |
218 for (octave_idx_type i = 0; i < nvr; i++) | 221 float imag_part = vr.elem (i, j+1); |
219 v.elem (i, j) = vr.elem (i, j); | 222 v.elem (i, j) = FloatComplex (real_part, imag_part); |
223 v.elem (i, j+1) = FloatComplex (real_part, -imag_part); | |
220 } | 224 } |
221 else | 225 j++; |
222 { | |
223 if (j+1 >= n) | |
224 { | |
225 (*current_liboctave_error_handler) ("EIG: internal error"); | |
226 return -1; | |
227 } | |
228 | |
229 lambda.elem (j) = FloatComplex (wr.elem (j), wi.elem (j)); | |
230 lambda.elem (j+1) = FloatComplex (wr.elem (j+1), wi.elem (j+1)); | |
231 | |
232 for (octave_idx_type i = 0; i < nvr; i++) | |
233 { | |
234 float real_part = vr.elem (i, j); | |
235 float imag_part = vr.elem (i, j+1); | |
236 v.elem (i, j) = FloatComplex (real_part, imag_part); | |
237 v.elem (i, j+1) = FloatComplex (real_part, -imag_part); | |
238 } | |
239 j++; | |
240 } | |
241 } | 226 } |
242 } | 227 } |
243 else | |
244 (*current_liboctave_error_handler) ("sgeev workspace query failed"); | |
245 | 228 |
246 return info; | 229 return info; |
247 } | 230 } |
248 | 231 |
249 octave_idx_type | 232 octave_idx_type |
250 FloatEIG::symmetric_init (const FloatMatrix& a, bool calc_ev) | 233 FloatEIG::symmetric_init (const FloatMatrix& a, bool calc_ev) |
251 { | 234 { |
252 octave_idx_type n = a.rows (); | 235 octave_idx_type n = a.rows (); |
253 | 236 |
254 if (n != a.cols ()) | 237 if (n != a.cols ()) |
255 { | 238 (*current_liboctave_error_handler) ("EIG requires square matrix"); |
256 (*current_liboctave_error_handler) ("EIG requires square matrix"); | |
257 return -1; | |
258 } | |
259 | 239 |
260 octave_idx_type info = 0; | 240 octave_idx_type info = 0; |
261 | 241 |
262 FloatMatrix atmp = a; | 242 FloatMatrix atmp = a; |
263 float *tmp_data = atmp.fortran_vec (); | 243 float *tmp_data = atmp.fortran_vec (); |
272 F77_CONST_CHAR_ARG2 ("U", 1), | 252 F77_CONST_CHAR_ARG2 ("U", 1), |
273 n, tmp_data, n, pwr, &dummy_work, lwork, info | 253 n, tmp_data, n, pwr, &dummy_work, lwork, info |
274 F77_CHAR_ARG_LEN (1) | 254 F77_CHAR_ARG_LEN (1) |
275 F77_CHAR_ARG_LEN (1))); | 255 F77_CHAR_ARG_LEN (1))); |
276 | 256 |
277 if (info == 0) | 257 if (info != 0) |
278 { | |
279 lwork = static_cast<octave_idx_type> (dummy_work); | |
280 Array<float> work (dim_vector (lwork, 1)); | |
281 float *pwork = work.fortran_vec (); | |
282 | |
283 F77_XFCN (ssyev, SSYEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
284 F77_CONST_CHAR_ARG2 ("U", 1), | |
285 n, tmp_data, n, pwr, pwork, lwork, info | |
286 F77_CHAR_ARG_LEN (1) | |
287 F77_CHAR_ARG_LEN (1))); | |
288 | |
289 if (info < 0) | |
290 { | |
291 (*current_liboctave_error_handler) ("unrecoverable error in ssyev"); | |
292 return info; | |
293 } | |
294 | |
295 if (info > 0) | |
296 { | |
297 (*current_liboctave_error_handler) ("ssyev failed to converge"); | |
298 return info; | |
299 } | |
300 | |
301 lambda = FloatComplexColumnVector (wr); | |
302 v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix (); | |
303 } | |
304 else | |
305 (*current_liboctave_error_handler) ("ssyev workspace query failed"); | 258 (*current_liboctave_error_handler) ("ssyev workspace query failed"); |
259 | |
260 lwork = static_cast<octave_idx_type> (dummy_work); | |
261 Array<float> work (dim_vector (lwork, 1)); | |
262 float *pwork = work.fortran_vec (); | |
263 | |
264 F77_XFCN (ssyev, SSYEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
265 F77_CONST_CHAR_ARG2 ("U", 1), | |
266 n, tmp_data, n, pwr, pwork, lwork, info | |
267 F77_CHAR_ARG_LEN (1) | |
268 F77_CHAR_ARG_LEN (1))); | |
269 | |
270 if (info < 0) | |
271 (*current_liboctave_error_handler) ("unrecoverable error in ssyev"); | |
272 | |
273 if (info > 0) | |
274 (*current_liboctave_error_handler) ("ssyev failed to converge"); | |
275 | |
276 lambda = FloatComplexColumnVector (wr); | |
277 v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix (); | |
306 | 278 |
307 return info; | 279 return info; |
308 } | 280 } |
309 | 281 |
310 octave_idx_type | 282 octave_idx_type |
311 FloatEIG::init (const FloatComplexMatrix& a, bool calc_ev) | 283 FloatEIG::init (const FloatComplexMatrix& a, bool calc_ev) |
312 { | 284 { |
313 if (a.any_element_is_inf_or_nan ()) | 285 if (a.any_element_is_inf_or_nan ()) |
314 { | 286 (*current_liboctave_error_handler) |
315 (*current_liboctave_error_handler) | 287 ("EIG: matrix contains Inf or NaN values"); |
316 ("EIG: matrix contains Inf or NaN values"); | |
317 return -1; | |
318 } | |
319 | 288 |
320 if (a.is_hermitian ()) | 289 if (a.is_hermitian ()) |
321 return hermitian_init (a, calc_ev); | 290 return hermitian_init (a, calc_ev); |
322 | 291 |
323 octave_idx_type n = a.rows (); | 292 octave_idx_type n = a.rows (); |
324 | 293 |
325 if (n != a.cols ()) | 294 if (n != a.cols ()) |
326 { | 295 (*current_liboctave_error_handler) ("EIG requires square matrix"); |
327 (*current_liboctave_error_handler) ("EIG requires square matrix"); | |
328 return -1; | |
329 } | |
330 | 296 |
331 octave_idx_type info = 0; | 297 octave_idx_type info = 0; |
332 | 298 |
333 FloatComplexMatrix atmp = a; | 299 FloatComplexMatrix atmp = a; |
334 FloatComplex *tmp_data = atmp.fortran_vec (); | 300 FloatComplex *tmp_data = atmp.fortran_vec (); |
355 n, tmp_data, n, pw, dummy, idummy, | 321 n, tmp_data, n, pw, dummy, idummy, |
356 pv, n, &dummy_work, lwork, prwork, info | 322 pv, n, &dummy_work, lwork, prwork, info |
357 F77_CHAR_ARG_LEN (1) | 323 F77_CHAR_ARG_LEN (1) |
358 F77_CHAR_ARG_LEN (1))); | 324 F77_CHAR_ARG_LEN (1))); |
359 | 325 |
360 if (info == 0) | 326 if (info != 0) |
361 { | |
362 lwork = static_cast<octave_idx_type> (dummy_work.real ()); | |
363 Array<FloatComplex> work (dim_vector (lwork, 1)); | |
364 FloatComplex *pwork = work.fortran_vec (); | |
365 | |
366 F77_XFCN (cgeev, CGEEV, (F77_CONST_CHAR_ARG2 ("N", 1), | |
367 F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
368 n, tmp_data, n, pw, dummy, idummy, | |
369 pv, n, pwork, lwork, prwork, info | |
370 F77_CHAR_ARG_LEN (1) | |
371 F77_CHAR_ARG_LEN (1))); | |
372 | |
373 if (info < 0) | |
374 { | |
375 (*current_liboctave_error_handler) ("unrecoverable error in cgeev"); | |
376 return info; | |
377 } | |
378 | |
379 if (info > 0) | |
380 { | |
381 (*current_liboctave_error_handler) ("cgeev failed to converge"); | |
382 return info; | |
383 } | |
384 | |
385 lambda = w; | |
386 v = vtmp; | |
387 } | |
388 else | |
389 (*current_liboctave_error_handler) ("cgeev workspace query failed"); | 327 (*current_liboctave_error_handler) ("cgeev workspace query failed"); |
328 | |
329 lwork = static_cast<octave_idx_type> (dummy_work.real ()); | |
330 Array<FloatComplex> work (dim_vector (lwork, 1)); | |
331 FloatComplex *pwork = work.fortran_vec (); | |
332 | |
333 F77_XFCN (cgeev, CGEEV, (F77_CONST_CHAR_ARG2 ("N", 1), | |
334 F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
335 n, tmp_data, n, pw, dummy, idummy, | |
336 pv, n, pwork, lwork, prwork, info | |
337 F77_CHAR_ARG_LEN (1) | |
338 F77_CHAR_ARG_LEN (1))); | |
339 | |
340 if (info < 0) | |
341 (*current_liboctave_error_handler) ("unrecoverable error in cgeev"); | |
342 | |
343 if (info > 0) | |
344 (*current_liboctave_error_handler) ("cgeev failed to converge"); | |
345 | |
346 lambda = w; | |
347 v = vtmp; | |
390 | 348 |
391 return info; | 349 return info; |
392 } | 350 } |
393 | 351 |
394 octave_idx_type | 352 octave_idx_type |
395 FloatEIG::hermitian_init (const FloatComplexMatrix& a, bool calc_ev) | 353 FloatEIG::hermitian_init (const FloatComplexMatrix& a, bool calc_ev) |
396 { | 354 { |
397 octave_idx_type n = a.rows (); | 355 octave_idx_type n = a.rows (); |
398 | 356 |
399 if (n != a.cols ()) | 357 if (n != a.cols ()) |
400 { | 358 (*current_liboctave_error_handler) ("EIG requires square matrix"); |
401 (*current_liboctave_error_handler) ("EIG requires square matrix"); | |
402 return -1; | |
403 } | |
404 | 359 |
405 octave_idx_type info = 0; | 360 octave_idx_type info = 0; |
406 | 361 |
407 FloatComplexMatrix atmp = a; | 362 FloatComplexMatrix atmp = a; |
408 FloatComplex *tmp_data = atmp.fortran_vec (); | 363 FloatComplex *tmp_data = atmp.fortran_vec (); |
422 n, tmp_data, n, pwr, &dummy_work, lwork, | 377 n, tmp_data, n, pwr, &dummy_work, lwork, |
423 prwork, info | 378 prwork, info |
424 F77_CHAR_ARG_LEN (1) | 379 F77_CHAR_ARG_LEN (1) |
425 F77_CHAR_ARG_LEN (1))); | 380 F77_CHAR_ARG_LEN (1))); |
426 | 381 |
427 if (info == 0) | 382 if (info != 0) |
428 { | |
429 lwork = static_cast<octave_idx_type> (dummy_work.real ()); | |
430 Array<FloatComplex> work (dim_vector (lwork, 1)); | |
431 FloatComplex *pwork = work.fortran_vec (); | |
432 | |
433 F77_XFCN (cheev, CHEEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
434 F77_CONST_CHAR_ARG2 ("U", 1), | |
435 n, tmp_data, n, pwr, pwork, lwork, prwork, info | |
436 F77_CHAR_ARG_LEN (1) | |
437 F77_CHAR_ARG_LEN (1))); | |
438 | |
439 if (info < 0) | |
440 { | |
441 (*current_liboctave_error_handler) ("unrecoverable error in cheev"); | |
442 return info; | |
443 } | |
444 | |
445 if (info > 0) | |
446 { | |
447 (*current_liboctave_error_handler) ("cheev failed to converge"); | |
448 return info; | |
449 } | |
450 | |
451 lambda = FloatComplexColumnVector (wr); | |
452 v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix (); | |
453 } | |
454 else | |
455 (*current_liboctave_error_handler) ("cheev workspace query failed"); | 383 (*current_liboctave_error_handler) ("cheev workspace query failed"); |
384 | |
385 lwork = static_cast<octave_idx_type> (dummy_work.real ()); | |
386 Array<FloatComplex> work (dim_vector (lwork, 1)); | |
387 FloatComplex *pwork = work.fortran_vec (); | |
388 | |
389 F77_XFCN (cheev, CHEEV, (F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
390 F77_CONST_CHAR_ARG2 ("U", 1), | |
391 n, tmp_data, n, pwr, pwork, lwork, prwork, info | |
392 F77_CHAR_ARG_LEN (1) | |
393 F77_CHAR_ARG_LEN (1))); | |
394 | |
395 if (info < 0) | |
396 (*current_liboctave_error_handler) ("unrecoverable error in cheev"); | |
397 | |
398 if (info > 0) | |
399 (*current_liboctave_error_handler) ("cheev failed to converge"); | |
400 | |
401 lambda = FloatComplexColumnVector (wr); | |
402 v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix (); | |
456 | 403 |
457 return info; | 404 return info; |
458 } | 405 } |
459 | 406 |
460 octave_idx_type | 407 octave_idx_type |
461 FloatEIG::init (const FloatMatrix& a, const FloatMatrix& b, bool calc_ev) | 408 FloatEIG::init (const FloatMatrix& a, const FloatMatrix& b, bool calc_ev) |
462 { | 409 { |
463 if (a.any_element_is_inf_or_nan () || b.any_element_is_inf_or_nan ()) | 410 if (a.any_element_is_inf_or_nan () || b.any_element_is_inf_or_nan ()) |
464 { | 411 (*current_liboctave_error_handler) |
465 (*current_liboctave_error_handler) | 412 ("EIG: matrix contains Inf or NaN values"); |
466 ("EIG: matrix contains Inf or NaN values"); | |
467 return -1; | |
468 } | |
469 | 413 |
470 octave_idx_type n = a.rows (); | 414 octave_idx_type n = a.rows (); |
471 octave_idx_type nb = b.rows (); | 415 octave_idx_type nb = b.rows (); |
472 | 416 |
473 if (n != a.cols () || nb != b.cols ()) | 417 if (n != a.cols () || nb != b.cols ()) |
474 { | 418 (*current_liboctave_error_handler) ("EIG requires square matrix"); |
475 (*current_liboctave_error_handler) ("EIG requires square matrix"); | |
476 return -1; | |
477 } | |
478 | 419 |
479 if (n != nb) | 420 if (n != nb) |
480 { | 421 (*current_liboctave_error_handler) ("EIG requires same size matrices"); |
481 (*current_liboctave_error_handler) ("EIG requires same size matrices"); | |
482 return -1; | |
483 } | |
484 | 422 |
485 octave_idx_type info = 0; | 423 octave_idx_type info = 0; |
486 | 424 |
487 FloatMatrix tmp = b; | 425 FloatMatrix tmp = b; |
488 float *tmp_data = tmp.fortran_vec (); | 426 float *tmp_data = tmp.fortran_vec (); |
528 dummy, idummy, pvr, n, | 466 dummy, idummy, pvr, n, |
529 &dummy_work, lwork, info | 467 &dummy_work, lwork, info |
530 F77_CHAR_ARG_LEN (1) | 468 F77_CHAR_ARG_LEN (1) |
531 F77_CHAR_ARG_LEN (1))); | 469 F77_CHAR_ARG_LEN (1))); |
532 | 470 |
533 if (info == 0) | 471 if (info != 0) |
472 (*current_liboctave_error_handler) ("sggev workspace query failed"); | |
473 | |
474 lwork = static_cast<octave_idx_type> (dummy_work); | |
475 Array<float> work (dim_vector (lwork, 1)); | |
476 float *pwork = work.fortran_vec (); | |
477 | |
478 F77_XFCN (sggev, SGGEV, (F77_CONST_CHAR_ARG2 ("N", 1), | |
479 F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
480 n, atmp_data, n, btmp_data, n, | |
481 par, pai, pbeta, | |
482 dummy, idummy, pvr, n, | |
483 pwork, lwork, info | |
484 F77_CHAR_ARG_LEN (1) | |
485 F77_CHAR_ARG_LEN (1))); | |
486 | |
487 if (info < 0) | |
488 (*current_liboctave_error_handler) ("unrecoverable error in sggev"); | |
489 | |
490 if (info > 0) | |
491 (*current_liboctave_error_handler) ("sggev failed to converge"); | |
492 | |
493 lambda.resize (n); | |
494 v.resize (nvr, nvr); | |
495 | |
496 for (octave_idx_type j = 0; j < n; j++) | |
534 { | 497 { |
535 lwork = static_cast<octave_idx_type> (dummy_work); | 498 if (ai.elem (j) == 0.0) |
536 Array<float> work (dim_vector (lwork, 1)); | |
537 float *pwork = work.fortran_vec (); | |
538 | |
539 F77_XFCN (sggev, SGGEV, (F77_CONST_CHAR_ARG2 ("N", 1), | |
540 F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
541 n, atmp_data, n, btmp_data, n, | |
542 par, pai, pbeta, | |
543 dummy, idummy, pvr, n, | |
544 pwork, lwork, info | |
545 F77_CHAR_ARG_LEN (1) | |
546 F77_CHAR_ARG_LEN (1))); | |
547 | |
548 if (info < 0) | |
549 { | 499 { |
550 (*current_liboctave_error_handler) ("unrecoverable error in sggev"); | 500 lambda.elem (j) = FloatComplex (ar.elem (j) / beta.elem (j)); |
551 return info; | 501 for (octave_idx_type i = 0; i < nvr; i++) |
502 v.elem (i, j) = vr.elem (i, j); | |
552 } | 503 } |
553 | 504 else |
554 if (info > 0) | |
555 { | 505 { |
556 (*current_liboctave_error_handler) ("sggev failed to converge"); | 506 if (j+1 >= n) |
557 return info; | 507 (*current_liboctave_error_handler) ("EIG: internal error"); |
558 } | 508 |
559 | 509 lambda.elem (j) = FloatComplex (ar.elem (j) / beta.elem (j), |
560 lambda.resize (n); | 510 ai.elem (j) / beta.elem (j)); |
561 v.resize (nvr, nvr); | 511 lambda.elem (j+1) = FloatComplex (ar.elem (j+1) / beta.elem (j+1), |
562 | 512 ai.elem (j+1) / beta.elem (j+1)); |
563 for (octave_idx_type j = 0; j < n; j++) | 513 |
564 { | 514 for (octave_idx_type i = 0; i < nvr; i++) |
565 if (ai.elem (j) == 0.0) | |
566 { | 515 { |
567 lambda.elem (j) = FloatComplex (ar.elem (j) / beta.elem (j)); | 516 float real_part = vr.elem (i, j); |
568 for (octave_idx_type i = 0; i < nvr; i++) | 517 float imag_part = vr.elem (i, j+1); |
569 v.elem (i, j) = vr.elem (i, j); | 518 v.elem (i, j) = FloatComplex (real_part, imag_part); |
519 v.elem (i, j+1) = FloatComplex (real_part, -imag_part); | |
570 } | 520 } |
571 else | 521 j++; |
572 { | |
573 if (j+1 >= n) | |
574 { | |
575 (*current_liboctave_error_handler) ("EIG: internal error"); | |
576 return -1; | |
577 } | |
578 | |
579 lambda.elem (j) = FloatComplex (ar.elem (j) / beta.elem (j), | |
580 ai.elem (j) / beta.elem (j)); | |
581 lambda.elem (j+1) = FloatComplex (ar.elem (j+1) / beta.elem (j+1), | |
582 ai.elem (j+1) / beta.elem (j+1)); | |
583 | |
584 for (octave_idx_type i = 0; i < nvr; i++) | |
585 { | |
586 float real_part = vr.elem (i, j); | |
587 float imag_part = vr.elem (i, j+1); | |
588 v.elem (i, j) = FloatComplex (real_part, imag_part); | |
589 v.elem (i, j+1) = FloatComplex (real_part, -imag_part); | |
590 } | |
591 j++; | |
592 } | |
593 } | 522 } |
594 } | 523 } |
595 else | |
596 (*current_liboctave_error_handler) ("sggev workspace query failed"); | |
597 | 524 |
598 return info; | 525 return info; |
599 } | 526 } |
600 | 527 |
601 octave_idx_type | 528 octave_idx_type |
604 { | 531 { |
605 octave_idx_type n = a.rows (); | 532 octave_idx_type n = a.rows (); |
606 octave_idx_type nb = b.rows (); | 533 octave_idx_type nb = b.rows (); |
607 | 534 |
608 if (n != a.cols () || nb != b.cols ()) | 535 if (n != a.cols () || nb != b.cols ()) |
609 { | 536 (*current_liboctave_error_handler) ("EIG requires square matrix"); |
610 (*current_liboctave_error_handler) ("EIG requires square matrix"); | |
611 return -1; | |
612 } | |
613 | 537 |
614 if (n != nb) | 538 if (n != nb) |
615 { | 539 (*current_liboctave_error_handler) ("EIG requires same size matrices"); |
616 (*current_liboctave_error_handler) ("EIG requires same size matrices"); | |
617 return -1; | |
618 } | |
619 | 540 |
620 octave_idx_type info = 0; | 541 octave_idx_type info = 0; |
621 | 542 |
622 FloatMatrix atmp = a; | 543 FloatMatrix atmp = a; |
623 float *atmp_data = atmp.fortran_vec (); | 544 float *atmp_data = atmp.fortran_vec (); |
637 btmp_data, n, | 558 btmp_data, n, |
638 pwr, &dummy_work, lwork, info | 559 pwr, &dummy_work, lwork, info |
639 F77_CHAR_ARG_LEN (1) | 560 F77_CHAR_ARG_LEN (1) |
640 F77_CHAR_ARG_LEN (1))); | 561 F77_CHAR_ARG_LEN (1))); |
641 | 562 |
642 if (info == 0) | 563 if (info != 0) |
643 { | |
644 lwork = static_cast<octave_idx_type> (dummy_work); | |
645 Array<float> work (dim_vector (lwork, 1)); | |
646 float *pwork = work.fortran_vec (); | |
647 | |
648 F77_XFCN (ssygv, SSYGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
649 F77_CONST_CHAR_ARG2 ("U", 1), | |
650 n, atmp_data, n, | |
651 btmp_data, n, | |
652 pwr, pwork, lwork, info | |
653 F77_CHAR_ARG_LEN (1) | |
654 F77_CHAR_ARG_LEN (1))); | |
655 | |
656 if (info < 0) | |
657 { | |
658 (*current_liboctave_error_handler) ("unrecoverable error in ssygv"); | |
659 return info; | |
660 } | |
661 | |
662 if (info > 0) | |
663 { | |
664 (*current_liboctave_error_handler) ("ssygv failed to converge"); | |
665 return info; | |
666 } | |
667 | |
668 lambda = FloatComplexColumnVector (wr); | |
669 v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix (); | |
670 } | |
671 else | |
672 (*current_liboctave_error_handler) ("ssygv workspace query failed"); | 564 (*current_liboctave_error_handler) ("ssygv workspace query failed"); |
565 | |
566 lwork = static_cast<octave_idx_type> (dummy_work); | |
567 Array<float> work (dim_vector (lwork, 1)); | |
568 float *pwork = work.fortran_vec (); | |
569 | |
570 F77_XFCN (ssygv, SSYGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
571 F77_CONST_CHAR_ARG2 ("U", 1), | |
572 n, atmp_data, n, | |
573 btmp_data, n, | |
574 pwr, pwork, lwork, info | |
575 F77_CHAR_ARG_LEN (1) | |
576 F77_CHAR_ARG_LEN (1))); | |
577 | |
578 if (info < 0) | |
579 (*current_liboctave_error_handler) ("unrecoverable error in ssygv"); | |
580 | |
581 if (info > 0) | |
582 (*current_liboctave_error_handler) ("ssygv failed to converge"); | |
583 | |
584 lambda = FloatComplexColumnVector (wr); | |
585 v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix (); | |
673 | 586 |
674 return info; | 587 return info; |
675 } | 588 } |
676 | 589 |
677 octave_idx_type | 590 octave_idx_type |
678 FloatEIG::init (const FloatComplexMatrix& a, const FloatComplexMatrix& b, | 591 FloatEIG::init (const FloatComplexMatrix& a, const FloatComplexMatrix& b, |
679 bool calc_ev) | 592 bool calc_ev) |
680 { | 593 { |
681 if (a.any_element_is_inf_or_nan () || b.any_element_is_inf_or_nan ()) | 594 if (a.any_element_is_inf_or_nan () || b.any_element_is_inf_or_nan ()) |
682 { | 595 (*current_liboctave_error_handler) |
683 (*current_liboctave_error_handler) | 596 ("EIG: matrix contains Inf or NaN values"); |
684 ("EIG: matrix contains Inf or NaN values"); | |
685 return -1; | |
686 } | |
687 | 597 |
688 octave_idx_type n = a.rows (); | 598 octave_idx_type n = a.rows (); |
689 octave_idx_type nb = b.rows (); | 599 octave_idx_type nb = b.rows (); |
690 | 600 |
691 if (n != a.cols () || nb != b.cols ()) | 601 if (n != a.cols () || nb != b.cols ()) |
692 { | 602 (*current_liboctave_error_handler) ("EIG requires square matrix"); |
693 (*current_liboctave_error_handler) ("EIG requires square matrix"); | |
694 return -1; | |
695 } | |
696 | 603 |
697 if (n != nb) | 604 if (n != nb) |
698 { | 605 (*current_liboctave_error_handler) ("EIG requires same size matrices"); |
699 (*current_liboctave_error_handler) ("EIG requires same size matrices"); | |
700 return -1; | |
701 } | |
702 | 606 |
703 octave_idx_type info = 0; | 607 octave_idx_type info = 0; |
704 | 608 |
705 FloatComplexMatrix tmp = b; | 609 FloatComplexMatrix tmp = b; |
706 FloatComplex *tmp_data = tmp.fortran_vec (); | 610 FloatComplex *tmp_data = tmp.fortran_vec (); |
746 palpha, pbeta, dummy, idummy, | 650 palpha, pbeta, dummy, idummy, |
747 pv, n, &dummy_work, lwork, prwork, info | 651 pv, n, &dummy_work, lwork, prwork, info |
748 F77_CHAR_ARG_LEN (1) | 652 F77_CHAR_ARG_LEN (1) |
749 F77_CHAR_ARG_LEN (1))); | 653 F77_CHAR_ARG_LEN (1))); |
750 | 654 |
751 if (info == 0) | 655 if (info != 0) |
752 { | |
753 lwork = static_cast<octave_idx_type> (dummy_work.real ()); | |
754 Array<FloatComplex> work (dim_vector (lwork, 1)); | |
755 FloatComplex *pwork = work.fortran_vec (); | |
756 | |
757 F77_XFCN (cggev, CGGEV, (F77_CONST_CHAR_ARG2 ("N", 1), | |
758 F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
759 n, atmp_data, n, btmp_data, n, | |
760 palpha, pbeta, dummy, idummy, | |
761 pv, n, pwork, lwork, prwork, info | |
762 F77_CHAR_ARG_LEN (1) | |
763 F77_CHAR_ARG_LEN (1))); | |
764 | |
765 if (info < 0) | |
766 { | |
767 (*current_liboctave_error_handler) ("unrecoverable error in cggev"); | |
768 return info; | |
769 } | |
770 | |
771 if (info > 0) | |
772 { | |
773 (*current_liboctave_error_handler) ("cggev failed to converge"); | |
774 return info; | |
775 } | |
776 | |
777 lambda.resize (n); | |
778 | |
779 for (octave_idx_type j = 0; j < n; j++) | |
780 lambda.elem (j) = alpha.elem (j) / beta.elem (j); | |
781 | |
782 v = vtmp; | |
783 } | |
784 else | |
785 (*current_liboctave_error_handler) ("cggev workspace query failed"); | 656 (*current_liboctave_error_handler) ("cggev workspace query failed"); |
657 | |
658 lwork = static_cast<octave_idx_type> (dummy_work.real ()); | |
659 Array<FloatComplex> work (dim_vector (lwork, 1)); | |
660 FloatComplex *pwork = work.fortran_vec (); | |
661 | |
662 F77_XFCN (cggev, CGGEV, (F77_CONST_CHAR_ARG2 ("N", 1), | |
663 F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
664 n, atmp_data, n, btmp_data, n, | |
665 palpha, pbeta, dummy, idummy, | |
666 pv, n, pwork, lwork, prwork, info | |
667 F77_CHAR_ARG_LEN (1) | |
668 F77_CHAR_ARG_LEN (1))); | |
669 | |
670 if (info < 0) | |
671 (*current_liboctave_error_handler) ("unrecoverable error in cggev"); | |
672 | |
673 if (info > 0) | |
674 (*current_liboctave_error_handler) ("cggev failed to converge"); | |
675 | |
676 lambda.resize (n); | |
677 | |
678 for (octave_idx_type j = 0; j < n; j++) | |
679 lambda.elem (j) = alpha.elem (j) / beta.elem (j); | |
680 | |
681 v = vtmp; | |
786 | 682 |
787 return info; | 683 return info; |
788 } | 684 } |
789 | 685 |
790 octave_idx_type | 686 octave_idx_type |
793 { | 689 { |
794 octave_idx_type n = a.rows (); | 690 octave_idx_type n = a.rows (); |
795 octave_idx_type nb = b.rows (); | 691 octave_idx_type nb = b.rows (); |
796 | 692 |
797 if (n != a.cols () || nb != b.cols ()) | 693 if (n != a.cols () || nb != b.cols ()) |
798 { | 694 (*current_liboctave_error_handler) ("EIG requires square matrix"); |
799 (*current_liboctave_error_handler) ("EIG requires square matrix"); | |
800 return -1; | |
801 } | |
802 | 695 |
803 if (n != nb) | 696 if (n != nb) |
804 { | 697 (*current_liboctave_error_handler) ("EIG requires same size matrices"); |
805 (*current_liboctave_error_handler) ("EIG requires same size matrices"); | |
806 return -1; | |
807 } | |
808 | 698 |
809 octave_idx_type info = 0; | 699 octave_idx_type info = 0; |
810 | 700 |
811 FloatComplexMatrix atmp = a; | 701 FloatComplexMatrix atmp = a; |
812 FloatComplex *atmp_data = atmp.fortran_vec (); | 702 FloatComplex *atmp_data = atmp.fortran_vec (); |
831 pwr, &dummy_work, lwork, | 721 pwr, &dummy_work, lwork, |
832 prwork, info | 722 prwork, info |
833 F77_CHAR_ARG_LEN (1) | 723 F77_CHAR_ARG_LEN (1) |
834 F77_CHAR_ARG_LEN (1))); | 724 F77_CHAR_ARG_LEN (1))); |
835 | 725 |
836 if (info == 0) | 726 if (info != 0) |
837 { | |
838 lwork = static_cast<octave_idx_type> (dummy_work.real ()); | |
839 Array<FloatComplex> work (dim_vector (lwork, 1)); | |
840 FloatComplex *pwork = work.fortran_vec (); | |
841 | |
842 F77_XFCN (chegv, CHEGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
843 F77_CONST_CHAR_ARG2 ("U", 1), | |
844 n, atmp_data, n, | |
845 btmp_data, n, | |
846 pwr, pwork, lwork, prwork, info | |
847 F77_CHAR_ARG_LEN (1) | |
848 F77_CHAR_ARG_LEN (1))); | |
849 | |
850 if (info < 0) | |
851 { | |
852 (*current_liboctave_error_handler) ("unrecoverable error in zhegv"); | |
853 return info; | |
854 } | |
855 | |
856 if (info > 0) | |
857 { | |
858 (*current_liboctave_error_handler) ("zhegv failed to converge"); | |
859 return info; | |
860 } | |
861 | |
862 lambda = FloatComplexColumnVector (wr); | |
863 v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix (); | |
864 } | |
865 else | |
866 (*current_liboctave_error_handler) ("zhegv workspace query failed"); | 727 (*current_liboctave_error_handler) ("zhegv workspace query failed"); |
867 | 728 |
729 lwork = static_cast<octave_idx_type> (dummy_work.real ()); | |
730 Array<FloatComplex> work (dim_vector (lwork, 1)); | |
731 FloatComplex *pwork = work.fortran_vec (); | |
732 | |
733 F77_XFCN (chegv, CHEGV, (1, F77_CONST_CHAR_ARG2 (calc_ev ? "V" : "N", 1), | |
734 F77_CONST_CHAR_ARG2 ("U", 1), | |
735 n, atmp_data, n, | |
736 btmp_data, n, | |
737 pwr, pwork, lwork, prwork, info | |
738 F77_CHAR_ARG_LEN (1) | |
739 F77_CHAR_ARG_LEN (1))); | |
740 | |
741 if (info < 0) | |
742 (*current_liboctave_error_handler) ("unrecoverable error in zhegv"); | |
743 | |
744 if (info > 0) | |
745 (*current_liboctave_error_handler) ("zhegv failed to converge"); | |
746 | |
747 lambda = FloatComplexColumnVector (wr); | |
748 v = calc_ev ? FloatComplexMatrix (atmp) : FloatComplexMatrix (); | |
749 | |
868 return info; | 750 return info; |
869 } | 751 } |