Macaulay2 Engine
Loading...
Searching...
No Matches

◆ eigenvectors() [3/4]

bool Lapack::eigenvectors ( const DMatRR * A,
DMatCC * eigenvals,
DMatCC * eigenvecs )
static

Definition at line 365 of file lapack.cpp.

368{
369 int size = static_cast<int>(A->numRows());
370 if (size != static_cast<int>(A->numColumns()))
371 {
372 ERROR("expected a square matrix");
373 return false;
374 }
375
376 if (size == 0)
377 {
378 eigvals->resize(0, 1); // TODO: is this 1 correct?
379 eigvecs->resize(0, 0);
380 return true;
381 }
382
383 bool ret = true;
384 char dont = 'N';
385 char doit = 'V';
386 int wsize = 4 * size;
387
388 double *workspace = new double[2*wsize];
389 int info;
390
391 std::vector<double> copyA = make_lapack_array(*A);
392 double *real = new double[size]; // real components of eigvals
393 double *imag = new double[size]; // imaginary components
394 double *eigen = new double[size * size]; // eigvecs
395
396 dgeev_(&dont, /* left e-vectors */
397 &doit, /* right e-vectors */
398 &size,
399 copyA.data(),
400 &size,
401 real,
402 imag,
403 static_cast<double *>(nullptr),
404 &size, /* left eigvecs */
405 eigen,
406 &size, /* right eigvecs */
407 workspace,
408 &wsize,
409 &info);
410
411 if (info < 0)
412 {
413 ERROR("argument passed to dgeev had an illegal value");
414 ret = false;
415 }
416 else if (info > 0)
417 {
418 ERROR("the QR algorithm in dgeev failed to compute all eigvals");
419 ret = false;
420 }
421 else
422 {
423 // Make the complex arrays of eigvals and eigvecs
424 eigvals->resize(size, 1);
425 eigvecs->resize(size, size);
426 // DMatCC::ElementType *elems = eigvals->rowMajorArray();
427 double* eigenLoc = eigen; // current row (eigenvector) in the eigen array
428 for (int j = 0; j < size; j++, eigenLoc += size)
429 {
430 eigvals->ring().set_from_doubles(eigvals->entry(j,0), real[j], imag[j]);
431
432 // now set j-th column of eigvecs
433 if (imag[j] == 0)
434 {
435 for (int i = 0; i < size; ++i)
436 {
437 eigvecs->entry(i,j).re = eigenLoc[i];
438 eigvecs->entry(i,j).im = 0;
439 }
440 }
441 else if (imag[j] > 0)
442 {
443 for (int i = 0; i < size; ++i)
444 {
445 eigvecs->ring().set_from_doubles(eigvecs->entry(i,j),
446 eigenLoc[i], eigenLoc[size + i]);
447 eigvecs->ring().set_from_doubles(eigvecs->entry(i,j+1),
448 eigenLoc[i], - eigenLoc[size + i]);
449 }
450 }
451 }
452 }
453
454 delete [] workspace;
455 delete [] real;
456 delete [] imag;
457 delete [] eigen;
458
459 return ret;
460}
size_t numRows() const
Definition dmat.hpp:144
size_t numColumns() const
Definition dmat.hpp:145
std::vector< double > make_lapack_array(const DMatRR &mat)
Definition lapack.cpp:20
int dgeev_(char *n, char *n2, int *size, double *M, int *size1, double *E, double *E2, double *, int *, double *, int *, double *, int *, int *)
const int ERROR
Definition m2-mem.cpp:55

References dgeev_(), DMat< ACoeffRing >::entry(), ERROR, cc_doubles_struct::im, make_lapack_array(), DMat< ACoeffRing >::numColumns(), DMat< ACoeffRing >::numRows(), cc_doubles_struct::re, DMat< ACoeffRing >::resize(), DMat< ACoeffRing >::ring(), and M2::ARingCC::set_from_doubles().