ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fvar_m24.cpp
Go to the documentation of this file.
1 
6 #include <fvar.hpp>
7 #ifndef OPT_LIB
8  #include <cassert>
9  #include <climits>
10 #endif
11 
12 #ifdef __TURBOC__
13  #pragma hdrstop
14  #include <iostream.h>
15 #endif
16 
17 #if defined (__WAT32__)
18  #include <iostream.h>
19  #include <strstrea.h>
20 #endif
21 
22 #ifdef __ZTC__
23  #include <iostream.hpp>
24 #endif
25 
26 #define TINY 1.0e-20;
27 void dmdv_solve(void);
28 
29 dvar_vector solve(const dvar_matrix& aa, const dvar_vector& z,
30  prevariable& ln_unsigned_det, const prevariable& sign);
38 {
39  dvariable ln_unsigned_det;
41  dvar_vector sol=solve(aa,z,ln_unsigned_det,sign);
42  return sol;
43 }
44 
57  prevariable& ln_unsigned_det, const prevariable& _sign)
58 {
59  prevariable& sign=(prevariable&) _sign;
60 
64 
65 #if !defined(OPT_LIB) && (__cplusplus >= 201103L)
66  int n = [](unsigned int colsize) -> int
67  {
68  assert(colsize <= INT_MAX);
69  return static_cast<int>(colsize);
70  } (aa.colsize());
71 #else
72  int n = static_cast<int>(aa.colsize());
73 #endif
74  int lb=aa.colmin();
75  int ub=aa.colmax();
76  if (lb!=aa.rowmin()||ub!=aa.colmax())
77  {
78  cerr << "Error matrix not square in solve()"<<endl;
79  ad_exit(1);
80  }
81  ivector indx(lb,ub);
82  int One=1;
83  indx.fill_seqadd(lb,One);
84  double d;
85  double big,dum,sum,temp;
86  dvar_matrix_position dmp(aa,0);
87  dmatrix bb=value(aa);
88  kkludge_object kkk;
89  dvar_vector vc(lb,ub,kkk);
90  dvector vv(lb,ub);
91 
92  d=1.0;
93  double* pvv = vv.get_v() + lb;
94  dvector* pbbi = &bb.elem(lb);
95  for (int i=lb;i<=ub;i++)
96  {
97  big=0.0;
98  double* pbbij = pbbi->get_v() + lb;
99  for (int j=lb;j<=ub;j++)
100  {
101  temp=fabs(*pbbij);
102  if (temp > big)
103  {
104  big=temp;
105  }
106  ++pbbij;
107  }
108  if (big == 0.0)
109  {
110  cerr << "Error in matrix inverse -- matrix singular in "
111  "solve(dvar_dmatrix)\n";
112  }
113  *pvv = 1.0/big;
114  ++pvv;
115  ++pbbi;
116  }
117 
118  dvector* pbbj = &bb.elem(lb);
119  for (int j=lb;j<=ub;j++)
120  {
121  dvector* pbbi = &bb.elem(lb);
122  for (int i = lb; i < j; ++i)
123  {
124  double* pbbij = pbbi->get_v() + j;
125  sum = *pbbij;
126 
127  double* pbbik = pbbi->get_v() + lb;
128  dvector* pbbk = &bb.elem(lb);
129  for (int k=lb;k<i;k++)
130  {
131  sum -= *pbbik * *(pbbk->get_v() + j);
132  ++pbbik;
133  ++pbbk;
134  }
135 
136  //a[i][j]=sum;
137  *pbbij = sum;
138 
139  ++pbbi;
140  }
141 
142  int imax = j;
143  big=0.0;
144  pvv = vv.get_v() + j;
145 
146  pbbi = pbbj;
147  for (int i=j;i<=ub;i++)
148  {
149  double* pbbij = pbbi->get_v() + j;
150  sum = *pbbij;
151 
152  double* pbbik = pbbi->get_v() + lb;
153  dvector* pbbk = &bb.elem(lb);
154  for (int k=lb;k<j;k++)
155  {
156  sum -= *pbbik * *(pbbk->get_v() + j);
157  ++pbbik;
158  ++pbbk;
159  }
160  *pbbij = sum;
161  dum = *pvv * fabs(sum);
162  if (dum >= big)
163  {
164  big = dum;
165  imax = i;
166  }
167  ++pvv;
168  ++pbbi;
169  }
170 
171  if (j != imax)
172  {
173  double* pbbimaxk = bb.elem(imax).get_v() + lb;
174  double* pbbjk = pbbj->get_v() + lb;
175  for (int k=lb;k<=ub;k++)
176  {
177  dum = *pbbimaxk;
178  *pbbimaxk = *pbbjk;
179  *pbbjk = dum;
180 
181  ++pbbimaxk;
182  ++pbbjk;
183  }
184 
185  d = -1.*d;
186  vv[imax]=vv[j];
187 
188  //if (j<ub)
189  int* pindximax = indx.get_v() + imax;
190  int* pindxj = indx.get_v() + j;
191  {
192  int itemp = *pindximax;
193  *pindximax = *pindxj;
194  *pindxj = itemp;
195  }
196  //cout << "indx= " <<indx<<endl;
197  }
198 
199  double* pbbjj = pbbj->get_v() + j;
200  if (*pbbjj == 0.0)
201  {
202  *pbbjj = TINY;
203  }
204 
205  if (j != n)
206  {
207  dum = 1.0 / *pbbjj;
208  dvector* pbbi = &bb.elem(j + 1);
209  for (int i=j+1;i<=ub;i++)
210  {
211  double* pbbij = pbbi->get_v() + j;
212  *pbbij = *pbbij * dum;
213 
214  ++pbbi;
215  }
216  }
217 
218  ++pbbj;
219  }
220 
221  // get the determinant
222  sign=d;
223  dvector part_prod(lb,ub);
224  part_prod(lb)=log(fabs(bb(lb,lb)));
225  if (bb(lb,lb)<0) sign=-sign;
226  for (int j=lb+1;j<=ub;j++)
227  {
228  double bbjj = bb(j, j);
229  if (bbjj < 0) sign=-sign;
230  part_prod(j)=part_prod(j-1)+log(fabs(bbjj));
231  }
232  ln_unsigned_det=part_prod(ub);
233 
234  dvector x(lb,ub);
235  dvector y(lb,ub);
236  //int lb=rowmin;
237  //int ub=rowmax;
238  dmatrix& b=bb;
239  ivector indxinv(lb,ub);
240 
241  int* pindx = indx.get_v() + lb;
242  int* pindxinv = indxinv.get_v();
243  for (int i = lb; i <= ub; ++i)
244  {
245  *(pindxinv + *pindx) = i;
246  ++pindx;
247  }
248 
249  double_and_int* pz = z.get_va() + lb;
250  pindxinv = indxinv.get_v() + lb;
251  double* py = y.get_v();
252  for (int i = lb; i <= ub; ++i)
253  {
254  *(py + *pindxinv) = pz->x;
255 
256  ++pz;
257  ++pindxinv;
258  }
259 
260  py = y.get_v() + lb;
261  dvector* pbi = &b.elem(lb);
262  for (int i=lb;i<=ub;i++)
263  {
264  sum = *py;
265 
266  double* pyj = y.get_v() + lb;
267  double* pbij = pbi->get_v() + lb;
268  for (int j=lb;j<=i-1;j++)
269  {
270  sum -= *pbij * *pyj;
271 
272  ++pyj;
273  ++pbij;
274  }
275 
276  *py = sum;
277 
278  ++py;
279  ++pbi;
280  }
281 
282  py = y.get_v() + ub;
283  double* px = x.get_v() + ub;
284  pbi = &b.elem(ub);
285  for (int i=ub;i>=lb;i--)
286  {
287  sum = *py;
288 
289  double* pxj = x.get_v() + i + 1;
290  double* pbij = pbi->get_v() + i + 1;
291  for (int j=i+1;j<=ub;j++)
292  {
293  sum -= *pbij * *pxj;
294 
295  ++pxj;
296  ++pbij;
297  }
298  *px = sum / *(pbi->get_v() + i);
299 
300  --pbi;
301  --py;
302  --px;
303  }
304 
305  vc=nograd_assign(x);
306  save_identifier_string("PLACE8");
307  fp->save_prevariable_position(ln_unsigned_det);
308  save_identifier_string("PLACE7");
309  fp->save_dvector_value(part_prod);
310  fp->save_dvector_position(part_prod);
311  save_identifier_string("PLACE6");
312  fp->save_dvector_value(y);
313  fp->save_dvector_value(x);
314  save_identifier_string("PLACE5");
315  fp->save_dvector_position(x);
316  save_identifier_string("PLACE4");
317  fp->save_dvector_position(y);
318  fp->save_ivector_value(indx);
319  save_identifier_string("PLACE3a");
320  fp->save_ivector_position(indx);
321  save_identifier_string("PLACE3");
323  save_identifier_string("PLACE2b");
325  save_identifier_string("PLACE2a");
326  fp->save_dmatrix_value(bb);
327  save_identifier_string("PLACE2");
328  fp->save_dmatrix_position(bb);
329  save_identifier_string("PLACE1");
331  save_identifier_string("PLACE0");
334  return vc;
335 }
336 
339 void dmdv_solve(void)
340 {
342 
343  verify_identifier_string("PLACE0");
345  verify_identifier_string("PLACE1");
347  verify_identifier_string("PLACE2");
348  dmatrix b=fp->restore_dmatrix_value(bpos);
349  verify_identifier_string("PLACE2a");
351  verify_identifier_string("PLACE2b");
353  verify_identifier_string("PLACE3");
355  verify_identifier_string("PLACE3a");
356  ivector indx=restore_ivector_value(indx_pos);
358  verify_identifier_string("PLACE4");
360  verify_identifier_string("PLACE5");
361  dvector x=fp->restore_dvector_value(x_pos);
362  dvector y=fp->restore_dvector_value(y_pos);
363  verify_identifier_string("PLACE6");
364  dvector_position part_prod_pos=fp->restore_dvector_position();
365  dvector part_prod=fp->restore_dvector_value(part_prod_pos);
366  verify_identifier_string("PLACE7");
367  double df_ln_det=fp->restore_prevariable_derivative();
368  verify_identifier_string("PLACE8");
369  int lb=b.colmin();
370  int ub=b.colmax();
371  dmatrix dfb(lb,ub,lb,ub);
372  dvector dfz(lb,ub);
374  dvector dfy(lb,ub);
375  dvector dfpart_prod(lb,ub);
376  ivector indxinv(lb,ub);
377 
378  int* pindx = indx.get_v() + lb;
379  int* pindxinv = indxinv.get_v();
380  for (int i = lb; i <= ub; ++i)
381  {
382  *(pindxinv + *pindx) = i;
383  ++pindx;
384  }
385 
386  double dfsum=0.;
387  #ifndef SAFE_INITIALIZE
388  dfb.initialize();
389  dfy.initialize();
390  dfz.initialize();
391  dfpart_prod.initialize();
392  #endif
393 
394  double* pdfxi = dfx.get_v() + lb;
395  double* pdfyi = dfy.get_v() + lb;
396  double* pxi = x.get_v() + lb;
397  dvector* pbi = &b.elem(lb);
398  dvector* pdfbi = &dfb.elem(lb);
399  for (int i = lb; i <= ub; ++i)
400  {
401  double* pbii = pbi->get_v() + i;
402 
403  // x.elem(i)=sum/b.elem(i,i);
404  dfsum += *pdfxi / *pbii;
405  *(pdfbi->get_v() + i) -= *pdfxi * *pxi / *pbii;
406  *pdfxi = 0.0;
407 
408  double* pxj = x.get_v() + ub;
409  double* pdfxj = dfx.get_v() + ub;
410  double* pbij = pbi->get_v() + ub;
411  double* pdfbij = pdfbi->get_v() + ub;
412  for (int j = ub; j >= i + 1; --j)
413  {
414  // sum -=b.elem(i,j)*x.elem(j);
415  *pdfbij -= dfsum* *pxj;
416  *pdfxj -= dfsum * *pbij;
417  --pxj;
418  --pdfxj;
419  --pbij;
420  --pdfbij;
421  }
422 
423  // sum=y.elem(i);
424  *pdfyi += dfsum;
425  dfsum = 0.0;
426 
427  ++pdfxi;
428  ++pdfyi;
429  ++pxi;
430  ++pbi;
431  ++pdfbi;
432  }
433 
434  pdfyi = dfy.get_v() + ub;
435  pdfbi = &dfb.elem(ub);
436  pbi = &b.elem(ub);
437  for (int i=ub;i>=lb;i--)
438  {
439  // y.elem(i)=sum;
440  dfsum += *pdfyi;
441  *pdfyi = 0.0;
442 
443  double* pdfyj = dfy.get_v() + i - 1;
444  double* pyj = y.get_v() + i - 1;
445  double* pdfbij = pdfbi->get_v() + i - 1;
446  double* pbij = pbi->get_v() + i - 1;
447  for (int j=i-1;j>=lb;j--)
448  {
449  // sum-=b.elem(i,j)*y.elem(j);
450  *pdfbij -= dfsum * *pyj;
451  *pdfyj -= dfsum * *pbij;
452 
453  --pdfyj;
454  --pyj;
455  --pdfbij;
456  --pbij;
457  }
458  //sum=y.elem(i);
459  *pdfyi = dfsum;
460  dfsum = 0.0;
461 
462  --pdfyi;
463  --pdfbi;
464  --pbi;
465  }
466 
467  double* pdfz = dfz.get_v() + ub;
468  double* pdfy = dfy.get_v();
469  pindxinv = indxinv.get_v() + ub;
470  for (int i=ub;i>=lb;i--)
471  {
472  //y.elem(indxinv(i))=z.elem_value(i);
473  *pdfz = *(pdfy + *pindxinv);
474  --pdfz;
475  --pindxinv;
476  }
477 
478  dfz.save_dvector_derivatives(zpos);
479 
480  double* pdfpart_prod = dfpart_prod.get_v() + ub;
481  //ln_unsigned_det=part_prod(ub);
482  *pdfpart_prod += df_ln_det;
483  df_ln_det=0.0;
484 
485  dvector* pbj = &b.elem(ub);
486  dvector* pdfbj = &dfb.elem(ub);
487  for (int j=ub;j>=lb+1;j--)
488  {
489  double* pdfpart_prod2 = pdfpart_prod - 1;
490  //part_prod(j)=part_prod(j-1)+log(fabs(bb(j,j));
491  *pdfpart_prod2 += *pdfpart_prod;
492  *(pdfbj->get_v() + j) += *pdfpart_prod / *(pbj->get_v() + j);
493  *pdfpart_prod = 0.0;
494 
495  --pdfpart_prod;
496  --pbj;
497  --pdfbj;
498  }
499 
500  //part_prod(lb)=log(fabs(bb(lb,lb));
501  *(pdfbj->get_v() + lb) += *pdfpart_prod / *(pbj->get_v() + lb);
502  *pdfpart_prod = 0.0;
503 
504  pdfbj = &dfb(ub);
505  for (int j = ub; j >= lb; --j)
506  {
507  double bjj = b(j, j);
508  double* pdfbjj = pdfbj->get_v() + j;
509 
510  int* pindxi = indx.get_v() + ub;
511 
512  dvector* pdfbi = &dfb(ub);
513  dvector* pbi = &b(ub);
514  for (int i = ub; i >= lb; --i)
515  {
516  double* pdfbij = pdfbi->get_v() + j;
517  double* pbij = pbi->get_v() + j;
518  if (i<=j)
519  {
520  // b.elem(i,j)=sum;
521  dfsum += *pdfbij;
522  *pdfbij = 0.0;
523  }
524  else
525  {
526  // b.elem(i,j)=sum/b.elem(j,j);
527  dfsum+= *pdfbij / bjj;
528  *pdfbjj -= *pdfbij * *pbij / bjj;
529  *pdfbij = 0.0;
530  }
531 
532  int kmax = min(i - 1, j - 1);
533  if (kmax >= lb)
534  {
535  double* pdfbik = pdfbi->get_v() + kmax;
536  dvector* pdfbk = &dfb(kmax);
537  double* pbik = pbi->get_v() + kmax;
538  dvector* pbk = &b(kmax);
539  for (int k = kmax; k >= lb; --k)
540  {
541  // sum-=b.elem(i,k)*b.elem(k,j);
542  *pdfbik -= dfsum * *(pbk->get_v() + j);
543  *(pdfbk->get_v() + j) -= dfsum * *pbik;
544 
545  --pdfbik;
546  --pdfbk;
547  --pbik;
548  --pbk;
549  }
550  }
551  // sum=value(a(indx.elem(i),j);
552  save_dmatrix_derivatives(a_pos, dfsum, *pindxi, j); // like this
553  dfsum=0.;
554 
555  --pindxi;
556  --pdfbi;
557  --pbi;
558  }
559  --pdfbj;
560  }
561 }
562 #undef TINY
Description not yet available.
Definition: fvar.hpp:4883
Base class for dvariable.
Definition: fvar.hpp:1315
void dmdv_solve(void)
Adjoint code for dvar_vector solve(const dvar_matrix&amp; aa, const dvar_vector&amp; z,.
Definition: fvar_m24.cpp:339
double restore_prevariable_derivative()
Definition: cmpdif8.cpp:147
#define TINY
Definition: fvar_m24.cpp:26
void save_ivector_position(const ivector &v)
Definition: cmpdif3.cpp:198
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_and_int * get_va()
Definition: fvar.hpp:2231
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
void save_dvector_derivatives(const dvar_vector_position &pos) const
Puts the derivative values in a dvector into a dvar_vector&#39;s guts.
Definition: cmpdif5.cpp:212
Description not yet available.
Definition: fvar.hpp:4814
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
Null class to allow specialized function overloads.
Definition: fvar.hpp:469
ADMB variable vector.
Definition: fvar.hpp:2172
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
Holds the data for the prevariable class.
Definition: fvar.hpp:191
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
dvector solve(const dmatrix &aa, const dvector &z)
Solve a linear system using LU decomposition.
Definition: dmat34.cpp:46
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
dvar_vector_position restore_dvar_vector_position()
Definition: cmpdif4.cpp:69
void RETURN_ARRAYS_INCREMENT()
Definition: gradstrc.cpp:478
#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
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
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
void save_dvar_vector_position(const dvar_vector &v)
Definition: cmpdif3.cpp:214
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.
dvector restore_dvar_vector_derivatives(const dvar_vector_position &tmp)
Description not yet available.
Definition: cmpdif5.cpp:150
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
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
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
double x
&lt; value of the variable
Definition: fvar.hpp:195
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