ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dveigenv.cpp
Go to the documentation of this file.
1 
10 #define EIGEN_VECTORS
11 
12 #include <fvar.hpp>
13 #ifndef OPT_LIB
14  #include <cassert>
15  #include <climits>
16 #endif
17 
18 #ifdef ISZERO
19  #undef ISZERO
20 #endif
21 #define ISZERO(d) ((d)==0.0)
22 
23 #ifdef EIGEN_VECTORS
24  void tri_dagv(const dvar_matrix& ,const dvar_vector& , const dvar_vector& );
25 #else
26  void tri_dag(const dvar_matrix& m,const dvar_vector& d,const dvar_vector& e);
27 #endif
28 #ifdef EIGEN_VECTORS
29  void get_eigenv(const dvar_vector& d, const dvar_vector& e,
30  const dvar_matrix& z);
31 #else
32  void get_eigen(const dvar_vector& d, const dvar_vector& e,
33  const dvar_matrix& z);
34 #endif
35 
43 {
44  if (m.rowsize()!=m.colsize())
45  {
46  cerr << "Error -- non square matrix passed to "
47  "dvector eigen(const dmatrix& m)\n";
48  ad_exit(1);
49  }
50 
51  dvar_matrix m1=symmetrize(m);
52 #if !defined(OPT_LIB) && (__cplusplus >= 201103L)
53  int n = [](unsigned int rowsize) -> int
54  {
55  assert(rowsize <= INT_MAX);
56  return static_cast<int>(rowsize);
57  } (m1.rowsize());
58 #else
59  int n = static_cast<int>(m1.rowsize());
60 #endif
61  m1.colshift(1); // set minimum column and row indices to 1
62  m1.rowshift(1);
63  dvar_vector diag(1,n);
64  dvar_vector off_diag(1,n);
65 
66  #ifdef EIGEN_VECTORS
67  tri_dagv(m1,diag,off_diag);
68  #else
69  tri_dag(m1,diag,off_diag);
70  #endif
71 
72  #ifdef EIGEN_VECTORS
73  get_eigenv(diag,off_diag,m1); // eigenvalues are returned in diag
74  #else
75  get_eigen(diag,off_diag,m1); // eigenvalues are returned in diag
76  #endif
77  // eigenvalues are returned in columns of z
78  return m1;
79 }
80 
92 #ifdef EIGEN_VECTORS
93 void tri_dagv(const dvar_matrix& _m,const dvar_vector& _d,
94  const dvar_vector& _e)
95 #else
96 void tri_dagv(const dvar_matrix& _m,const dvar_vector& _d,
97  const dvar_vector& _e)
98 #endif
99 {
102  dvar_matrix& m=(dvar_matrix&) _m;
103  if (m.rowsize() != m.colsize())
104  {
105  cerr << "Error -- non square matrix passed to "
106  "void tridag(const dvar_matrix& m)\n";
107  ad_exit(1);
108  }
109  if (m.rowsize() != d.size() || m.rowsize() != e.size()
110  || d.indexmin() != 1 || e.indexmin() !=1 )
111  {
112  cerr <<"Error -- incorrect vector size passed to "
113  "void tridag(const dmatrix& m)\n";
114  ad_exit(1);
115  }
116 #if !defined(OPT_LIB) && (__cplusplus >= 201103L)
117  int n = [](unsigned int rowsize) -> int
118  {
119  assert(rowsize <= INT_MAX);
120  return static_cast<int>(rowsize);
121  } (m.rowsize());
122 #else
123  int n = static_cast<int>(m.rowsize());
124 #endif
125  int l,k,j,i;
126  dvariable scale,hh,h,g,f;
127 
128  for (i=n;i>=2;i--)
129  {
130  l=i-1;
131  h=scale=0.0;
132  if (l > 1)
133  {
134  for (k=1;k<=l;k++)
135  scale += fabs(m[i][k]);
136  if (scale == 0.0)
137  e[i]=m[i][l];
138  else
139  {
140  for (k=1;k<=l;k++)
141  {
142  m[i][k] /= scale;
143  h += m[i][k]*m[i][k];
144  }
145  f=m[i][l];
146  g = f>0. ? -sqrt(h) : sqrt(h);
147  e[i]=scale*g;
148  h -= f*g;
149  m[i][l]=f-g;
150  f=0.0;
151  for (j=1;j<=l;j++)
152  {
153  #ifdef EIGEN_VECTORS
154  /* Next statement can be omitted if eigenvectors not wanted */
155  m[j][i]=m[i][j]/h;
156  #endif
157  g=0.0;
158  for (k=1;k<=j;k++)
159  g += m[j][k]*m[i][k];
160  for (k=j+1;k<=l;k++)
161  g += m[k][j]*m[i][k];
162  e[j]=g/h;
163  f += e[j]*m[i][j];
164  }
165  hh=f/(h+h);
166  for (j=1;j<=l;j++)
167  {
168  f=m[i][j];
169  e[j]=g=e[j]-hh*f;
170  for (k=1;k<=j;k++)
171  m[j][k] -= (f*e[k]+g*m[i][k]);
172  }
173  }
174  }
175  else
176  {
177  e[i]=m[i][l];
178  }
179  d[i]=h;
180  }
181  /* Next statement can be omitted if eigenvectors not wanted */
182  d[1]=0.0;
183  e[1]=0.0;
184  /* Contents of this loop can be omitted if eigenvectors not
185  wanted except for statement d[i]=a[i][i]; */
186  #ifdef EIGEN_VECTORS
187  for (i=1;i<=n;i++)
188  {
189  l=i-1;
190  if (!ISZERO(value(d[i])))
191  {
192  for (j=1;j<=l;j++)
193  {
194  g=0.0;
195  for (k=1;k<=l;k++)
196  g += m[i][k]*m[k][j];
197  for (k=1;k<=l;k++)
198  m[k][j] -= g*m[k][i];
199  }
200  }
201  d[i]=m[i][i];
202  m[i][i]=1.0;
203  for (j=1;j<=l;j++) m[j][i]=m[i][j]=0.0;
204  }
205  #endif
206 }
207 
214 {
215  if (y<0.)
216  {
217  return -fabs(x);
218  }
219  else
220  {
221  return fabs(x);
222  }
223 }
224 
235 #ifdef EIGEN_VECTORS
236  void get_eigenv(const dvar_vector& _d, const dvar_vector& _e,
237  const dvar_matrix& _z)
238 #else
239  void get_eigen(const dvar_vector& _d, const dvar_vector& _e,
240  const dvar_matrix& _z)
241 #endif
242 {
244  dvar_vector& e=(dvar_vector&) _e;
245  dvar_vector& d=(dvar_vector&) _d;
246 #if !defined(OPT_LIB) && (__cplusplus >= 201103L)
247  int n = [](unsigned int size) -> int
248  {
249  assert(size <= INT_MAX);
250  return static_cast<int>(size);
251  } (d.size());
252 #else
253  int n = static_cast<int>(d.size());
254 #endif
255  int m,l,iter,i,k;
256  dvariable s,r,p,g,f,dd,c,b;
257 
258  for (i=2;i<=n;i++) e[i-1]=e[i];
259  e[n]=0.0;
260  for (l=1;l<=n;l++) {
261  iter=0;
262  do {
263  for (m=l;m<=n-1;m++) {
264  dd=fabs(d[m])+fabs(d[m+1]);
265  if (fabs(e[m])+dd == dd) break;
266  }
267  if (m != l)
268  {
269  if (iter++ == 30)
270  {
271  cerr << "Maximum number of iterations exceeded in"
272  " dvector eigen(const dmatrix& m)\n";
273  ad_exit(1);
274  }
275  g=(d[l+1]-d[l])/(2.0*e[l]);
276  r=sqrt((g*g)+1.0);
277  g=d[m]-d[l]+e[l]/(g+SIGNV(r,g));
278  s=c=1.0;
279  p=0.0;
280  for (i=m-1;i>=l;i--) {
281  f=s*e[i];
282  b=c*e[i];
283  if (fabs(f) >= fabs(g)) {
284  c=g/f;
285  r=sqrt((c*c)+1.0);
286  e[i+1]=f*r;
287  c *= (s=1.0/r);
288  } else {
289  s=f/g;
290  r=sqrt((s*s)+1.0);
291  e[i+1]=g*r;
292  s *= (c=1.0/r);
293  }
294  g=d[i+1]-p;
295  r=(d[i]-g)*s+2.0*c*b;
296  p=s*r;
297  d[i+1]=g+p;
298  g=c*r-b;
299  /* Next loop can be omitted if eigenvectors not wanted */
300  #ifdef EIGEN_VECTORS
301  for (k=1;k<=n;k++)
302  {
303  f=z[k][i+1];
304  z[k][i+1]=s*z[k][i]+c*f;
305  z[k][i]=c*z[k][i]-s*f;
306  }
307  #endif
308  }
309  d[l]=d[l]-p;
310  e[l]=g;
311  e[m]=0.0;
312  }
313  } while (m != l);
314  }
315 }
316 #undef EIGEN_VECTORS
Base class for dvariable.
Definition: fvar.hpp:1315
#define x
#define ADUNCONST(type, obj)
Creates a shallow copy of obj that is not CONST.
Definition: fvar.hpp:140
df1_two_variable fabs(const df1_two_variable &x)
Definition: df12fun.cpp:891
exitptr ad_exit
Definition: gradstrc.cpp:53
ADMB variable vector.
Definition: fvar.hpp:2172
unsigned int size() const
Definition: fvar.hpp:2297
int rowsize(void) const
Definition: fvar.hpp:3859
void get_eigen(const dvar_vector &d, const dvar_vector &e, const dvar_matrix &z)
Eigenvalues.
Definition: dveigen.cpp:187
void get_eigenv(const dvar_vector &d, const dvar_vector &e, const dvar_matrix &z)
Eigenvalues and eigenvectors.
Definition: dveigenv.cpp:236
dmatrix symmetrize(const dmatrix &matrix)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dmat12.cpp:14
dmatrix eigenvectors(const banded_symmetric_dmatrix &_SS, const dvector &_e)
Description not yet available.
Definition: dmat28.cpp:442
d3_array sqrt(const d3_array &arr3)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr2c.cpp:11
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
void rowshift(int min)
Description not yet available.
Definition: fvar_ma9.cpp:17
#define ISZERO(d)
Definition: dveigenv.cpp:21
unsigned int rowsize() const
Definition: fvar.hpp:2578
void tri_dag(const dvar_matrix &, const dvar_vector &, const dvar_vector &)
Householder transformation for eigenvalue computation.
Definition: dveigen.cpp:54
Class definition of matrix with derivitive information .
Definition: fvar.hpp:2480
void tri_dagv(const dvar_matrix &, const dvar_vector &, const dvar_vector &)
Householder transformation for eivenvector computation.
Definition: dveigenv.cpp:93
dvariable SIGNV(const prevariable &x, const prevariable &y)
Change sign.
Definition: dveigenv.cpp:213
dvector value(const df1_one_vector &v)
Definition: df11fun.cpp:69
void colshift(int min)
Description not yet available.
Definition: fvar_ma9.cpp:28
Fundamental data type for reverse mode automatic differentiation.
Definition: fvar.hpp:1518
unsigned int colsize() const
Definition: fvar.hpp:2584