CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
atomic_base.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_CORE_ATOMIC_BASE_HPP
2 # define CPPAD_CORE_ATOMIC_BASE_HPP
3 
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6 
7 CppAD is distributed under multiple licenses. This distribution is under
8 the terms of the
9  Eclipse Public License Version 1.0.
10 
11 A copy of this license is included in the COPYING file of this distribution.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14 
15 # include <set>
18 // needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
20 
21 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
22 /*!
23 \file atomic_base.hpp
24 Base class for atomic user operations.
25 */
26 
27 template <class Base>
28 class atomic_base {
29 // ===================================================================
30 public:
31  enum option_enum {
35  };
36 private:
37  // ------------------------------------------------------
38  // constants
39  //
40  /// index of this object in class_object
41  const size_t index_;
42 
43  // -----------------------------------------------------
44  // variables
45  //
46  /// sparsity pattern this object is currently using
47  /// (set by constructor and option member functions)
49 
50  /// temporary work space used by member functions, declared here to avoid
51  // memory allocation/deallocation for each usage
52  struct work_struct {
57  //
59  //
64  //
69  //
74  };
75  // Use pointers, to avoid false sharing between threads.
76  // Not using: vector<work_struct*> work_;
77  // so that deprecated atomic examples do not result in a memory leak.
78  work_struct* work_[CPPAD_MAX_NUM_THREADS];
79  // -----------------------------------------------------
80  // static member functions
81  //
82  /// List of all the object in this class
83  static std::vector<atomic_base *>& class_object(void)
85  static std::vector<atomic_base *> list_;
86  return list_;
87  }
88  /// List of names for each object in this class
89  static std::vector<std::string>& class_name(void)
91  static std::vector<std::string> list_;
92  return list_;
93  }
94  // =====================================================================
95 public:
96  // -----------------------------------------------------
97  // member functions not in user API
98  //
99  /// current sparsity setting
100  option_enum sparsity(void) const
101  { return sparsity_; }
102 
103  /// Name corresponding to a base_atomic object
104  const std::string& afun_name(void) const
105  { return class_name()[index_]; }
106 /*
107 $begin atomic_ctor$$
108 $spell
109  enum
110  sq
111  std
112  afun
113  arg
114  CppAD
115  bool
116  ctor
117  const
118  mat_mul_xam.cpp
119  hpp
120 $$
121 
122 $section Atomic Function Constructor$$
123 
124 $head Syntax$$
125 $icode%atomic_user afun%(%ctor_arg_list%)
126 %$$
127 $codei%atomic_base<%Base%>(%name%, %sparsity%)
128 %$$
129 
130 $head atomic_user$$
131 
132 $subhead ctor_arg_list$$
133 Is a list of arguments for the $icode atomic_user$$ constructor.
134 
135 $subhead afun$$
136 The object $icode afun$$ must stay in scope for as long
137 as the corresponding atomic function is used.
138 This includes use by any $cref/ADFun<Base>/ADFun/$$ that
139 has this $icode atomic_user$$ operation in its
140 $cref/operation sequence/glossary/Operation/Sequence/$$.
141 
142 $subhead Implementation$$
143 The user defined $icode atomic_user$$ class is a publicly derived class of
144 $codei%atomic_base<%Base%>%$$.
145 It should be declared as follows:
146 $codei%
147  class %atomic_user% : public CppAD::atomic_base<%Base%> {
148  public:
149  %atomic_user%(%ctor_arg_list%) : atomic_base<%Base%>(%name%, %sparsity%)
150  %...%
151  };
152 %$$
153 where $icode ...$$
154 denotes the rest of the implementation of the derived class.
155 This includes completing the constructor and
156 all the virtual functions that have their
157 $code atomic_base$$ implementations replaced by
158 $icode atomic_user$$ implementations.
159 
160 $head atomic_base$$
161 
162 $subhead Restrictions$$
163 The $code atomic_base$$ constructor cannot be called in
164 $cref/parallel/ta_in_parallel/$$ mode.
165 
166 $subhead Base$$
167 The template parameter determines the
168 $icode Base$$ type for this $codei%AD<%Base%>%$$ atomic operation.
169 
170 $subhead name$$
171 This $code atomic_base$$ constructor argument has the following prototype
172 $codei%
173  const std::string& %name%
174 %$$
175 It is the name for this atomic function and is used for error reporting.
176 The suggested value for $icode name$$ is $icode afun$$ or $icode atomic_user$$,
177 i.e., the name of the corresponding atomic object or class.
178 
179 $subhead sparsity$$
180 This $code atomic_base$$ constructor argument has prototype
181 $codei%
182  atomic_base<%Base%>::option_enum %sparsity%
183 %$$
184 The current $icode sparsity$$ for an $code atomic_base$$ object
185 determines which type of sparsity patterns it uses
186 and its value is one of the following:
187 $table
188 $icode sparsity$$ $cnext sparsity patterns $rnext
189 $codei%atomic_base<%Base%>::pack_sparsity_enum%$$ $pre $$ $cnext
190  $cref/vectorBool/CppAD_vector/vectorBool/$$
191 $rnext
192 $codei%atomic_base<%Base%>::bool_sparsity_enum%$$ $pre $$ $cnext
193  $cref/vector/CppAD_vector/$$$code <bool>$$
194 $rnext
195 $codei%atomic_base<%Base%>::set_sparsity_enum%$$ $pre $$ $cnext
196  $cref/vector/CppAD_vector/$$$code <std::set<std::size_t> >$$
197 $tend
198 There is a default value for $icode sparsity$$ if it is not
199 included in the constructor (which may be either the bool or set option).
200 
201 $head Example$$
202 
203 $subhead Define Constructor$$
204 The following is an example of a user atomic function constructor definitions:
205 $cref%get_started.cpp%atomic_get_started.cpp%Constructor%$$.
206 
207 $subhead Use Constructor$$
208 The following is an example using a user atomic function constructor:
209 $cref%get_started.cpp%atomic_get_started.cpp%Use Atomic Function%Constructor%$$.
210 
211 $end
212 */
213 /*!
214 Base class for atomic_user functions.
215 
216 \tparam Base
217 This class is used for defining an AD<Base> atomic operation y = f(x).
218 */
219 /// make sure user does not invoke the default constructor
221 { CPPAD_ASSERT_KNOWN(false,
222  "Attempt to use the atomic_base default constructor"
223  );
224 }
225 /*!
226 Constructor
227 
228 \param name
229 name used for error reporting
230 
231 \param sparsity [in]
232 what type of sparsity patterns are computed by this function,
233 bool_sparsity_enum or set_sparsity_enum. Default value is
234 bool sparsity patterns.
235 */
237  const std::string& name,
239 ) :
240 index_ ( class_object().size() ) ,
244  "atomic_base: constructor cannot be called in parallel mode."
245  );
246  class_object().push_back(this);
247  class_name().push_back(name);
248  CPPAD_ASSERT_UNKNOWN( class_object().size() == class_name().size() );
249  //
250  // initialize work pointers as null;
251  for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)
252  work_[thread] = CPPAD_NULL;
253 }
254 /// destructor informs CppAD that this atomic function with this index
255 /// has dropped out of scope by setting its pointer to null
256 virtual ~atomic_base(void)
258  // change object pointer to null, but leave name for error reporting
259  class_object()[index_] = CPPAD_NULL;
260  //
261  // free temporary work memory
262  for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)
263  free_work(thread);
264 }
265 /// allocates work_ for a specified thread
266 void allocate_work(size_t thread)
267 { if( work_[thread] == CPPAD_NULL )
268  { // allocate the raw memory
269  size_t min_bytes = sizeof(work_struct);
270  size_t num_bytes;
271  void* v_ptr = thread_alloc::get_memory(min_bytes, num_bytes);
272  // save in work_
273  work_[thread] = reinterpret_cast<work_struct*>( v_ptr );
274  // call constructor
275  new( work_[thread] ) work_struct;
276  }
277  return;
278 }
279 /// frees work_ for a specified thread
280 void free_work(size_t thread)
281 { if( work_[thread] != CPPAD_NULL )
282  { // call destructor
283  work_[thread]->~work_struct();
284  // return memory to avialable pool for this thread
285  thread_alloc::return_memory( reinterpret_cast<void*>(work_[thread]) );
286  // mark this thread as not allocated
287  work_[thread] = CPPAD_NULL;
288  }
289  return;
290 }
291 /// atomic_base function object corresponding to a certain index
292 static atomic_base* class_object(size_t index)
293 { CPPAD_ASSERT_UNKNOWN( class_object().size() > index );
294  return class_object()[index];
295 }
296 /// atomic_base function name corresponding to a certain index
297 static const std::string& class_name(size_t index)
298 { CPPAD_ASSERT_UNKNOWN( class_name().size() > index );
299  return class_name()[index];
300 }
301 /*
302 $begin atomic_option$$
303 $spell
304  sq
305  enum
306  afun
307  bool
308  CppAD
309  std
310  typedef
311 $$
312 
313 $section Set Atomic Function Options$$
314 
315 $head Syntax$$
316 $icode%afun%.option(%option_value%)%$$
317 These settings do not apply to individual $icode afun$$ calls,
318 but rather all subsequent uses of the corresponding atomic operation
319 in an $cref ADFun$$ object.
320 
321 $head atomic_sparsity$$
322 Note that, if you use $cref optimize$$, these sparsity patterns are used
323 to determine the $cref/dependency/dependency.cpp/$$ relationship between
324 argument and result variables.
325 
326 $subhead pack_sparsity_enum$$
327 If $icode option_value$$ is $codei%atomic_base<%Base%>::pack_sparsity_enum%$$,
328 then the type used by $icode afun$$ for
329 $cref/sparsity patterns/glossary/Sparsity Pattern/$$,
330 (after the option is set) will be
331 $codei%
332  typedef CppAD::vectorBool %atomic_sparsity%
333 %$$
334 If $icode r$$ is a sparsity pattern
335 for a matrix $latex R \in B^{p \times q}$$:
336 $icode%r%.size() == %p% * %q%$$.
337 
338 $subhead bool_sparsity_enum$$
339 If $icode option_value$$ is $codei%atomic_base<%Base%>::bool_sparsity_enum%$$,
340 then the type used by $icode afun$$ for
341 $cref/sparsity patterns/glossary/Sparsity Pattern/$$,
342 (after the option is set) will be
343 $codei%
344  typedef CppAD::vector<bool> %atomic_sparsity%
345 %$$
346 If $icode r$$ is a sparsity pattern
347 for a matrix $latex R \in B^{p \times q}$$:
348 $icode%r%.size() == %p% * %q%$$.
349 
350 $subhead set_sparsity_enum$$
351 If $icode option_value$$ is $icode%atomic_base<%Base%>::set_sparsity_enum%$$,
352 then the type used by $icode afun$$ for
353 $cref/sparsity patterns/glossary/Sparsity Pattern/$$,
354 (after the option is set) will be
355 $codei%
356  typedef CppAD::vector< std::set<size_t> > %atomic_sparsity%
357 %$$
358 If $icode r$$ is a sparsity pattern
359 for a matrix $latex R \in B^{p \times q}$$:
360 $icode%r%.size() == %p%$$, and for $latex i = 0 , \ldots , p-1$$,
361 the elements of $icode%r%[%i%]%$$ are between zero and $latex q-1$$ inclusive.
362 
363 $end
364 */
365 void option(enum option_enum option_value)
366 { switch( option_value )
367  { case pack_sparsity_enum:
368  case bool_sparsity_enum:
369  case set_sparsity_enum:
370  sparsity_ = option_value;
371  break;
372 
373  default:
375  false,
376  "atoic_base::option: option_value is not valid"
377  );
378  }
379  return;
380 }
381 /*
382 -----------------------------------------------------------------------------
383 $begin atomic_afun$$
384 
385 $spell
386  sq
387  mul
388  afun
389  const
390  CppAD
391  mat_mul.cpp
392 $$
393 
394 $section Using AD Version of Atomic Function$$
395 
396 $head Syntax$$
397 $icode%afun%(%ax%, %ay%)%$$
398 
399 $head Purpose$$
400 Given $icode ax$$,
401 this call computes the corresponding value of $icode ay$$.
402 If $codei%AD<%Base%>%$$ operations are being recorded,
403 it enters the computation as an atomic operation in the recording;
404 see $cref/start recording/Independent/Start Recording/$$.
405 
406 $head ADVector$$
407 The type $icode ADVector$$ must be a
408 $cref/simple vector class/SimpleVector/$$ with elements of type
409 $codei%AD<%Base%>%$$; see $cref/Base/atomic_ctor/atomic_base/Base/$$.
410 
411 $head afun$$
412 is a $cref/atomic_user/atomic_ctor/atomic_user/$$ object
413 and this $icode afun$$ function call is implemented by the
414 $cref/atomic_base/atomic_ctor/atomic_base/$$ class.
415 
416 $head ax$$
417 This argument has prototype
418 $codei%
419  const %ADVector%& %ax%
420 %$$
421 and size must be equal to $icode n$$.
422 It specifies vector $latex x \in B^n$$
423 at which an $codei%AD<%Base%>%$$ version of
424 $latex y = f(x)$$ is to be evaluated; see
425 $cref/Base/atomic_ctor/atomic_base/Base/$$.
426 
427 $head ay$$
428 This argument has prototype
429 $codei%
430  %ADVector%& %ay%
431 %$$
432 and size must be equal to $icode m$$.
433 The input values of its elements
434 are not specified (must not matter).
435 Upon return, it is an $codei%AD<%Base%>%$$ version of
436 $latex y = f(x)$$.
437 
438 $head Examples$$
439 The following files contain example uses of
440 the AD version of atomic functions during recording:
441 $cref%get_started.cpp%atomic_get_started.cpp%Use Atomic Function%Recording%$$,
442 $cref%norm_sq.cpp%atomic_norm_sq.cpp%Use Atomic Function%Recording%$$,
443 $cref%reciprocal.cpp%atomic_reciprocal.cpp%Use Atomic Function%Recording%$$,
444 $cref%tangent.cpp%atomic_tangent.cpp%Use Atomic Function%Recording%$$,
445 $cref%mat_mul.cpp%atomic_mat_mul.cpp%Use Atomic Function%Recording%$$.
446 
447 $end
448 -----------------------------------------------------------------------------
449 */
450 /*!
451 Implement the user call to <tt>afun(ax, ay)</tt> and old_atomic call to
452 <tt>afun(ax, ay, id)</tt>.
453 
454 \tparam ADVector
455 A simple vector class with elements of type <code>AD<Base></code>.
456 
457 \param id
458 optional extra information vector that is just passed through by CppAD,
459 and used by old_atomic derived class (not other derived classes).
460 This is an extra parameter to the virtual callbacks for old_atomic;
461 see the set_old member function.
462 
463 \param ax
464 is the argument vector for this call,
465 <tt>ax.size()</tt> determines the number of arguments.
466 
467 \param ay
468 is the result vector for this call,
469 <tt>ay.size()</tt> determines the number of results.
470 */
471 template <class ADVector>
473  const ADVector& ax ,
474  ADVector& ay ,
475  size_t id = 0 )
476 { size_t i, j;
477  size_t n = ax.size();
478  size_t m = ay.size();
479 # ifndef NDEBUG
480  bool ok;
481  std::string msg = "atomic_base: " + afun_name() + ".eval: ";
482  if( (n == 0) | (m == 0) )
483  { msg += "ax.size() or ay.size() is zero";
484  CPPAD_ASSERT_KNOWN(false, msg.c_str() );
485  }
486 # endif
487  size_t thread = thread_alloc::thread_num();
488  allocate_work(thread);
489  vector <Base>& tx = work_[thread]->tx;
490  vector <Base>& ty = work_[thread]->ty;
491  vector <bool>& vx = work_[thread]->vx;
492  vector <bool>& vy = work_[thread]->vy;
493  //
494  if( vx.size() != n )
495  { vx.resize(n);
496  tx.resize(n);
497  }
498  if( vy.size() != m )
499  { vy.resize(m);
500  ty.resize(m);
501  }
502  //
503  // Determine tape corresponding to variables in ax
504  tape_id_t tape_id = 0;
505  local::ADTape<Base>* tape = CPPAD_NULL;
506  for(j = 0; j < n; j++)
507  { tx[j] = ax[j].value_;
508  vx[j] = Variable( ax[j] );
509  if( vx[j] )
510  {
511  if( tape_id == 0 )
512  { tape = ax[j].tape_this();
513  tape_id = ax[j].tape_id_;
514  CPPAD_ASSERT_UNKNOWN( tape != CPPAD_NULL );
515  }
516 # ifndef NDEBUG
517  if( tape_id != ax[j].tape_id_ )
518  { msg += afun_name() +
519  ": ax contains variables from different threads.";
520  CPPAD_ASSERT_KNOWN(false, msg.c_str());
521  }
522 # endif
523  }
524  }
525  // Use zero order forward mode to compute values
526  size_t p = 0, q = 0;
527  set_old(id);
528 # ifdef NDEBUG
529  forward(p, q, vx, vy, tx, ty);
530 # else
531  ok = forward(p, q, vx, vy, tx, ty);
532  if( ! ok )
533  { msg += afun_name() + ": ok is false for "
534  "zero order forward mode calculation.";
535  CPPAD_ASSERT_KNOWN(false, msg.c_str());
536  }
537 # endif
538  bool record_operation = false;
539  for(i = 0; i < m; i++)
540  {
541  // pass back values
542  ay[i].value_ = ty[i];
543 
544  // initialize entire vector parameters (not in tape)
545  ay[i].tape_id_ = 0;
546  ay[i].taddr_ = 0;
547 
548  // we need to record this operation if
549  // any of the eleemnts of ay are variables,
550  record_operation |= vy[i];
551  }
552 # ifndef NDEBUG
553  if( record_operation & (tape == CPPAD_NULL) )
554  { msg +=
555  "all elements of vx are false but vy contains a true element";
556  CPPAD_ASSERT_KNOWN(false, msg.c_str() );
557  }
558 # endif
559  // if tape is not null, ay is on the tape
560  if( record_operation )
561  {
562  // Operator that marks beginning of this atomic operation
565  CPPAD_ASSERT_KNOWN( std::numeric_limits<addr_t>::max() >=
566  std::max( std::max( std::max(index_, id), n), m ),
567  "atomic_base: cppad_tape_addr_type maximum not large enough"
568  );
569  tape->Rec_.PutArg(addr_t(index_), addr_t(id), addr_t(n), addr_t(m));
570  tape->Rec_.PutOp(local::UserOp);
571 
572  // Now put n operators, one for each element of argument vector
577  for(j = 0; j < n; j++)
578  { if( vx[j] )
579  { // information for an argument that is a variable
580  tape->Rec_.PutArg(ax[j].taddr_);
581  tape->Rec_.PutOp(local::UsravOp);
582  }
583  else
584  { // information for an argument that is parameter
585  addr_t par = tape->Rec_.PutPar(ax[j].value_);
586  tape->Rec_.PutArg(par);
587  tape->Rec_.PutOp(local::UsrapOp);
588  }
589  }
590 
591  // Now put m operators, one for each element of result vector
596  for(i = 0; i < m; i++)
597  { if( vy[i] )
598  { ay[i].taddr_ = tape->Rec_.PutOp(local::UsrrvOp);
599  ay[i].tape_id_ = tape_id;
600  }
601  else
602  { addr_t par = tape->Rec_.PutPar(ay[i].value_);
603  tape->Rec_.PutArg(par);
604  tape->Rec_.PutOp(local::UsrrpOp);
605  }
606  }
607 
608  // Put a duplicate UserOp at end of UserOp sequence
609  CPPAD_ASSERT_KNOWN( std::numeric_limits<addr_t>::max() >=
610  std::max( std::max( std::max(index_, id), n), m ),
611  "atomic_base: cppad_tape_addr_type maximum not large enough"
612  );
613  tape->Rec_.PutArg(addr_t(index_), addr_t(id), addr_t(n), addr_t(m));
614  tape->Rec_.PutOp(local::UserOp);
615  }
616  return;
617 }
618 /*
619 -----------------------------------------------------------------------------
620 $begin atomic_forward$$
621 $spell
622  sq
623  mul.hpp
624  hes
625  afun
626  vx
627  vy
628  ty
629  Taylor
630  const
631  CppAD
632  bool
633 $$
634 
635 $section Atomic Forward Mode$$
636 $mindex callback virtual$$
637 
638 
639 $head Syntax$$
640 $icode%ok% = %afun%.forward(%p%, %q%, %vx%, %vy%, %tx%, %ty%)%$$
641 
642 $head Purpose$$
643 This virtual function is used by $cref atomic_afun$$
644 to evaluate function values.
645 It is also used buy $cref/forward/Forward/$$
646 to compute function vales and derivatives.
647 
648 $head Implementation$$
649 This virtual function must be defined by the
650 $cref/atomic_user/atomic_ctor/atomic_user/$$ class.
651 It can just return $icode%ok% == false%$$
652 (and not compute anything) for values
653 of $icode%q% > 0%$$ that are greater than those used by your
654 $cref/forward/Forward/$$ mode calculations.
655 
656 $head p$$
657 The argument $icode p$$ has prototype
658 $codei%
659  size_t %p%
660 %$$
661 It specifies the lowest order Taylor coefficient that we are evaluating.
662 During calls to $cref atomic_afun$$, $icode%p% == 0%$$.
663 
664 $head q$$
665 The argument $icode q$$ has prototype
666 $codei%
667  size_t %q%
668 %$$
669 It specifies the highest order Taylor coefficient that we are evaluating.
670 During calls to $cref atomic_afun$$, $icode%q% == 0%$$.
671 
672 $head vx$$
673 The $code forward$$ argument $icode vx$$ has prototype
674 $codei%
675  const CppAD::vector<bool>& %vx%
676 %$$
677 The case $icode%vx%.size() > 0%$$ only occurs while evaluating a call to
678 $cref atomic_afun$$.
679 In this case,
680 $icode%p% == %q% == 0%$$,
681 $icode%vx%.size() == %n%$$, and
682 for $latex j = 0 , \ldots , n-1$$,
683 $icode%vx%[%j%]%$$ is true if and only if
684 $icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$
685 in the corresponding call to
686 $codei%
687  %afun%(%ax%, %ay%)
688 %$$
689 If $icode%vx%.size() == 0%$$,
690 then $icode%vy%.size() == 0%$$ and neither of these vectors
691 should be used.
692 
693 $head vy$$
694 The $code forward$$ argument $icode vy$$ has prototype
695 $codei%
696  CppAD::vector<bool>& %vy%
697 %$$
698 If $icode%vy%.size() == 0%$$, it should not be used.
699 Otherwise,
700 $icode%q% == 0%$$ and $icode%vy%.size() == %m%$$.
701 The input values of the elements of $icode vy$$
702 are not specified (must not matter).
703 Upon return, for $latex j = 0 , \ldots , m-1$$,
704 $icode%vy%[%i%]%$$ is true if and only if
705 $icode%ay%[%i%]%$$ is a variable
706 (CppAD uses $icode vy$$ to reduce the necessary computations).
707 
708 $head tx$$
709 The argument $icode tx$$ has prototype
710 $codei%
711  const CppAD::vector<%Base%>& %tx%
712 %$$
713 and $icode%tx%.size() == (%q%+1)*%n%$$.
714 For $latex j = 0 , \ldots , n-1$$ and $latex k = 0 , \ldots , q$$,
715 we use the Taylor coefficient notation
716 $latex \[
717 \begin{array}{rcl}
718  x_j^k & = & tx [ j * ( q + 1 ) + k ]
719  \\
720  X_j (t) & = & x_j^0 + x_j^1 t^1 + \cdots + x_j^q t^q
721 \end{array}
722 \] $$
723 Note that superscripts represent an index for $latex x_j^k$$
724 and an exponent for $latex t^k$$.
725 Also note that the Taylor coefficients for $latex X(t)$$ correspond
726 to the derivatives of $latex X(t)$$ at $latex t = 0$$ in the following way:
727 $latex \[
728  x_j^k = \frac{1}{ k ! } X_j^{(k)} (0)
729 \] $$
730 
731 $head ty$$
732 The argument $icode ty$$ has prototype
733 $codei%
734  CppAD::vector<%Base%>& %ty%
735 %$$
736 and $icode%tx%.size() == (%q%+1)*%m%$$.
737 Upon return,
738 For $latex i = 0 , \ldots , m-1$$ and $latex k = 0 , \ldots , q$$,
739 $latex \[
740 \begin{array}{rcl}
741  Y_i (t) & = & f_i [ X(t) ]
742  \\
743  Y_i (t) & = & y_i^0 + y_i^1 t^1 + \cdots + y_i^q t^q + o ( t^q )
744  \\
745  ty [ i * ( q + 1 ) + k ] & = & y_i^k
746 \end{array}
747 \] $$
748 where $latex o( t^q ) / t^q \rightarrow 0$$ as $latex t \rightarrow 0$$.
749 Note that superscripts represent an index for $latex y_j^k$$
750 and an exponent for $latex t^k$$.
751 Also note that the Taylor coefficients for $latex Y(t)$$ correspond
752 to the derivatives of $latex Y(t)$$ at $latex t = 0$$ in the following way:
753 $latex \[
754  y_j^k = \frac{1}{ k ! } Y_j^{(k)} (0)
755 \] $$
756 If $latex p > 0$$,
757 for $latex i = 0 , \ldots , m-1$$ and $latex k = 0 , \ldots , p-1$$,
758 the input of $icode ty$$ satisfies
759 $latex \[
760  ty [ i * ( q + 1 ) + k ] = y_i^k
761 \]$$
762 and hence the corresponding elements need not be recalculated.
763 
764 $head ok$$
765 If the required results are calculated, $icode ok$$ should be true.
766 Otherwise, it should be false.
767 
768 $head Discussion$$
769 For example, suppose that $icode%q% == 2%$$,
770 and you know how to compute the function $latex f(x)$$,
771 its first derivative $latex f^{(1)} (x)$$,
772 and it component wise Hessian $latex f_i^{(2)} (x)$$.
773 Then you can compute $icode ty$$ using the following formulas:
774 $latex \[
775 \begin{array}{rcl}
776 y_i^0 & = & Y(0)
777  = f_i ( x^0 )
778 \\
779 y_i^1 & = & Y^{(1)} ( 0 )
780  = f_i^{(1)} ( x^0 ) X^{(1)} ( 0 )
781  = f_i^{(1)} ( x^0 ) x^1
782 \\
783 y_i^2
784 & = & \frac{1}{2 !} Y^{(2)} (0)
785 \\
786 & = & \frac{1}{2} X^{(1)} (0)^\R{T} f_i^{(2)} ( x^0 ) X^{(1)} ( 0 )
787  + \frac{1}{2} f_i^{(1)} ( x^0 ) X^{(2)} ( 0 )
788 \\
789 & = & \frac{1}{2} (x^1)^\R{T} f_i^{(2)} ( x^0 ) x^1
790  + f_i^{(1)} ( x^0 ) x^2
791 \end{array}
792 \] $$
793 For $latex i = 0 , \ldots , m-1$$, and $latex k = 0 , 1 , 2$$,
794 $latex \[
795  ty [ i * (q + 1) + k ] = y_i^k
796 \] $$
797 
798 $children%
799  example/atomic/forward.cpp
800 %$$
801 $head Examples$$
802 The file $cref atomic_forward.cpp$$ contains an example and test
803 that uses this routine.
804 It returns true if the test passes and false if it fails.
805 
806 $end
807 -----------------------------------------------------------------------------
808 */
809 /*!
810 Link from atomic_base to forward mode
811 
812 \param p [in]
813 lowerest order for this forward mode calculation.
814 
815 \param q [in]
816 highest order for this forward mode calculation.
817 
818 \param vx [in]
819 if size not zero, which components of \c x are variables
820 
821 \param vy [out]
822 if size not zero, which components of \c y are variables
823 
824 \param tx [in]
825 Taylor coefficients corresponding to \c x for this calculation.
826 
827 \param ty [out]
828 Taylor coefficient corresponding to \c y for this calculation
829 
830 See the forward mode in user's documentation for base_atomic
831 */
832 virtual bool forward(
833  size_t p ,
834  size_t q ,
835  const vector<bool>& vx ,
836  vector<bool>& vy ,
837  const vector<Base>& tx ,
838  vector<Base>& ty )
839 { return false; }
840 /*
841 -----------------------------------------------------------------------------
842 $begin atomic_reverse$$
843 $spell
844  sq
845  mul.hpp
846  afun
847  ty
848  px
849  py
850  Taylor
851  const
852  CppAD
853 $$
854 
855 $section Atomic Reverse Mode$$
856 $spell
857  bool
858 $$
859 
860 $head Syntax$$
861 $icode%ok% = %afun%.reverse(%q%, %tx%, %ty%, %px%, %py%)%$$
862 
863 $head Purpose$$
864 This function is used by $cref/reverse/Reverse/$$
865 to compute derivatives.
866 
867 $head Implementation$$
868 If you are using
869 $cref/reverse/Reverse/$$ mode,
870 this virtual function must be defined by the
871 $cref/atomic_user/atomic_ctor/atomic_user/$$ class.
872 It can just return $icode%ok% == false%$$
873 (and not compute anything) for values
874 of $icode q$$ that are greater than those used by your
875 $cref/reverse/Reverse/$$ mode calculations.
876 
877 $head q$$
878 The argument $icode q$$ has prototype
879 $codei%
880  size_t %q%
881 %$$
882 It specifies the highest order Taylor coefficient that
883 computing the derivative of.
884 
885 $head tx$$
886 The argument $icode tx$$ has prototype
887 $codei%
888  const CppAD::vector<%Base%>& %tx%
889 %$$
890 and $icode%tx%.size() == (%q%+1)*%n%$$.
891 For $latex j = 0 , \ldots , n-1$$ and $latex k = 0 , \ldots , q$$,
892 we use the Taylor coefficient notation
893 $latex \[
894 \begin{array}{rcl}
895  x_j^k & = & tx [ j * ( q + 1 ) + k ]
896  \\
897  X_j (t) & = & x_j^0 + x_j^1 t^1 + \cdots + x_j^q t^q
898 \end{array}
899 \] $$
900 Note that superscripts represent an index for $latex x_j^k$$
901 and an exponent for $latex t^k$$.
902 Also note that the Taylor coefficients for $latex X(t)$$ correspond
903 to the derivatives of $latex X(t)$$ at $latex t = 0$$ in the following way:
904 $latex \[
905  x_j^k = \frac{1}{ k ! } X_j^{(k)} (0)
906 \] $$
907 
908 $head ty$$
909 The argument $icode ty$$ has prototype
910 $codei%
911  const CppAD::vector<%Base%>& %ty%
912 %$$
913 and $icode%tx%.size() == (%q%+1)*%m%$$.
914 For $latex i = 0 , \ldots , m-1$$ and $latex k = 0 , \ldots , q$$,
915 we use the Taylor coefficient notation
916 $latex \[
917 \begin{array}{rcl}
918  Y_i (t) & = & f_i [ X(t) ]
919  \\
920  Y_i (t) & = & y_i^0 + y_i^1 t^1 + \cdots + y_i^q t^q + o ( t^q )
921  \\
922  y_i^k & = & ty [ i * ( q + 1 ) + k ]
923 \end{array}
924 \] $$
925 where $latex o( t^q ) / t^q \rightarrow 0$$ as $latex t \rightarrow 0$$.
926 Note that superscripts represent an index for $latex y_j^k$$
927 and an exponent for $latex t^k$$.
928 Also note that the Taylor coefficients for $latex Y(t)$$ correspond
929 to the derivatives of $latex Y(t)$$ at $latex t = 0$$ in the following way:
930 $latex \[
931  y_j^k = \frac{1}{ k ! } Y_j^{(k)} (0)
932 \] $$
933 
934 
935 $head F$$
936 We use the notation $latex \{ x_j^k \} \in B^{n \times (q+1)}$$ for
937 $latex \[
938  \{ x_j^k \W{:} j = 0 , \ldots , n-1, k = 0 , \ldots , q \}
939 \]$$
940 We use the notation $latex \{ y_i^k \} \in B^{m \times (q+1)}$$ for
941 $latex \[
942  \{ y_i^k \W{:} i = 0 , \ldots , m-1, k = 0 , \ldots , q \}
943 \]$$
944 We define the function
945 $latex F : B^{n \times (q+1)} \rightarrow B^{m \times (q+1)}$$ by
946 $latex \[
947  y_i^k = F_i^k [ \{ x_j^k \} ]
948 \] $$
949 Note that
950 $latex \[
951  F_i^0 ( \{ x_j^k \} ) = f_i ( X(0) ) = f_i ( x^0 )
952 \] $$
953 We also note that
954 $latex F_i^\ell ( \{ x_j^k \} )$$ is a function of
955 $latex x^0 , \ldots , x^\ell$$
956 and is determined by the derivatives of $latex f_i (x)$$
957 up to order $latex \ell$$.
958 
959 
960 $head G, H$$
961 We use $latex G : B^{m \times (q+1)} \rightarrow B$$
962 to denote an arbitrary scalar valued function of $latex \{ y_i^k \}$$.
963 We use $latex H : B^{n \times (q+1)} \rightarrow B$$
964 defined by
965 $latex \[
966  H ( \{ x_j^k \} ) = G[ F( \{ x_j^k \} ) ]
967 \] $$
968 
969 $head py$$
970 The argument $icode py$$ has prototype
971 $codei%
972  const CppAD::vector<%Base%>& %py%
973 %$$
974 and $icode%py%.size() == m * (%q%+1)%$$.
975 For $latex i = 0 , \ldots , m-1$$, $latex k = 0 , \ldots , q$$,
976 $latex \[
977  py[ i * (q + 1 ) + k ] = \partial G / \partial y_i^k
978 \] $$
979 
980 $subhead px$$
981 The $icode px$$ has prototype
982 $codei%
983  CppAD::vector<%Base%>& %px%
984 %$$
985 and $icode%px%.size() == n * (%q%+1)%$$.
986 The input values of the elements of $icode px$$
987 are not specified (must not matter).
988 Upon return,
989 for $latex j = 0 , \ldots , n-1$$ and $latex \ell = 0 , \ldots , q$$,
990 $latex \[
991 \begin{array}{rcl}
992 px [ j * (q + 1) + \ell ] & = & \partial H / \partial x_j^\ell
993 \\
994 & = &
995 ( \partial G / \partial \{ y_i^k \} ) \cdot
996  ( \partial \{ y_i^k \} / \partial x_j^\ell )
997 \\
998 & = &
999 \sum_{k=0}^q
1000 \sum_{i=0}^{m-1}
1001 ( \partial G / \partial y_i^k ) ( \partial y_i^k / \partial x_j^\ell )
1002 \\
1003 & = &
1004 \sum_{k=\ell}^q
1005 \sum_{i=0}^{m-1}
1006 py[ i * (q + 1 ) + k ] ( \partial F_i^k / \partial x_j^\ell )
1007 \end{array}
1008 \] $$
1009 Note that we have used the fact that for $latex k < \ell$$,
1010 $latex \partial F_i^k / \partial x_j^\ell = 0$$.
1011 
1012 $head ok$$
1013 The return value $icode ok$$ has prototype
1014 $codei%
1015  bool %ok%
1016 %$$
1017 If it is $code true$$, the corresponding evaluation succeeded,
1018 otherwise it failed.
1019 
1020 $children%
1021  example/atomic/reverse.cpp
1022 %$$
1023 $head Examples$$
1024 The file $cref atomic_reverse.cpp$$ contains an example and test
1025 that uses this routine.
1026 It returns true if the test passes and false if it fails.
1027 
1028 $end
1029 -----------------------------------------------------------------------------
1030 */
1031 /*!
1032 Link from reverse mode sweep to users routine.
1033 
1034 \param q [in]
1035 highest order for this reverse mode calculation.
1036 
1037 \param tx [in]
1038 Taylor coefficients corresponding to \c x for this calculation.
1039 
1040 \param ty [in]
1041 Taylor coefficient corresponding to \c y for this calculation
1042 
1043 \param px [out]
1044 Partials w.r.t. the \c x Taylor coefficients.
1045 
1046 \param py [in]
1047 Partials w.r.t. the \c y Taylor coefficients.
1048 
1049 See atomic_reverse mode use documentation
1050 */
1051 virtual bool reverse(
1052  size_t q ,
1053  const vector<Base>& tx ,
1054  const vector<Base>& ty ,
1055  vector<Base>& px ,
1056  const vector<Base>& py )
1057 { return false; }
1058 /*
1059 -------------------------------------- ---------------------------------------
1060 $begin atomic_for_sparse_jac$$
1061 $spell
1062  sq
1063  mul.hpp
1064  afun
1065  Jacobian
1066  jac
1067  const
1068  CppAD
1069  std
1070  bool
1071  std
1072 $$
1073 
1074 $section Atomic Forward Jacobian Sparsity Patterns$$
1075 
1076 $head Syntax$$
1077 $icode%ok% = %afun%.for_sparse_jac(%q%, %r%, %s%, %x%)
1078 %$$
1079 
1080 $head Deprecated 2016-06-27$$
1081 $icode%ok% = %afun%.for_sparse_jac(%q%, %r%, %s%)
1082 %$$
1083 
1084 $head Purpose$$
1085 This function is used by $cref ForSparseJac$$ to compute
1086 Jacobian sparsity patterns.
1087 For a fixed matrix $latex R \in B^{n \times q}$$,
1088 the Jacobian of $latex f( x + R * u)$$ with respect to $latex u \in B^q$$ is
1089 $latex \[
1090  S(x) = f^{(1)} (x) * R
1091 \] $$
1092 Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$,
1093 $code for_sparse_jac$$ computes a sparsity pattern for $latex S(x)$$.
1094 
1095 $head Implementation$$
1096 If you are using
1097 $cref ForSparseJac$$,
1098 $cref ForSparseHes$$, or
1099 $cref RevSparseHes$$,
1100 one of the versions of this
1101 virtual function must be defined by the
1102 $cref/atomic_user/atomic_ctor/atomic_user/$$ class.
1103 
1104 $subhead q$$
1105 The argument $icode q$$ has prototype
1106 $codei%
1107  size_t %q%
1108 %$$
1109 It specifies the number of columns in
1110 $latex R \in B^{n \times q}$$ and the Jacobian
1111 $latex S(x) \in B^{m \times q}$$.
1112 
1113 $subhead r$$
1114 This argument has prototype
1115 $codei%
1116  const %atomic_sparsity%& %r%
1117 %$$
1118 and is a $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
1119 $latex R \in B^{n \times q}$$.
1120 
1121 $subhead s$$
1122 This argument has prototype
1123 $codei%
1124  %atomic_sparsity%& %s%
1125 %$$
1126 The input values of its elements
1127 are not specified (must not matter).
1128 Upon return, $icode s$$ is a
1129 $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
1130 $latex S(x) \in B^{m \times q}$$.
1131 
1132 $subhead x$$
1133 $index deprecated$$
1134 The argument has prototype
1135 $codei%
1136  const CppAD::vector<%Base%>& %x%
1137 %$$
1138 and size is equal to the $icode n$$.
1139 This is the $cref Value$$ value corresponding to the parameters in the
1140 vector $cref/ax/atomic_afun/ax/$$ (when the atomic function was called).
1141 To be specific, if
1142 $codei%
1143  if( Parameter(%ax%[%i%]) == true )
1144  %x%[%i%] = Value( %ax%[%i%] );
1145  else
1146  %x%[%i%] = CppAD::numeric_limits<%Base%>::quiet_NaN();
1147 %$$
1148 The version of this function with out the $icode x$$ argument is deprecated;
1149 i.e., you should include the argument even if you do not use it.
1150 
1151 $head ok$$
1152 The return value $icode ok$$ has prototype
1153 $codei%
1154  bool %ok%
1155 %$$
1156 If it is $code true$$, the corresponding evaluation succeeded,
1157 otherwise it failed.
1158 
1159 $children%
1160  example/atomic/for_sparse_jac.cpp
1161 %$$
1162 $head Examples$$
1163 The file $cref atomic_for_sparse_jac.cpp$$ contains an example and test
1164 that uses this routine.
1165 It returns true if the test passes and false if it fails.
1166 
1167 $end
1168 -----------------------------------------------------------------------------
1169 */
1170 /*!
1171 Link, after case split, from for_jac_sweep to atomic_base.
1172 
1173 \param q
1174 is the column dimension for the Jacobian sparsity partterns.
1175 
1176 \param r
1177 is the Jacobian sparsity pattern for the argument vector x
1178 
1179 \param s
1180 is the Jacobian sparsity pattern for the result vector y
1181 
1182 \param x
1183 is the integer value for x arguments that are parameters.
1184 */
1185 virtual bool for_sparse_jac(
1186  size_t q ,
1187  const vector< std::set<size_t> >& r ,
1188  vector< std::set<size_t> >& s ,
1189  const vector<Base>& x )
1190 { return false; }
1191 virtual bool for_sparse_jac(
1192  size_t q ,
1193  const vector<bool>& r ,
1194  vector<bool>& s ,
1195  const vector<Base>& x )
1196 { return false; }
1197 virtual bool for_sparse_jac(
1198  size_t q ,
1199  const vectorBool& r ,
1200  vectorBool& s ,
1201  const vector<Base>& x )
1202 { return false; }
1203 // deprecated versions
1204 virtual bool for_sparse_jac(
1205  size_t q ,
1206  const vector< std::set<size_t> >& r ,
1207  vector< std::set<size_t> >& s )
1208 { return false; }
1209 virtual bool for_sparse_jac(
1210  size_t q ,
1211  const vector<bool>& r ,
1212  vector<bool>& s )
1213 { return false; }
1214 virtual bool for_sparse_jac(
1215  size_t q ,
1216  const vectorBool& r ,
1217  vectorBool& s )
1218 { return false; }
1219 
1220 /*!
1221 Link, before case split, from for_jac_sweep to atomic_base.
1222 
1223 \tparam InternalSparsity
1224 Is the used internaly for sparsity calculations; i.e.,
1225 sparse_pack or sparse_list.
1226 
1227 \param x
1228 is parameter arguments to the function, other components are nan.
1229 
1230 \param x_index
1231 is the variable index, on the tape, for the arguments to this function.
1232 This size of x_index is n, the number of arguments to this function.
1233 
1234 \param y_index
1235 is the variable index, on the tape, for the results for this function.
1236 This size of y_index is m, the number of results for this function.
1237 
1238 \param var_sparsity
1239 On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],
1240 is the sparsity for the j-th argument to this atomic function.
1241 On input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],
1242 is empty. On output, it is the sparsity
1243 for the j-th result for this atomic function.
1244 */
1245 template <class InternalSparsity>
1247  const vector<Base>& x ,
1248  const vector<size_t>& x_index ,
1249  const vector<size_t>& y_index ,
1250  InternalSparsity& var_sparsity )
1251 {
1252  // intial results are empty during forward mode
1253  size_t q = var_sparsity.end();
1254  bool input_empty = true;
1255  bool zero_empty = true;
1256  bool transpose = false;
1257  size_t m = y_index.size();
1258  bool ok = false;
1259  size_t thread = thread_alloc::thread_num();
1260  allocate_work(thread);
1261  //
1262  std::string msg = ": atomic_base.for_sparse_jac: returned false";
1263  if( sparsity_ == pack_sparsity_enum )
1264  { vectorBool& pack_r ( work_[thread]->pack_r );
1265  vectorBool& pack_s ( work_[thread]->pack_s );
1267  transpose, x_index, var_sparsity, pack_r
1268  );
1269  //
1270  pack_s.resize(m * q );
1271  ok = for_sparse_jac(q, pack_r, pack_s, x);
1272  if( ! ok )
1273  ok = for_sparse_jac(q, pack_r, pack_s);
1274  if( ! ok )
1275  { msg = afun_name() + msg + " sparsity = pack_sparsity_enum";
1276  CPPAD_ASSERT_KNOWN(false, msg.c_str());
1277  }
1278  local::set_internal_sparsity(zero_empty, input_empty,
1279  transpose, y_index, var_sparsity, pack_s
1280  );
1281  }
1282  else if( sparsity_ == bool_sparsity_enum )
1283  { vector<bool>& bool_r ( work_[thread]->bool_r );
1284  vector<bool>& bool_s ( work_[thread]->bool_s );
1286  transpose, x_index, var_sparsity, bool_r
1287  );
1288  bool_s.resize(m * q );
1289  ok = for_sparse_jac(q, bool_r, bool_s, x);
1290  if( ! ok )
1291  ok = for_sparse_jac(q, bool_r, bool_s);
1292  if( ! ok )
1293  { msg = afun_name() + msg + " sparsity = bool_sparsity_enum";
1294  CPPAD_ASSERT_KNOWN(false, msg.c_str());
1295  }
1296  local::set_internal_sparsity(zero_empty, input_empty,
1297  transpose, y_index, var_sparsity, bool_s
1298  );
1299  }
1300  else
1302  vector< std::set<size_t> >& set_r ( work_[thread]->set_r );
1303  vector< std::set<size_t> >& set_s ( work_[thread]->set_s );
1305  transpose, x_index, var_sparsity, set_r
1306  );
1307  //
1308  set_s.resize(m);
1309  ok = for_sparse_jac(q, set_r, set_s, x);
1310  if( ! ok )
1311  ok = for_sparse_jac(q, set_r, set_s);
1312  if( ! ok )
1313  { msg = afun_name() + msg + " sparsity = set_sparsity_enum";
1314  CPPAD_ASSERT_KNOWN(false, msg.c_str());
1315  }
1316  local::set_internal_sparsity(zero_empty, input_empty,
1317  transpose, y_index, var_sparsity, set_s
1318  );
1319  }
1320  return;
1321 }
1322 /*
1323 -------------------------------------- ---------------------------------------
1324 $begin atomic_rev_sparse_jac$$
1325 $spell
1326  sq
1327  mul.hpp
1328  rt
1329  afun
1330  Jacobian
1331  jac
1332  CppAD
1333  std
1334  bool
1335  const
1336  hes
1337 $$
1338 
1339 $section Atomic Reverse Jacobian Sparsity Patterns$$
1340 
1341 $head Syntax$$
1342 $icode%ok% = %afun%.rev_sparse_jac(%q%, %rt%, %st%, %x%)
1343 %$$
1344 
1345 $head Deprecated 2016-06-27$$
1346 $icode%ok% = %afun%.rev_sparse_jac(%q%, %rt%, %st%)
1347 %$$
1348 
1349 $head Purpose$$
1350 This function is used by
1351 $cref RevSparseJac$$ to compute
1352 Jacobian sparsity patterns.
1353 If you are using $cref RevSparseJac$$,
1354 one of the versions of this
1355 virtual function must be defined by the
1356 $cref/atomic_user/atomic_ctor/atomic_user/$$ class.
1357 $pre
1358 
1359 $$
1360 For a fixed matrix $latex R \in B^{q \times m}$$,
1361 the Jacobian of $latex R * f( x )$$ with respect to $latex x \in B^n$$ is
1362 $latex \[
1363  S(x) = R * f^{(1)} (x)
1364 \] $$
1365 Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$,
1366 $code rev_sparse_jac$$ computes a sparsity pattern for $latex S(x)$$.
1367 
1368 $head Implementation$$
1369 If you are using
1370 $cref RevSparseJac$$ or $cref ForSparseHes$$,
1371 this virtual function must be defined by the
1372 $cref/atomic_user/atomic_ctor/atomic_user/$$ class.
1373 
1374 $subhead q$$
1375 The argument $icode q$$ has prototype
1376 $codei%
1377  size_t %q%
1378 %$$
1379 It specifies the number of rows in
1380 $latex R \in B^{q \times m}$$ and the Jacobian
1381 $latex S(x) \in B^{q \times n}$$.
1382 
1383 $subhead rt$$
1384 This argument has prototype
1385 $codei%
1386  const %atomic_sparsity%& %rt%
1387 %$$
1388 and is a
1389 $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
1390 $latex R^\R{T} \in B^{m \times q}$$.
1391 
1392 $subhead st$$
1393 This argument has prototype
1394 $codei%
1395  %atomic_sparsity%& %st%
1396 %$$
1397 The input value of its elements
1398 are not specified (must not matter).
1399 Upon return, $icode s$$ is a
1400 $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
1401 $latex S(x)^\R{T} \in B^{n \times q}$$.
1402 
1403 $subhead x$$
1404 $index deprecated$$
1405 The argument has prototype
1406 $codei%
1407  const CppAD::vector<%Base%>& %x%
1408 %$$
1409 and size is equal to the $icode n$$.
1410 This is the $cref Value$$ corresponding to the parameters in the
1411 vector $cref/ax/atomic_afun/ax/$$ (when the atomic function was called).
1412 To be specific, if
1413 $codei%
1414  if( Parameter(%ax%[%i%]) == true )
1415  %x%[%i%] = Value( %ax%[%i%] );
1416  else
1417  %x%[%i%] = CppAD::numeric_limits<%Base%>::quiet_NaN();
1418 %$$
1419 The version of this function with out the $icode x$$ argument is deprecated;
1420 i.e., you should include the argument even if you do not use it.
1421 
1422 $head ok$$
1423 The return value $icode ok$$ has prototype
1424 $codei%
1425  bool %ok%
1426 %$$
1427 If it is $code true$$, the corresponding evaluation succeeded,
1428 otherwise it failed.
1429 
1430 $children%
1431  example/atomic/rev_sparse_jac.cpp
1432 %$$
1433 $head Examples$$
1434 The file $cref atomic_rev_sparse_jac.cpp$$ contains an example and test
1435 that uses this routine.
1436 It returns true if the test passes and false if it fails.
1437 
1438 $end
1439 -----------------------------------------------------------------------------
1440 */
1441 /*!
1442 Link, after case split, from rev_jac_sweep to atomic_base
1443 
1444 \param q [in]
1445 is the row dimension for the Jacobian sparsity partterns
1446 
1447 \param rt [out]
1448 is the tansposed Jacobian sparsity pattern w.r.t to range variables y
1449 
1450 \param st [in]
1451 is the tansposed Jacobian sparsity pattern for the argument variables x
1452 
1453 \param x
1454 is the integer value for x arguments that are parameters.
1455 */
1456 virtual bool rev_sparse_jac(
1457  size_t q ,
1458  const vector< std::set<size_t> >& rt ,
1459  vector< std::set<size_t> >& st ,
1460  const vector<Base>& x )
1461 { return false; }
1462 virtual bool rev_sparse_jac(
1463  size_t q ,
1464  const vector<bool>& rt ,
1465  vector<bool>& st ,
1466  const vector<Base>& x )
1467 { return false; }
1468 virtual bool rev_sparse_jac(
1469  size_t q ,
1470  const vectorBool& rt ,
1471  vectorBool& st ,
1472  const vector<Base>& x )
1473 { return false; }
1474 // deprecated versions
1475 virtual bool rev_sparse_jac(
1476  size_t q ,
1477  const vector< std::set<size_t> >& rt ,
1478  vector< std::set<size_t> >& st )
1479 { return false; }
1480 virtual bool rev_sparse_jac(
1481  size_t q ,
1482  const vector<bool>& rt ,
1483  vector<bool>& st )
1484 { return false; }
1485 virtual bool rev_sparse_jac(
1486  size_t q ,
1487  const vectorBool& rt ,
1488  vectorBool& st )
1489 { return false; }
1490 
1491 /*!
1492 Link, before case split, from rev_jac_sweep to atomic_base.
1493 
1494 \tparam InternalSparsity
1495 Is the used internaly for sparsity calculations; i.e.,
1496 sparse_pack or sparse_list.
1497 
1498 \param x
1499 is parameter arguments to the function, other components are nan.
1500 
1501 \param x_index
1502 is the variable index, on the tape, for the arguments to this function.
1503 This size of x_index is n, the number of arguments to this function.
1504 
1505 \param y_index
1506 is the variable index, on the tape, for the results for this function.
1507 This size of y_index is m, the number of results for this function.
1508 
1509 \param var_sparsity
1510 On input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],
1511 is the sparsity for the i-th argument to this atomic function.
1512 On output, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],
1513 the sparsity has been updated to remove y as a function of x.
1514 */
1515 template <class InternalSparsity>
1517  const vector<Base>& x ,
1518  const vector<size_t>& x_index ,
1519  const vector<size_t>& y_index ,
1520  InternalSparsity& var_sparsity )
1521 {
1522  // initial results may be non-empty during reverse mode
1523  size_t q = var_sparsity.end();
1524  bool input_empty = false;
1525  bool zero_empty = true;
1526  bool transpose = false;
1527  size_t n = x_index.size();
1528  bool ok = false;
1529  size_t thread = thread_alloc::thread_num();
1530  allocate_work(thread);
1531  //
1532  std::string msg = ": atomic_base.rev_sparse_jac: returned false";
1533  if( sparsity_ == pack_sparsity_enum )
1534  { vectorBool& pack_rt ( work_[thread]->pack_r );
1535  vectorBool& pack_st ( work_[thread]->pack_s );
1537  transpose, y_index, var_sparsity, pack_rt
1538  );
1539  //
1540  pack_st.resize(n * q );
1541  ok = rev_sparse_jac(q, pack_rt, pack_st, x);
1542  if( ! ok )
1543  ok = rev_sparse_jac(q, pack_rt, pack_st);
1544  if( ! ok )
1545  { msg = afun_name() + msg + " sparsity = pack_sparsity_enum";
1546  CPPAD_ASSERT_KNOWN(false, msg.c_str());
1547  }
1548  local::set_internal_sparsity(zero_empty, input_empty,
1549  transpose, x_index, var_sparsity, pack_st
1550  );
1551  }
1552  else if( sparsity_ == bool_sparsity_enum )
1553  { vector<bool>& bool_rt ( work_[thread]->bool_r );
1554  vector<bool>& bool_st ( work_[thread]->bool_s );
1556  transpose, y_index, var_sparsity, bool_rt
1557  );
1558  bool_st.resize(n * q );
1559  ok = rev_sparse_jac(q, bool_rt, bool_st, x);
1560  if( ! ok )
1561  ok = rev_sparse_jac(q, bool_rt, bool_st);
1562  if( ! ok )
1563  { msg = afun_name() + msg + " sparsity = bool_sparsity_enum";
1564  CPPAD_ASSERT_KNOWN(false, msg.c_str());
1565  }
1566  local::set_internal_sparsity(zero_empty, input_empty,
1567  transpose, x_index, var_sparsity, bool_st
1568  );
1569  }
1570  else
1572  vector< std::set<size_t> >& set_rt ( work_[thread]->set_r );
1573  vector< std::set<size_t> >& set_st ( work_[thread]->set_s );
1575  transpose, y_index, var_sparsity, set_rt
1576  );
1577  set_st.resize(n);
1578  ok = rev_sparse_jac(q, set_rt, set_st, x);
1579  if( ! ok )
1580  ok = rev_sparse_jac(q, set_rt, set_st);
1581  if( ! ok )
1582  { msg = afun_name() + msg + " sparsity = set_sparsity_enum";
1583  CPPAD_ASSERT_KNOWN(false, msg.c_str());
1584  }
1585  local::set_internal_sparsity(zero_empty, input_empty,
1586  transpose, x_index, var_sparsity, set_st
1587  );
1588  }
1589  return;
1590 }
1591 /*
1592 -------------------------------------- ---------------------------------------
1593 $begin atomic_for_sparse_hes$$
1594 $spell
1595  sq
1596  mul.hpp
1597  vx
1598  afun
1599  Jacobian
1600  jac
1601  CppAD
1602  std
1603  bool
1604  hes
1605  const
1606 $$
1607 
1608 $section Atomic Forward Hessian Sparsity Patterns$$
1609 
1610 $head Syntax$$
1611 $icode%ok% = %afun%.for_sparse_hes(%vx%, %r%, %s%, %h%, %x%)%$$
1612 
1613 $head Deprecated 2016-06-27$$
1614 $icode%ok% = %afun%.for_sparse_hes(%vx%, %r%, %s%, %h%)%$$
1615 
1616 $head Purpose$$
1617 This function is used by $cref ForSparseHes$$ to compute
1618 Hessian sparsity patterns.
1619 If you are using $cref ForSparseHes$$,
1620 one of the versions of this
1621 virtual function must be defined by the
1622 $cref/atomic_user/atomic_ctor/atomic_user/$$ class.
1623 $pre
1624 
1625 $$
1626 Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for
1627 a diagonal matrix $latex R \in B^{n \times n}$$, and
1628 a row vector $latex S \in B^{1 \times m}$$,
1629 this routine computes the sparsity pattern for
1630 $latex \[
1631  H(x) = R^\R{T} \cdot (S \cdot f)^{(2)}( x ) \cdot R
1632 \] $$
1633 
1634 $head Implementation$$
1635 If you are using and $cref ForSparseHes$$,
1636 this virtual function must be defined by the
1637 $cref/atomic_user/atomic_ctor/atomic_user/$$ class.
1638 
1639 $subhead vx$$
1640 The argument $icode vx$$ has prototype
1641 $codei%
1642  const CppAD:vector<bool>& %vx%
1643 %$$
1644 $icode%vx%.size() == %n%$$, and
1645 for $latex j = 0 , \ldots , n-1$$,
1646 $icode%vx%[%j%]%$$ is true if and only if
1647 $icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$
1648 in the corresponding call to
1649 $codei%
1650  %afun%(%ax%, %ay%)
1651 %$$
1652 
1653 $subhead r$$
1654 This argument has prototype
1655 $codei%
1656  const CppAD:vector<bool>& %r%
1657 %$$
1658 and is a $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
1659 the diagonal of $latex R \in B^{n \times n}$$.
1660 
1661 $subhead s$$
1662 The argument $icode s$$ has prototype
1663 $codei%
1664  const CppAD:vector<bool>& %s%
1665 %$$
1666 and its size is $icode m$$.
1667 It is a sparsity pattern for $latex S \in B^{1 \times m}$$.
1668 
1669 $subhead h$$
1670 This argument has prototype
1671 $codei%
1672  %atomic_sparsity%& %h%
1673 %$$
1674 The input value of its elements
1675 are not specified (must not matter).
1676 Upon return, $icode h$$ is a
1677 $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
1678 $latex H(x) \in B^{n \times n}$$ which is defined above.
1679 
1680 $subhead x$$
1681 $index deprecated$$
1682 The argument has prototype
1683 $codei%
1684  const CppAD::vector<%Base%>& %x%
1685 %$$
1686 and size is equal to the $icode n$$.
1687 This is the $cref Value$$ value corresponding to the parameters in the
1688 vector $cref/ax/atomic_afun/ax/$$ (when the atomic function was called).
1689 To be specific, if
1690 $codei%
1691  if( Parameter(%ax%[%i%]) == true )
1692  %x%[%i%] = Value( %ax%[%i%] );
1693  else
1694  %x%[%i%] = CppAD::numeric_limits<%Base%>::quiet_NaN();
1695 %$$
1696 The version of this function with out the $icode x$$ argument is deprecated;
1697 i.e., you should include the argument even if you do not use it.
1698 
1699 $children%
1700  example/atomic/for_sparse_hes.cpp
1701 %$$
1702 $head Examples$$
1703 The file $cref atomic_for_sparse_hes.cpp$$ contains an example and test
1704 that uses this routine.
1705 It returns true if the test passes and false if it fails.
1706 
1707 $end
1708 -----------------------------------------------------------------------------
1709 */
1710 /*!
1711 Link, after case split, from for_hes_sweep to atomic_base.
1712 
1713 \param vx [in]
1714 which componens of x are variables.
1715 
1716 \param r [in]
1717 is the forward Jacobian sparsity pattern w.r.t the argument vector x.
1718 
1719 \param s [in]
1720 is the reverse Jacobian sparsity pattern w.r.t the result vector y.
1721 
1722 \param h [out]
1723 is the Hessian sparsity pattern w.r.t the argument vector x.
1724 
1725 \param x
1726 is the integer value of the x arguments that are parameters.
1727 */
1728 virtual bool for_sparse_hes(
1729  const vector<bool>& vx ,
1730  const vector<bool>& r ,
1731  const vector<bool>& s ,
1732  vector< std::set<size_t> >& h ,
1733  const vector<Base>& x )
1734 { return false; }
1735 virtual bool for_sparse_hes(
1736  const vector<bool>& vx ,
1737  const vector<bool>& r ,
1738  const vector<bool>& s ,
1739  vector<bool>& h ,
1740  const vector<Base>& x )
1741 { return false; }
1742 virtual bool for_sparse_hes(
1743  const vector<bool>& vx ,
1744  const vector<bool>& r ,
1745  const vector<bool>& s ,
1746  vectorBool& h ,
1747  const vector<Base>& x )
1748 // deprecated
1749 { return false; }
1750 virtual bool for_sparse_hes(
1751  const vector<bool>& vx ,
1752  const vector<bool>& r ,
1753  const vector<bool>& s ,
1754  vector< std::set<size_t> >& h )
1755 { return false; }
1756 // deprecated versions
1757 virtual bool for_sparse_hes(
1758  const vector<bool>& vx ,
1759  const vector<bool>& r ,
1760  const vector<bool>& s ,
1761  vector<bool>& h )
1762 { return false; }
1763 virtual bool for_sparse_hes(
1764  const vector<bool>& vx ,
1765  const vector<bool>& r ,
1766  const vector<bool>& s ,
1767  vectorBool& h )
1768 { return false; }
1769 /*!
1770 Link, before case split, from for_hes_sweep to atomic_base.
1771 
1772 \tparam InternalSparsity
1773 Is the used internaly for sparsity calculations; i.e.,
1774 sparse_pack or sparse_list.
1775 
1776 \param x
1777 is parameter arguments to the function, other components are nan.
1778 
1779 \param x_index
1780 is the variable index, on the tape, for the arguments to this function.
1781 This size of x_index is n, the number of arguments to this function.
1782 
1783 \param y_index
1784 is the variable index, on the tape, for the results for this function.
1785 This size of y_index is m, the number of results for this function.
1786 
1787 \param for_jac_sparsity
1788 On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],
1789 is the forward Jacobian sparsity for the j-th argument to this atomic function.
1790 
1791 \param rev_jac_sparsity
1792 On input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],
1793 is the reverse Jacobian sparsity for the i-th result to this atomic function.
1794 This shows which components of the result affect the function we are
1795 computing the Hessian of.
1796 
1797 \param for_hes_sparsity
1798 This is the sparsity pattern for the Hessian. On input, the non-linear
1799 terms in the atomic fuction have not been included. Upon return, they
1800 have been included.
1801 */
1802 template <class InternalSparsity>
1804  const vector<Base>& x ,
1805  const vector<size_t>& x_index ,
1806  const vector<size_t>& y_index ,
1807  const InternalSparsity& for_jac_sparsity ,
1808  const InternalSparsity& rev_jac_sparsity ,
1809  InternalSparsity& for_hes_sparsity )
1810 { typedef typename InternalSparsity::const_iterator const_iterator;
1811  CPPAD_ASSERT_UNKNOWN( rev_jac_sparsity.end() == 1 );
1812  size_t n = x_index.size();
1813  size_t m = y_index.size();
1814  bool ok = false;
1815  size_t thread = thread_alloc::thread_num();
1816  allocate_work(thread);
1817  //
1818  // vx
1819  vector<bool> vx(n);
1820  for(size_t j = 0; j < n; j++)
1821  vx[j] = x_index[j] != 0;
1822  //
1823  // bool_r
1824  vector<bool>& bool_r( work_[thread]->bool_r );
1825  bool_r.resize(n);
1826  for(size_t j = 0; j < n; j++)
1827  { // check if we must compute row and column j of h
1828  const_iterator itr(for_jac_sparsity, x_index[j]);
1829  size_t i = *itr;
1830  bool_r[j] = i < for_jac_sparsity.end();
1831  }
1832  //
1833  // bool s
1834  vector<bool>& bool_s( work_[thread]->bool_s );
1835  bool_s.resize(m);
1836  for(size_t i = 0; i < m; i++)
1837  { // check if row i of result is included in h
1838  bool_s[i] = rev_jac_sparsity.is_element(y_index[i], 0);
1839  }
1840  //
1841  // h
1842  vectorBool& pack_h( work_[thread]->pack_h );
1843  vector<bool>& bool_h( work_[thread]->bool_h );
1844  vector< std::set<size_t> >& set_h( work_[thread]->set_h );
1845  //
1846  // call user's version of atomic function
1847  std::string msg = ": atomic_base.for_sparse_hes: returned false";
1848  if( sparsity_ == pack_sparsity_enum )
1849  { pack_h.resize(n * n);
1850  ok = for_sparse_hes(vx, bool_r, bool_s, pack_h, x);
1851  if( ! ok )
1852  ok = for_sparse_hes(vx, bool_r, bool_s, pack_h);
1853  if( ! ok )
1854  { msg = afun_name() + msg + " sparsity = pack_sparsity_enum";
1855  CPPAD_ASSERT_KNOWN(false, msg.c_str());
1856  }
1857  }
1858  else if( sparsity_ == bool_sparsity_enum )
1859  { bool_h.resize(n * n);
1860  ok = for_sparse_hes(vx, bool_r, bool_s, bool_h, x);
1861  if( ! ok )
1862  ok = for_sparse_hes(vx, bool_r, bool_s, bool_h);
1863  if( ! ok )
1864  { msg = afun_name() + msg + " sparsity = bool_sparsity_enum";
1865  CPPAD_ASSERT_KNOWN(false, msg.c_str());
1866  }
1867  }
1868  else
1870  set_h.resize(n);
1871  ok = for_sparse_hes(vx, bool_r, bool_s, set_h, x);
1872  if( ! ok )
1873  ok = for_sparse_hes(vx, bool_r, bool_s, set_h);
1874  if( ! ok )
1875  { msg = afun_name() + msg + " sparsity = set_sparsity_enum";
1876  CPPAD_ASSERT_KNOWN(false, msg.c_str());
1877  }
1878  }
1879  CPPAD_ASSERT_UNKNOWN( ok );
1880  //
1881  // modify hessian in calling routine
1882  for(size_t i = 0; i < n; i++)
1883  { for(size_t j = 0; j < n; j++)
1884  { if( (x_index[i] > 0) & (x_index[j] > 0) )
1885  { bool flag = false;
1886  switch( sparsity_ )
1887  { case pack_sparsity_enum:
1888  flag = pack_h[i * n + j];
1889  break;
1890  //
1891  case bool_sparsity_enum:
1892  flag = bool_h[i * n + j];
1893  break;
1894  //
1895  case set_sparsity_enum:
1896  flag = set_h[i].find(j) != set_h[i].end();
1897  break;
1898  }
1899  if( flag )
1900  { const_iterator itr_i(for_jac_sparsity, x_index[i]);
1901  size_t i_x = *itr_i;
1902  while( i_x < for_jac_sparsity.end() )
1903  { for_hes_sparsity.binary_union(
1904  i_x, i_x, x_index[j], for_jac_sparsity
1905  );
1906  i_x = *(++itr_i);
1907  }
1908  const_iterator itr_j(for_jac_sparsity, x_index[j]);
1909  size_t j_x = *itr_j;
1910  while( j_x < for_jac_sparsity.end() )
1911  { for_hes_sparsity.binary_union(
1912  j_x, j_x, x_index[i], for_jac_sparsity
1913  );
1914  j_x = *(++itr_j);
1915  }
1916  }
1917  }
1918  }
1919  }
1920  return;
1921 }
1922 /*
1923 -------------------------------------- ---------------------------------------
1924 $begin atomic_rev_sparse_hes$$
1925 $spell
1926  sq
1927  mul.hpp
1928  vx
1929  afun
1930  Jacobian
1931  jac
1932  CppAD
1933  std
1934  bool
1935  hes
1936  const
1937 $$
1938 
1939 $section Atomic Reverse Hessian Sparsity Patterns$$
1940 
1941 $head Syntax$$
1942 $icode%ok% = %afun%.rev_sparse_hes(%vx%, %s%, %t%, %q%, %r%, %u%, %v%, %x%)%$$
1943 
1944 $head Deprecated 2016-06-27$$
1945 $icode%ok% = %afun%.rev_sparse_hes(%vx%, %s%, %t%, %q%, %r%, %u%, %v%)%$$
1946 
1947 $head Purpose$$
1948 This function is used by $cref RevSparseHes$$ to compute
1949 Hessian sparsity patterns.
1950 If you are using $cref RevSparseHes$$ to compute
1951 one of the versions of this
1952 virtual function muse be defined by the
1953 $cref/atomic_user/atomic_ctor/atomic_user/$$ class.
1954 $pre
1955 
1956 $$
1957 There is an unspecified scalar valued function
1958 $latex g : B^m \rightarrow B$$.
1959 Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for
1960 $latex R \in B^{n \times q}$$,
1961 and information about the function $latex z = g(y)$$,
1962 this routine computes the sparsity pattern for
1963 $latex \[
1964  V(x) = (g \circ f)^{(2)}( x ) R
1965 \] $$
1966 
1967 $head Implementation$$
1968 If you are using and $cref RevSparseHes$$,
1969 this virtual function must be defined by the
1970 $cref/atomic_user/atomic_ctor/atomic_user/$$ class.
1971 
1972 $subhead vx$$
1973 The argument $icode vx$$ has prototype
1974 $codei%
1975  const CppAD:vector<bool>& %vx%
1976 %$$
1977 $icode%vx%.size() == %n%$$, and
1978 for $latex j = 0 , \ldots , n-1$$,
1979 $icode%vx%[%j%]%$$ is true if and only if
1980 $icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$
1981 in the corresponding call to
1982 $codei%
1983  %afun%(%ax%, %ay%)
1984 %$$
1985 
1986 $subhead s$$
1987 The argument $icode s$$ has prototype
1988 $codei%
1989  const CppAD:vector<bool>& %s%
1990 %$$
1991 and its size is $icode m$$.
1992 It is a sparsity pattern for
1993 $latex S(x) = g^{(1)} [ f(x) ] \in B^{1 \times m}$$.
1994 
1995 $subhead t$$
1996 This argument has prototype
1997 $codei%
1998  CppAD:vector<bool>& %t%
1999 %$$
2000 and its size is $icode m$$.
2001 The input values of its elements
2002 are not specified (must not matter).
2003 Upon return, $icode t$$ is a
2004 sparsity pattern for
2005 $latex T(x) \in B^{1 \times n}$$ where
2006 $latex \[
2007  T(x) = (g \circ f)^{(1)} (x) = S(x) * f^{(1)} (x)
2008 \]$$
2009 
2010 $subhead q$$
2011 The argument $icode q$$ has prototype
2012 $codei%
2013  size_t %q%
2014 %$$
2015 It specifies the number of columns in
2016 $latex R \in B^{n \times q}$$,
2017 $latex U(x) \in B^{m \times q}$$, and
2018 $latex V(x) \in B^{n \times q}$$.
2019 
2020 $subhead r$$
2021 This argument has prototype
2022 $codei%
2023  const %atomic_sparsity%& %r%
2024 %$$
2025 and is a $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
2026 $latex R \in B^{n \times q}$$.
2027 
2028 $head u$$
2029 This argument has prototype
2030 $codei%
2031  const %atomic_sparsity%& %u%
2032 %$$
2033 and is a $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
2034 $latex U(x) \in B^{m \times q}$$ which is defined by
2035 $latex \[
2036 \begin{array}{rcl}
2037 U(x)
2038 & = &
2039 \{ \partial_u \{ \partial_y g[ y + f^{(1)} (x) R u ] \}_{y=f(x)} \}_{u=0}
2040 \\
2041 & = &
2042 \partial_u \{ g^{(1)} [ f(x) + f^{(1)} (x) R u ] \}_{u=0}
2043 \\
2044 & = &
2045 g^{(2)} [ f(x) ] f^{(1)} (x) R
2046 \end{array}
2047 \] $$
2048 
2049 $subhead v$$
2050 This argument has prototype
2051 $codei%
2052  %atomic_sparsity%& %v%
2053 %$$
2054 The input value of its elements
2055 are not specified (must not matter).
2056 Upon return, $icode v$$ is a
2057 $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
2058 $latex V(x) \in B^{n \times q}$$ which is defined by
2059 $latex \[
2060 \begin{array}{rcl}
2061 V(x)
2062 & = &
2063 \partial_u [ \partial_x (g \circ f) ( x + R u ) ]_{u=0}
2064 \\
2065 & = &
2066 \partial_u [ (g \circ f)^{(1)}( x + R u ) ]_{u=0}
2067 \\
2068 & = &
2069 (g \circ f)^{(2)}( x ) R
2070 \\
2071 & = &
2072 f^{(1)} (x)^\R{T} g^{(2)} [ f(x) ] f^{(1)} (x) R
2073 +
2074 \sum_{i=1}^m g_i^{(1)} [ f(x) ] \; f_i^{(2)} (x) R
2075 \\
2076 & = &
2077 f^{(1)} (x)^\R{T} U(x)
2078 +
2079 \sum_{i=1}^m S_i (x) \; f_i^{(2)} (x) R
2080 \end{array}
2081 \] $$
2082 
2083 $subhead x$$
2084 $index deprecated$$
2085 The argument has prototype
2086 $codei%
2087  const CppAD::vector<%Base%>& %x%
2088 %$$
2089 and size is equal to the $icode n$$.
2090 This is the $cref Value$$ value corresponding to the parameters in the
2091 vector $cref/ax/atomic_afun/ax/$$ (when the atomic function was called).
2092 To be specific, if
2093 $codei%
2094  if( Parameter(%ax%[%i%]) == true )
2095  %x%[%i%] = Value( %ax%[%i%] );
2096  else
2097  %x%[%i%] = CppAD::numeric_limits<%Base%>::quiet_NaN();
2098 %$$
2099 The version of this function with out the $icode x$$ argument is deprecated;
2100 i.e., you should include the argument even if you do not use it.
2101 
2102 $children%
2103  example/atomic/rev_sparse_hes.cpp
2104 %$$
2105 $head Examples$$
2106 The file $cref atomic_rev_sparse_hes.cpp$$ contains an example and test
2107 that uses this routine.
2108 It returns true if the test passes and false if it fails.
2109 
2110 $end
2111 -----------------------------------------------------------------------------
2112 */
2113 /*!
2114 Link from reverse Hessian sparsity sweep to base_atomic
2115 
2116 \param vx [in]
2117 which componens of x are variables.
2118 
2119 \param s [in]
2120 is the reverse Jacobian sparsity pattern w.r.t the result vector y.
2121 
2122 \param t [out]
2123 is the reverse Jacobian sparsity pattern w.r.t the argument vector x.
2124 
2125 \param q [in]
2126 is the column dimension for the sparsity partterns.
2127 
2128 \param r [in]
2129 is the forward Jacobian sparsity pattern w.r.t the argument vector x
2130 
2131 \param u [in]
2132 is the Hessian sparsity pattern w.r.t the result vector y.
2133 
2134 \param v [out]
2135 is the Hessian sparsity pattern w.r.t the argument vector x.
2136 
2137 \param x [in]
2138 is the integer value of the x arguments that are parameters.
2139 */
2140 virtual bool rev_sparse_hes(
2141  const vector<bool>& vx ,
2142  const vector<bool>& s ,
2143  vector<bool>& t ,
2144  size_t q ,
2145  const vector< std::set<size_t> >& r ,
2146  const vector< std::set<size_t> >& u ,
2147  vector< std::set<size_t> >& v ,
2148  const vector<Base>& x )
2149 { return false; }
2150 virtual bool rev_sparse_hes(
2151  const vector<bool>& vx ,
2152  const vector<bool>& s ,
2153  vector<bool>& t ,
2154  size_t q ,
2155  const vector<bool>& r ,
2156  const vector<bool>& u ,
2157  vector<bool>& v ,
2158  const vector<Base>& x )
2159 { return false; }
2160 virtual bool rev_sparse_hes(
2161  const vector<bool>& vx ,
2162  const vector<bool>& s ,
2163  vector<bool>& t ,
2164  size_t q ,
2165  const vectorBool& r ,
2166  const vectorBool& u ,
2167  vectorBool& v ,
2168  const vector<Base>& x )
2169 { return false; }
2170 // deprecated
2171 virtual bool rev_sparse_hes(
2172  const vector<bool>& vx ,
2173  const vector<bool>& s ,
2174  vector<bool>& t ,
2175  size_t q ,
2176  const vector< std::set<size_t> >& r ,
2177  const vector< std::set<size_t> >& u ,
2178  vector< std::set<size_t> >& v )
2179 { return false; }
2180 virtual bool rev_sparse_hes(
2181  const vector<bool>& vx ,
2182  const vector<bool>& s ,
2183  vector<bool>& t ,
2184  size_t q ,
2185  const vector<bool>& r ,
2186  const vector<bool>& u ,
2187  vector<bool>& v )
2188 { return false; }
2189 virtual bool rev_sparse_hes(
2190  const vector<bool>& vx ,
2191  const vector<bool>& s ,
2192  vector<bool>& t ,
2193  size_t q ,
2194  const vectorBool& r ,
2195  const vectorBool& u ,
2196  vectorBool& v )
2197 { return false; }
2198 /*!
2199 Link, before case split, from rev_hes_sweep to atomic_base.
2200 
2201 \tparam InternalSparsity
2202 Is the used internaly for sparsity calculations; i.e.,
2203 sparse_pack or sparse_list.
2204 
2205 \param x
2206 is parameter arguments to the function, other components are nan.
2207 
2208 \param x_index
2209 is the variable index, on the tape, for the arguments to this function.
2210 This size of x_index is n, the number of arguments to this function.
2211 
2212 \param y_index
2213 is the variable index, on the tape, for the results for this function.
2214 This size of y_index is m, the number of results for this function.
2215 
2216 \param for_jac_sparsity
2217 On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],
2218 is the forward Jacobian sparsity for the j-th argument to this atomic function.
2219 
2220 \param rev_jac_flag
2221 This shows which variables affect the function we are
2222 computing the Hessian of.
2223 On input, for i = 0, ... , m-1, the rev_jac_flag[ y_index[i] ] is true
2224 if the Jacobian of function (we are computing sparsity for) is no-zero.
2225 Upon return, for j = 0, ... , n-1, rev_jac_flag [ x_index[j] ]
2226 as been adjusted to accound removing this atomic function.
2227 
2228 \param rev_hes_sparsity
2229 This is the sparsity pattern for the Hessian.
2230 On input, for i = 0, ... , m-1, row y_index[i] is the reverse Hessian sparsity
2231 with one of the partials with respect to to y_index[i].
2232 */
2233 template <class InternalSparsity>
2235  const vector<Base>& x ,
2236  const vector<size_t>& x_index ,
2237  const vector<size_t>& y_index ,
2238  const InternalSparsity& for_jac_sparsity ,
2239  bool* rev_jac_flag ,
2240  InternalSparsity& rev_hes_sparsity )
2241 { CPPAD_ASSERT_UNKNOWN( for_jac_sparsity.end() == rev_hes_sparsity.end() );
2242  size_t q = rev_hes_sparsity.end();
2243  size_t n = x_index.size();
2244  size_t m = y_index.size();
2245  bool ok = false;
2246  size_t thread = thread_alloc::thread_num();
2247  allocate_work(thread);
2248  bool zero_empty = true;
2249  bool input_empty = false;
2250  bool transpose = false;
2251  //
2252  // vx
2253  vector<bool> vx(n);
2254  for(size_t j = 0; j < n; j++)
2255  vx[j] = x_index[j] != 0;
2256  //
2257  // note that s and t are vectors so transpose does not matter for bool case
2258  vector<bool> bool_s( work_[thread]->bool_s );
2259  vector<bool> bool_t( work_[thread]->bool_t );
2260  //
2261  bool_s.resize(m);
2262  bool_t.resize(n);
2263  //
2264  for(size_t i = 0; i < m; i++)
2265  { if( y_index[i] > 0 )
2266  bool_s[i] = rev_jac_flag[ y_index[i] ];
2267  }
2268  //
2269  std::string msg = ": atomic_base.rev_sparse_hes: returned false";
2270  if( sparsity_ == pack_sparsity_enum )
2271  { vectorBool& pack_r( work_[thread]->pack_r );
2272  vectorBool& pack_u( work_[thread]->pack_u );
2273  vectorBool& pack_v( work_[thread]->pack_h );
2274  //
2275  pack_v.resize(n * q);
2276  //
2278  transpose, x_index, for_jac_sparsity, pack_r
2279  );
2281  transpose, y_index, rev_hes_sparsity, pack_u
2282  );
2283  //
2284  ok = rev_sparse_hes(vx, bool_s, bool_t, q, pack_r, pack_u, pack_v, x);
2285  if( ! ok )
2286  ok = rev_sparse_hes(vx, bool_s, bool_t, q, pack_r, pack_u, pack_v);
2287  if( ! ok )
2288  { msg = afun_name() + msg + " sparsity = pack_sparsity_enum";
2289  CPPAD_ASSERT_KNOWN(false, msg.c_str());
2290  }
2291  local::set_internal_sparsity(zero_empty, input_empty,
2292  transpose, x_index, rev_hes_sparsity, pack_v
2293  );
2294  }
2295  else if( sparsity_ == bool_sparsity_enum )
2296  { vector<bool>& bool_r( work_[thread]->bool_r );
2297  vector<bool>& bool_u( work_[thread]->bool_u );
2298  vector<bool>& bool_v( work_[thread]->bool_h );
2299  //
2300  bool_v.resize(n * q);
2301  //
2303  transpose, x_index, for_jac_sparsity, bool_r
2304  );
2306  transpose, y_index, rev_hes_sparsity, bool_u
2307  );
2308  //
2309  ok = rev_sparse_hes(vx, bool_s, bool_t, q, bool_r, bool_u, bool_v, x);
2310  if( ! ok )
2311  ok = rev_sparse_hes(vx, bool_s, bool_t, q, bool_r, bool_u, bool_v);
2312  if( ! ok )
2313  { msg = afun_name() + msg + " sparsity = bool_sparsity_enum";
2314  CPPAD_ASSERT_KNOWN(false, msg.c_str());
2315  }
2316  local::set_internal_sparsity(zero_empty, input_empty,
2317  transpose, x_index, rev_hes_sparsity, bool_v
2318  );
2319  }
2320  else
2322  vector< std::set<size_t> >& set_r( work_[thread]->set_r );
2323  vector< std::set<size_t> >& set_u( work_[thread]->set_u );
2324  vector< std::set<size_t> >& set_v( work_[thread]->set_h );
2325  //
2326  set_v.resize(n);
2327  //
2329  transpose, x_index, for_jac_sparsity, set_r
2330  );
2332  transpose, y_index, rev_hes_sparsity, set_u
2333  );
2334  //
2335  ok = rev_sparse_hes(vx, bool_s, bool_t, q, set_r, set_u, set_v, x);
2336  if( ! ok )
2337  ok = rev_sparse_hes(vx, bool_s, bool_t, q, set_r, set_u, set_v);
2338  if( ! ok )
2339  { msg = afun_name() + msg + " sparsity = set_sparsity_enum";
2340  CPPAD_ASSERT_KNOWN(false, msg.c_str());
2341  }
2342  local::set_internal_sparsity(zero_empty, input_empty,
2343  transpose, x_index, rev_hes_sparsity, set_v
2344  );
2345  }
2346  for(size_t j = 0; j < n; j++)
2347  { if( x_index[j] > 0 )
2348  rev_jac_flag[ x_index[j] ] |= bool_t[j];
2349  }
2350  return;
2351 }
2352 /*
2353 ------------------------------------------------------------------------------
2354 $begin atomic_base_clear$$
2355 $spell
2356  sq
2357  alloc
2358 $$
2359 
2360 $section Free Static Variables$$
2361 $mindex clear$$
2362 
2363 $head Syntax$$
2364 $codei%atomic_base<%Base%>::clear()%$$
2365 
2366 $head Purpose$$
2367 Each $code atomic_base$$ objects holds onto work space in order to
2368 avoid repeated memory allocation calls and thereby increase speed
2369 (until it is deleted).
2370 If an the $code atomic_base$$ object is global or static because,
2371 the it does not get deleted.
2372 This is a problem when using
2373 $code thread_alloc$$ $cref/free_all/ta_free_all/$$
2374 to check that all allocated memory has been freed.
2375 Calling this $code clear$$ function will free all the
2376 memory currently being held onto by the
2377 $codei%atomic_base<%Base%>%$$ class.
2378 
2379 $head Future Use$$
2380 If there is future use of an $code atomic_base$$ object,
2381 after a call to $code clear$$,
2382 the work space will be reallocated and held onto.
2383 
2384 $head Restriction$$
2385 This routine cannot be called
2386 while in $cref/parallel/ta_in_parallel/$$ execution mode.
2387 
2388 $end
2389 ------------------------------------------------------------------------------
2390 */
2391 /*!
2392 Free all thread_alloc static memory held by atomic_base (avoids reallocations).
2393 (This does not include class_object() which is an std::vector.)
2394 */
2395 /// Free vector memory used by this class (work space)
2396 static void clear(void)
2399  "cannot use atomic_base clear during parallel execution"
2400  );
2401  size_t i = class_object().size();
2402  while(i--)
2403  { atomic_base* op = class_object()[i];
2404  if( op != CPPAD_NULL )
2405  { for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)
2406  op->free_work(thread);
2407  }
2408  }
2409  return;
2410 }
2411 // -------------------------------------------------------------------------
2412 /*!
2413 Set value of id (used by deprecated old_atomic class)
2414 
2415 This function is called just before calling any of the virtual function
2416 and has the corresponding id of the corresponding virtual call.
2417 */
2418 virtual void set_old(size_t id)
2419 { }
2420 // ---------------------------------------------------------------------------
2421 };
2422 } // END_CPPAD_NAMESPACE
2423 # endif
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vector< bool > &h)
virtual bool rev_sparse_jac(size_t q, const vector< std::set< size_t > > &rt, vector< std::set< size_t > > &st, const vector< Base > &x)
Link, after case split, from rev_jac_sweep to atomic_base.
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
vector< std::set< size_t > > set_s
Definition: atomic_base.hpp:72
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vectorBool &h)
void free_work(size_t thread)
frees work_ for a specified thread
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vectorBool &h, const vector< Base > &x)
static std::vector< atomic_base * > & class_object(void)
List of all the object in this class.
Definition: atomic_base.hpp:83
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vector< std::set< size_t > > &r, const vector< std::set< size_t > > &u, vector< std::set< size_t > > &v)
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vectorBool &r, const vectorBool &u, vectorBool &v, const vector< Base > &x)
static void return_memory(void *v_ptr)
Return memory that was obtained by get_memory.
virtual bool for_sparse_jac(size_t q, const vectorBool &r, vectorBool &s, const vector< Base > &x)
CPPAD_TAPE_ADDR_TYPE addr_t
Definition: declare_ad.hpp:44
atomic_base(void)
Base class for atomic_user functions.
void get_internal_sparsity(bool transpose, const vector< size_t > &internal_index, const InternalSparsity &internal_pattern, sparse_rc< SizeVector > &pattern_out)
Get sparsity pattern for a sub-set of variables.
static bool in_parallel(void)
Are we in a parallel execution state; i.e., is it possible that other threads are currently executing...
virtual bool rev_sparse_jac(size_t q, const vector< bool > &rt, vector< bool > &st)
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Definition: op_code.hpp:175
void for_sparse_jac(const vector< Base > &x, const vector< size_t > &x_index, const vector< size_t > &y_index, InternalSparsity &var_sparsity)
Link, before case split, from for_jac_sweep to atomic_base.
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vector< std::set< size_t > > &h)
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
void for_sparse_hes(const vector< Base > &x, const vector< size_t > &x_index, const vector< size_t > &y_index, const InternalSparsity &for_jac_sparsity, const InternalSparsity &rev_jac_sparsity, InternalSparsity &for_hes_sparsity)
Link, before case split, from for_hes_sweep to atomic_base.
static size_t thread_num(void)
Get current thread number.
#define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
Check that the first call to a routine is not during parallel execution mode.
virtual ~atomic_base(void)
destructor informs CppAD that this atomic function with this index has dropped out of scope by settin...
void resize(size_t n)
change the number of elements in this vector.
Definition: vector.hpp:399
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
Definition: op_code.hpp:281
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vector< std::set< size_t > > &h, const vector< Base > &x)
Link, after case split, from for_hes_sweep to atomic_base.
virtual bool forward(size_t p, size_t q, const vector< bool > &vx, vector< bool > &vy, const vector< Base > &tx, vector< Base > &ty)
Link from atomic_base to forward mode.
virtual bool reverse(size_t q, const vector< Base > &tx, const vector< Base > &ty, vector< Base > &px, const vector< Base > &py)
Link from reverse mode sweep to users routine.
virtual bool rev_sparse_jac(size_t q, const vector< std::set< size_t > > &rt, vector< std::set< size_t > > &st)
vector< std::set< size_t > > set_h
Definition: atomic_base.hpp:70
static std::vector< std::string > & class_name(void)
List of names for each object in this class.
Definition: atomic_base.hpp:89
static void * get_memory(size_t min_bytes, size_t &cap_bytes)
Use thread_alloc to get a specified amount of memory.
virtual bool for_sparse_jac(size_t q, const vector< bool > &r, vector< bool > &s)
vector< std::set< size_t > > set_r
Definition: atomic_base.hpp:71
virtual void set_old(size_t id)
Set value of id (used by deprecated old_atomic class)
size_t size(void) const
number of elements currently in this vector.
Definition: vector.hpp:387
static const std::string & class_name(size_t index)
atomic_base function name corresponding to a certain index
void operator()(const ADVector &ax, ADVector &ay, size_t id=0)
Implement the user call to afun(ax, ay) and old_atomic call to afun(ax, ay, id).
virtual bool for_sparse_jac(size_t q, const vector< std::set< size_t > > &r, vector< std::set< size_t > > &s)
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vectorBool &r, const vectorBool &u, vectorBool &v)
option_enum sparsity(void) const
current sparsity setting
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vector< bool > &r, const vector< bool > &u, vector< bool > &v, const vector< Base > &x)
static atomic_base * class_object(size_t index)
atomic_base function object corresponding to a certain index
vector< std::set< size_t > > set_u
Definition: atomic_base.hpp:73
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION bool Variable(const AD< Base > &x)
Definition: par_var.hpp:99
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vector< std::set< size_t > > &r, const vector< std::set< size_t > > &u, vector< std::set< size_t > > &v, const vector< Base > &x)
Link from reverse Hessian sparsity sweep to base_atomic.
void allocate_work(size_t thread)
allocates work_ for a specified thread
option_enum sparsity_
sparsity pattern this object is currently using (set by constructor and option member functions) ...
Definition: atomic_base.hpp:48
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
virtual bool for_sparse_jac(size_t q, const vectorBool &r, vectorBool &s)
work_struct * work_[CPPAD_MAX_NUM_THREADS]
Definition: atomic_base.hpp:78
const size_t index_
index of this object in class_object
Definition: atomic_base.hpp:41
local::recorder< Base > Rec_
This is where the information is recorded.
Definition: ad_tape.hpp:106
virtual bool rev_sparse_jac(size_t q, const vectorBool &rt, vectorBool &st)
static void clear(void)
Free all thread_alloc static memory held by atomic_base (avoids reallocations).
Class used to hold tape that records AD&lt;Base&gt; operations.
Definition: ad_tape.hpp:26
void rev_sparse_jac(const vector< Base > &x, const vector< size_t > &x_index, const vector< size_t > &y_index, InternalSparsity &var_sparsity)
Link, before case split, from rev_jac_sweep to atomic_base.
virtual bool for_sparse_jac(size_t q, const vector< bool > &r, vector< bool > &s, const vector< Base > &x)
const std::string & afun_name(void) const
Name corresponding to a base_atomic object.
File used to define the CppAD multi-threading allocator class.
void set_internal_sparsity(bool zero_empty, bool input_empty, bool transpose, const vector< size_t > &internal_index, InternalSparsity &internal_pattern, const sparse_rc< SizeVector > &pattern_in)
Update the internal sparsity pattern for a sub-set of rows.
virtual bool rev_sparse_jac(size_t q, const vector< bool > &rt, vector< bool > &st, const vector< Base > &x)
void rev_sparse_hes(const vector< Base > &x, const vector< size_t > &x_index, const vector< size_t > &y_index, const InternalSparsity &for_jac_sparsity, bool *rev_jac_flag, InternalSparsity &rev_hes_sparsity)
Link, before case split, from rev_hes_sweep to atomic_base.
virtual bool for_sparse_jac(size_t q, const vector< std::set< size_t > > &r, vector< std::set< size_t > > &s, const vector< Base > &x)
Link, after case split, from for_jac_sweep to atomic_base.
Routines that enable code to be independent of which internal spasity pattern is used.
void resize(size_t n)
change number of elements in this vector
Definition: vector.hpp:721
atomic_base(const std::string &name, option_enum sparsity=bool_sparsity_enum)
Constructor.
virtual bool rev_sparse_jac(size_t q, const vectorBool &rt, vectorBool &st, const vector< Base > &x)
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vector< bool > &r, const vector< bool > &u, vector< bool > &v)
void option(enum option_enum option_value)
CPPAD_TAPE_ID_TYPE tape_id_t
Definition: declare_ad.hpp:45
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vector< bool > &h, const vector< Base > &x)
temporary work space used by member functions, declared here to avoid
Definition: atomic_base.hpp:52