ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
f1b2fnl3.cpp
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Author: David Fournier
5  * Copyright (c) 2008-2012 Regents of the University of California
6  */
11 #include <df1b2fnl.h>
12 #include <adrndeff.h>
13 
14 #ifndef OPT_LIB
15  #include <cassert>
16  #include <climits>
17 #endif
18 
25 {
26  // we need g_xu g_uu f_x and f_u
31 
34 
35  int us=0; int xs=0;
36 #ifndef OPT_LIB
37  assert(funnel_init_var::num_active_parameters <= INT_MAX);
38 #endif
40  ivector lfe_index(1, (int)funnel_init_var::num_active_parameters);
41 
42  for (int i=1;i<=(int)funnel_init_var::num_active_parameters;i++)
43  {
44  if (list(i,1)>xsize)
45  {
46  lre_index(++us)=i;
47  }
48  else if (list(i,1)>0)
49  {
50  lfe_index(++xs)=i;
51  }
52  }
53 
54  dvector local_xadjoint(1,xs);
55  dvector local_uadjoint(1,us);
56 
57  int* plfe_indexi = lfe_index.get_v() + 1;
58  double* plocal_xadjointi = local_xadjoint.get_v() + 1;
59  for (int i=1;i<=xs;i++)
60  {
61  int ii = *plfe_indexi;
62  *plocal_xadjointi = (*grad_x_u)(list(ii,1));
63 
64  ++plfe_indexi;
65  ++plocal_xadjointi;
66  }
67  int* plre_indexi = lre_index.get_v() + 1;
68  double* plocal_uadjointi = local_xadjoint.get_v() + 1;
69  for (int i=1;i<=us;i++)
70  {
71  int ii=*plre_indexi;
72  *plocal_uadjointi = (*grad_x_u)(list(ii,1));
73 
74  ++plre_indexi;
75  ++plocal_uadjointi;
76  }
77  dvector tmp;
78  if (us>0)
79  {
80  dmatrix local_Hess(1,us,1,us);
81  dvector local_grad(1,us);
82  dmatrix local_Dux(1,us,1,xs);
83  local_Hess.initialize();
84 
85  dvector* plocal_Hessi = &local_Hess(1);
86  plre_indexi = lre_index.get_v() + 1;
87  for (int i=1;i<=us;i++)
88  {
89  int i2=list(*plre_indexi, 2);
90 
91  double* plocal_Hessij = plocal_Hessi->get_v() + 1;
92  int* plre_indexj = lre_index.get_v() + 1;
93  for (int j=1;j<=us;j++)
94  {
95  int j2=list(*plre_indexj, 2);
96  *plocal_Hessij += locy(i2).u_bar[j2-1];
97 
98  ++plocal_Hessij;
99  ++plre_indexj;
100  }
101 
102  ++plocal_Hessi;
103  ++plre_indexi;
104  }
105  dvector* plocal_Duxi = &local_Dux(1);
106  plre_indexi = lre_index.get_v() + 1;
107  for (int i=1;i<=us;i++)
108  {
109  int i2=list(*plre_indexi, 2);
110 
111  double* plocal_Duxij = plocal_Duxi->get_v() + 1;
112  int* plfe_indexj = lfe_index.get_v() + 1;
113  for (int j=1;j<=xs;j++)
114  {
115  int j2=list(*plfe_indexj, 2);
116  *plocal_Duxij = locy(i2).u_bar[j2-1];
117 
118  ++plfe_indexj;
119  ++plocal_Duxij;
120  }
121 
122  ++plre_indexi;
123  ++plocal_Duxi;
124  }
125  tmp=solve(local_Hess,local_uadjoint)*local_Dux;
126  }
127 
128  plfe_indexi = lfe_index.get_v() + 1;
129  double* ptmpi = tmp.get_v() + 1;
130  for (int i=1;i<=xs;i++)
131  {
132  int ii = *plfe_indexi;
133  (*grad_x)(list(ii,1)) += *ptmpi;
134 
135  ++plfe_indexi;
136  ++ptmpi;
137  }
138  f1b2gradlist->reset();
146  funnel_init_var::num_active_parameters=0;
148 }
149 
160 {
161  set_dependent_variable(ff);// Initializs "dot_bar" for reverse mode AD
164  df1b2_gradcalc1();// Forward mode AD follow by a series of reverse sweeps
165 
166  // Independent variables for separable function
168  imatrix& list=*funnel_init_var::plist; // Index into "locy"
169 
170  int us=0; int xs=0; // us = #u's and xs = #x's
171 #ifndef OPT_LIB
172  assert(funnel_init_var::num_active_parameters <= INT_MAX);
173 #endif
175  ivector lfe_index(1, (int)funnel_init_var::num_active_parameters);
176 
177  // count to find us and xs, and find indexes of fixed and random effects
178  for (int i=1;i<=(int)funnel_init_var::num_active_parameters;i++)
179  {
180  if (list(i,1)>xsize) // x's are stored first in the joint vector
181  {
182  lre_index(++us)=i;
183  }
184  else if (list(i,1)>0)
185  {
186  lfe_index(++xs)=i;
187  }
188  }
189 
190  dvector local_xadjoint(1,xs); // First order derivative of ff wrt x
191  double* plocal_xadjointj = local_xadjoint.get_v() + 1;
192  int* plfe_indexj = lfe_index.get_v() + 1;
193  for (int j=1;j<=xs;j++)
194  {
195  int j2=list(*plfe_indexj, 2);
196  local_xadjoint(j)=ff.u_dot[j2-1]; // u_dot is the result of forward AD
197 
198  ++plocal_xadjointj;
199  ++plfe_indexj;
200  }
201 
202  if (us>0)
203  {
204  // Find Hessian matrix needed for Laplace approximation
205  dmatrix local_Hess(1,us,1,us);
206  dvector local_grad(1,us);
207  dmatrix local_Dux(1,us,1,xs);
208  local_Hess.initialize();
209  dvector local_uadjoint(1,us);
210 
211  dvector* plocal_Hessi = &local_Hess(1);
212  int* plre_indexi = lre_index.get_v() + 1;
213  for (int i=1;i<=us;i++)
214  {
215  int i2 = list(*plre_indexi, 2);
216 
217  double* plocal_Hessij = plocal_Hessi->get_v() + 1;
218  int* plre_indexj = lre_index.get_v() + 1;
219  for (int j=1;j<=us;j++)
220  {
221  int j2=list(*plre_indexj, 2);
222  *plocal_Hessij += locy(i2).u_bar[j2-1];
223 
224  ++plocal_Hessij;
225  ++plre_indexj;
226  }
227  ++plocal_Hessi;
228  ++plre_indexi;
229  }
230 
231  // First order derivative of separable function wrt u
232  plre_indexi = lre_index.get_v() + 1;
233  double* plocal_uadjointi = local_uadjoint.get_v() + 1;
234  for (int i=1;i<=us;i++)
235  {
236  int i2=list(*plre_indexi, 2);
237  *plocal_uadjointi = ff.u_dot[i2-1];
238 
239  ++plre_indexi;
240  ++plocal_uadjointi;
241  }
242 
243  // Mixed derivatives wrt x and u needed in the sensitivity of u_hat wrt x
244  dvector* plocal_Duxi = &local_Dux(1);
245  plre_indexi = lre_index.get_v() + 1;
246  for (int i=1;i<=us;i++)
247  {
248  int i2=list(*plre_indexi,2);
249 
250  int* plfe_indexj = lfe_index.get_v() + 1;
251  double* plocal_Duxij = plocal_Duxi->get_v() + 1;
252  for (int j=1;j<=xs;j++)
253  {
254  int j2=list(*plfe_indexj, 2);
255  *plocal_Duxij = locy(i2).u_bar[j2-1];
256 
257  ++plocal_Duxij;
258  ++plfe_indexj;
259  }
260  ++plocal_Duxi;
261  ++plre_indexi;
262  }
263 
264  // Enter calculations for the derivative of log(det(Hessian))
265 
266  //if (initial_df1b2params::separable_calculation_type==3)
267  {
268  //int nvar=us*us;
269  double f;// 0.5*log(det(local_Hess))
271  initial_df1b2params::cobjfun+=f; // Adds 0.5*log(det(local_Hess))
272 
273  dvector* pHessadjointi = &Hessadjoint(1);
274  plre_indexi = lre_index.get_v() + 1;
275  for (int i=1;i<=us;i++)
276  {
277  int i2=list(*plre_indexi, 2);
278 
279  double* pHessadjointij = pHessadjointi->get_v() + 1;
280  int* plre_indexj = lre_index.get_v() + 1;
281  for (int j=1;j<=us;j++)
282  {
283  int j2=list(*plre_indexj, 2);
284  locy(i2).get_u_bar_tilde()[j2-1] = *pHessadjointij;
285 
286  ++pHessadjointij;
287  ++plre_indexj;
288  }
289 
290  ++pHessadjointi;
291  ++plre_indexi;
292  }
293 
295  df1b2_gradcalc1();
296 
298  df1b2_gradcalc1();
299  dvector xtmp(1,xs);
300  xtmp.initialize();
301 
302  int* plfe_indexi = lfe_index.get_v() + 1;
303  double* pxtmpi = xtmp.get_v() + 1;
304  double* plocal_xadjointi = local_xadjoint.get_v() + 1;
305  for (int i=1;i<=xs;i++)
306  {
307  int i2=list(*plfe_indexi, 2);
308  *pxtmpi += locy[i2].u_tilde[0];
309  *plocal_xadjointi += locy[i2].u_tilde[0];
310 
311  ++plfe_indexi;
312  ++pxtmpi;
313  ++plocal_xadjointi;
314  }
315 
316  dvector utmp(1,us);
317  utmp.initialize();
318 
319  int* plre_indexi = lre_index.get_v() + 1;
320  double* putmpi = utmp.get_v() + 1;
321  double* plocal_uadjointi = local_uadjoint.get_v() + 1;
322  for (int i=1;i<=us;i++)
323  {
324  int i2=list(*plre_indexi, 2);
325  *putmpi += locy[i2].u_tilde[0];
326  *plocal_uadjointi += locy[i2].u_tilde[0];
327 
328  ++putmpi;
329  ++plre_indexi;
330  ++plocal_uadjointi;
331  }
332  if (xs>0)
333  local_xadjoint -= local_uadjoint*inv(local_Hess)*local_Dux;
334  }
335  }
336  int* plfe_indexi = lfe_index.get_v() + 1;
337  double* plocal_xadjointi = local_xadjoint.get_v() + 1;
338  for (int i=1;i<=xs;i++)
339  {
340  int ii = *plfe_indexi;
341  // Ads contribution to "global" gradient vector
342  xadjoint(list(ii,1)) += *plocal_xadjointi;
343 
344  ++plocal_xadjointi;
345  ++plfe_indexi;
346  }
347  f1b2gradlist->reset();
355  funnel_init_var::num_active_parameters=0;
357 }
358 
364  (const dmatrix& local_Hess,double & f)
365 {
366  int us=local_Hess.indexmax();
367  int nvar=us*us;
368  independent_variables cy(1,nvar);
369  cy.initialize();
370 
371  double* pcyii = cy.get_v() + 1;
372  const dvector* plocal_Hessi = &local_Hess(1);
373  for (int i=1;i<=us;i++)
374  {
375  double* plocal_Hessij = plocal_Hessi->get_v() + 1;
376  for (int j=1;j<=us;j++)
377  {
378  *pcyii = *plocal_Hessij;
379 
380  ++pcyii;
381  ++plocal_Hessij;
382  }
383  ++plocal_Hessi;
384  }
385 
386  dvar_vector vy=dvar_vector(cy);
387  dvar_matrix vHess(1,us,1,us);
388 
389  int ii=1;
390  dvar_vector* pvHessi = &vHess(1);
391  for (int i=1;i<=us;i++)
392  {
393  for (int j=1;j<=us;j++)
394  {
395  (*pvHessi)(j) = vy(ii++);
396  }
397  ++pvHessi;
398  }
399 
400  dvariable vf=0.0;
401  int sgn=0;
402  if (pmin->multinomial_weights==0)
403  {
404  vf+=0.5*ln_det(vHess,sgn);
405  }
406  else
407  {
408  dvector & w= *(pmin->multinomial_weights);
409  double w_i=w[separable_calls_counter];
410  double d=vHess.indexmax()-vHess.indexmin()+1;
411  vf+=w_i*(0.5*ln_det(vHess,sgn)-0.5*d*log(w_i));
412  vf-=w_i*d*.91893853320467241;
413  }
414  f=value(vf);
415  dvector g(1,nvar);
416  gradcalc(nvar,g);
417 
418  dmatrix hessadjoint(1,us,1,us);
419 
420  dvector* phessadjointi = &hessadjoint(1);
421  double* pgii = g.get_v() + 1;
422  for (int i=1;i<=us;i++)
423  {
424  double* phessadjointij = phessadjointi->get_v() + 1;
425  for (int j=1;j<=us;j++)
426  {
427  *phessadjointij = *pgii;
428 
429  ++phessadjointij;
430  ++pgii;
431  }
432 
433  ++phessadjointi;
434  }
435 
436  return hessadjoint;
437 }
void initialize(void)
Description not yet available.
Definition: df1b2f14.cpp:155
df1b2_gradlist * f1b2gradlist
Definition: df1b2glo.cpp:49
void set_dependent_variable(const df1b2variable &_x)
Description not yet available.
Definition: df1b2fn2.cpp:699
static void set_no_derivatives(void)
Definition: df1b2fun.h:760
Description not yet available.
Definition: imatrix.h:69
Description not yet available.
static double cobjfun
Definition: df1b2fun.h:1360
Vector of double precision numbers.
Definition: dvector.h:50
static int passnumber
Definition: df1b2fun.h:289
static int num_inactive_vars
Definition: df1b2fnl.h:66
void initialize(void)
Description not yet available.
Definition: df1b2f10.cpp:171
ADMB variable vector.
Definition: fvar.hpp:2172
Description not yet available.
Definition: df1b2fun.h:266
void gradcalc(int nvar, const dvector &g)
Definition: sgradclc.cpp:77
ivector sgn(const dvector &v)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dvect24.cpp:11
fixed_smartlist nlist
Definition: df1b2fun.h:754
void initialize(void)
Description not yet available.
Definition: df1b2f13.cpp:158
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
Description not yet available.
Definition: fvar.hpp:1937
test_smartlist list
Definition: df1b2fun.h:753
Array of integers(int) with indexes from index_min to indexmax.
Definition: ivector.h:50
static unsigned int num_active_parameters
Definition: df1b2fnl.h:67
fixed_smartlist2 nlist3
Definition: df1b2fun.h:758
Description not yet available.
fixed_smartlist2 nlist2
Definition: df1b2fun.h:756
static imatrix * plist
Definition: df1b2fnl.h:69
Description not yet available.
Definition: fvar.hpp:2819
void initialize(void)
Initialze all elements of dvector to zero.
Definition: dvect5.cpp:10
double ln_det(const dmatrix &m1, int &sgn)
Compute log determinant of a constant matrix.
Definition: dmat3.cpp:536
int indexmax() const
Definition: fvar.hpp:2921
test_smartlist list3
Definition: df1b2fun.h:757
int indexmax(void) const
Definition: fvar.hpp:2572
Description not yet available.
Definition: df1b2fun.h:373
Class definition of matrix with derivitive information .
Definition: fvar.hpp:2480
#define w
void do_separable_stuff_x_u_block_diagonal(df1b2variable &ff)
Description not yet available.
Definition: f1b2fnl3.cpp:24
dvector value(const df1_one_vector &v)
Definition: df11fun.cpp:69
static unsigned int num_vars
Definition: df1b2fnl.h:64
static init_df1b2vector * py
Definition: df1b2fnl.h:68
void initialize(void)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dmat7.cpp:12
void do_separable_stuff_laplace_approximation_block_diagonal(df1b2variable &)
Calculates the Laplace approximation for a single separable function in the &quot;block diagonal&quot;...
Definition: f1b2fnl3.cpp:159
double *& get_v(void)
Definition: dvector.h:148
int indexmin(void) const
Definition: fvar.hpp:2568
void reset(void)
Description not yet available.
Definition: df1b2fn2.cpp:581
test_smartlist list2
Definition: df1b2fun.h:755
Fundamental data type for reverse mode automatic differentiation.
Definition: fvar.hpp:1518
double * u_dot
Definition: df1b2fun.h:196
df1_one_variable inv(const df1_one_variable &x)
Definition: df11fun.cpp:384
d3_array log(const d3_array &arr3)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr2a.cpp:13
void df1b2_gradcalc1(void)
Description not yet available.
Definition: df1b2fun.cpp:145
dmatrix get_gradient_for_hessian_calcs(const dmatrix &local_Hess, double &f)
Description not yet available.
Definition: f1b2fnl3.cpp:364