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
41
42
43namespace itpp
44{
45
46#if defined(HAVE_LAPACK)
47
48bool 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
69bool 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
90bool 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
112bool 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
136bool 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
176bool 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
201bool 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
226bool 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
252bool 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
258bool 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
264bool 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
270bool 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
277bool 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
283bool eig(const mat &A, cvec &d)
284{
285 it_error("LAPACK library is needed to use eig() function");
286 return false;
287}
288
289bool 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
295bool 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
303vec eig_sym(const mat &A)
304{
305 vec d;
306 eig_sym(A, d);
307 return d;
308}
309
310vec eig_sym(const cmat &A)
311{
312 vec d;
313 eig_sym(A, d);
314 return d;
315}
316
317
318cvec eig(const mat &A)
319{
320 cvec d;
321 eig(A, d);
322 return d;
323}
324
325cvec eig(const cmat &A)
326{
327 cvec d;
328 eig(A, d);
329 return d;
330}
331
332} //namespace itpp
Definitions of converters between different vector and matrix types.
Definitions of eigenvalue decomposition functions.
#define it_error(s)
Abort unconditionally.
Definition itassert.h:126
#define it_assert_debug(t, s)
Abort if t is not true and NDEBUG is not defined.
Definition itassert.h:107
bool eig(const mat &A, cvec &d, cmat &V)
Calculates the eigenvalues and eigenvectors of a real non-symmetric matrix.
Definition eigen.cpp:277
bool eig_sym(const mat &A, vec &d, mat &V)
Calculates the eigenvalues and eigenvectors of a symmetric real matrix.
Definition eigen.cpp:252
itpp namespace
Definition itmex.h:37
cvec to_cvec(const Vec< T > &v)
Converts a Vec<T> to cvec.
Definition converters.h:107
SourceForge Logo

Generated on Tue Dec 10 2024 04:49:37 for IT++ by Doxygen 1.12.0