ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dveigen.cpp
Go to the documentation of this file.
1 
6 //#define EIGEN_VECTORS
7 
8 #include <fvar.hpp>
9 #ifndef OPT_LIB
10  #include <cassert>
11  #include <climits>
12 #endif
13 
14 void tri_dag(const dvar_matrix& ,const dvar_vector& ,const dvar_vector& );
15 void get_eigen(const dvar_vector& d,const dvar_vector& e, const dvar_matrix& z);
16 
18 {
19  if (m.rowsize()!=m.colsize())
20  {
21  cerr << "Error -- non square matrix passed to "
22  "dvector eigen(const dvar_matrix& m)\n";
23  ad_exit(1);
24  }
25  dvar_matrix m1=symmetrize(m);
26 #ifndef OPT_LIB
27  assert(m1.rowsize() <= INT_MAX);
28 #endif
29  int n = static_cast<int>(m1.rowsize());
30  m1.colshift(1); // set minimum column and row indices to 1
31  m1.rowshift(1);
32  dvar_vector diag(1,n);
33  dvar_vector off_diag(1,n);
34 
35  tri_dag(m1,diag,off_diag);
36 
37  // eigenvalues are returned in diag
38  get_eigen(diag,off_diag,m1);
39 
40  // eigenvalues are returned in columns of z
41  return diag;
42 }
43 
54 void tri_dag(const dvar_matrix& _m,const dvar_vector& _d, const dvar_vector& _e)
55 {
58  dvar_matrix& m=(dvar_matrix&) _m;
59  if (m.rowsize() != m.colsize())
60  {
61  cerr << "Error -- non square matrix passed to "
62  "void tridag(const dmatrix& m)\n";
63  ad_exit(1);
64  }
65  if (m.rowsize() != d.size() || m.rowsize() != e.size()
66  || d.indexmin() != 1 || e.indexmin() !=1 )
67  {
68  cerr <<"Error -- incorrect vector size passed to "
69  "void tridag(const dmatrix& m)\n";
70  ad_exit(1);
71  }
72 #ifndef OPT_LIB
73  assert(m.rowsize() <= INT_MAX);
74 #endif
75  int n = static_cast<int>(m.rowsize());
76  int l,k,j,i;
77  dvariable scale,hh,h,g,f;
78 
79  for (i=n;i>=2;i--)
80  {
81  l=i-1;
82  h=scale=0.0;
83  if (l > 1)
84  {
85  for (k=1;k<=l;k++)
86  scale += fabs(m[i][k]);
87  if (scale == 0.0)
88  e[i]=m[i][l];
89  else
90  {
91  for (k=1;k<=l;k++)
92  {
93  m[i][k] /= scale;
94  h += m[i][k]*m[i][k];
95  }
96  f=m[i][l];
97  g = f>0. ? -sqrt(h) : sqrt(h);
98  e[i]=scale*g;
99  h -= f*g;
100  m[i][l]=f-g;
101  f=0.0;
102  for (j=1;j<=l;j++)
103  {
104  #ifdef EIGEN_VECTORS
105  /* Next statement can be omitted if eigenvectors not wanted */
106  m[j][i]=m[i][j]/h;
107  #endif
108  g=0.0;
109  for (k=1;k<=j;k++)
110  g += m[j][k]*m[i][k];
111  for (k=j+1;k<=l;k++)
112  g += m[k][j]*m[i][k];
113  e[j]=g/h;
114  f += e[j]*m[i][j];
115  }
116  hh=f/(h+h);
117  for (j=1;j<=l;j++)
118  {
119  f=m[i][j];
120  e[j]=g=e[j]-hh*f;
121  for (k=1;k<=j;k++)
122  m[j][k] -= (f*e[k]+g*m[i][k]);
123  }
124  }
125  }
126  else
127  {
128  e[i]=m[i][l];
129  }
130  d[i]=h;
131  }
132  /* Next statement can be omitted if eigenvectors not wanted */
133  d[1]=0.0;
134  e[1]=0.0;
135  /* Contents of this loop can be omitted if eigenvectors not
136  wanted except for statement d[i]=a[i][i]; */
137  #ifdef EIGEN_VECTORS
138  for (i=1;i<=n;i++)
139  {
140  l=i-1;
141  if (d[i])
142  {
143  for (j=1;j<=l;j++)
144  {
145  g=0.0;
146  for (k=1;k<=l;k++)
147  g += m[i][k]*m[k][j];
148  for (k=1;k<=l;k++)
149  m[k][j] -= g*m[k][i];
150  }
151  }
152  d[i]=m[i][i];
153  m[i][i]=1.0;
154  for (j=1;j<=l;j++) m[j][i]=m[i][j]=0.0;
155  }
156  #else
157  for (i=1;i<=n;i++)
158  {
159  d[i]=m[i][i];
160  }
161  #endif
162 }
163 
165 {
166  if (value(y) < 0)
167  {
168  return -fabs(x);
169  }
170  else
171  {
172  return fabs(x);
173  }
174 }
175 //#define SIGN(a,b) ((b)<0 ? -fabs(a) : fabs(a))
176 
187 void get_eigen(const dvar_vector& _d,const dvar_vector& _e,
188  const dvar_matrix& z)
189 {
192 #ifndef OPT_LIB
193  assert(d.size() <= INT_MAX);
194 #endif
195  int n = static_cast<int>(d.size());
196  int m,l,iter,i;
197  dvariable s,r,p,g,f,dd,c,b;
198 
199  for (i=2;i<=n;i++) e[i-1]=e[i];
200  e[n]=0.0;
201  for (l=1;l<=n;l++) {
202  iter=0;
203  do {
204  for (m=l;m<=n-1;m++) {
205  dd=fabs(d[m])+fabs(d[m+1]);
206  if (fabs(e[m])+dd == dd) break;
207  }
208  if (m != l)
209  {
210  if (iter++ == 30)
211  {
212  cerr << "Maximum number of iterations exceeded in"
213  " dvector eigen(const dmatrix& m)\n";
214  ad_exit(1);
215  }
216  g=(d[l+1]-d[l])/(2.0*e[l]);
217  r=sqrt((g*g)+1.0);
218  g=d[m]-d[l]+e[l]/(g+SIGN(r,g));
219  s=c=1.0;
220  p=0.0;
221  for (i=m-1;i>=l;i--) {
222  f=s*e[i];
223  b=c*e[i];
224  if (fabs(f) >= fabs(g)) {
225  c=g/f;
226  r=sqrt((c*c)+1.0);
227  e[i+1]=f*r;
228  c *= (s=1.0/r);
229  } else {
230  s=f/g;
231  r=sqrt((s*s)+1.0);
232  e[i+1]=g*r;
233  s *= (c=1.0/r);
234  }
235  g=d[i+1]-p;
236  r=(d[i]-g)*s+2.0*c*b;
237  p=s*r;
238  d[i+1]=g+p;
239  g=c*r-b;
240  /* Next loop can be omitted if eigenvectors not wanted */
241  #ifdef EIGEN_VECTORS
242  for (int k=1;k<=n;k++)
243  {
244  f=z[k][i+1];
245  z[k][i+1]=s*z[k][i]+c*f;
246  z[k][i]=c*z[k][i]-s*f;
247  }
248  #endif
249  }
250  d[l]=d[l]-p;
251  e[l]=g;
252  e[m]=0.0;
253  }
254  } while (m != l);
255  }
256 }
257 
270 {
273 
274  dvar_vector d(ddd.indexmin(),ddd.indexmax());
275  dvar_vector e(eee.indexmin(),eee.indexmax());
276 
277  d=ddd;
278  e=eee;
279 
280 #ifndef OPT_LIB
281  assert(d.size() <= INT_MAX);
282 #endif
283  int n = static_cast<int>(d.size());
284  int m,l,iter,i;
285  dvariable s,r,p,g,f,dd,c,b;
286 
287  for (i=2;i<=n;i++) e[i-1]=e[i];
288  e[n]=0.0;
289  for (l=1;l<=n;l++) {
290  iter=0;
291  do {
292  for (m=l;m<=n-1;m++) {
293  dd=fabs(d[m])+fabs(d[m+1]);
294  if (fabs(e[m])+dd == dd) break;
295  }
296  if (m != l)
297  {
298  if (iter++ == 30)
299  {
300  cerr << "Maximum number of iterations exceeded in"
301  " dvector eigen(const dmatrix& m)\n";
302  ad_exit(1);
303  }
304  g=(d[l+1]-d[l])/(2.0*e[l]);
305  r=sqrt((g*g)+1.0);
306  g=d[m]-d[l]+e[l]/(g+SIGN(r,g));
307  s=c=1.0;
308  p=0.0;
309  for (i=m-1;i>=l;i--) {
310  f=s*e[i];
311  b=c*e[i];
312  if (fabs(f) >= fabs(g)) {
313  c=g/f;
314  r=sqrt((c*c)+1.0);
315  e[i+1]=f*r;
316  c *= (s=1.0/r);
317  } else {
318  s=f/g;
319  r=sqrt((s*s)+1.0);
320  e[i+1]=g*r;
321  s *= (c=1.0/r);
322  }
323  g=d[i+1]-p;
324  r=(d[i]-g)*s+2.0*c*b;
325  p=s*r;
326  d[i+1]=g+p;
327  g=c*r-b;
328  /* Next loop can be omitted if eigenvectors not wanted */
329  }
330  d[l]=d[l]-p;
331  e[l]=g;
332  e[m]=0.0;
333  }
334  } while (m != l);
335  }
336  return d;
337 }
338 #undef EIGEN_VECTORS
Base class for dvariable.
Definition: fvar.hpp:1315
dvar_vector get_eigen_values(const dvar_vector &_ddd, const dvar_vector &_eee)
Eigenvalues and eigenvectors.
Definition: dveigen.cpp:269
dvector eigenvalues(const banded_symmetric_dmatrix &_SS)
Description not yet available.
Definition: dmat28.cpp:411
#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
void get_eigen(const dvar_vector &d, const dvar_vector &e, const dvar_matrix &z)
Eigenvalues.
Definition: dveigen.cpp:187
dmatrix symmetrize(const dmatrix &matrix)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dmat12.cpp:14
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
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
dvector value(const df1_one_vector &v)
Definition: df11fun.cpp:69
void colshift(int min)
Description not yet available.
Definition: fvar_ma9.cpp:28
#define SIGN(a, b)
Definition: dmat42.cpp:20
Fundamental data type for reverse mode automatic differentiation.
Definition: fvar.hpp:1518
unsigned int colsize() const
Definition: fvar.hpp:2584