Bridge++  Version 1.5.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
decompose_LU_Cmplx.cpp
Go to the documentation of this file.
1 
14 #include "decompose_LU_Cmplx.h"
15 
16 //====================================================================
17 void Decompose_LU_Cmplx::set_matrix(const double *mat)
18 {
19  for (int i = 0; i < size; ++i) {
20  m_lu[i] = mat[i];
21  }
22 
23  // double epsilon = DBL_EPSILON;
24  for (int r = 0; r < N - 1; ++r) {
25  double norm_rr = m_lu[re(r, r)] * m_lu[re(r, r)] + m_lu[im(r, r)] * m_lu[im(r, r)];
26 
27  double inv_rr_re = m_lu[re(r, r)] / norm_rr;
28  double inv_rr_im = -m_lu[im(r, r)] / norm_rr;
29  // a_{ir} /= a_{rr}
30  // a_{ij} -= a_{ir} a_{rj} (j > r)
31  for (int i = r + 1; i < N; ++i) {
32  double ir_re = m_lu[re(i, r)];
33  double ir_im = m_lu[im(i, r)];
34  m_lu[re(i, r)] = ir_re * inv_rr_re - ir_im * inv_rr_im;
35  m_lu[im(i, r)] = ir_re * inv_rr_im + ir_im * inv_rr_re;
36  ir_re = m_lu[re(i, r)];
37  ir_im = m_lu[im(i, r)];
38 
39  for (int j = r + 1; j < N; ++j) {
40  double& rj_re = m_lu[re(r, j)];
41  double& rj_im = m_lu[im(r, j)];
42  m_lu[re(i, j)] -= ir_re * rj_re - ir_im * rj_im;
43  m_lu[im(i, j)] -= ir_re * rj_im + ir_im * rj_re;
44  }
45  }
46  }
47 }
48 
49 
50 //====================================================================
51 void Decompose_LU_Cmplx::solve(double *vec)
52 {
53  // Forward substitution
54  for (int i = 0; i < N; ++i) {
55  for (int j = 0; j < i; ++j) {
56  vec[re(i)] -= m_lu[re(i, j)] * vec[re(j)] - m_lu[im(i, j)] * vec[im(j)];
57  vec[im(i)] -= m_lu[re(i, j)] * vec[im(j)] + m_lu[im(i, j)] * vec[re(j)];
58  }
59  }
60  // Back substitution
61  for (int i = N - 1; i >= 0; --i) {
62  for (int j = i + 1; j < N; ++j) {
63  vec[re(i)] -= m_lu[re(i, j)] * vec[re(j)] - m_lu[im(i, j)] * vec[im(j)];
64  vec[im(i)] -= m_lu[re(i, j)] * vec[im(j)] + m_lu[im(i, j)] * vec[re(j)];
65  }
66  double inv_norm = 1 / (m_lu[re(i, i)] * m_lu[re(i, i)] + m_lu[im(i, i)] * m_lu[im(i, i)]);
67  double real = vec[re(i)];
68  double imag = vec[im(i)];
69 
70  vec[re(i)] = (real * m_lu[re(i, i)] + imag * m_lu[im(i, i)]) * inv_norm;
71  vec[im(i)] = (imag * m_lu[re(i, i)] - real * m_lu[im(i, i)]) * inv_norm;
72  }
73 }
74 
75 
76 //====================================================================
78 {
79  for (int i = 0; i < size; ++i) {
80  mat[i] = 0;
81  }
82  for (int i = 0; i < N; ++i) {
83  mat[re(i, i)] = 1;
84  }
85 
86  mult_inverse(mat);
87 }
88 
89 
90 //====================================================================
92 {
93  // Forward substitution
94  for (int i = 0; i < N; ++i) {
95  for (int r = 0; r < i; ++r) {
96  double& luir_re = m_lu[re(i, r)];
97  double& luir_im = m_lu[im(i, r)];
98  for (int j = 0; j < N; ++j) {
99  mat[re(i, j)] -= luir_re * mat[re(r, j)] - luir_im * mat[im(r, j)];
100  mat[im(i, j)] -= luir_re * mat[im(r, j)] + luir_im * mat[re(r, j)];
101  }
102  }
103  }
104 
105  // Back substitution
106  for (int i = N - 1; i >= 0; --i) {
107  for (int r = i + 1; r < N; ++r) {
108  double& luir_re = m_lu[re(i, r)];
109  double& luir_im = m_lu[im(i, r)];
110  for (int j = 0; j < N; ++j) {
111  mat[re(i, j)] -= luir_re * mat[re(r, j)] - luir_im * mat[im(r, j)];
112  mat[im(i, j)] -= luir_re * mat[im(r, j)] + luir_im * mat[re(r, j)];
113  }
114  }
115  for (int j = 0; j < N; ++j) {
116  double inv = 1 / (m_lu[re(i, i)] * m_lu[re(i, i)] + m_lu[im(i, i)] * m_lu[im(i, i)]);
117  double real = mat[re(i, j)];
118  double imag = mat[im(i, j)];
119 
120  mat[re(i, j)] = (real * m_lu[re(i, i)] + imag * m_lu[im(i, i)]) * inv;
121  mat[im(i, j)] = (imag * m_lu[re(i, i)] - real * m_lu[im(i, i)]) * inv;
122  }
123  }
124 }
125 
126 
127 //====================================================================
129 {
130  double real = 1;
131  double imag = 0;
132 
133  for (int i = 0; i < N; ++i) {
134  double old_re = real;
135  double old_im = imag;
136  real = old_re * m_lu[re(i, i)] - old_im * m_lu[im(i, i)];
137  imag = old_re * m_lu[im(i, i)] + old_im * m_lu[re(i, i)];
138  }
139 
140  return cmplx(real, imag);
141 }
142 
143 
144 //====================================================================
145 
146 /*
147 void Decompose_LU_Cmplx::copy_LU(double* l, double* u)
148 {
149  for (int i = 0; i < N; ++i) {
150  for (int j = 0; j < i; ++j) {
151  l[re(i,j)] = m_lu[re(i,j)];
152  l[im(i,j)] = m_lu[im(i,j)];
153  u[re(i,j)] = 0;
154  u[im(i,j)] = 0;
155  }
156  l[re(i,i)] = 1;
157  l[im(i,i)] = 0;
158  u[re(i,i)] = m_lu[re(i,i)];
159  u[im(i,i)] = m_lu[im(i,i)];
160  for (int j = i+1; j < N; ++j) {
161  l[re(i,j)] = 0;
162  l[im(i,j)] = 0;
163  u[re(i,j)] = m_lu[re(i,j)];
164  u[im(i,j)] = m_lu[im(i,j)];
165  }
166  }
167 
168 }
169 */
170 
171 //====================================================================
void mult_inverse(double *mat)
std::valarray< double > m_lu
void solve(double *vec)
void get_inverse(double *mat_inv)
size_t im(int i, int j)
void set_matrix(const double *mat)
size_t re(int i, int j)