Bridge++  Version 1.5.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
decompose_Hessenberg_Cmplx.cpp
Go to the documentation of this file.
1 
15 
16 //====================================================================
18 {
19  // double epsilon = DBL_EPSILON;
20 
21  // matrix copy
22  for (int i = 0; i < size; ++i) {
23  m_H[i] = mat[i];
24  }
25 
26  // Householder trans for r col.
27  for (int r = 0; r < N - 1; ++r) {
28  // sub diagnal part
29  double& alpha_re = m_H[re(r + 1, r)];
30  double& alpha_im = m_H[im(r + 1, r)];
31 
32  // make Householder vector v and factor tau.
33  // H = I - tau vv^\dag
34  // H^\dag x = (beta, 0, ...)^T
35  // nu = |x| sign(Re(x_1))
36 
37  // tau = sigma / nu
38  // beta = - nu
39  // Re(sigma) = Re(x_1) + nu
40  // Im(sigma) = Im(x_1)
41  // v = (1, x_2/sigma, ..., x_n/sigma);
42 
43 
44  double nu = 0;
45  for (int i = r + 1; i < N; ++i) {
46  nu += m_H[re(i, r)] * m_H[re(i, r)] + m_H[im(i, r)] * m_H[im(i, r)];
47  }
48 
49  /*
50  if (nu < epsilon) {
51  // assertion?
52  }
53  */
54 
55  nu = std::sqrt(nu) * ((alpha_re < 0) ? -1 : 1);
56  m_tau[re(r)] = alpha_re + nu;
57  m_tau[im(r)] = alpha_im;
58 
59  double norm2_sigma = m_tau[re(r)] * m_tau[re(r)] + m_tau[im(r)] * m_tau[im(r)];
60  double inv_sigma_re = m_tau[re(r)] / norm2_sigma;
61  double inv_sigma_im = -m_tau[im(r)] / norm2_sigma;
62 
63  m_tau[re(r)] /= nu;
64  m_tau[im(r)] /= nu;
65 
66  // m_H[r+1,r] = -nu
67  // m_H[i,r] /= sigma
68  alpha_re = -nu;
69  alpha_im = 0;
70  for (int i = r + 2; i < N; ++i) {
71  double ir_re = m_H[re(i, r)];
72  double ir_im = m_H[im(i, r)];
73 
74  m_H[re(i, r)] = ir_re * inv_sigma_re - ir_im * inv_sigma_im;
75  m_H[im(i, r)] = ir_im * inv_sigma_re + ir_re * inv_sigma_im;
76  }
77 
78  // H^\dag a_j
79  for (int j = r + 1; j < N; ++j) {
80  // va = <v|a_j>
81  double va_re = m_H[re(r + 1, j)];
82  double va_im = m_H[im(r + 1, j)];
83  for (int i = r + 2; i < N; ++i) {
84  va_re += m_H[re(i, r)] * m_H[re(i, j)] + m_H[im(i, r)] * m_H[im(i, j)];
85  va_im += m_H[re(i, r)] * m_H[im(i, j)] - m_H[im(i, r)] * m_H[re(i, j)];
86  }
87  // beta = tau^* * va
88  // a_j -= bata * v
89  double beta_re = m_tau[re(r)] * va_re + m_tau[im(r)] * va_im;
90  double beta_im = m_tau[re(r)] * va_im - m_tau[im(r)] * va_re;
91  m_H[re(r + 1, j)] -= beta_re;
92  m_H[im(r + 1, j)] -= beta_im;
93  for (int i = r + 2; i < N; ++i) {
94  double vi_re = m_H[re(i, r)];
95  double vi_im = m_H[im(i, r)];
96 
97  m_H[re(i, j)] -= beta_re * vi_re - beta_im * vi_im;
98  m_H[im(i, j)] -= beta_re * vi_im + beta_im * vi_re;
99  }
100  }
101  // AH = (H^\dag A^\dag)^\dag
102  // A = (a_0, ...,a_{n-1})^T
103  for (int i = 0; i < N; ++i) {
104  // va = <v|a_i^*> v=H.col(r)
105  double va_re = m_H[re(i, r + 1)];
106  double va_im = -m_H[im(i, r + 1)];
107  for (int j = r + 2; j < N; ++j) {
108  va_re += m_H[re(j, r)] * m_H[re(i, j)] - m_H[im(j, r)] * m_H[im(i, j)];
109  va_im -= m_H[re(j, r)] * m_H[im(i, j)] + m_H[im(j, r)] * m_H[re(i, j)];
110  }
111  // beta = tau^* * va
112  // a_i^* -= bata * v
113  double beta_re = m_tau[re(r)] * va_re + m_tau[im(r)] * va_im;
114  double beta_im = m_tau[re(r)] * va_im - m_tau[im(r)] * va_re;
115  m_H[re(i, r + 1)] -= beta_re;
116  m_H[im(i, r + 1)] += beta_im;
117  for (int j = r + 2; j < N; ++j) {
118  double vj_re = m_H[re(j, r)];
119  double vj_im = m_H[im(j, r)];
120 
121  m_H[re(i, j)] -= beta_re * vj_re - beta_im * vj_im;
122  m_H[im(i, j)] += beta_re * vj_im + beta_im * vj_re;
123  }
124  }
125  }
126 }
127 
128 
129 //====================================================================
131 {
132  for (int i = 0; i < size; ++i) {
133  mat[i] = m_H[i];
134  }
135  for (int i = 0; i < N; ++i) {
136  for (int j = 0; j < i - 1; ++j) {
137  mat[re(i, j)] = mat[im(i, j)] = 0;
138  }
139  }
140 }
141 
142 
143 //====================================================================
145 {
146  for (int i = 0; i < size; ++i) {
147  mat[i] = 0;
148  }
149  for (int i = 0; i < N; ++i) {
150  mat[re(i, i)] = 1;
151  }
152 
153  mult_Q(mat);
154 }
155 
156 
157 //====================================================================
159 {
160  for (int r = N - 2; r >= 0; --r) {
161  for (int j = 0; j < N; ++j) {
162  // vm = <v|m_j>
163  double vm_re = mat[re(r + 1, j)];
164  double vm_im = mat[im(r + 1, j)];
165  for (int i = r + 2; i < N; ++i) {
166  vm_re += m_H[re(i, r)] * mat[re(i, j)] + m_H[im(i, r)] * mat[im(i, j)];
167  vm_im += m_H[re(i, r)] * mat[im(i, j)] - m_H[im(i, r)] * mat[re(i, j)];
168  }
169  // beta = tau * va
170  // m_j -= beta * v
171  double beta_re = m_tau[re(r)] * vm_re - m_tau[im(r)] * vm_im;
172  double beta_im = m_tau[re(r)] * vm_im + m_tau[im(r)] * vm_re;
173  mat[re(r + 1, j)] -= beta_re;
174  mat[im(r + 1, j)] -= beta_im;
175  for (int i = r + 2; i < N; ++i) {
176  double vi_re = m_H[re(i, r)];
177  double vi_im = m_H[im(i, r)];
178  mat[re(i, j)] -= beta_re * vi_re - beta_im * vi_im;
179  mat[im(i, j)] -= beta_re * vi_im + beta_im * vi_re;
180  }
181  }
182  }
183 }
184 
185 
186 //====================================================================
size_t re(const size_t i, const size_t j)
size_t im(const size_t i, const size_t j)