1 #ifndef CPPAD_CG_FUNCTOR_GENERIC_MODEL_INCLUDED 2 #define CPPAD_CG_FUNCTOR_GENERIC_MODEL_INCLUDED 34 class FunctorGenericModel :
public GenericModel<Base> {
36 static constexpr
const char* ERROR_LIBRARY_NOT_READY =
"The model library is not ready. The model library that" 37 " provided this model might have been closed or deleted.";
44 std::vector<const Base*> _in;
45 std::vector<const Base*> _inHess;
46 std::vector<Base*> _out;
48 std::vector<std::string> _atomicNames;
49 std::vector<ExternalFunctionWrapper<Base>* > _atomic;
50 size_t _missingAtomicFunctions;
57 int (*_reverseOne)(Base
const tx[], Base
const ty[], Base px[], Base
const py[],
LangCAtomicFun);
59 int (*_reverseTwo)(Base
const tx[], Base
const ty[], Base px[], Base
const py[],
LangCAtomicFun);
61 void (*_jacobian)(Base
const*
const*, Base *
const*,
LangCAtomicFun);
63 void (*_hessian)(Base
const*
const*, Base *
const*,
LangCAtomicFun);
65 int (*_sparseForwardOne)(
unsigned long, Base
const *
const *, Base *
const *,
LangCAtomicFun);
67 int (*_sparseReverseOne)(
unsigned long, Base
const *
const *, Base *
const *,
LangCAtomicFun);
69 int (*_sparseReverseTwo)(
unsigned long, Base
const *
const *, Base *
const *,
LangCAtomicFun);
71 void (*_sparseJacobian)(Base
const*
const*, Base *
const*,
LangCAtomicFun);
73 void (*_sparseHessian)(Base
const*
const*, Base *
const*,
LangCAtomicFun);
75 void (*_forwardOneSparsity)(
unsigned long,
unsigned long const**,
unsigned long*);
77 void (*_reverseOneSparsity)(
unsigned long,
unsigned long const**,
unsigned long*);
79 void (*_reverseTwoSparsity)(
unsigned long,
unsigned long const**,
unsigned long*);
81 void (*_jacobianSparsity)(
unsigned long const** row,
82 unsigned long const** col,
85 void (*_hessianSparsity)(
unsigned long const** row,
86 unsigned long const** col,
88 void (*_hessianSparsity2)(
unsigned long i,
89 unsigned long const** row,
90 unsigned long const** col,
92 void (*_atomicFunctions)(
const char*** names,
99 _isLibraryReady(other._isLibraryReady),
100 _name(std::move(other._name)),
103 _in(std::move(other._in)),
104 _inHess(std::move(other._inHess)),
105 _out(std::move(other._out)),
106 _atomicFuncArg{
this, &atomicForward, &atomicReverse},
107 _atomicNames(std::move(other._atomicNames)),
108 _atomic(std::move(other._atomic)),
109 _missingAtomicFunctions(other._missingAtomicFunctions),
111 _forwardOne(other._forwardOne),
112 _reverseOne(other._reverseOne),
113 _reverseTwo(other._reverseTwo),
114 _jacobian(other._jacobian),
115 _hessian(other._hessian),
116 _sparseForwardOne(other._sparseForwardOne),
117 _sparseReverseOne(other._sparseReverseOne),
118 _sparseReverseTwo(other._sparseReverseTwo),
119 _sparseJacobian(other._sparseJacobian),
120 _sparseHessian(other._sparseHessian),
121 _forwardOneSparsity(other._forwardOneSparsity),
122 _reverseOneSparsity(other._reverseOneSparsity),
123 _reverseTwoSparsity(other._reverseTwoSparsity),
124 _jacobianSparsity(other._jacobianSparsity),
125 _hessianSparsity(other._hessianSparsity),
126 _hessianSparsity2(other._hessianSparsity2),
127 _atomicFunctions(other._atomicFunctions) {
129 other._isLibraryReady =
false;
136 for (
size_t i = 0; i < _atomic.size(); i++) {
151 (atomic, atomic.atomic_name());
161 return _jacobianSparsity !=
nullptr;
164 std::vector<bool> JacobianSparsityBool()
override {
165 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
166 CPPADCG_ASSERT_KNOWN(_jacobianSparsity !=
nullptr,
"No Jacobian sparsity function defined in the dynamic library")
168 unsigned long const* row, *col;
170 (*_jacobianSparsity)(&row, &col, &nnz);
172 bool set_type =
true;
175 loadSparsity(set_type, s, _m, _n, row, col, nnz);
180 std::vector<std::set<size_t> > JacobianSparsitySet()
override {
181 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
182 CPPADCG_ASSERT_KNOWN(_jacobianSparsity !=
nullptr,
"No Jacobian sparsity function defined in the dynamic library")
184 unsigned long const* row, *col;
186 (*_jacobianSparsity)(&row, &col, &nnz);
188 std::set<size_t> set_type;
189 std::vector<std::set<size_t> > s;
191 loadSparsity(set_type, s, _m, _n, row, col, nnz);
196 void JacobianSparsity(std::vector<size_t>& equations,
197 std::vector<size_t>& variables)
override {
198 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
199 CPPADCG_ASSERT_KNOWN(_jacobianSparsity !=
nullptr,
"No Jacobian sparsity function defined in the dynamic library")
201 unsigned long const* row, *col;
203 (*_jacobianSparsity)(&row, &col, &nnz);
205 equations.resize(nnz);
206 variables.resize(nnz);
208 std::copy(row, row + nnz, equations.begin());
209 std::copy(col, col + nnz, variables.begin());
214 return _hessianSparsity !=
nullptr;
217 std::vector<bool> HessianSparsityBool()
override {
218 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
219 CPPADCG_ASSERT_KNOWN(_hessianSparsity !=
nullptr,
"No Hessian sparsity function defined in the dynamic library")
221 unsigned long const* row, *col;
223 (*_hessianSparsity)(&row, &col, &nnz);
225 bool set_type =
true;
228 loadSparsity(set_type, s, _n, _n, row, col, nnz);
234 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
235 CPPADCG_ASSERT_KNOWN(_hessianSparsity !=
nullptr,
"No Hessian sparsity function defined in the dynamic library")
237 unsigned long const* row, *col;
239 (*_hessianSparsity)(&row, &col, &nnz);
241 std::set<size_t> set_type;
242 std::vector<std::set<size_t> > s;
244 loadSparsity(set_type, s, _n, _n, row, col, nnz);
249 void HessianSparsity(std::vector<size_t>& rows,
250 std::vector<size_t>& cols)
override {
251 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
252 CPPADCG_ASSERT_KNOWN(_hessianSparsity !=
nullptr,
"No Hessian sparsity function defined in the dynamic library")
254 unsigned long const* row, *col;
256 (*_hessianSparsity)(&row, &col, &nnz);
261 std::copy(row, row + nnz, rows.begin());
262 std::copy(col, col + nnz, cols.begin());
266 return _hessianSparsity2 !=
nullptr;
270 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
271 CPPADCG_ASSERT_KNOWN(_hessianSparsity2 !=
nullptr,
"No Hessian sparsity function defined in the dynamic library")
273 unsigned long const* row, *col;
275 (*_hessianSparsity2)(i, &row, &col, &nnz);
277 bool set_type =
true;
280 loadSparsity(set_type, s, _n, _n, row, col, nnz);
286 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
287 CPPADCG_ASSERT_KNOWN(_hessianSparsity2 !=
nullptr,
"No Hessian sparsity function defined in the dynamic library")
289 unsigned long const* row, *col;
291 (*_hessianSparsity2)(i, &row, &col, &nnz);
293 std::set<size_t> set_type;
294 std::vector<std::set<size_t> > s;
296 loadSparsity(set_type, s, _n, _n, row, col, nnz);
302 std::vector<size_t>& cols)
override {
303 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
304 CPPADCG_ASSERT_KNOWN(_hessianSparsity2 !=
nullptr,
"No Hessian sparsity function defined in the dynamic library")
306 unsigned long const* row, *col;
308 (*_hessianSparsity2)(i, &row, &col, &nnz);
313 std::copy(row, row + nnz, rows.begin());
314 std::copy(col, col + nnz, cols.begin());
330 return _zero !=
nullptr;
338 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
339 CPPADCG_ASSERT_KNOWN(_zero !=
nullptr,
"No zero order forward function defined in the dynamic library")
340 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 341 " please use the variable size methods")
342 CPPADCG_ASSERT_KNOWN(dep.
size() == _m,
"Invalid dependent array size")
343 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size")
344 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
347 _out[0] = dep.
data();
349 (*_zero)(&_in[0], &_out[0], _atomicFuncArg);
354 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
355 CPPADCG_ASSERT_KNOWN(_zero !=
nullptr,
"No zero order forward function defined in the dynamic library")
356 CPPADCG_ASSERT_KNOWN(_in.size() == x.size(),
"The number of independent variable arrays is invalid")
357 CPPADCG_ASSERT_KNOWN(dep.
size() == _m,
"Invalid dependent array size")
358 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
360 _out[0] = dep.
data();
362 (*_zero)(&x[0], &_out[0], _atomicFuncArg);
369 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
370 CPPADCG_ASSERT_KNOWN(_zero !=
nullptr,
"No zero order forward function defined in the dynamic library")
371 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 372 " please use the variable size methods")
373 CPPADCG_ASSERT_KNOWN(tx.
size() == _n,
"Invalid independent array size")
374 CPPADCG_ASSERT_KNOWN(ty.
size() == _m,
"Invalid dependent array size")
375 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
380 (*_zero)(&_in[0], &_out[0], _atomicFuncArg);
383 CPPADCG_ASSERT_KNOWN(vx.size() >= _n,
"Invalid vx size")
384 CPPADCG_ASSERT_KNOWN(vy.size() >= _m,
"Invalid vy size")
385 const std::vector<std::set<size_t> > jacSparsity = JacobianSparsitySet();
386 for (
size_t i = 0; i < _m; i++) {
387 for (
size_t j : jacSparsity[i]) {
398 return _jacobian !=
nullptr;
404 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
405 CPPADCG_ASSERT_KNOWN(_jacobian !=
nullptr,
"No Jacobian function defined in the dynamic library")
406 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 407 " please use the variable size methods")
408 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size")
409 CPPADCG_ASSERT_KNOWN(jac.
size() == _m * _n,
"Invalid Jacobian array size")
410 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
414 _out[0] = jac.
data();
416 (*_jacobian)(&_in[0], &_out[0], _atomicFuncArg);
420 return _hessian !=
nullptr;
427 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
428 CPPADCG_ASSERT_KNOWN(_hessian !=
nullptr,
"No Hessian function defined in the dynamic library")
429 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 430 " please use the variable size methods")
431 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size")
432 CPPADCG_ASSERT_KNOWN(w.
size() == _m,
"Invalid multiplier array size")
433 CPPADCG_ASSERT_KNOWN(hess.
size() == _n * _n,
"Invalid Hessian size")
434 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
436 _inHess[0] = x.
data();
437 _inHess[1] = w.
data();
438 _out[0] = hess.
data();
440 (*_hessian)(&_inHess[0], &_out[0], _atomicFuncArg);
444 return _forwardOne !=
nullptr;
451 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
452 CPPADCG_ASSERT_KNOWN(_forwardOne !=
nullptr,
"No forward one function defined in the dynamic library")
453 CPPADCG_ASSERT_KNOWN(tx.
size() >= (k + 1) * _n,
"Invalid tx size")
454 CPPADCG_ASSERT_KNOWN(ty.
size() >= (k + 1) * _m,
"Invalid ty size")
455 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
457 int ret = (*_forwardOne)(tx.
data(), ty.
data(), _atomicFuncArg);
459 CPPADCG_ASSERT_KNOWN(ret == 0,
"First-order forward mode failed.")
463 return _forwardOneSparsity !=
nullptr && _sparseForwardOne !=
nullptr;
467 size_t tx1Nnz,
const size_t idx[],
const Base tx1[],
469 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
470 CPPADCG_ASSERT_KNOWN(_sparseForwardOne !=
nullptr,
"No sparse forward one function defined in the dynamic library")
471 CPPADCG_ASSERT_KNOWN(_forwardOneSparsity !=
nullptr,
"No forward one sparsity function defined in the dynamic library")
472 CPPADCG_ASSERT_KNOWN(x.
size() >= _n,
"Invalid x size")
473 CPPADCG_ASSERT_KNOWN(ty1.
size() >= _m,
"Invalid ty1 size")
474 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
476 std::fill(ty1.
data(), ty1.
data() + _m, Base(0));
480 unsigned long const* pos;
484 Base* compressed = &_ty[0];
486 _inHess[0] = x.
data();
487 _out[0] = compressed;
489 for (
size_t ej = 0; ej < tx1Nnz; ej++) {
491 (*_forwardOneSparsity)(j, &pos, &nnz);
493 _inHess[1] = &tx1[ej];
494 int ret = (*_sparseForwardOne)(j, &_inHess[0], &_out[0], _atomicFuncArg);
496 CPPADCG_ASSERT_KNOWN(ret == 0,
"First-order forward mode failed.")
498 for (
size_t ePos = 0; ePos < nnz; ePos++) {
499 ty1[pos[ePos]] += compressed[ePos];
505 return _reverseOne !=
nullptr;
513 const size_t k1 = k + 1;
515 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
516 CPPADCG_ASSERT_KNOWN(_reverseOne !=
nullptr,
"No reverse one function defined in the dynamic library")
517 CPPADCG_ASSERT_KNOWN(tx.
size() >= k1 * _n,
"Invalid tx size")
518 CPPADCG_ASSERT_KNOWN(ty.
size() >= k1 * _m,
"Invalid ty size")
519 CPPADCG_ASSERT_KNOWN(px.
size() >= k1 * _n,
"Invalid px size")
520 CPPADCG_ASSERT_KNOWN(py.
size() >= k1 * _m,
"Invalid py size")
521 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
523 int ret = (*_reverseOne)(tx.
data(), ty.
data(), px.
data(), py.
data(), _atomicFuncArg);
525 CPPADCG_ASSERT_KNOWN(ret == 0,
"First-order reverse mode failed.")
529 return _reverseOneSparsity !=
nullptr && _sparseReverseOne !=
nullptr;
534 size_t pyNnz,
const size_t idx[],
const Base py[])
override {
535 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
536 CPPADCG_ASSERT_KNOWN(_sparseReverseOne !=
nullptr,
"No sparse reverse one function defined in the dynamic library")
537 CPPADCG_ASSERT_KNOWN(_reverseOneSparsity !=
nullptr,
"No reverse one sparsity function defined in the dynamic library")
538 CPPADCG_ASSERT_KNOWN(x.
size() >= _n,
"Invalid x size")
539 CPPADCG_ASSERT_KNOWN(px.
size() >= _n,
"Invalid px size")
540 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
542 std::fill(px.
data(), px.
data() + _n, Base(0));
546 unsigned long const* pos;
550 Base* compressed = &_px[0];
552 _inHess[0] = x.
data();
553 _out[0] = compressed;
555 for (
size_t ei = 0; ei < pyNnz; ei++) {
557 (*_reverseOneSparsity)(i, &pos, &nnz);
559 _inHess[1] = &py[ei];
560 int ret = (*_sparseReverseOne)(i, &_inHess[0], &_out[0], _atomicFuncArg);
562 CPPADCG_ASSERT_KNOWN(ret == 0,
"First-order reverse mode failed.")
564 for (
size_t ePos = 0; ePos < nnz; ePos++) {
565 px[pos[ePos]] += compressed[ePos];
571 return _reverseTwo !=
nullptr;
579 const size_t k1 = k + 1;
581 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
582 CPPADCG_ASSERT_KNOWN(_reverseTwo !=
nullptr,
"No sparse reverse two function defined in the dynamic library")
583 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1")
584 CPPADCG_ASSERT_KNOWN(tx.
size() >= k1 * _n,
"Invalid tx size")
585 CPPADCG_ASSERT_KNOWN(ty.
size() >= k1 * _m,
"Invalid ty size")
586 CPPADCG_ASSERT_KNOWN(px.
size() >= k1 * _n,
"Invalid px size")
587 CPPADCG_ASSERT_KNOWN(py.
size() >= k1 * _m,
"Invalid py size")
588 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
590 int ret = (*_reverseTwo)(tx.
data(), ty.
data(), px.
data(), py.
data(), _atomicFuncArg);
592 CPPADCG_ASSERT_KNOWN(ret != 1,
"Second-order reverse mode failed: py[2*i] (i=0...m) must be zero.")
593 CPPADCG_ASSERT_KNOWN(ret == 0,
"Second-order reverse mode failed.")
597 return _sparseReverseTwo !=
nullptr;
601 size_t tx1Nnz,
const size_t idx[],
const Base tx1[],
604 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
605 CPPADCG_ASSERT_KNOWN(_sparseReverseTwo !=
nullptr,
"No sparse reverse two function defined in the dynamic library")
606 CPPADCG_ASSERT_KNOWN(_reverseTwoSparsity !=
nullptr,
"No reverse two sparsity function defined in the dynamic library")
607 CPPADCG_ASSERT_KNOWN(x.
size() >= _n,
"Invalid x size")
608 CPPADCG_ASSERT_KNOWN(px2.
size() >= _n,
"Invalid px2 size")
609 CPPADCG_ASSERT_KNOWN(py2.
size() >= _m,
"Invalid py2 size")
610 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
612 std::fill(px2.
data(), px2.
data() + _n, Base(0));
616 unsigned long const* pos;
620 Base* compressed = &_px[0];
625 _out[0] = compressed;
627 for (
size_t ej = 0; ej < tx1Nnz; ej++) {
629 (*_reverseTwoSparsity)(j, &pos, &nnz);
632 int ret = (*_sparseReverseTwo)(j, &in[0], &_out[0], _atomicFuncArg);
634 CPPADCG_ASSERT_KNOWN(ret == 0,
"Second-order reverse mode failed.")
636 for (
size_t ePos = 0; ePos < nnz; ePos++) {
637 px2[pos[ePos]] += compressed[ePos];
643 return _jacobianSparsity !=
nullptr && _sparseJacobian !=
nullptr;
650 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
651 CPPADCG_ASSERT_KNOWN(_sparseJacobian !=
nullptr,
"No sparse jacobian function defined in the dynamic library")
652 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 653 " please use the variable size methods")
654 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size")
655 CPPADCG_ASSERT_KNOWN(jac.
size() == _m * _n,
"Invalid Jacobian size")
656 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
658 unsigned long const* row;
659 unsigned long const* col;
661 (*_jacobianSparsity)(&row, &col, &nnz);
667 _out[0] = &compressed[0];
669 (*_sparseJacobian)(&_in[0], &_out[0], _atomicFuncArg);
672 createDenseFromSparse(compressed,
680 std::vector<Base>& jac,
681 std::vector<size_t>& row,
682 std::vector<size_t>& col)
override {
683 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
684 CPPADCG_ASSERT_KNOWN(_sparseJacobian !=
nullptr,
"No sparse Jacobian function defined in the dynamic library")
685 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 686 " please use the variable size methods")
687 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
689 unsigned long const* drow;
690 unsigned long const* dcol;
692 (*_jacobianSparsity)(&drow, &dcol, &nnz);
702 (*_sparseJacobian)(&_in[0], &_out[0], _atomicFuncArg);
703 std::copy(drow, drow + nnz, row.begin());
704 std::copy(dcol, dcol + nnz, col.begin());
711 size_t const** col)
override {
712 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
713 CPPADCG_ASSERT_KNOWN(_sparseJacobian !=
nullptr,
"No sparse Jacobian function defined in the dynamic library")
714 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 715 " please use the variable size methods")
716 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size")
717 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
719 unsigned long const* drow;
720 unsigned long const* dcol;
722 (*_jacobianSparsity)(&drow, &dcol, &nnz);
723 CPPADCG_ASSERT_KNOWN(nnz == jac.
size(),
"Invalid number of non-zero elements in Jacobian")
729 _out[0] = jac.
data();
731 (*_sparseJacobian)(&_in[0], &_out[0], _atomicFuncArg);
738 size_t const** col)
override {
739 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
740 CPPADCG_ASSERT_KNOWN(_sparseJacobian !=
nullptr,
"No sparse Jacobian function defined in the dynamic library")
741 CPPADCG_ASSERT_KNOWN(_in.size() == x.size(),
"The number of independent variable arrays is invalid")
742 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
744 unsigned long const* drow;
745 unsigned long const* dcol;
747 (*_jacobianSparsity)(&drow, &dcol, &nnz);
748 CPPADCG_ASSERT_KNOWN(nnz == jac.
size(),
"Invalid number of non-zero elements in Jacobian")
753 _out[0] = jac.
data();
755 (*_sparseJacobian)(&x[0], &_out[0], _atomicFuncArg);
760 return _hessianSparsity !=
nullptr && _sparseHessian !=
nullptr;
768 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
769 CPPADCG_ASSERT_KNOWN(_sparseHessian !=
nullptr,
"No sparse Hessian function defined in the dynamic library")
770 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size")
771 CPPADCG_ASSERT_KNOWN(w.
size() == _m,
"Invalid multiplier array size")
773 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 774 " please use the variable size methods")
775 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
777 unsigned long const* row, *col;
779 (*_hessianSparsity)(&row, &col, &nnz);
783 _inHess[0] = x.
data();
784 _inHess[1] = w.
data();
785 _out[0] = &compressed[0];
787 (*_sparseHessian)(&_inHess[0], &_out[0], _atomicFuncArg);
790 createDenseFromSparse(compressed,
798 const std::vector<Base> &w,
799 std::vector<Base>& hess,
800 std::vector<size_t>& row,
801 std::vector<size_t>& col)
override {
802 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
803 CPPADCG_ASSERT_KNOWN(_sparseHessian !=
nullptr,
"No sparse Hessian function defined in the dynamic library")
804 CPPADCG_ASSERT_KNOWN(x.size() == _n,
"Invalid independent array size")
805 CPPADCG_ASSERT_KNOWN(w.size() == _m,
"Invalid multiplier array size")
806 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 807 " please use the variable size methods")
808 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
810 unsigned long const* drow, *dcol;
812 (*_hessianSparsity)(&drow, &dcol, &nnz);
819 std::copy(drow, drow + nnz, row.begin());
820 std::copy(dcol, dcol + nnz, col.begin());
826 (*_sparseHessian)(&_inHess[0], &_out[0], _atomicFuncArg);
834 size_t const** col)
override {
835 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
836 CPPADCG_ASSERT_KNOWN(_sparseHessian !=
nullptr,
"No sparse Hessian function defined in the dynamic library")
837 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 838 " please use the variable size methods")
839 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size")
840 CPPADCG_ASSERT_KNOWN(w.
size() == _m,
"Invalid multiplier array size")
841 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
843 unsigned long const* drow, *dcol;
845 (*_hessianSparsity)(&drow, &dcol, &nnz);
846 CPPADCG_ASSERT_KNOWN(nnz == hess.
size(),
"Invalid number of non-zero elements in Hessian")
851 _inHess[0] = x.
data();
852 _inHess[1] = w.
data();
853 _out[0] = hess.
data();
855 (*_sparseHessian)(&_inHess[0], &_out[0], _atomicFuncArg);
863 size_t const** col)
override {
864 CPPADCG_ASSERT_KNOWN(_isLibraryReady, ERROR_LIBRARY_NOT_READY)
865 CPPADCG_ASSERT_KNOWN(_sparseHessian !=
nullptr,
"No sparse Hessian function defined in the dynamic library")
866 CPPADCG_ASSERT_KNOWN(_in.size() == x.size(),
"The number of independent variable arrays is invalid")
867 CPPADCG_ASSERT_KNOWN(w.
size() == _m,
"Invalid multiplier array size")
868 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet")
870 unsigned long const* drow, *dcol;
872 (*_hessianSparsity)(&drow, &dcol, &nnz);
873 CPPADCG_ASSERT_KNOWN(nnz == hess.
size(),
"Invalid number of non-zero elements in Hessian")
878 std::copy(x.begin(), x.end(), _inHess.begin());
879 _inHess.back() = w.
data();
880 _out[0] = hess.
data();
882 (*_sparseHessian)(&_inHess[0], &_out[0], _atomicFuncArg);
894 _isLibraryReady(false),
895 _name(
std::move(name)),
898 _atomicFuncArg{
nullptr},
899 _missingAtomicFunctions(0),
901 _forwardOne(
nullptr),
902 _reverseOne(
nullptr),
903 _reverseTwo(
nullptr),
906 _sparseForwardOne(
nullptr),
907 _sparseReverseOne(
nullptr),
908 _sparseReverseTwo(
nullptr),
909 _sparseJacobian(
nullptr),
910 _sparseHessian(
nullptr),
911 _forwardOneSparsity(
nullptr),
912 _reverseOneSparsity(
nullptr),
913 _reverseTwoSparsity(
nullptr),
914 _jacobianSparsity(
nullptr),
915 _hessianSparsity(
nullptr),
916 _hessianSparsity2(
nullptr),
917 _atomicFunctions(
nullptr) {
921 virtual void init() {
929 virtual void* loadFunction(
const std::string& functionName,
930 bool required =
true) = 0;
936 void (*infoFunc)(
const char** baseName,
unsigned long*,
unsigned long*,
unsigned int*,
unsigned int*);
940 const char* localBaseName =
typeid (Base).name();
944 const char* dynamicLibBaseName =
nullptr;
945 unsigned int inSize = 0;
946 unsigned int outSize = 0;
947 (*infoFunc)(&dynamicLibBaseName, &_m, &_n, &inSize, &outSize);
950 _inHess.resize(inSize + 1);
951 _out.resize(outSize);
953 CPPADCG_ASSERT_KNOWN(local == std::string(dynamicLibBaseName),
954 (std::string(
"Invalid data type in dynamic library. Expected '") + local
955 +
"' but the library provided '" + dynamicLibBaseName +
"'.").c_str())
956 CPPADCG_ASSERT_KNOWN(inSize > 0,
957 "Invalid dimension received from the dynamic library.")
958 CPPADCG_ASSERT_KNOWN(outSize > 0,
959 "Invalid dimension received from the dynamic library.")
961 _isLibraryReady =
true;
984 CPPADCG_ASSERT_KNOWN((_sparseForwardOne ==
nullptr) == (_forwardOneSparsity ==
nullptr),
"Missing functions in the dynamic library")
985 CPPADCG_ASSERT_KNOWN((_sparseForwardOne ==
nullptr) == (_forwardOne ==
nullptr),
"Missing functions in the dynamic library")
986 CPPADCG_ASSERT_KNOWN((_sparseReverseOne ==
nullptr) == (_reverseOneSparsity ==
nullptr),
"Missing functions in the dynamic library")
987 CPPADCG_ASSERT_KNOWN((_sparseReverseOne ==
nullptr) == (_reverseOne ==
nullptr),
"Missing functions in the dynamic library")
988 CPPADCG_ASSERT_KNOWN((_sparseReverseTwo ==
nullptr) == (_reverseTwoSparsity ==
nullptr),
"Missing functions in the dynamic library")
989 CPPADCG_ASSERT_KNOWN((_sparseReverseTwo ==
nullptr) == (_reverseTwo ==
nullptr),
"Missing functions in the dynamic library")
990 CPPADCG_ASSERT_KNOWN((_sparseJacobian ==
nullptr) || (_jacobianSparsity !=
nullptr),
"Missing functions in the dynamic library")
991 CPPADCG_ASSERT_KNOWN((_sparseHessian ==
nullptr) || (_hessianSparsity !=
nullptr),
"Missing functions in the dynamic library")
998 (*_atomicFunctions)(&names, &n);
1000 _atomicNames.resize(n);
1001 for (
unsigned long i = 0; i < n; ++i) {
1002 _atomicNames[i] = std::string(names[i]);
1006 _atomicFuncArg.forward = &atomicForward;
1007 _atomicFuncArg.reverse = &atomicReverse;
1009 _missingAtomicFunctions = n;
1012 template <
class VectorSet>
1013 inline void loadSparsity(
bool set_type,
1015 unsigned long nrows,
unsigned long ncols,
1016 unsigned long const* rows,
unsigned long const* cols,
1017 unsigned long nnz) {
1018 s.resize(nrows * ncols,
false);
1020 for (
unsigned long i = 0; i < nnz; i++) {
1021 s[rows[i] * ncols + cols[i]] =
true;
1025 template <
class VectorSet>
1026 inline void loadSparsity(
const std::set<size_t>& set_type,
1028 unsigned long nrows,
unsigned long ncols,
1029 unsigned long const* rows,
unsigned long const* cols,
1030 unsigned long nnz) {
1035 for (
unsigned long i = 0; i < nnz; i++) {
1036 s[rows[i]].insert(cols[i]);
1041 unsigned long nrows,
unsigned long ncols,
1042 unsigned long const* rows,
unsigned long const* cols,
1045 CPPADCG_ASSERT_KNOWN(mat.
size() == nrows * ncols,
"Invalid matrix size")
1048 for (
size_t i = 0; i < nnz; i++) {
1049 mat[rows[i] * ncols + cols[i]] = compressed[i];
1053 virtual void modelLibraryClosed() {
1054 _isLibraryReady =
false;
1056 _forwardOne =
nullptr;
1057 _reverseOne =
nullptr;
1058 _reverseTwo =
nullptr;
1059 _jacobian =
nullptr;
1061 _sparseForwardOne =
nullptr;
1062 _sparseReverseOne =
nullptr;
1063 _sparseReverseTwo =
nullptr;
1064 _sparseJacobian =
nullptr;
1065 _sparseHessian =
nullptr;
1066 _forwardOneSparsity =
nullptr;
1067 _reverseOneSparsity =
nullptr;
1068 _reverseTwoSparsity =
nullptr;
1069 _jacobianSparsity =
nullptr;
1070 _hessianSparsity =
nullptr;
1071 _hessianSparsity2 =
nullptr;
1076 template<
class ExtFunc,
class Wrapper>
1077 inline bool addExternalFunction(ExtFunc& atomic,
1078 const std::string& name) {
1079 size_t n = _atomicNames.size();
1080 for (
size_t i = 0; i < n; i++) {
1081 if (name == _atomicNames[i]) {
1082 if (_atomic[i] ==
nullptr) {
1083 _missingAtomicFunctions--;
1087 _atomic[i] =
new Wrapper(atomic);
1094 static int atomicForward(
void* libModelIn,
1103 return externalFunc->forward(*libModel, q, p, tx, *ty);
1106 static int atomicReverse(
void* libModelIn,
1115 return externalFunc->reverse(*libModel, p, tx, *px, py);
1117 #ifdef CPPAD_CG_SYSTEM_LINUX 1118 friend class LinuxDynamicLib<Base>;
FunctorGenericModel(std::string name)
void ForwardZero(const std::vector< const Base *> &x, ArrayView< Base > dep) override
void HessianSparsity(size_t i, std::vector< size_t > &rows, std::vector< size_t > &cols) override
void ForwardZero(const CppAD::vector< bool > &vx, CppAD::vector< bool > &vy, ArrayView< const Base > tx, ArrayView< Base > ty) override
bool isJacobianAvailable() override
const std::vector< std::string > & getAtomicFunctionNames() override
void ForwardOne(ArrayView< const Base > tx, ArrayView< Base > ty) override
std::vector< std::set< size_t > > HessianSparsitySet(size_t i) override
void SparseJacobian(ArrayView< const Base > x, ArrayView< Base > jac) override
calculate sparse Jacobians
size_t Range() const override
number of dependent variables
void SparseHessian(ArrayView< const Base > x, ArrayView< const Base > w, ArrayView< Base > hess) override
calculate sparse Hessians
bool isEquationHessianSparsityAvailable() override
bool isSparseHessianAvailable() override
void ForwardZero(ArrayView< const Base > x, ArrayView< Base > dep) override
calculate the dependent values (zero order)
std::vector< bool > HessianSparsityBool(size_t i) override
bool isSparseForwardOneAvailable() override
bool isJacobianSparsityAvailable() override
void ReverseTwo(ArrayView< const Base > tx, ArrayView< const Base > ty, ArrayView< Base > px, ArrayView< const Base > py) override
bool isSparseReverseTwoAvailable() override
void SparseJacobian(const std::vector< const Base *> &x, ArrayView< Base > jac, size_t const **row, size_t const **col) override
void SparseJacobian(const std::vector< Base > &x, std::vector< Base > &jac, std::vector< size_t > &row, std::vector< size_t > &col) override
size_t Domain() const override
number of independent variables
virtual void loadFunctions()
bool isReverseOneAvailable() override
const std::string _name
the model name
bool isHessianSparsityAvailable() override
bool isReverseTwoAvailable() override
void Hessian(ArrayView< const Base > x, ArrayView< const Base > w, ArrayView< Base > hess) override
calculate Hessian for one component of f
virtual const std::string & getName() const =0
const std::string & getName() const override
void ReverseOne(ArrayView< const Base > tx, ArrayView< const Base > ty, ArrayView< Base > px, ArrayView< const Base > py) override
void ForwardOne(ArrayView< const Base > x, size_t tx1Nnz, const size_t idx[], const Base tx1[], ArrayView< Base > ty1) override
void SparseHessian(const std::vector< Base > &x, const std::vector< Base > &w, std::vector< Base > &hess, std::vector< size_t > &row, std::vector< size_t > &col) override
void SparseHessian(const std::vector< const Base *> &x, ArrayView< const Base > w, ArrayView< Base > hess, size_t const **row, size_t const **col) override
void SparseHessian(ArrayView< const Base > x, ArrayView< const Base > w, ArrayView< Base > hess, size_t const **row, size_t const **col) override
void SparseJacobian(ArrayView< const Base > x, ArrayView< Base > jac, size_t const **row, size_t const **col) override
bool addAtomicFunction(atomic_base< Base > &atomic) override
size_t size() const noexcept
bool addExternalModel(GenericModel< Base > &atomic) override
bool isSparseJacobianAvailable() override
bool isForwardOneAvailable() override
std::vector< std::set< size_t > > HessianSparsitySet() override
bool isForwardZeroAvailable() override
void Jacobian(ArrayView< const Base > x, ArrayView< Base > jac) override
calculate entire Jacobian
void ReverseTwo(ArrayView< const Base > x, size_t tx1Nnz, const size_t idx[], const Base tx1[], ArrayView< Base > px2, ArrayView< const Base > py2) override
bool isHessianAvailable() override
bool isSparseReverseOneAvailable() override
void ReverseOne(ArrayView< const Base > x, ArrayView< Base > px, size_t pyNnz, const size_t idx[], const Base py[]) override