source: mmcs/armadillo_bits/fn_eig_pair.hpp @ 8daa049

matrices
Last change on this file since 8daa049 was 9dd61b1, checked in by rboet <rboet@…>, 9 years ago

Avance del proyecto 60%

  • Property mode set to 100644
File size: 5.9 KB
Line 
1// Copyright (C) 2013 Conrad Sanderson
2// Copyright (C) 2013 NICTA (www.nicta.com.au)
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
8
9//! \addtogroup fn_eig_pair
10//! @{
11
12
13//! eigenvalues for pair of N-by-N general real matrices (A,B)
14template<typename T, typename T1>
15inline
16Col< std::complex<T> >
17eig_pair
18  (
19  const Base<T, T1>& A,
20  const Base<T, T1>& B,
21  const typename arma_blas_type_only<T>::result* junk1 = 0,
22  const typename         arma_not_cx<T>::result* junk2 = 0 
23  )
24  {
25  arma_extra_debug_sigprint();
26  arma_ignore(junk1);
27  arma_ignore(junk2);
28 
29  Mat<T> l_eigvec;
30  Mat<T> r_eigvec;
31 
32  Col< std::complex<T> > eigval;
33 
34  const bool status = auxlib::eig_pair(eigval, l_eigvec, r_eigvec, A, B, 'n');
35 
36  if(status == false)
37    {
38    eigval.reset();
39    arma_bad("eig_pair(): failed to converge");
40    }
41 
42  return eigval;
43  }
44
45
46
47//! eigenvalues for pair of N-by-N general complex matrices (A,B)
48template<typename T, typename T1>
49inline
50Col< std::complex<T> >
51eig_pair
52  (
53  const Base< std::complex<T>, T1>& A, 
54  const Base< std::complex<T>, T1>& B, 
55  const typename arma_blas_type_only< std::complex<T> >::result* junk1 = 0,
56  const typename        arma_cx_only< std::complex<T> >::result* junk2 = 0 
57  )
58  {
59  arma_extra_debug_sigprint();
60  arma_ignore(junk1);
61  arma_ignore(junk2);
62 
63  Mat< std::complex<T> > l_eigvec;
64  Mat< std::complex<T> > r_eigvec;
65 
66  Col< std::complex<T> > eigval;
67 
68  const bool status = auxlib::eig_pair(eigval, l_eigvec, r_eigvec, A, B, 'n');
69 
70  if(status == false)
71    {
72    eigval.reset();
73    arma_bad("eig_pair(): failed to converge");
74    }
75 
76  return eigval;
77  }
78
79
80
81//! eigenvalues for pair of N-by-N general real matrices (A,B)
82template<typename eT, typename T1, typename T2>
83inline
84bool
85eig_pair
86  (
87         Col< std::complex<eT> >& eigval, 
88  const Base< eT, T1 >&           A,
89  const Base< eT, T2 >&           B,
90  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
91  )
92  {
93  arma_extra_debug_sigprint();
94  arma_ignore(junk);
95 
96  Mat<eT> l_eigvec;
97  Mat<eT> r_eigvec;
98 
99  const bool status = auxlib::eig_pair(eigval, l_eigvec, r_eigvec, A, B, 'n');
100 
101  if(status == false)
102    {
103    eigval.reset();
104    arma_bad("eig_pair(): failed to converge", false);
105    }
106 
107  return status;
108  }
109
110
111
112//! eigenvalues for pair of N-by-N general complex matrices (A,B)
113template<typename T, typename T1, typename T2>
114inline
115bool
116eig_pair
117  (
118         Col< std::complex<T> >&     eigval, 
119  const Base< std::complex<T>, T1 >& A,
120  const Base< std::complex<T>, T2 >& B,
121  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
122  )
123  {
124  arma_extra_debug_sigprint();
125  arma_ignore(junk);
126 
127  Mat< std::complex<T> > l_eigvec;
128  Mat< std::complex<T> > r_eigvec;
129 
130  const bool status = auxlib::eig_pair(eigval, l_eigvec, r_eigvec, A, B, 'n');
131 
132  if(status == false)
133    {
134    eigval.reset();
135    arma_bad("eig_pair(): failed to converge", false);
136    }
137 
138  return status;
139  }
140
141
142
143//! eigenvalues and eigenvectors for pair of N-by-N general real matrices (A,B)
144template<typename eT, typename T1, typename T2>
145inline
146bool
147eig_pair
148  (
149         Col< std::complex<eT> >& eigval, 
150         Mat< std::complex<eT> >& eigvec,
151  const Base< eT, T1 >&           A,
152  const Base< eT, T2 >&           B,
153  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
154  )
155  {
156  arma_extra_debug_sigprint();
157  arma_ignore(junk);
158 
159  arma_debug_check( ( ((void*)(&eigval)) == ((void*)(&eigvec)) ), "eig_pair(): eigval is an alias of eigvec" );
160 
161  Mat<eT> dummy_eigvec;
162  Mat<eT> tmp_eigvec;
163 
164  const bool status = auxlib::eig_pair(eigval, dummy_eigvec, tmp_eigvec, A, B, 'r');
165 
166  if(status == false)
167    {
168    eigval.reset();
169    eigvec.reset();
170    arma_bad("eig_pair(): failed to converge", false);
171    }
172  else
173    {
174    const uword n = eigval.n_elem;
175   
176    if(n > 0)
177      {
178      eigvec.set_size(n,n);
179     
180      // from LAPACK docs:
181      // If the j-th and (j+1)-th eigenvalues form a complex conjugate pair, then
182      // v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1).
183     
184      for(uword j=0; j<n; ++j)
185        {
186        if( (j < n-1) && (eigval[j] == std::conj(eigval[j+1])) )
187          {
188          // eigvec.col(j)   = Mat< std::complex<eT> >( tmp_eigvec.col(j),  tmp_eigvec.col(j+1) );
189          // eigvec.col(j+1) = Mat< std::complex<eT> >( tmp_eigvec.col(j), -tmp_eigvec.col(j+1) );
190         
191          for(uword i=0; i<n; ++i)
192            {
193            eigvec.at(i,j)   = std::complex<eT>( tmp_eigvec.at(i,j),  tmp_eigvec.at(i,j+1) );
194            eigvec.at(i,j+1) = std::complex<eT>( tmp_eigvec.at(i,j), -tmp_eigvec.at(i,j+1) );
195            }
196         
197          ++j;
198          }
199        else
200          {
201          // eigvec.col(i) = tmp_eigvec.col(i);
202         
203          for(uword i=0; i<n; ++i)
204            {
205            eigvec.at(i,j) = std::complex<eT>(tmp_eigvec.at(i,j), eT(0));
206            }
207          }
208        }
209      }
210    }
211 
212  return status;
213  }
214
215
216
217//! eigenvalues and eigenvectors for pair of N-by-N general complex matrices (A,B)
218template<typename T, typename T1, typename T2>
219inline
220bool
221eig_pair
222  (
223         Col< std::complex<T> >&     eigval, 
224         Mat< std::complex<T> >&     eigvec,
225  const Base< std::complex<T>, T1 >& A,
226  const Base< std::complex<T>, T2 >& B,
227  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
228  )
229  {
230  arma_extra_debug_sigprint();
231  arma_ignore(junk);
232 
233  arma_debug_check( ( ((void*)(&eigval)) == ((void*)(&eigvec)) ), "eig_pair(): eigval is an alias of eigvec" );
234 
235  Mat< std::complex<T> > dummy_eigvec;
236 
237  const bool status = auxlib::eig_pair(eigval, dummy_eigvec, eigvec, A, B, 'r');
238 
239  if(status == false)
240    {
241    eigval.reset();
242    eigvec.reset();
243    arma_bad("eig_pair(): failed to converge", false);
244    }
245 
246  return status;
247  }
248
249
250//! @}
Note: See TracBrowser for help on using the repository browser.