ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fvar_m15.cpp
Go to the documentation of this file.
1 
7 #include <fvar.hpp>
8 #ifndef OPT_LIB
9  #include <cassert>
10  #include <climits>
11 #endif
12 
13 #ifdef __TURBOC__
14  #pragma hdrstop
15  #include <iostream.h>
16 #endif
17 
18 #ifdef __ZTC__
19  #include <iostream.hpp>
20 #endif
21 
22 #define TINY 1.0e-20;
23 void dfinvpret(void);
24 
31 int min(const int a, const int b)
32 {
33  return a <= b ? a : b;
34 }
35 
44 {
45  int imax = 0;
46 #if !defined(OPT_LIB) && (__cplusplus >= 201103L)
47  int n = [](unsigned int colsize) -> int
48  {
49  assert(colsize <= INT_MAX);
50  return static_cast<int>(colsize);
51  } (aa.colsize());
52 #else
53  int n = static_cast<int>(aa.colsize());
54 #endif
55  int lb=aa.colmin();
56  int ub=aa.colmax();
57  dvar_matrix vc(lb,ub,lb,ub);
58  if (n==1)
59  {
60  if (aa(lb,lb)==0.0)
61  {
62  cerr << "Error in matrix inverse -- matrix singular in inv(dmatrix)\n";
63  ad_exit(1);
64  }
65  else
66  {
67  vc(lb,lb)=1.0/aa(lb,lb);
68  return vc;
69  }
70  }
71  ivector indx(lb,ub);
72  int One=1;
73  indx.fill_seqadd(lb,One);
74  double d;
75  double big,dum,sum,temp;
76  dvar_matrix_position dmp(aa,0);
77  dmatrix bb=value(aa);
78  dvector vv(lb,ub);
79 
80  d=1.0;
81  dvector* pbbi = &bb.elem(lb);
82  double* pvvi = vv.get_v() + lb;
83  for (int i=lb;i<=ub;i++)
84  {
85  big=0.0;
86  double* pbbij = pbbi->get_v() + lb;
87  for (int j=lb;j<=ub;j++)
88  {
89  temp = fabs(*pbbij);
90  if (temp > big)
91  {
92  big=temp;
93  }
94  ++pbbij;
95  }
96  if (big == 0.0)
97  {
98  cerr << "Error in matrix inverse -- matrix singular in inv(dmatrix)\n";
99  ad_exit(1);
100  }
101  *pvvi = 1.0 / big;
102 
103  ++pbbi;
104  ++pvvi;
105  }
106 
107  for (int j=lb;j<=ub;j++)
108  {
109  dvector* pbbi = &bb.elem(lb);
110  for (int i=lb;i<j;i++)
111  {
112  sum = *(pbbi->get_v() +j);
113 
114  double* pbbik = pbbi->get_v() + lb;
115  dvector* pbbk = &bb.elem(lb);
116  for (int k=lb;k<i;k++)
117  {
118  sum = sum - *pbbik * *(pbbk->get_v() + j);
119  ++pbbik;
120  ++pbbk;
121  }
122  //a[i][j]=sum;
123  *(pbbi->get_v() +j) = sum;
124 
125  ++pbbi;
126  }
127  big=0.0;
128  pbbi = &bb.elem(j);
129  for (int i=j;i<=ub;i++)
130  {
131  sum = *(pbbi->get_v() + j);
132 
133  double* pbbik = pbbi->get_v() + lb;
134  dvector* pbbk = &bb.elem(lb);
135  for (int k=lb;k<j;k++)
136  {
137  sum = sum - *pbbik * *(pbbk->get_v() + j);
138  ++pbbik;
139  ++pbbk;
140  }
141  *pbbik = sum;
142 
143  dum=vv[i]*fabs(sum);
144  if ( dum >= big)
145  {
146  big=dum;
147  imax=i;
148  }
149  ++pbbi;
150  }
151  if (j != imax)
152  {
153  double* pbbimaxk = bb.elem(imax).get_v() + lb;
154  double* pbbjk = bb.elem(j).get_v() + lb;
155  for (int k=lb;k<=ub;k++)
156  {
157  dum = *pbbimaxk;
158  *pbbimaxk = *pbbjk;
159  *pbbjk = dum;
160 
161  ++pbbimaxk;
162  ++pbbjk;
163  }
164  d = -1.*d;
165  vv[imax]=vv[j];
166 
167  //if (j<ub)
168  {
169  int itemp=indx.elem(imax);
170  indx.elem(imax)=indx.elem(j);
171  indx.elem(j)=itemp;
172  }
173  //cout << "indx= " <<indx<<endl;
174  }
175 
176  if (bb.elem(j,j) == 0.0)
177  {
178  bb.elem(j,j)=TINY;
179  }
180 
181  if (j != n)
182  {
183  dum=1.0/bb.elem(j,j);
184  pbbi = &bb.elem(j + 1);
185  for (int i=j+1;i<=ub;i++)
186  {
187  *(pbbi->get_v() + j) *= dum;
188  ++pbbi;
189  }
190  }
191  }
192 
195 
196  dvector y(lb,ub);
197  dvector x(lb,ub);
198  //int lb=rowmin;
199  //int ub=rowmax;
200  dmatrix& b=bb;
201  ivector indxinv(lb,ub);
202  int* pindx = indx.get_v() + lb;
203  int* pindxinv = indxinv.get_v();
204  for (int i=lb;i<=ub;i++)
205  {
206  *(pindxinv + *pindx)=i;
207  ++pindx;
208  }
209 
210  pindxinv = indxinv.get_v() + lb;
211  for (int ii=lb;ii<=ub;ii++)
212  {
213  y.initialize();
214  const int indxinvii = *pindxinv;
215  y(indxinvii) = 1.;
216 
217  dvector* pbi = &b.elem(indxinvii);
218  double* pyi = y.get_v() + indxinvii;
219  for (int i=indxinvii;i<=ub;i++)
220  {
221  // sum=y(ii,i);
222  if (i==indxinvii)
223  {
224  sum=1.;
225  }
226  else
227  {
228  sum=0.;
229  }
230  double* pbij = pbi->get_v() + indxinvii;
231  double* pyj = y.get_v() + indxinvii;
232  for (int j=indxinvii;j<=i-1;j++)
233  {
234  sum -= *pbij * *pyj;
235 
236  ++pbij;
237  ++pyj;
238  }
239  *pyi = sum;
240 
241  ++pbi;
242  ++pyi;
243  }
244  pyi = y.get_v() + ub;
245  double* pxi = x.get_v() + ub;
246  pbi = &b.elem(ub);
247  for (int i=ub;i>=lb;i--)
248  {
249  sum = *pyi;
250  double* pxj = x.get_v() + i + 1;
251  double* pbij = pbi->get_v() + i + 1;
252  for (int j=i+1;j<=ub;j++)
253  {
254  sum -= *pbij * *pxj;
255 
256  ++pxj;
257  ++pbij;
258  }
259  *pxi = sum / *(pbi->get_v() + i);
260 
261  --pyi;
262  --pbi;
263  --pxi;
264  }
265  fp->save_dvector_value(y);
266  fp->save_dvector_value(x);
267  nograd_assign_column(vc,x,ii);
268  ++pindxinv;
269  }
270 
272  fp->save_dvector_position(x);
273  fp->save_dvector_position(y);
274  fp->save_ivector_value(indx);
275  fp->save_ivector_position(indx);
278  fp->save_dmatrix_value(bb);
279  fp->save_dmatrix_position(bb);
282  return vc;
283 }
284 
287 void dfinvpret(void)
288 {
290 
293  dmatrix b=fp->restore_dmatrix_value(bpos);
297  ivector indx=restore_ivector_value(indx_pos);
301  int lb=b.colmin();
302  int ub=b.colmax();
303  dmatrix dfb(lb,ub,lb,ub);
304  ivector indxinv(lb,ub);
305 
306  int* pindx = indx.get_v() + lb;
307  int* pindxinv = indxinv.get_v();
308  for (int i=lb;i<=ub;i++)
309  {
310  *(pindxinv + *pindx) = i;
311  ++pindx;
312  }
313 
314  double dfsum=0.;
315  dvector dfy(lb,ub);
316  #ifndef SAFE_INITIALIZE
317  dfb.initialize();
318  dfy.initialize();
319  #endif
320  for (int ii=ub;ii>=lb;ii--)
321  {
322  //x.save_dvector_value();
323  dvector x=fp->restore_dvector_value(x_pos);
324  //y.save_dvector_value();
325  dvector y=fp->restore_dvector_value(y_pos);
327 
328  double* pdfxi = dfx.get_v() + lb;
329  double* pxi = x.get_v() + lb;
330  dvector* pdfbi = &dfb.elem(lb);
331  dvector* pbi = &b.elem(lb);
332  for (int i=lb;i<=ub;i++)
333  {
334  // x.elem(i)=sum/b.elem(i,i);
335  dfsum+= *pdfxi / b.elem(i,i);
336  *(pdfbi->get_v() + i) -= *pdfxi * *pxi / b.elem(i,i);
337  *pdfxi = 0.0;
338 
339  double* pdfxj = dfx.get_v() + ub;
340  double* pxj = x.get_v() + ub;
341  double* pdfbij = pdfbi->get_v() + ub;
342  double* pbij = pbi->get_v() + ub;
343  for (int j=ub;j>=i+1;j--)
344  {
345  // sum -=b.elem(i,j)*x.elem(j);
346  *pdfbij -= dfsum * *pxj;
347  *pdfxj -= dfsum * *pbij;
348 
349  --pdfxj;
350  --pxj;
351  --pdfbij;
352  --pbij;
353  }
354  // sum=y.elem(i);
355  dfy.elem(i)+=dfsum;
356  dfsum=0.;
357 
358  ++pdfxi;
359  ++pxi;
360  ++pdfbi;
361  ++pbi;
362  }
363 
364  //for (i=ub;i>=lb;i--)
365  int indxinvii = indxinv(ii);
366  double* pdfyi2 = dfy.get_v() + ub;
367  for (int i2=ub;i2>=indxinvii;i2--)
368  {
369  // y.elem(i)=sum;
370  dfsum += *pdfyi2;
371  *pdfyi2 = 0.0;
372  // for (int j=i-1;j>=lb;j--)
373  double* pyj = y.get_v() + i2 - 1;
374  double* pdfyj = dfy.get_v() + i2 - 1;
375  for (int j=i2-1;j>=indxinvii;j--)
376  {
377  // sum-=b.elem(i,j)*y.elem(j);
378  dfb.elem(i2,j) -= dfsum * *pyj;
379  *pdfyj -= dfsum*b.elem(i2,j);
380 
381  --pyj;
382  --pdfyj;
383  }
384  //sum=y.elem(i);
385  *pdfyi2 = dfsum;
386  dfsum = 0.0;
387 
388  --pdfyi2;
389  }
390  //x.initialize()
391  //y.initialize()
392  dfx.initialize();
393  dfy.initialize();
394  }
395 
396  for (int j=ub;j>=lb;j--)
397  {
398  double bjj = b.elem(j, j);
399  dvector* pdfbi = &dfb.elem(ub);
400  int* pindxi = indx.get_v() + ub;
401  for (int i=ub;i>=lb;i--)
402  {
403  double* pdfbij = pdfbi->get_v() + j;
404  if (i<=j)
405  {
406  // b.elem(i,j)=sum;
407  dfsum+= *pdfbij;
408  *pdfbij = 0.0;
409  }
410  else
411  {
412  // b.elem(i,j)=sum/b.elem(j,j);
413  dfsum += *pdfbij / bjj;
414  dfb.elem(j,j) -= *pdfbij * b.elem(i,j) / bjj;
415  *pdfbij = 0.0;
416  }
417 
418  for (int k=min(i-1,j-1);k>=lb;k--)
419  {
420  // sum-=b.elem(i,k)*b.elem(k,j);
421  dfb.elem(i,k)-=dfsum*b.elem(k,j);
422  dfb.elem(k,j)-=dfsum*b.elem(i,k);
423  }
424  // sum=value(a(indx.elem(i),j);
425  save_dmatrix_derivatives(a_pos,dfsum, *pindxi, j); // like this
426  dfsum=0.;
427 
428  --pindxi;
429  --pdfbi;
430  }
431  }
432 }
433 
434 #undef TINY
Description not yet available.
Definition: fvar.hpp:4883
int & elem(int i)
Definition: ivector.h:90
double & elem(int i)
Definition: dvector.h:152
dvector restore_dvar_matrix_derivative_column(const dvar_matrix_position &_pos, const int &ii)
Description not yet available.
Definition: cmpdif6.cpp:228
void save_ivector_position(const ivector &v)
Definition: cmpdif3.cpp:198
void dfinvpret(void)
Adjoint code for dvar_matrix inv(const dvar_matrix&amp; aa).
Definition: fvar_m15.cpp:287
int colmin(void) const
Definition: fvar.hpp:2552
#define x
Vector of double precision numbers.
Definition: dvector.h:50
ivector_position restore_ivector_position()
Definition: cmpdif4.cpp:49
void save_dmatrix_position(const dmatrix &m)
Definition: cmpdif6.cpp:31
double sum(const d3_array &darray)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr.cpp:21
df1_two_variable fabs(const df1_two_variable &x)
Definition: df12fun.cpp:891
exitptr ad_exit
Definition: gradstrc.cpp:53
dmatrix_position restore_dmatrix_position()
Definition: cmpdif6.cpp:147
Description not yet available.
Definition: fvar.hpp:4923
void save_dmatrix_value(const dmatrix &m)
Definition: cmpdif5.cpp:26
void verify_identifier_string(const char *)
Verifies gradient stack string.
Definition: cmpdif3.cpp:149
void fill_seqadd(int, int)
Fills ivector elements with values starting from base and incremented by offset.
Definition: cranfill.cpp:73
dvector restore_dvector_value(const dvector_position &tmp)
Definition: cmpdif4.cpp:178
dmatrix restore_dmatrix_value(const dmatrix_position &mpos)
Definition: cmpdif5.cpp:100
void set_gradient_stack(void(*func)(void), double *dep_addr, double *ind_addr1=NULL, double mult1=0, double *ind_addr2=NULL, double mult2=0)
Description not yet available.
Definition: fvar.hpp:1045
int * get_v() const
Definition: ivector.h:114
void save_dvector_position(const dvector &v)
Definition: cmpdif4.cpp:32
Array of integers(int) with indexes from index_min to indexmax.
Definition: ivector.h:50
void save_dvector_value(const dvector &v)
Definition: cmpdif4.cpp:130
#define min(a, b)
Definition: cbivnorm.cpp:188
Description not yet available.
Definition: fvar.hpp:4947
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
Description not yet available.
Definition: fvar.hpp:2819
void initialize(void)
Initialze all elements of dvector to zero.
Definition: dvect5.cpp:10
dvector & elem(int i)
Definition: fvar.hpp:3011
int save_identifier_string(const char *)
Writes a gradient stack verification string.
Definition: cmpdif2.cpp:315
dvector_position restore_dvector_position()
Definition: cmpdif4.cpp:88
dvar_matrix_position restore_dvar_matrix_position()
Definition: cmpdif6.cpp:114
static _THREAD DF_FILE * fp
void save_dvar_matrix_position(const dvar_matrix &m)
Definition: cmpdif5.cpp:345
ivector restore_ivector_value(const ivector_position &tmp)
Description not yet available.
Definition: cmpdif4.cpp:198
Class definition of matrix with derivitive information .
Definition: fvar.hpp:2480
Stores the adjoint gradient data that will be processed by gradcalc.
void nograd_assign_column(const dvar_matrix &m, const dvector &v, const int &ii)
Description not yet available.
Definition: cmpdif6.cpp:389
dvector value(const df1_one_vector &v)
Definition: df11fun.cpp:69
static _THREAD grad_stack * GRAD_STACK1
class for things related to the gradient structures, including dimension of arrays, size of buffers, etc.
void save_dmatrix_derivatives(const dvar_matrix_position &_pos, const double x, const int &i, int &j)
Description not yet available.
Definition: cmpdif5.cpp:265
void initialize(void)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dmat7.cpp:12
double *& get_v(void)
Definition: dvector.h:148
#define TINY
Definition: fvar_m15.cpp:22
df1_one_variable inv(const df1_one_variable &x)
Definition: df11fun.cpp:384
void save_ivector_value(const ivector &v)
Definition: cmpdif4.cpp:152
int colmax(void) const
Definition: fvar.hpp:2943
int colmax(void) const
Definition: fvar.hpp:2556
Description not yet available.
Definition: fvar.hpp:4843
unsigned int colsize() const
Definition: fvar.hpp:2584