18#ifndef OPAL_GSL_EIGEN_HH
19#define OPAL_GSL_EIGEN_HH
52 w->
work.resize(n * n);
78 w->
work.resize(n * n);
102 std::vector<std::complex<double>> matrix(n * n);
103 for (
size_t i = 0; i < n; ++i) {
104 for (
size_t j = 0; j < n; ++j) {
105 matrix[i * n + j] = std::complex<double>(*
gsl_matrix_ptr(A, i, j), 0.0);
110 const int max_iter = 100;
111 for (
int iter = 0; iter < max_iter; ++iter) {
113 std::vector<std::complex<double>> Q(n * n, 0.0);
114 std::vector<std::complex<double>> R(n * n, 0.0);
117 for (
size_t i = 0; i < n; ++i) {
122 for (
size_t j = 0; j < n; ++j) {
123 std::complex<double> norm = 0.0;
124 for (
size_t i = 0; i < n; ++i) {
125 norm += matrix[i * n + j] * std::conj(matrix[i * n + j]);
127 norm = std::sqrt(norm);
129 if (std::abs(norm) < 1e-15) {
131 for (
size_t i = 0; i < n; ++i) {
132 Q[i * n + j] = (i == j) ? 1.0 : 0.0;
136 for (
size_t i = 0; i < n; ++i) {
137 Q[i * n + j] = matrix[i * n + j] / norm;
140 for (
size_t k = j + 1; k < n; ++k) {
141 std::complex<double>
dot = 0.0;
142 for (
size_t i = 0; i < n; ++i) {
143 dot += std::conj(Q[i * n + j]) * matrix[i * n + k];
146 for (
size_t i = 0; i < n; ++i) {
147 matrix[i * n + k] -= Q[i * n + j] *
dot;
154 for (
size_t i = 0; i < n; ++i) {
155 for (
size_t j = 0; j < n; ++j) {
156 std::complex<double> sum = 0.0;
157 for (
size_t k = 0; k < n; ++k) {
158 sum += R[i * n + k] * Q[k * n + j];
160 matrix[i * n + j] = sum;
165 bool converged =
true;
166 for (
size_t i = 0; i < n; ++i) {
167 for (
size_t j = 0; j < n; ++j) {
168 if (i != j && std::abs(matrix[i * n + j]) > 1e-10) {
173 if (!converged)
break;
175 if (converged)
break;
179 for (
size_t i = 0; i < n; ++i) {
199 if (err != 0)
return err;
206 for (
size_t i = 0; i < n; ++i) {
211 for (
size_t row = 0; row < n; ++row) {
212 for (
size_t col = 0; col < n; ++col) {
226 for (
size_t j = 0; j < n; ++j) {
gsl_complex gsl_complex_sub(gsl_complex a, gsl_complex b)
Difference .
void gsl_eigen_nonsymmv_free(gsl_eigen_nonsymmv_workspace *w)
Free a workspace allocated by gsl_eigen_nonsymmv_alloc.
int gsl_eigen_nonsymm(gsl_matrix *A, gsl_vector_complex *eval, gsl_eigen_nonsymm_workspace *)
Compute eigenvalues of a real nonsymmetric matrix.
int gsl_eigen_nonsymmv(gsl_matrix *A, gsl_vector_complex *eval, gsl_matrix_complex *evec, gsl_eigen_nonsymmv_workspace *w)
Compute eigenvalues and a simplified set of eigenvectors.
void gsl_eigen_nonsymm_params(int, int, gsl_eigen_nonsymm_workspace *)
Accept GSL-style parameters (no-op in this implementation).
gsl_eigen_nonsymm_workspace * gsl_eigen_nonsymm_alloc(size_t n)
Allocate a nonsymmetric eigenvalue workspace for matrices.
void gsl_eigen_nonsymm_free(gsl_eigen_nonsymm_workspace *w)
Free a workspace allocated by gsl_eigen_nonsymm_alloc.
gsl_eigen_nonsymmv_workspace * gsl_eigen_nonsymmv_alloc(size_t n)
Allocate a nonsymmetric eigenvalue/vector workspace for matrices.
gsl_complex * gsl_vector_complex_ptr(gsl_vector_complex *v, size_t i)
Return pointer to element in a complex vector.
void gsl_matrix_complex_free(gsl_matrix_complex *m)
Free a matrix allocated by gsl_matrix_complex_alloc.
double * gsl_matrix_ptr(gsl_matrix *m, size_t i, size_t j)
Return pointer to element in a real matrix.
gsl_complex * gsl_matrix_complex_ptr(gsl_matrix_complex *m, size_t i, size_t j)
Return pointer to element in a complex matrix.
gsl_matrix_complex * gsl_matrix_complex_alloc(size_t n1, size_t n2)
Allocate a zero-initialized complex matrix of size .
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Complex number stored as .
Workspace for nonsymmetric eigenvalue computation.
gsl_eigen_nonsymm_workspace()
std::vector< double > work
Workspace for nonsymmetric eigenvalues/eigenvectors.
gsl_eigen_nonsymmv_workspace()
std::vector< double > work
Dense complex matrix in row-major storage.
Dense real matrix in row-major storage.
Dense complex vector with stride.