ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fvar_m42.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 #ifdef __TURBOC__
13  #pragma hdrstop
14  #include <iomanip.h>
15 #endif
16 
17 #ifdef __ZTC__
18  #include <iomanip.hpp>
19 #endif
20 
21 #define TINY 1.0e-20;
22 void dfinvpret(void);
23 
24 // int min(int a,int b);
25 void df_xldet(void);
26 
27 #if defined(max)
28 #undef max
29 #endif
30 #if defined(min)
31 #undef min
32 #endif
33 
34 dvariable ln_det(const dvar_matrix& aa, int& sgn);
35 
37 {
38  int sgn = 1;
39  return ln_det(a, sgn);
40 }
46 dvariable ln_det(const dvar_matrix& aa, int& sgn)
47 {
48  int errflag=0;
49  int i,j,k;
50 #if !defined(OPT_LIB) && (__cplusplus >= 201103L)
51  int n = [](unsigned int colsize) -> int
52  {
53  assert(colsize <= INT_MAX);
54  return static_cast<int>(colsize);
55  } (aa.colsize());
56 #else
57  int n = static_cast<int>(aa.colsize());
58 #endif
59  int lb=aa.colmin();
60  int ub=aa.colmax();
61  ivector indx(lb,ub);
62  if (lb!=aa.rowmin()||ub!=aa.colmax())
63  {
64  cerr << "Error matrix not square in det()"<<endl;
65  ad_exit(1);
66  }
67  int One=1;
68  indx.fill_seqadd(lb,One);
69  double ld;
70  double big,dum,sum,temp;
71  dvar_matrix_position dmp(aa,1);
72  dmatrix bb=value(aa);
73  dvector vv(lb,ub);
74  dvector part_prod(lb,ub);
75 
76  ld=0.0;
77 
78  dvector* pbbi = &bb(lb);
79  double* pvvi = vv.get_v() + lb;
80  for (i=lb;i<=ub;i++)
81  {
82  big=0.0;
83  double* pbbij = pbbi->get_v() + lb;
84  for (j=lb;j<=ub;j++)
85  {
86  temp=fabs(*pbbij);
87  if (temp > big)
88  {
89  big=temp;
90  }
91  ++pbbij;
92  }
93  if (big == 0.0)
94  {
95  cerr << "Error in matrix inverse -- matrix singular in "
96  "inv(dvar_matrix)\n";
97  big=1.e+10;
98  errflag=1;
99  }
100  *pvvi = 1.0 / big;
101 
102  ++pbbi;
103  ++pvvi;
104  }
105 
106  dvector* pbbj = &bb(lb);
107  double* pvvj = vv.get_v() + lb;
108  for (j=lb;j<=ub;j++)
109  {
110  pbbi = &bb(lb);
111  for (i=lb;i<j;i++)
112  {
113  sum = *(pbbi->get_v() + j);
114 
115  double* pbbik = pbbi->get_v() + lb;
116  dvector* pbbk = &bb(lb);
117  for (k=lb;k<i;k++)
118  {
119  sum = sum - *pbbik * *(pbbk->get_v() + j);
120 
121  ++pbbik;
122  ++pbbk;
123  }
124  //a[i][j]=sum;
125  *(pbbi->get_v() + j) = sum;
126 
127  ++pbbi;
128  }
129  int imax = j;
130  big=0.0;
131  pbbi = &bb(j);
132  pvvi = vv.get_v() + j;
133  for (i=j;i<=ub;i++)
134  {
135  sum = *(pbbi->get_v() + j);
136 
137  double* pbbik = pbbi->get_v() + lb;
138  dvector* pbbk = &bb(lb);
139  for (k=lb;k<j;k++)
140  {
141  sum = sum - *pbbik * *(pbbk->get_v() + j);
142  ++pbbik;
143  ++pbbk;
144  }
145  *(pbbi->get_v() + j) = sum;
146  dum = *pvvi * fabs(sum);
147  if ( dum >= big)
148  {
149  big=dum;
150  imax=i;
151  }
152  ++pbbi;
153  ++pvvi;
154  }
155  if (j != imax)
156  {
157  double* pbbimaxk = bb(imax).get_v() + lb;
158  double* pbbjk = pbbj->get_v() + lb;
159  for (k=lb;k<=ub;k++)
160  {
161  dum = *pbbimaxk;
162  *pbbimaxk = *pbbjk;
163  *pbbjk = dum;
164 
165  ++pbbimaxk;
166  ++pbbjk;
167  }
168  //d = -1.*d;
169  sgn=-1*sgn;
170  vv.elem(imax) = *pvvj;
171 
172  //if (j<ub)
173  {
174  int itemp=indx.elem(imax);
175  indx.elem(imax)=indx.elem(j);
176  indx.elem(j)=itemp;
177  }
178  //cout << "indx= " <<indx<<endl;
179  }
180 
181  double* pbbjj = pbbj->get_v() + j;
182  if (*pbbjj == 0.0)
183  {
184  *pbbjj = TINY;
185  }
186 
187  if (j != n)
188  {
189  dum = 1.0 / *pbbjj;
190 
191  dvector* pbbi = &bb(j + 1);
192  for (i=j+1;i<=ub;i++)
193  {
194  *(pbbi->get_v() + j) *= dum;
195  ++pbbi;
196  }
197  }
198  ++pvvj;
199  ++pbbj;
200  }
201  double bb11 = bb(1, 1);
202  if (bb11 > 0)
203  part_prod(1)=ld+log(bb11);
204  else
205  {
206  part_prod(1)=ld+log(-bb11);
207  sgn=-sgn;
208  }
209 
210  for (j=lb+1;j<=ub;j++)
211  {
212  double bbjj = bb(j, j);
213  if (bbjj > 0)
214  part_prod(j)=part_prod(j-1)+log(bbjj);
215  else
216  {
217  part_prod(j)=part_prod(j-1)+log(-(bbjj));
218  sgn=-sgn;
219  }
220  }
221  double ldet=part_prod(ub);
222  dvariable rdet=nograd_assign(ldet);
223 
226  save_identifier_string("PLACE7");
227  fp->save_dvector_value(part_prod);
228  fp->save_dvector_position(part_prod);
229  fp->save_ivector_value(indx);
230  fp->save_ivector_position(indx);
231  save_identifier_string("PLACE3");
233  fp->save_prevariable_position(rdet);
234  fp->save_dmatrix_value(bb);
235  save_identifier_string("PLACE2");
236  fp->save_dmatrix_position(bb);
237  save_identifier_string("PLACE1");
238  fp->save_double_value(ld);
239  save_identifier_string("PLACE0");
240  GRAD_STACK1->set_gradient_stack(df_xldet);
241 
242  if (errflag) sgn=-1;
243  return rdet;
244 }
245 
247 void df_xldet(void)
248 {
250 
251  verify_identifier_string("PLACE0");
252  /*double ld=*/fp->restore_double_value();
253  verify_identifier_string("PLACE1");
255  verify_identifier_string("PLACE2");
256  dmatrix b=fp->restore_dmatrix_value(bpos);
257  //dvar_matrix_position rdet_pos=restore_prevariable_position();
258  double dfdet=fp->restore_prevariable_derivative();
260  verify_identifier_string("PLACE3");
262  ivector indx=restore_ivector_value(indx_pos);
263  dvector_position part_prod_pos=fp->restore_dvector_position();
264  dvector part_prod=fp->restore_dvector_value(part_prod_pos);
265  verify_identifier_string("PLACE7");
266  int lb=b.colmin();
267  int ub=b.colmax();
268  dmatrix dfb(lb,ub,lb,ub);
269 
270  dvector dfpart_prod(lb,ub);
271 
272  #ifndef SAFE_INITIALIZE
273  dfb.initialize();
274  dfpart_prod.initialize();
275  #endif
276 
277  dfpart_prod(ub)=dfdet;
278 
279  double* pdfpart_prodj = dfpart_prod.get_v() + ub;
280  double* pdfpart_prodj_1 = dfpart_prod.get_v() + ub - 1;
281  dvector* pbj = &b(ub);
282  dvector* pdfbj = &dfb(ub);
283  for (int j=ub;j>=lb+1;j--)
284  {
285  double bjj = *(pbj->get_v() + j);
286  double* pdfbjj = pdfbj->get_v() + j;
287  if (bjj > 0)
288  {
289  // part_prod(j)=part_prod(j-1)+log(b(j,j));
290  *pdfpart_prodj_1 += *pdfpart_prodj;
291  *pdfbjj += *pdfpart_prodj / bjj;
292  }
293  else
294  {
295  // part_prod(j)=part_prod(j-1)+log(-b(j,j));
296  *pdfpart_prodj_1 += *pdfpart_prodj;
297  *pdfbjj += *pdfpart_prodj / bjj;
298  }
299  *pdfpart_prodj = 0.0;
300 
301  --pdfpart_prodj;
302  --pdfpart_prodj_1;
303  --pbj;
304  --pdfbj;
305  }
306  //part_prod(1)=ld+log(b(lb,lb));
307  dfb(lb,lb)+=dfpart_prod(lb)/b(lb,lb);
308  dfpart_prod(lb) = 0.0;
309 
310  double dfsum = 0.0;
311  pdfbj = &dfb(ub);
312  pbj = &b(ub);
313  for (int j=ub;j>=lb;j--)
314  {
315  double bjj = *(pbj->get_v() + j);
316  double* pdfbjj = pdfbj->get_v() + j;
317  dvector* pdfbi = &dfb(ub);
318  int* pindxi = indx.get_v() + ub;
319  dvector* pbi = &b(ub);
320  for (int i=ub;i>=lb;i--)
321  {
322  double* pdfbij = pdfbi->get_v() + j;
323  if (i<=j)
324  {
325  // b(i,j)=sum;
326  dfsum += *pdfbij;
327  *pdfbij = 0.0;
328  }
329  else
330  {
331  // b(i,j)=sum/b(j,j);
332  dfsum += *pdfbij / bjj;
333  *pdfbjj -= *pdfbij * *(pbi->get_v() + j) / bjj;
334  *pdfbij = 0.0;
335  }
336 
337  for (int k=min(i-1,j-1);k>=lb;k--)
338  {
339  // sum-=b(i,k)*b(k,j);
340  dfb(i,k)-=dfsum*b(k,j);
341  dfb(k,j)-=dfsum*b(i,k);
342  }
343  // sum=value(a(indx(i),j);
344  save_dmatrix_derivatives(a_pos,dfsum,*pindxi,j); // like this
345  dfsum = 0.0;
346 
347  --pdfbi;
348  --pindxi;
349  --pbi;
350  }
351 
352  --pdfbj;
353  --pbj;
354  }
355 }
356 
357 #undef TINY
Description not yet available.
Definition: fvar.hpp:4883
int & elem(int i)
Definition: ivector.h:90
Description not yet available.
Definition: fvar.hpp:920
double & elem(int i)
Definition: dvector.h:152
double restore_prevariable_derivative()
Definition: cmpdif8.cpp:147
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
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
#define TINY
Definition: fvar_m42.cpp:21
dvar_vector nograd_assign(dvector tmp)
Description not yet available.
Definition: cmpdif6.cpp:252
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
ivector sgn(const dvector &v)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dvect24.cpp:11
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
prnstream & endl(prnstream &)
Array of integers(int) with indexes from index_min to indexmax.
Definition: ivector.h:50
void save_prevariable_position(const prevariable &v)
Definition: cmpdif8.cpp:60
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.
double restore_double_value()
Definition: cmpdif8.cpp:186
int colmin(void) const
Definition: fvar.hpp:2939
int rowmin(void) const
Definition: fvar.hpp:2560
Description not yet available.
Definition: fvar.hpp:2819
void initialize(void)
Initialze all elements of dvector to zero.
Definition: dvect5.cpp:10
int save_identifier_string(const char *)
Writes a gradient stack verification string.
Definition: cmpdif2.cpp:315
double ln_det(const dmatrix &m1, int &sgn)
Compute log determinant of a constant matrix.
Definition: dmat3.cpp:536
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 df_xldet(void)
Adjoint code for dvariable ln_det(const dvar_matrix&amp; aa, int&amp; sgn).
Definition: fvar_m42.cpp:247
void save_double_value(double x)
Definition: cmpdif8.cpp:94
dvector value(const df1_one_vector &v)
Definition: df11fun.cpp:69
static _THREAD grad_stack * GRAD_STACK1
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
Fundamental data type for reverse mode automatic differentiation.
Definition: fvar.hpp:1518
void save_ivector_value(const ivector &v)
Definition: cmpdif4.cpp:152
d3_array log(const d3_array &arr3)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr2a.cpp:13
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