vnl_complex_eigensystem.cxx
Go to the documentation of this file.
1 // This is core/vnl/algo/vnl_complex_eigensystem.cxx
2 #include <iostream>
3 #include <cassert>
5 // \author fsm
6 
7 #include <vnl/vnl_matlab_print.h>
8 #include <vnl/vnl_complexify.h>
9 #include <vnl/algo/vnl_netlib.h> // zgeev_()
10 
11 void vnl_complex_eigensystem::compute(vnl_matrix<std::complex<double> > const & A,
12  bool right,
13  bool left)
14 {
15  A.assert_size(N, N);
16 
17  A.assert_finite();
18  assert(! A.is_zero());
19 
20  if (right)
21  R.set_size(N, N);
22  if (left)
23  L.set_size(N, N);
24 
25  //
26  // Remember that fortran matrices and C matrices are transposed
27  // relative to each other. Moreover, the documentation for zgeev
28  // says that left eigenvectors u satisfy u^h A = lambda u^h,
29  // where ^h denotes adjoint (conjugate transpose).
30  // So we pass our left eigenvector storage as their right
31  // eigenvector storage and vice versa.
32  // But then we also have to conjugate our R after calling the routine.
33  //
35 
36  long work_space=10*N;
37  vnl_vector<std::complex<double> > work(work_space);
38 
39  long rwork_space=2*N;
40  vnl_vector<double> rwork(rwork_space);
41 
42  long info;
43  long tmpN = N;
44  v3p_netlib_zgeev_(
45  right ? "V" : "N", // jobvl
46  left ? "V" : "N", // jobvr
47  &tmpN, // n
48  tmp.data_block(), // a
49  &tmpN, // lda
50  W.data_block(), // w
51  right ? R.data_block() : nullptr, // vl
52  &tmpN, // ldvl
53  left ? L.data_block() : nullptr, // vr
54  &tmpN, // ldvr
55  work.data_block(), // work
56  &work_space, // lwork
57  rwork.data_block(), // rwork
58  &info, // info
59  1, 1);
60  assert(tmpN == int(N));
61 
62  if (right) {
63  // conjugate all elements of R :
64  for (unsigned int i=0;i<N;i++)
65  for (unsigned int j=0;j<N;j++)
66  R(i,j) = std::conj( R(i,j) );
67  }
68 
69  if (info == 0) {
70  // success
71  }
72  else if (info < 0) {
73  std::cerr << __FILE__ ": info = " << info << std::endl
74  << __FILE__ ": " << (-info) << "th argument has illegal value\n";
75  assert(false);
76  }
77  else /* if (info > 0) */ {
78  std::cerr << __FILE__ ": info = " << info << std::endl
79  << __FILE__ ": QR algorithm failed to compute all eigenvalues.\n";
81  assert(false);
82  }
83 }
84 
85 //--------------------------------------------------------------------------------
86 
87 //
89  bool right,
90  bool left)
91  : N(A.rows())
92  // L and R are intentionally not initialized.
93  , W(N)
94 {
95  compute(A, right, left);
96 }
97 
98 //
100  vnl_matrix<double> const &A_imag,
101  bool right,
102  bool left)
103  : N(A_real.rows())
104  // L and R are intentionally not initialized.
105  , W(N)
106 {
107  A_real.assert_size(N,N);
108  A_imag.assert_size(N,N);
109 
111  vnl_complexify(A_real.begin(), A_imag.begin(), A.begin(), A.size());
112 
113  compute(A, right, left);
114 }
vnl_complex_eigensystem(vnl_matrix< double > const &A_real, vnl_matrix< double > const &A_imag, bool right=true, bool left=false)
Print matrices and vectors in nice MATLAB format.
Functions to create complex vectors and matrices from real ones.
vnl_matrix< std::complex< double > > R
void compute(vnl_matrix< std::complex< double > > const &, bool, bool)
T const * data_block() const
Access the contiguous block storing the elements in the vector. O(1).
Definition: vnl_vector.h:230
iterator begin()
Iterator pointing to start of data.
Definition: vnl_matrix.h:620
vnl_matrix< std::complex< double > > L
Calculates eigenvalues and eigenvectors of a square complex matrix.
VNL_EXPORT std::ostream & vnl_matlab_print(std::ostream &, T const *array, unsigned length, vnl_matlab_print_format=vnl_matlab_print_format_default)
print a 1D array.
An ordinary mathematical matrix.
Definition: vnl_adjugate.h:22
Declare in a central place the list of symbols from netlib.
void assert_size(unsigned VXL_USED_IN_DEBUG(r), unsigned VXL_USED_IN_DEBUG(c)) const
abort if size is not as expected.
Definition: vnl_matrix.h:574
Mathematical vector class, templated by type of element.
Definition: vnl_fwd.h:16
T const * data_block() const
Access the contiguous block storing the elements in the matrix row-wise. O(1).
Definition: vnl_matrix.h:601
void vnl_complexify(T const *src, std::complex< T > *dst, unsigned n)
Overwrite complex array C (sz n) with complexified version of real array R.
unsigned int size() const
Return the total number of elements stored by the matrix.
Definition: vnl_matrix.h:176
bool set_size(unsigned r, unsigned c)
Resize to r rows by c columns. Old data lost.
Definition: vnl_matrix.hxx:390
vnl_vector< std::complex< double > > W