CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
generic_model_external_function_wrapper.hpp
1 #ifndef CPPAD_CG_GENERIC_MODEL_EXTERNAL_FUNCTION_WRAPPER_INCLUDED
2 #define CPPAD_CG_GENERIC_MODEL_EXTERNAL_FUNCTION_WRAPPER_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2014 Ciengis
6  *
7  * CppADCodeGen is distributed under multiple licenses:
8  *
9  * - Eclipse Public License Version 1.0 (EPL1), and
10  * - GNU General Public License Version 3 (GPL3).
11  *
12  * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
13  * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
14  * ----------------------------------------------------------------------------
15  * Author: Joao Leal
16  */
17 
18 namespace CppAD {
19 namespace cg {
20 
21 template<class Base>
23 private:
24  GenericModel<Base>* model_;
25 public:
26 
28  model_(&model) {
29  }
30 
31  inline virtual ~GenericModelExternalFunctionWrapper() {
32  }
33 
34  virtual bool forward(FunctorGenericModel<Base>& libModel,
35  int q,
36  int p,
37  const Array tx[],
38  Array& ty) {
39  CPPADCG_ASSERT_KNOWN(!tx[0].sparse, "independent array must be dense");
40  ArrayView<const Base> x(static_cast<const Base*> (tx[0].data), tx[0].size);
41 
42  CPPADCG_ASSERT_KNOWN(!ty.sparse, "dependent array must be dense");
43  ArrayView<Base> y(static_cast<Base*> (ty.data), ty.size);
44 
45 
46  if (p == 0) {
47  model_->ForwardZero(x, y);
48  return true;
49 
50  } else if (p == 1) {
51  CPPADCG_ASSERT_KNOWN(tx[1].sparse, "independent Taylor array must be sparse");
52  Base* tx1 = static_cast<Base*> (tx[1].data);
53 
54  model_->ForwardOne(x,
55  tx[1].nnz, tx[1].idx, tx1,
56  y);
57  return true;
58  }
59 
60  return false;
61  }
62 
63  virtual bool reverse(FunctorGenericModel<Base>& libModel,
64  int p,
65  const Array tx[],
66  Array& px,
67  const Array py[]) {
68  CPPADCG_ASSERT_KNOWN(!tx[0].sparse, "independent array must be dense");
69  ArrayView<const Base> x(static_cast<const Base*> (tx[0].data), tx[0].size);
70 
71  CPPADCG_ASSERT_KNOWN(!px.sparse, "independent partials array must be dense");
72  ArrayView<Base> pxb(static_cast<Base*> (px.data), px.size);
73 
74  if (p == 0) {
75  CPPADCG_ASSERT_KNOWN(py[0].sparse, "dependent partials array must be sparse");
76  Base* pyb = static_cast<Base*> (py[0].data);
77 
78  model_->ReverseOne(x,
79  pxb,
80  py[0].nnz, py[0].idx, pyb);
81  return true;
82 
83  } else if (p == 1) {
84  CPPADCG_ASSERT_KNOWN(tx[1].sparse, "independent array must be sparse");
85  const Base* tx1 = static_cast<const Base*> (tx[1].data);
86  CPPADCG_ASSERT_KNOWN(py[0].sparse, "dependent partials array must be sparse");
87  CPPADCG_ASSERT_KNOWN(py[0].nnz == 0, "first order dependent partials must be zero");
88  CPPADCG_ASSERT_KNOWN(!py[1].sparse, "independent partials array must be dense");
89  ArrayView<const Base> py2(static_cast<Base*> (py[1].data), py[1].size);
90 
91  model_->ReverseTwo(x,
92  tx[1].nnz, tx[1].idx, tx1,
93  pxb,
94  py2);
95  return true;
96  }
97 
98  return false;
99  }
100 
101 };
102 
103 } // END cg namespace
104 } // END CppAD namespace
105 
106 #endif
VectorBase ForwardZero(const VectorBase &x)
VectorBase ReverseTwo(const VectorBase &tx, const VectorBase &ty, const VectorBase &py)
virtual bool forward(FunctorGenericModel< Base > &libModel, int q, int p, const Array tx[], Array &ty)
unsigned long size
VectorBase ForwardOne(const VectorBase &tx)
VectorBase ReverseOne(const VectorBase &tx, const VectorBase &ty, const VectorBase &py)
virtual bool reverse(FunctorGenericModel< Base > &libModel, int p, const Array tx[], Array &px, const Array py[])