ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
linad99/expm.cpp
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Authors: Anders Nielsen <anders@nielsensweb.org> and Casper Berg <cbe@aqua.dtu.dk>
5  * Copyright (c) 2008-2012 Regents of the University of California
6  */
11 #include <fvar.hpp>
12 #ifndef OPT_LIB
13  #include <cassert>
14  #include <climits>
15 #endif
16 #define TINY 1.0e-20;
17 
22 dmatrix fabs(const dmatrix & X){
23  int rmin = X.rowmin();
24  int rmax = X.rowmax();
25  int cmin = X.colmin();
26  int cmax = X.colmax();
27  dmatrix ret(rmin,rmax,cmin,cmax);
28  for(int i = rmin; i<=rmax; ++i){
29  for(int j = cmin; j<=cmax; ++j){
30  ret(i,j) = fabs(X(i,j));
31  }
32  }
33  return ret;
34 }
35 
36 dvar_matrix solve(const dvar_matrix& aa, const dvar_matrix& tz,
37  dvariable ln_unsigned_det, dvariable& sign);
38 
40 {
41  dvariable ln;
42  dvariable sgn;
43  return solve(aa,tz,ln,sgn);
44 }
45 
67 dmatrix expm(const dmatrix& A)
68 {
69  int rmin = A.rowmin();
70  int rmax = A.rowmax();
71  if(rmax != A.colmax())
72  {
73  cout<<"Error: Not square matrix in expm."<<endl;
74  ad_exit(1);
75  }
76  if(rmin != A.colmin())
77  {
78  cout<<"Error: Not square matrix in expm."<<endl;
79  ad_exit(1);
80  }
81  dmatrix I(rmin,rmax,rmin,rmax);
82  dmatrix AA(rmin,rmax,rmin,rmax);
83  dmatrix X(rmin,rmax,rmin,rmax);
84  dmatrix E(rmin,rmax,rmin,rmax);
85  dmatrix D(rmin,rmax,rmin,rmax);
86  dmatrix cX(rmin,rmax,rmin,rmax);
87  I.initialize();
88  for(int i = rmin; i<=rmax; ++i){I(i,i) = 1.0;}
89  double log2NormInf;
90  log2NormInf = log(max(rowsum(fabs(A))));
91  log2NormInf/=log(2.0);
92  int e = (int)log2NormInf + 1;
93  int s = e+1;
94  s = (s<0) ? 0 : s;
95  AA = 1.0/pow(2.0,s)*A;
96  X = AA;
97  double c = 0.5;
98 
99  E = I+c*AA;
100  D = I-c*AA;
101  int q = 6, p = 1;
102  for(int k = 2; k<=q; ++k){
103  c*=((double)q-k+1.0)/((double)k*(2*q-k+1));
104  X = AA*X;
105  cX = c*X;
106  E+=cX;
107  if(p==1){D+=cX;}else{D-=cX;}
108  p = (p==1) ? 0 : 1;
109  }
110  // E = inv(D)*E;
111  E = solve(D,E);
112  for(int k = 1; k<=s; ++k){
113  E = E*E;
114  }
115  return E;
116 }
117 
141 {
144 
145  int rmin = A.rowmin();
146  int rmax = A.rowmax();
147 
148  if(rmax != A.colmax())
149  {
150  cout<<"Error: Not square matrix in expm."<<endl;
151  ad_exit(1);
152  }
153  if(rmin != A.colmin())
154  {
155  cout<<"Error: Not square matrix in expm."<<endl;
156  ad_exit(1);
157  }
158 
159  dvar_matrix I(rmin,rmax,rmin,rmax);
160  dvar_matrix AA(rmin,rmax,rmin,rmax);
161  dvar_matrix X(rmin,rmax,rmin,rmax);
162  dvar_matrix E(rmin,rmax,rmin,rmax);
163  dvar_matrix D(rmin,rmax,rmin,rmax);
164  dvar_matrix cX(rmin,rmax,rmin,rmax);
165 
166  I.initialize();
167  for(int i = rmin; i<=rmax; ++i){I(i,i) = 1.0;}
168 
169  dvariable log2NormInf;
170  log2NormInf = log(max(rowsum(fabs(value(A)))));
171  log2NormInf/=log(2.0);
172  int e = (int)value(log2NormInf) + 1;
173  int s = e+1;
174  s = (s<0) ? 0 : s;
175  AA = 1.0/pow(2.0,s)*A;
176 
177  X = AA;
178  dvariable c = 0.5;
179 
180  E = I+c*AA;
181  D = I-c*AA;
182  int q = 6, p = 1, k;
183  for(k = 2; k<=q; ++k){
184  c*=((double)q-k+1.0)/((double)k*(2*q-k+1));
185  X = AA*X;
186  cX = c*X;
187  E+=cX;
188  if(p==1){D+=cX;}else{D-=cX;}
189  p = (p==1) ? 0 : 1;
190  }
191  // E = inv(D)*E;
192  E = solve(D,E);
193  for(k = 1; k<=s; ++k){
194  E = E*E;
195  }
197  return E;
198 }
199 
201  dvariable ln_unsigned_det, dvariable& sign)
202 {
205 
206 #if !defined(OPT_LIB) && (__cplusplus >= 201103L)
207  int n = [](unsigned int colsize) -> int
208  {
209  assert(colsize <= INT_MAX);
210  return static_cast<int>(colsize);
211  } (aa.colsize());
212 #else
213  int n = static_cast<int>(aa.colsize());
214 #endif
215  int lb=aa.colmin();
216  int ub=aa.colmax();
217  if (lb!=aa.rowmin()||ub!=aa.colmax())
218  {
219  cerr << "Error matrix not square in solve()"<<endl;
220  ad_exit(1);
221  }
222  dvar_matrix bb(lb,ub,lb,ub);
223  bb=aa;
224  ivector indx(lb,ub);
225  int One=1;
226  indx.fill_seqadd(lb,One);
227  dvariable d;
228  dvariable big,dum,sum,temp;
229  dvar_vector vv(lb,ub);
230 
231  d=1.0;
232  for (int i=lb;i<=ub;i++)
233  {
234  big=0.0;
235  for (int j=lb;j<=ub;j++)
236  {
237  temp=fabs(bb(i,j));
238  if (temp > big)
239  {
240  big=temp;
241  }
242  }
243  if (big == 0.0)
244  {
245  cerr << "Error in matrix inverse -- matrix singular in inv(dvar_matrix)\n";
246  }
247  vv[i]=1.0/big;
248  }
249 
250  for (int j=lb;j<=ub;j++)
251  {
252  for (int i=lb;i<j;i++)
253  {
254  sum=bb(i,j);
255  for (int k=lb;k<i;k++)
256  {
257  sum -= bb(i,k)*bb(k,j);
258  }
259  //a[i][j]=sum;
260  bb(i,j)=sum;
261  }
262  int imax = j;
263  big=0.0;
264  for (int i=j;i<=ub;i++)
265  {
266  sum=bb(i,j);
267  for (int k=lb;k<j;k++)
268  {
269  sum -= bb(i,k)*bb(k,j);
270  }
271  bb(i,j)=sum;
272  dum=vv[i]*fabs(sum);
273  if ( dum >= big)
274  {
275  big=dum;
276  imax=i;
277  }
278  }
279  if (j != imax)
280  {
281  for (int k=lb;k<=ub;k++)
282  {
283  dum=bb(imax,k);
284  bb(imax,k)=bb(j,k);
285  bb(j,k)=dum;
286  }
287  d = -1.*d;
288  vv[imax]=vv[j];
289 
290  //if (j<ub)
291  {
292  int itemp=indx(imax);
293  indx(imax)=indx(j);
294  indx(j)=itemp;
295  }
296  //cout << "indx= " <<indx<<endl;
297  }
298 
299  if (bb(j,j) == 0.0)
300  {
301  bb(j,j)=TINY;
302  }
303 
304  if (j != n)
305  {
306  dum=1.0/bb(j,j);
307  for (int i=j+1;i<=ub;i++)
308  {
309  bb(i,j) = bb(i,j) * dum;
310  }
311  }
312  }
313 
314  // get the determinant
315  sign=d;
316  dvar_vector part_prod(lb,ub);
317  part_prod(lb)=log(fabs(bb(lb,lb)));
318  if (bb(lb,lb)<0) sign=-sign;
319  for (int j=lb+1;j<=ub;j++)
320  {
321  if (bb(j,j)<0) sign=-sign;
322  part_prod(j)=part_prod(j-1)+log(fabs(bb(j,j)));
323  }
324  ln_unsigned_det=part_prod(ub);
325 
326  dvar_matrix z=trans(tz);
327  int mmin=z.indexmin();
328  int mmax=z.indexmax();
329  dvar_matrix x(mmin,mmax,lb,ub);
330  //dvar_vector x(lb,ub);
331 
332  dvar_vector y(lb,ub);
333  //int lb=rowmin;
334  //int ub=rowmax;
335  dvar_matrix& b=bb;
336  ivector indxinv(lb,ub);
337  for (int i=lb;i<=ub;i++)
338  {
339  indxinv(indx(i))=i;
340  }
341  for (int kk=mmin;kk<=mmax;kk++)
342  {
343  for (int i=lb;i<=ub;i++)
344  {
345  y(indxinv(i))=z(kk)(i);
346  }
347 
348  for (int i=lb;i<=ub;i++)
349  {
350  sum=y(i);
351  for (int j=lb;j<=i-1;j++)
352  {
353  sum-=b(i,j)*y(j);
354  }
355  y(i)=sum;
356  }
357  for (int i=ub;i>=lb;i--)
358  {
359  sum=y(i);
360  for (int j=i+1;j<=ub;j++)
361  {
362  sum-=b(i,j)*x(kk)(j);
363  }
364  x(kk)(i)=sum/b(i,i);
365  }
366  }
368  return trans(x);
369 }
370 #undef TINY
int rowmax(void) const
Definition: fvar.hpp:2564
int colmin(void) const
Definition: fvar.hpp:2552
dmatrix trans(const dmatrix &m1)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dmat2.cpp:13
dmatrix expm(const dmatrix &A)
Matrix exponential.
#define x
void initialize(void)
Zero initialize allocated dvar_matrix, then saves adjoint function and position data.
Definition: fvar_ma7.cpp:48
double sum(const d3_array &darray)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr.cpp:21
exitptr ad_exit
Definition: gradstrc.cpp:53
df1_two_variable fabs(const df1_two_variable &x)
Definition: df12fun.cpp:891
ADMB variable vector.
Definition: fvar.hpp:2172
void fill_seqadd(int, int)
Fills ivector elements with values starting from base and incremented by offset.
Definition: cranfill.cpp:73
ivector sgn(const dvector &v)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dvect24.cpp:11
dvector solve(const dmatrix &aa, const dvector &z)
Solve a linear system using LU decomposition.
Definition: dmat34.cpp:46
prnstream & endl(prnstream &)
Array of integers(int) with indexes from index_min to indexmax.
Definition: ivector.h:50
int rowmax() const
Definition: fvar.hpp:2929
dvector rowsum(const dmatrix &matrix)
Returns dvector where each element contains the sum total of each row in matrix.
Definition: dvect12.cpp:61
void RETURN_ARRAYS_INCREMENT()
Definition: gradstrc.cpp:478
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
static _THREAD gradient_structure * _instance
int colmin(void) const
Definition: fvar.hpp:2939
int rowmin(void) const
Definition: fvar.hpp:2560
Description not yet available.
Definition: fvar.hpp:2819
int indexmax(void) const
Definition: fvar.hpp:2572
Class definition of matrix with derivitive information .
Definition: fvar.hpp:2480
#define TINY
double sign(const double x)
The sign of a number.
Definition: gaussher.cpp:25
void RETURN_ARRAYS_DECREMENT()
Definition: gradstrc.cpp:511
dvector value(const df1_one_vector &v)
Definition: df11fun.cpp:69
#define max(a, b)
Definition: cbivnorm.cpp:189
class for things related to the gradient structures, including dimension of arrays, size of buffers, etc.
void initialize(void)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dmat7.cpp:12
int indexmin(void) const
Definition: fvar.hpp:2568
int rowmin() const
Definition: fvar.hpp:2925
Fundamental data type for reverse mode automatic differentiation.
Definition: fvar.hpp:1518
d3_array log(const d3_array &arr3)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr2a.cpp:13
d3_array pow(const d3_array &m, int e)
Description not yet available.
Definition: d3arr6.cpp:17
int colmax(void) const
Definition: fvar.hpp:2943
int colmax(void) const
Definition: fvar.hpp:2556
unsigned int colsize() const
Definition: fvar.hpp:2584