IT++ Logo
eigen.cpp
Go to the documentation of this file.
1 
29 #ifndef _MSC_VER
30 # include <itpp/config.h>
31 #else
32 # include <itpp/config_msvc.h>
33 #endif
34 
35 #if defined(HAVE_LAPACK)
36 # include <itpp/base/algebra/lapack.h>
37 #endif
38 
40 #include <itpp/base/converters.h>
41 
42 
43 namespace itpp
44 {
45 
46 #if defined(HAVE_LAPACK)
47 
48 bool eig_sym(const mat &A, vec &d, mat &V)
49 {
50  it_assert_debug(A.rows() == A.cols(), "eig_sym: Matrix is not symmetric");
51 
52  // Test for symmetric?
53 
54  char jobz = 'V', uplo = 'U';
55  int n, lda, lwork, info;
56  n = lda = A.rows();
57  lwork = std::max(1, 3 * n - 1); // This may be choosen better!
58 
59  d.set_size(n, false);
60  vec work(lwork);
61 
62  V = A; // The routine overwrites input matrix with eigenvectors
63 
64  dsyev_(&jobz, &uplo, &n, V._data(), &lda, d._data(), work._data(), &lwork, &info);
65 
66  return (info == 0);
67 }
68 
69 bool eig_sym(const mat &A, vec &d)
70 {
71  it_assert_debug(A.rows() == A.cols(), "eig_sym: Matrix is not symmetric");
72 
73  // Test for symmetric?
74 
75  char jobz = 'N', uplo = 'U';
76  int n, lda, lwork, info;
77  n = lda = A.rows();
78  lwork = std::max(1, 3 * n - 1); // This may be choosen better!
79 
80  d.set_size(n, false);
81  vec work(lwork);
82 
83  mat B(A); // The routine overwrites input matrix
84 
85  dsyev_(&jobz, &uplo, &n, B._data(), &lda, d._data(), work._data(), &lwork, &info);
86 
87  return (info == 0);
88 }
89 
90 bool eig_sym(const cmat &A, vec &d, cmat &V)
91 {
92  it_assert_debug(A.rows() == A.cols(), "eig_sym: Matrix is not hermitian");
93 
94  // Test for symmetric?
95 
96  char jobz = 'V', uplo = 'U';
97  int n, lda, lwork, info;
98  n = lda = A.rows();
99  lwork = std::max(1, 2 * n - 1); // This may be choosen better!
100 
101  d.set_size(n, false);
102  cvec work(lwork);
103  vec rwork(std::max(1, 3*n - 2)); // This may be choosen better!
104 
105  V = A; // The routine overwrites input matrix with eigenvectors
106 
107  zheev_(&jobz, &uplo, &n, V._data(), &lda, d._data(), work._data(), &lwork, rwork._data(), &info);
108 
109  return (info == 0);
110 }
111 
112 bool eig_sym(const cmat &A, vec &d)
113 {
114  it_assert_debug(A.rows() == A.cols(), "eig_sym: Matrix is not hermitian");
115 
116  // Test for symmetric?
117 
118  char jobz = 'N', uplo = 'U';
119  int n, lda, lwork, info;
120  n = lda = A.rows();
121  lwork = std::max(1, 2 * n - 1); // This may be choosen better!
122 
123  d.set_size(n, false);
124  cvec work(lwork);
125  vec rwork(std::max(1, 3*n - 2)); // This may be choosen better!
126 
127  cmat B(A); // The routine overwrites input matrix
128 
129  zheev_(&jobz, &uplo, &n, B._data(), &lda, d._data(), work._data(), &lwork, rwork._data(), &info);
130 
131  return (info == 0);
132 }
133 
134 
135 // Non-symmetric matrix
136 bool eig(const mat &A, cvec &d, cmat &V)
137 {
138  it_assert_debug(A.rows() == A.cols(), "eig: Matrix is not square");
139 
140  char jobvl = 'N', jobvr = 'V';
141  int n, lda, ldvl, ldvr, lwork, info;
142  n = lda = A.rows();
143  ldvl = 1;
144  ldvr = n;
145  lwork = std::max(1, 4 * n); // This may be choosen better!
146 
147  vec work(lwork);
148  vec rwork(std::max(1, 2*n)); // This may be choosen better
149  vec wr(n), wi(n);
150  mat vl, vr(n, n);
151 
152  mat B(A); // The routine overwrites input matrix
153 
154  dgeev_(&jobvl, &jobvr, &n, B._data(), &lda, wr._data(), wi._data(), vl._data(), &ldvl, vr._data(), &ldvr, work._data(), &lwork, &info);
155 
156  d = to_cvec(wr, wi);
157 
158  // Fix V
159  V.set_size(n, n, false);
160  for (int j = 0; j < n; j++) {
161  // if d(j) and d(j+1) are complex conjugate pairs, treat special
162  if ((j < n - 1) && d(j) == std::conj(d(j + 1))) {
163  V.set_col(j, to_cvec(vr.get_col(j), vr.get_col(j + 1)));
164  V.set_col(j + 1, to_cvec(vr.get_col(j), -vr.get_col(j + 1)));
165  j++;
166  }
167  else {
168  V.set_col(j, to_cvec(vr.get_col(j)));
169  }
170  }
171 
172  return (info == 0);
173 }
174 
175 // Non-symmetric matrix
176 bool eig(const mat &A, cvec &d)
177 {
178  it_assert_debug(A.rows() == A.cols(), "eig: Matrix is not square");
179 
180  char jobvl = 'N', jobvr = 'N';
181  int n, lda, ldvl, ldvr, lwork, info;
182  n = lda = A.rows();
183  ldvl = 1;
184  ldvr = 1;
185  lwork = std::max(1, 4 * n); // This may be choosen better!
186 
187  vec work(lwork);
188  vec rwork(std::max(1, 2*n)); // This may be choosen better
189  vec wr(n), wi(n);
190  mat vl, vr;
191 
192  mat B(A); // The routine overwrites input matrix
193 
194  dgeev_(&jobvl, &jobvr, &n, B._data(), &lda, wr._data(), wi._data(), vl._data(), &ldvl, vr._data(), &ldvr, work._data(), &lwork, &info);
195 
196  d = to_cvec(wr, wi);
197 
198  return (info == 0);
199 }
200 
201 bool eig(const cmat &A, cvec &d, cmat &V)
202 {
203  it_assert_debug(A.rows() == A.cols(), "eig: Matrix is not square");
204 
205  char jobvl = 'N', jobvr = 'V';
206  int n, lda, ldvl, ldvr, lwork, info;
207  n = lda = A.rows();
208  ldvl = 1;
209  ldvr = n;
210  lwork = std::max(1, 2 * n); // This may be choosen better!
211 
212  d.set_size(n, false);
213  V.set_size(n, n, false);
214  cvec work(lwork);
215  vec rwork(std::max(1, 2*n)); // This may be choosen better!
216  cmat vl;
217 
218  cmat B(A); // The routine overwrites input matrix
219 
220  zgeev_(&jobvl, &jobvr, &n, B._data(), &lda, d._data(), vl._data(), &ldvl, V._data(), &ldvr, work._data(), &lwork, rwork._data(), &info);
221 
222 
223  return (info == 0);
224 }
225 
226 bool eig(const cmat &A, cvec &d)
227 {
228  it_assert_debug(A.rows() == A.cols(), "eig: Matrix is not square");
229 
230  char jobvl = 'N', jobvr = 'N';
231  int n, lda, ldvl, ldvr, lwork, info;
232  n = lda = A.rows();
233  ldvl = 1;
234  ldvr = 1;
235  lwork = std::max(1, 2 * n); // This may be choosen better!
236 
237  d.set_size(n, false);
238  cvec work(lwork);
239  vec rwork(std::max(1, 2*n)); // This may be choosen better!
240  cmat vl, vr;
241 
242  cmat B(A); // The routine overwrites input matrix
243 
244  zgeev_(&jobvl, &jobvr, &n, B._data(), &lda, d._data(), vl._data(), &ldvl, vr._data(), &ldvr, work._data(), &lwork, rwork._data(), &info);
245 
246 
247  return (info == 0);
248 }
249 
250 #else
251 
252 bool eig_sym(const mat &A, vec &d, mat &V)
253 {
254  it_error("LAPACK library is needed to use eig_sym() function");
255  return false;
256 }
257 
258 bool eig_sym(const mat &A, vec &d)
259 {
260  it_error("LAPACK library is needed to use eig_sym() function");
261  return false;
262 }
263 
264 bool eig_sym(const cmat &A, vec &d, cmat &V)
265 {
266  it_error("LAPACK library is needed to use eig_sym() function");
267  return false;
268 }
269 
270 bool eig_sym(const cmat &A, vec &d)
271 {
272  it_error("LAPACK library is needed to use eig_sym() function");
273  return false;
274 }
275 
276 
277 bool eig(const mat &A, cvec &d, cmat &V)
278 {
279  it_error("LAPACK library is needed to use eig() function");
280  return false;
281 }
282 
283 bool eig(const mat &A, cvec &d)
284 {
285  it_error("LAPACK library is needed to use eig() function");
286  return false;
287 }
288 
289 bool eig(const cmat &A, cvec &d, cmat &V)
290 {
291  it_error("LAPACK library is needed to use eig() function");
292  return false;
293 }
294 
295 bool eig(const cmat &A, cvec &d)
296 {
297  it_error("LAPACK library is needed to use eig() function");
298  return false;
299 }
300 
301 #endif // HAVE_LAPACK
302 
303 vec eig_sym(const mat &A)
304 {
305  vec d;
306  eig_sym(A, d);
307  return d;
308 }
309 
310 vec eig_sym(const cmat &A)
311 {
312  vec d;
313  eig_sym(A, d);
314  return d;
315 }
316 
317 
318 cvec eig(const mat &A)
319 {
320  cvec d;
321  eig(A, d);
322  return d;
323 }
324 
325 cvec eig(const cmat &A)
326 {
327  cvec d;
328  eig(A, d);
329  return d;
330 }
331 
332 } //namespace itpp
SourceForge Logo

Generated on Sat May 25 2013 16:32:18 for IT++ by Doxygen 1.8.2