20 #include <tensor/tensor.h>
21 #include <tensor/tensor_lapack.h>
22 #include <tensor/linalg.h>
28 using namespace lapack;
48 assert(A.
rank() == 2);
53 integer lda, ldvl, ldvr, lwork, info;
54 double *vl, *vr, *wr, *wi;
56 double *a = tensor_pointer(aux);
61 std::cerr <<
"Routine eig() can only compute eigenvalues of square matrices, and you\n"
62 <<
"have passed a matrix that is " << A.
rows() <<
" by " << A.
columns();
68 vl = tensor_pointer(*realL);
76 vr = tensor_pointer(*realR);
85 wr = tensor_pointer(real);
86 wi = tensor_pointer(imag);
88 #ifdef TENSOR_USE_ACML
89 dgeev(*jobvl, *jobvr, n, a, lda, wr, wi, vl, ldvl, vr,
94 F77NAME(dgeev)(jobvl, jobvr, &n, a, &lda, wr, wi, vl, &ldvl, vr, &ldvr, work0, &lwork,
96 lwork = (int)work0[0];
97 double *work =
new double[lwork];
98 F77NAME(dgeev)(jobvl, jobvr, &n, a, &lda, wr, wi, vl, &ldvl, vr, &ldvr, work, &lwork,
103 CTensor output(to_complex(real));
104 if (L) *L = to_complex(*realL);
105 if (R) *R = to_complex(*realR);
106 for (
size_t i = 0; i < (size_t)n; i++) {
110 output.
at(i) = tensor::to_complex(real[i],imag[i]);
111 output.
at(i+1) = tensor::to_complex(real[i],-imag[i]);
113 for (
size_t j = 0; j < (size_t)n; j++) {
114 double re = (*realL)(j,i);
115 double im = (*realL)(j,i+1);
116 (*L).at(j,i) = tensor::to_complex(re,im);
117 (*L).at(j,i+1) = tensor::to_complex(re,-im);
121 for (
size_t j = 0; j < (size_t)n; j++) {
122 double re = (*realR)(j,i);
123 double im = (*realR)(j,i+1);
124 (*R).at(j,i) = tensor::to_complex(re,im);
125 (*R).at(j,i+1) = tensor::to_complex(re,-im);
int rank() const
Number of Tensor indices.
const CTensor eig(const RTensor &A, CTensor *R=0, CTensor *L=0)
Eigenvalue decomposition of a real matrix.
index columns() const
Query the size of 2nd index.
index rows() const
Query then size of 1st index.
Real Tensor with elements of type "double".
Complex Tensor with elements of type "cdouble".
elt_t & at(index i)
Return a mutable reference to an element of a 1D Tensor.