22 double Stop_cond = DBL_EPSILON;
24 std::valarray<double> eigen_val(
N2);
26 for (
int i = 0; i <
size; ++i) {
30 for (
int i = 0; i <
N; ++i) {
31 m_q[i *
N2 + i * 2] = 1;
42 for (
int i_iter = 0; i_iter < Niter; ++i_iter) {
49 double d_re =
m_mat[
re(r1, r1)];
50 double d_im =
m_mat[
im(r1, r1)];
54 eigen_val[
re(0)] = d_re;
55 eigen_val[
im(0)] = d_im;
60 double a_re =
m_mat[
re(r2, r2)];
61 double a_im =
m_mat[
im(r2, r2)];
62 double& c_re =
m_mat[
re(r1, r2)];
63 double& c_im =
m_mat[
im(r1, r2)];
65 double norm_ad = a_re * a_re + a_im * a_im + d_re * d_re + d_im * d_im;
66 double norm_c = c_re * c_re + c_im * c_im;
68 if (norm_c < norm_ad * Stop_cond * Stop_cond) {
70 eigen_val[
re(r1)] = d_re;
71 eigen_val[
im(r1)] = d_im;
79 for (
int r = 0; r < Neigen; ++r) {
88 for (
int r = 0; r < Neigen; ++r) {
101 std::valarray<double> tau(rank * 2);
103 for (
int r = 0; r < rank - 1; ++r) {
105 double& alpha_re =
m_mat[
re(r, r)];
106 double& alpha_im =
m_mat[
im(r, r)];
108 double& v1_re =
m_mat[
re(r + 1, r)];
109 double& v1_im =
m_mat[
im(r + 1, r)];
111 double nu = alpha_re * alpha_re + alpha_im * alpha_im + v1_re * v1_re + v1_im * v1_im;
113 nu = std::sqrt(nu) * ((alpha_re < 0) ? -1 : 1);
114 tau[
re(r)] = alpha_re + nu;
115 tau[
im(r)] = alpha_im;
117 double norm2_sigma = tau[
re(r)] * tau[
re(r)] + tau[
im(r)] * tau[
im(r)];
118 double inv_sigma_re = tau[
re(r)] / norm2_sigma;
119 double inv_sigma_im = -tau[
im(r)] / norm2_sigma;
131 v1_re = v_re * inv_sigma_re - v_im * inv_sigma_im;
132 v1_im = v_im * inv_sigma_re + v_re * inv_sigma_im;
135 for (
int j = r + 1; j <
N; ++j) {
137 double va_re =
m_mat[
re(r, j)];
138 double va_im =
m_mat[
im(r, j)];
139 va_re += v1_re *
m_mat[
re(r + 1, j)] + v1_im *
m_mat[
im(r + 1, j)];
140 va_im += v1_re * m_mat[
im(r + 1, j)] - v1_im * m_mat[
re(r + 1, j)];
142 double beta_re = tau[
re(r)] * va_re + tau[
im(r)] * va_im;
143 double beta_im = tau[
re(r)] * va_im - tau[
im(r)] * va_re;
145 m_mat[
re(r, j)] -= beta_re;
146 m_mat[
im(r, j)] -= beta_im;
148 m_mat[
re(r + 1, j)] -= beta_re * v1_re - beta_im * v1_im;
149 m_mat[
im(r + 1, j)] -= beta_re * v1_im + beta_im * v1_re;
153 for (
int i = 0; i <
N; ++i) {
155 double va_re =
m_q[
re(i, r)];
156 double va_im = -
m_q[
im(i, r)];
157 va_re += v1_re *
m_q[
re(i, r + 1)] - v1_im *
m_q[
im(i, r + 1)];
158 va_im -= v1_re * m_q[
im(i, r + 1)] + v1_im * m_q[
re(i, r + 1)];
160 double beta_re = tau[
re(r)] * va_re + tau[
im(r)] * va_im;
161 double beta_im = tau[
re(r)] * va_im - tau[
im(r)] * va_re;
163 m_q[
re(i, r)] -= beta_re;
164 m_q[
im(i, r)] += beta_im;
166 m_q[
re(i, r + 1)] -= beta_re * v1_re - beta_im * v1_im;
167 m_q[
im(i, r + 1)] += beta_re * v1_im + beta_im * v1_re;
172 for (
int r = 0; r < rank - 1; ++r) {
173 double v1_re =
m_mat[
re(r + 1, r)];
174 double v1_im =
m_mat[
im(r + 1, r)];
176 for (
int i = 0; i <= r + 1; ++i) {
177 double va_re =
m_mat[
re(i, r)];
178 double va_im = -
m_mat[
im(i, r)];
179 va_re += v1_re *
m_mat[
re(i, r + 1)] - v1_im *
m_mat[
im(i, r + 1)];
180 va_im -= v1_re * m_mat[
im(i, r + 1)] + v1_im * m_mat[
re(i, r + 1)];
184 double beta_re = tau[
re(r)] * va_re + tau[
im(r)] * va_im;
185 double beta_im = tau[
re(r)] * va_im - tau[
im(r)] * va_re;
187 m_mat[
re(i, r)] -= beta_re;
188 m_mat[
im(i, r)] += beta_im;
190 m_mat[
re(i, r + 1)] -= beta_re * v1_re - beta_im * v1_im;
191 m_mat[
im(i, r + 1)] += beta_re * v1_im + beta_im * v1_re;
200 for (
int i = 0; i <
size; ++i) {
209 for (
int i = 0; i <
size; ++i) {
size_t im(const size_t i, const size_t j)
size_t re(const size_t i, const size_t j)
void get_Hessenberg(double *mat)
std::valarray< double > solve(const double *matrix)
void qr_step(const int rank)
std::valarray< double > m_mat
void set_matrix(const double *mat)
std::valarray< double > m_q
static const std::string class_name