1 #ifndef CPPAD_CG_FUNCTOR_GENERIC_MODEL_INCLUDED 2 #define CPPAD_CG_FUNCTOR_GENERIC_MODEL_INCLUDED 34 class FunctorGenericModel :
public GenericModel<Base> {
41 std::vector<const Base*> _in;
42 std::vector<const Base*> _inHess;
43 std::vector<Base*> _out;
45 std::vector<std::string> _atomicNames;
46 std::vector<ExternalFunctionWrapper<Base>* > _atomic;
47 size_t _missingAtomicFunctions;
54 int (*_reverseOne)(Base
const tx[], Base
const ty[], Base px[], Base
const py[],
LangCAtomicFun);
56 int (*_reverseTwo)(Base
const tx[], Base
const ty[], Base px[], Base
const py[],
LangCAtomicFun);
58 void (*_jacobian)(Base
const*
const*, Base *
const*,
LangCAtomicFun);
60 void (*_hessian)(Base
const*
const*, Base *
const*,
LangCAtomicFun);
62 int (*_sparseForwardOne)(
unsigned long, Base
const *
const *, Base *
const *,
LangCAtomicFun);
64 int (*_sparseReverseOne)(
unsigned long, Base
const *
const *, Base *
const *,
LangCAtomicFun);
66 int (*_sparseReverseTwo)(
unsigned long, Base
const *
const *, Base *
const *,
LangCAtomicFun);
68 void (*_sparseJacobian)(Base
const*
const*, Base *
const*,
LangCAtomicFun);
70 void (*_sparseHessian)(Base
const*
const*, Base *
const*,
LangCAtomicFun);
72 void (*_forwardOneSparsity)(
unsigned long,
unsigned long const**,
unsigned long*);
74 void (*_reverseOneSparsity)(
unsigned long,
unsigned long const**,
unsigned long*);
76 void (*_reverseTwoSparsity)(
unsigned long,
unsigned long const**,
unsigned long*);
78 void (*_jacobianSparsity)(
unsigned long const** row,
79 unsigned long const** col,
82 void (*_hessianSparsity)(
unsigned long const** row,
83 unsigned long const** col,
85 void (*_hessianSparsity2)(
unsigned long i,
86 unsigned long const** row,
87 unsigned long const** col,
89 void (*_atomicFunctions)(
const char*** names,
98 for (
size_t i = 0; i < _atomic.size(); i++) {
113 (atomic, atomic.afun_name());
123 return _jacobianSparsity !=
nullptr;
126 std::vector<bool> JacobianSparsityBool()
override {
127 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Dynamic library closed");
128 CPPADCG_ASSERT_KNOWN(_jacobianSparsity !=
nullptr,
"No Jacobian sparsity function defined in the dynamic library");
130 unsigned long const* row, *col;
132 (*_jacobianSparsity)(&row, &col, &nnz);
134 bool set_type =
true;
137 loadSparsity(set_type, s, _m, _n, row, col, nnz);
142 std::vector<std::set<size_t> > JacobianSparsitySet()
override {
143 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
144 CPPADCG_ASSERT_KNOWN(_jacobianSparsity !=
nullptr,
"No Jacobian sparsity function defined in the dynamic library");
146 unsigned long const* row, *col;
148 (*_jacobianSparsity)(&row, &col, &nnz);
150 std::set<size_t> set_type;
151 std::vector<std::set<size_t> > s;
153 loadSparsity(set_type, s, _m, _n, row, col, nnz);
158 void JacobianSparsity(std::vector<size_t>& equations,
159 std::vector<size_t>& variables)
override {
160 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
161 CPPADCG_ASSERT_KNOWN(_jacobianSparsity !=
nullptr,
"No Jacobian sparsity function defined in the dynamic library");
163 unsigned long const* row, *col;
165 (*_jacobianSparsity)(&row, &col, &nnz);
167 equations.resize(nnz);
168 variables.resize(nnz);
170 std::copy(row, row + nnz, equations.begin());
171 std::copy(col, col + nnz, variables.begin());
176 return _hessianSparsity !=
nullptr;
179 std::vector<bool> HessianSparsityBool()
override {
180 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
181 CPPADCG_ASSERT_KNOWN(_hessianSparsity !=
nullptr,
"No Hessian sparsity function defined in the dynamic library");
183 unsigned long const* row, *col;
185 (*_hessianSparsity)(&row, &col, &nnz);
187 bool set_type =
true;
190 loadSparsity(set_type, s, _n, _n, row, col, nnz);
196 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
197 CPPADCG_ASSERT_KNOWN(_hessianSparsity !=
nullptr,
"No Hessian sparsity function defined in the dynamic library");
199 unsigned long const* row, *col;
201 (*_hessianSparsity)(&row, &col, &nnz);
203 std::set<size_t> set_type;
204 std::vector<std::set<size_t> > s;
206 loadSparsity(set_type, s, _n, _n, row, col, nnz);
211 void HessianSparsity(std::vector<size_t>& rows,
212 std::vector<size_t>& cols)
override {
213 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
214 CPPADCG_ASSERT_KNOWN(_hessianSparsity !=
nullptr,
"No Hessian sparsity function defined in the dynamic library");
216 unsigned long const* row, *col;
218 (*_hessianSparsity)(&row, &col, &nnz);
223 std::copy(row, row + nnz, rows.begin());
224 std::copy(col, col + nnz, cols.begin());
228 return _hessianSparsity2 !=
nullptr;
231 std::vector<bool> HessianSparsityBool(
size_t i)
override {
232 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
233 CPPADCG_ASSERT_KNOWN(_hessianSparsity2 !=
nullptr,
"No Hessian sparsity function defined in the dynamic library");
235 unsigned long const* row, *col;
237 (*_hessianSparsity2)(i, &row, &col, &nnz);
239 bool set_type =
true;
242 loadSparsity(set_type, s, _n, _n, row, col, nnz);
248 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
249 CPPADCG_ASSERT_KNOWN(_hessianSparsity2 !=
nullptr,
"No Hessian sparsity function defined in the dynamic library");
251 unsigned long const* row, *col;
253 (*_hessianSparsity2)(i, &row, &col, &nnz);
255 std::set<size_t> set_type;
256 std::vector<std::set<size_t> > s;
258 loadSparsity(set_type, s, _n, _n, row, col, nnz);
263 void HessianSparsity(
size_t i, std::vector<size_t>& rows,
264 std::vector<size_t>& cols)
override {
265 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
266 CPPADCG_ASSERT_KNOWN(_hessianSparsity2 !=
nullptr,
"No Hessian sparsity function defined in the dynamic library");
268 unsigned long const* row, *col;
270 (*_hessianSparsity2)(i, &row, &col, &nnz);
275 std::copy(row, row + nnz, rows.begin());
276 std::copy(col, col + nnz, cols.begin());
292 return _zero !=
nullptr;
298 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
299 CPPADCG_ASSERT_KNOWN(_zero !=
nullptr,
"No zero order forward function defined in the dynamic library");
300 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 301 " please use the variable size methods");
302 CPPADCG_ASSERT_KNOWN(dep.
size() == _m,
"Invalid dependent array size");
303 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size");
304 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
307 _out[0] = dep.
data();
309 (*_zero)(&_in[0], &_out[0], _atomicFuncArg);
314 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
315 CPPADCG_ASSERT_KNOWN(_zero !=
nullptr,
"No zero order forward function defined in the dynamic library");
316 CPPADCG_ASSERT_KNOWN(_in.size() == x.size(),
"The number of independent variable arrays is invalid");
317 CPPADCG_ASSERT_KNOWN(dep.
size() == _m,
"Invalid dependent array size");
318 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
320 _out[0] = dep.
data();
322 (*_zero)(&x[0], &_out[0], _atomicFuncArg);
329 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
330 CPPADCG_ASSERT_KNOWN(_zero !=
nullptr,
"No zero order forward function defined in the dynamic library");
331 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 332 " please use the variable size methods");
333 CPPADCG_ASSERT_KNOWN(tx.
size() == _n,
"Invalid independent array size");
334 CPPADCG_ASSERT_KNOWN(ty.
size() == _m,
"Invalid dependent array size");
335 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
340 (*_zero)(&_in[0], &_out[0], _atomicFuncArg);
343 CPPADCG_ASSERT_KNOWN(vx.size() >= _n,
"Invalid vx size");
344 CPPADCG_ASSERT_KNOWN(vy.size() >= _m,
"Invalid vy size");
345 const std::vector<std::set<size_t> > jacSparsity = JacobianSparsitySet();
346 for (
size_t i = 0; i < _m; i++) {
347 for (
size_t j : jacSparsity[i]) {
358 return _jacobian !=
nullptr;
364 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
365 CPPADCG_ASSERT_KNOWN(_jacobian !=
nullptr,
"No Jacobian function defined in the dynamic library");
366 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 367 " please use the variable size methods");
368 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size");
369 CPPADCG_ASSERT_KNOWN(jac.
size() == _m * _n,
"Invalid Jacobian array size");
370 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
374 _out[0] = jac.
data();
376 (*_jacobian)(&_in[0], &_out[0], _atomicFuncArg);
380 return _hessian !=
nullptr;
387 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
388 CPPADCG_ASSERT_KNOWN(_hessian !=
nullptr,
"No Hessian function defined in the dynamic library");
389 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 390 " please use the variable size methods");
391 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size");
392 CPPADCG_ASSERT_KNOWN(w.
size() == _m,
"Invalid multiplier array size");
393 CPPADCG_ASSERT_KNOWN(hess.
size() == _n * _n,
"Invalid Hessian size");
394 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
396 _inHess[0] = x.
data();
397 _inHess[1] = w.
data();
398 _out[0] = hess.
data();
400 (*_hessian)(&_inHess[0], &_out[0], _atomicFuncArg);
404 return _forwardOne !=
nullptr;
411 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
412 CPPADCG_ASSERT_KNOWN(_forwardOne !=
nullptr,
"No forward one function defined in the dynamic library");
413 CPPADCG_ASSERT_KNOWN(tx.
size() >= (k + 1) * _n,
"Invalid tx size");
414 CPPADCG_ASSERT_KNOWN(ty.
size() >= (k + 1) * _m,
"Invalid ty size");
415 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
417 int ret = (*_forwardOne)(tx.
data(), ty.
data(), _atomicFuncArg);
419 CPPADCG_ASSERT_KNOWN(ret == 0,
"First-order forward mode failed.");
423 return _forwardOneSparsity !=
nullptr && _sparseForwardOne !=
nullptr;
427 size_t tx1Nnz,
const size_t idx[],
const Base tx1[],
429 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
430 CPPADCG_ASSERT_KNOWN(_sparseForwardOne !=
nullptr,
"No sparse forward one function defined in the dynamic library");
431 CPPADCG_ASSERT_KNOWN(_forwardOneSparsity !=
nullptr,
"No forward one sparsity function defined in the dynamic library");
432 CPPADCG_ASSERT_KNOWN(x.
size() >= _n,
"Invalid x size");
433 CPPADCG_ASSERT_KNOWN(ty1.
size() >= _m,
"Invalid ty1 size");
434 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
436 std::fill(ty1.
data(), ty1.
data() + _m, Base(0));
440 unsigned long const* pos;
444 Base* compressed = &_ty[0];
446 _inHess[0] = x.
data();
447 _out[0] = compressed;
449 for (
size_t ej = 0; ej < tx1Nnz; ej++) {
451 (*_forwardOneSparsity)(j, &pos, &nnz);
453 _inHess[1] = &tx1[ej];
454 int ret = (*_sparseForwardOne)(j, &_inHess[0], &_out[0], _atomicFuncArg);
456 CPPADCG_ASSERT_KNOWN(ret == 0,
"First-order forward mode failed.");
458 for (
size_t ePos = 0; ePos < nnz; ePos++) {
459 ty1[pos[ePos]] += compressed[ePos];
465 return _reverseOne !=
nullptr;
473 const size_t k1 = k + 1;
475 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
476 CPPADCG_ASSERT_KNOWN(_reverseOne !=
nullptr,
"No reverse one function defined in the dynamic library");
477 CPPADCG_ASSERT_KNOWN(tx.
size() >= k1 * _n,
"Invalid tx size");
478 CPPADCG_ASSERT_KNOWN(ty.
size() >= k1 * _m,
"Invalid ty size");
479 CPPADCG_ASSERT_KNOWN(px.
size() >= k1 * _n,
"Invalid px size");
480 CPPADCG_ASSERT_KNOWN(py.
size() >= k1 * _m,
"Invalid py size");
481 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
483 int ret = (*_reverseOne)(tx.
data(), ty.
data(), px.
data(), py.
data(), _atomicFuncArg);
485 CPPADCG_ASSERT_KNOWN(ret == 0,
"First-order reverse mode failed.");
489 return _reverseOneSparsity !=
nullptr && _sparseReverseOne !=
nullptr;
494 size_t pyNnz,
const size_t idx[],
const Base py[])
override {
495 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
496 CPPADCG_ASSERT_KNOWN(_sparseReverseOne !=
nullptr,
"No sparse reverse one function defined in the dynamic library");
497 CPPADCG_ASSERT_KNOWN(_reverseOneSparsity !=
nullptr,
"No reverse one sparsity function defined in the dynamic library");
498 CPPADCG_ASSERT_KNOWN(x.
size() >= _n,
"Invalid x size");
499 CPPADCG_ASSERT_KNOWN(px.
size() >= _n,
"Invalid px size");
500 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
502 std::fill(px.
data(), px.
data() + _n, Base(0));
506 unsigned long const* pos;
510 Base* compressed = &_px[0];
512 _inHess[0] = x.
data();
513 _out[0] = compressed;
515 for (
size_t ei = 0; ei < pyNnz; ei++) {
517 (*_reverseOneSparsity)(i, &pos, &nnz);
519 _inHess[1] = &py[ei];
520 int ret = (*_sparseReverseOne)(i, &_inHess[0], &_out[0], _atomicFuncArg);
522 CPPADCG_ASSERT_KNOWN(ret == 0,
"First-order reverse mode failed.");
524 for (
size_t ePos = 0; ePos < nnz; ePos++) {
525 px[pos[ePos]] += compressed[ePos];
531 return _reverseTwo !=
nullptr;
539 const size_t k1 = k + 1;
541 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
542 CPPADCG_ASSERT_KNOWN(_reverseTwo !=
nullptr,
"No sparse reverse two function defined in the dynamic library");
543 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1");
544 CPPADCG_ASSERT_KNOWN(tx.
size() >= k1 * _n,
"Invalid tx size");
545 CPPADCG_ASSERT_KNOWN(ty.
size() >= k1 * _m,
"Invalid ty size");
546 CPPADCG_ASSERT_KNOWN(px.
size() >= k1 * _n,
"Invalid px size");
547 CPPADCG_ASSERT_KNOWN(py.
size() >= k1 * _m,
"Invalid py size");
548 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
550 int ret = (*_reverseTwo)(tx.
data(), ty.
data(), px.
data(), py.
data(), _atomicFuncArg);
552 CPPADCG_ASSERT_KNOWN(ret != 1,
"Second-order reverse mode failed: py[2*i] (i=0...m) must be zero.");
553 CPPADCG_ASSERT_KNOWN(ret == 0,
"Second-order reverse mode failed.");
557 return _sparseReverseTwo !=
nullptr;
561 size_t tx1Nnz,
const size_t idx[],
const Base tx1[],
564 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
565 CPPADCG_ASSERT_KNOWN(_sparseReverseTwo !=
nullptr,
"No sparse reverse two function defined in the dynamic library");
566 CPPADCG_ASSERT_KNOWN(_reverseTwoSparsity !=
nullptr,
"No reverse two sparsity function defined in the dynamic library");
567 CPPADCG_ASSERT_KNOWN(x.
size() >= _n,
"Invalid x size");
568 CPPADCG_ASSERT_KNOWN(px2.
size() >= _n,
"Invalid px2 size");
569 CPPADCG_ASSERT_KNOWN(py2.
size() >= _m,
"Invalid py2 size");
570 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
572 std::fill(px2.
data(), px2.
data() + _n, Base(0));
576 unsigned long const* pos;
580 Base* compressed = &_px[0];
585 _out[0] = compressed;
587 for (
size_t ej = 0; ej < tx1Nnz; ej++) {
589 (*_reverseTwoSparsity)(j, &pos, &nnz);
592 int ret = (*_sparseReverseTwo)(j, &in[0], &_out[0], _atomicFuncArg);
594 CPPADCG_ASSERT_KNOWN(ret == 0,
"Second-order reverse mode failed.");
596 for (
size_t ePos = 0; ePos < nnz; ePos++) {
597 px2[pos[ePos]] += compressed[ePos];
603 return _jacobianSparsity !=
nullptr && _sparseJacobian !=
nullptr;
610 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
611 CPPADCG_ASSERT_KNOWN(_sparseJacobian !=
nullptr,
"No sparse jacobian function defined in the dynamic library");
612 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 613 " please use the variable size methods");
614 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size");
615 CPPADCG_ASSERT_KNOWN(jac.
size() == _m * _n,
"Invalid Jacobian size");
616 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
618 unsigned long const* row;
619 unsigned long const* col;
621 (*_jacobianSparsity)(&row, &col, &nnz);
627 _out[0] = &compressed[0];
629 (*_sparseJacobian)(&_in[0], &_out[0], _atomicFuncArg);
632 createDenseFromSparse(compressed,
640 std::vector<Base>& jac,
641 std::vector<size_t>& row,
642 std::vector<size_t>& col)
override {
643 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
644 CPPADCG_ASSERT_KNOWN(_sparseJacobian !=
nullptr,
"No sparse Jacobian function defined in the dynamic library");
645 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 646 " please use the variable size methods");
647 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
649 unsigned long const* drow;
650 unsigned long const* dcol;
652 (*_jacobianSparsity)(&drow, &dcol, &nnz);
662 (*_sparseJacobian)(&_in[0], &_out[0], _atomicFuncArg);
663 std::copy(drow, drow + nnz, row.begin());
664 std::copy(dcol, dcol + nnz, col.begin());
671 size_t const** col)
override {
672 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
673 CPPADCG_ASSERT_KNOWN(_sparseJacobian !=
nullptr,
"No sparse Jacobian function defined in the dynamic library");
674 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 675 " please use the variable size methods");
676 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size");
677 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
679 unsigned long const* drow;
680 unsigned long const* dcol;
682 (*_jacobianSparsity)(&drow, &dcol, &nnz);
683 CPPADCG_ASSERT_KNOWN(nnz == jac.
size(),
"Invalid number of non-zero elements in Jacobian");
689 _out[0] = jac.
data();
691 (*_sparseJacobian)(&_in[0], &_out[0], _atomicFuncArg);
698 size_t const** col)
override {
699 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
700 CPPADCG_ASSERT_KNOWN(_sparseJacobian !=
nullptr,
"No sparse Jacobian function defined in the dynamic library");
701 CPPADCG_ASSERT_KNOWN(_in.size() == x.size(),
"The number of independent variable arrays is invalid");
702 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
704 unsigned long const* drow;
705 unsigned long const* dcol;
707 (*_jacobianSparsity)(&drow, &dcol, &nnz);
708 CPPADCG_ASSERT_KNOWN(nnz == jac.
size(),
"Invalid number of non-zero elements in Jacobian");
713 _out[0] = jac.
data();
715 (*_sparseJacobian)(&x[0], &_out[0], _atomicFuncArg);
720 return _hessianSparsity !=
nullptr && _sparseHessian !=
nullptr;
728 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
729 CPPADCG_ASSERT_KNOWN(_sparseHessian !=
nullptr,
"No sparse Hessian function defined in the dynamic library");
730 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size");
731 CPPADCG_ASSERT_KNOWN(w.
size() == _m,
"Invalid multiplier array size");
733 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 734 " please use the variable size methods");
735 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
737 unsigned long const* row, *col;
739 (*_hessianSparsity)(&row, &col, &nnz);
743 _inHess[0] = x.
data();
744 _inHess[1] = w.
data();
745 _out[0] = &compressed[0];
747 (*_sparseHessian)(&_inHess[0], &_out[0], _atomicFuncArg);
750 createDenseFromSparse(compressed,
758 const std::vector<Base> &w,
759 std::vector<Base>& hess,
760 std::vector<size_t>& row,
761 std::vector<size_t>& col)
override {
762 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
763 CPPADCG_ASSERT_KNOWN(_sparseHessian !=
nullptr,
"No sparse Hessian function defined in the dynamic library");
764 CPPADCG_ASSERT_KNOWN(x.size() == _n,
"Invalid independent array size");
765 CPPADCG_ASSERT_KNOWN(w.size() == _m,
"Invalid multiplier array size");
766 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 767 " please use the variable size methods");
768 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
770 unsigned long const* drow, *dcol;
772 (*_hessianSparsity)(&drow, &dcol, &nnz);
779 std::copy(drow, drow + nnz, row.begin());
780 std::copy(dcol, dcol + nnz, col.begin());
786 (*_sparseHessian)(&_inHess[0], &_out[0], _atomicFuncArg);
794 size_t const** col)
override {
795 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
796 CPPADCG_ASSERT_KNOWN(_sparseHessian !=
nullptr,
"No sparse Hessian function defined in the dynamic library");
797 CPPADCG_ASSERT_KNOWN(_in.size() == 1,
"The number of independent variable arrays is higher than 1," 798 " please use the variable size methods");
799 CPPADCG_ASSERT_KNOWN(x.
size() == _n,
"Invalid independent array size");
800 CPPADCG_ASSERT_KNOWN(w.
size() == _m,
"Invalid multiplier array size");
801 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
803 unsigned long const* drow, *dcol;
805 (*_hessianSparsity)(&drow, &dcol, &nnz);
806 CPPADCG_ASSERT_KNOWN(nnz == hess.
size(),
"Invalid number of non-zero elements in Hessian");
811 _inHess[0] = x.
data();
812 _inHess[1] = w.
data();
813 _out[0] = hess.
data();
815 (*_sparseHessian)(&_inHess[0], &_out[0], _atomicFuncArg);
823 size_t const** col)
override {
824 CPPADCG_ASSERT_KNOWN(_isLibraryReady,
"Model library is not ready (possibly closed)");
825 CPPADCG_ASSERT_KNOWN(_sparseHessian !=
nullptr,
"No sparse Hessian function defined in the dynamic library");
826 CPPADCG_ASSERT_KNOWN(_in.size() == x.size(),
"The number of independent variable arrays is invalid");
827 CPPADCG_ASSERT_KNOWN(w.
size() == _m,
"Invalid multiplier array size");
828 CPPADCG_ASSERT_KNOWN(_missingAtomicFunctions == 0,
"Some atomic functions used by the compiled model have not been specified yet");
830 unsigned long const* drow, *dcol;
832 (*_hessianSparsity)(&drow, &dcol, &nnz);
833 CPPADCG_ASSERT_KNOWN(nnz == hess.
size(),
"Invalid number of non-zero elements in Hessian");
838 std::copy(x.begin(), x.end(), _inHess.begin());
839 _inHess.back() = w.
data();
840 _out[0] = hess.
data();
842 (*_sparseHessian)(&_inHess[0], &_out[0], _atomicFuncArg);
854 _isLibraryReady(false),
858 _atomicFuncArg{
nullptr},
859 _missingAtomicFunctions(0),
861 _forwardOne(
nullptr),
862 _reverseOne(
nullptr),
863 _reverseTwo(
nullptr),
866 _sparseForwardOne(
nullptr),
867 _sparseReverseOne(
nullptr),
868 _sparseReverseTwo(
nullptr),
869 _sparseJacobian(
nullptr),
870 _sparseHessian(
nullptr),
871 _forwardOneSparsity(
nullptr),
872 _reverseOneSparsity(
nullptr),
873 _reverseTwoSparsity(
nullptr),
874 _jacobianSparsity(
nullptr),
875 _hessianSparsity(
nullptr),
876 _hessianSparsity2(
nullptr) {
880 virtual void init() {
888 virtual void* loadFunction(
const std::string& functionName,
889 bool required =
true) = 0;
895 void (*infoFunc)(
const char** baseName,
unsigned long*,
unsigned long*,
unsigned int*,
unsigned int*);
899 const char* localBaseName =
typeid (Base).name();
903 const char* dynamicLibBaseName =
nullptr;
904 unsigned int inSize = 0;
905 unsigned int outSize = 0;
906 (*infoFunc)(&dynamicLibBaseName, &_m, &_n, &inSize, &outSize);
909 _inHess.resize(inSize + 1);
910 _out.resize(outSize);
912 CPPADCG_ASSERT_KNOWN(local == std::string(dynamicLibBaseName),
913 (std::string(
"Invalid data type in dynamic library. Expected '") + local
914 +
"' but the library provided '" + dynamicLibBaseName +
"'.").c_str());
915 CPPADCG_ASSERT_KNOWN(inSize > 0,
916 "Invalid dimension received from the dynamic library.");
917 CPPADCG_ASSERT_KNOWN(outSize > 0,
918 "Invalid dimension received from the dynamic library.");
920 _isLibraryReady =
true;
943 CPPADCG_ASSERT_KNOWN((_sparseForwardOne ==
nullptr) == (_forwardOneSparsity ==
nullptr),
"Missing functions in the dynamic library");
944 CPPADCG_ASSERT_KNOWN((_sparseForwardOne ==
nullptr) == (_forwardOne ==
nullptr),
"Missing functions in the dynamic library");
945 CPPADCG_ASSERT_KNOWN((_sparseReverseOne ==
nullptr) == (_reverseOneSparsity ==
nullptr),
"Missing functions in the dynamic library");
946 CPPADCG_ASSERT_KNOWN((_sparseReverseOne ==
nullptr) == (_reverseOne ==
nullptr),
"Missing functions in the dynamic library");
947 CPPADCG_ASSERT_KNOWN((_sparseReverseTwo ==
nullptr) == (_reverseTwoSparsity ==
nullptr),
"Missing functions in the dynamic library");
948 CPPADCG_ASSERT_KNOWN((_sparseReverseTwo ==
nullptr) == (_reverseTwo ==
nullptr),
"Missing functions in the dynamic library");
949 CPPADCG_ASSERT_KNOWN((_sparseJacobian ==
nullptr) || (_jacobianSparsity !=
nullptr),
"Missing functions in the dynamic library");
950 CPPADCG_ASSERT_KNOWN((_sparseHessian ==
nullptr) || (_hessianSparsity !=
nullptr),
"Missing functions in the dynamic library");
957 (*_atomicFunctions)(&names, &n);
959 _atomicNames.resize(n);
960 for (
unsigned long i = 0; i < n; ++i) {
961 _atomicNames[i] = std::string(names[i]);
965 _atomicFuncArg.forward = &atomicForward;
966 _atomicFuncArg.reverse = &atomicReverse;
968 _missingAtomicFunctions = n;
971 template <
class VectorSet>
972 inline void loadSparsity(
bool set_type,
974 unsigned long nrows,
unsigned long ncols,
975 unsigned long const* rows,
unsigned long const* cols,
977 s.resize(nrows * ncols,
false);
979 for (
unsigned long i = 0; i < nnz; i++) {
980 s[rows[i] * ncols + cols[i]] =
true;
984 template <
class VectorSet>
985 inline void loadSparsity(
const std::set<size_t>& set_type,
987 unsigned long nrows,
unsigned long ncols,
988 unsigned long const* rows,
unsigned long const* cols,
994 for (
unsigned long i = 0; i < nnz; i++) {
995 s[rows[i]].insert(cols[i]);
1000 unsigned long nrows,
unsigned long ncols,
1001 unsigned long const* rows,
unsigned long const* cols,
1004 CPPADCG_ASSERT_KNOWN(mat.
size() == nrows * ncols,
"Invalid matrix size");
1007 for (
size_t i = 0; i < nnz; i++) {
1008 mat[rows[i] * ncols + cols[i]] = compressed[i];
1012 virtual void modelLibraryClosed() {
1013 _isLibraryReady =
false;
1015 _forwardOne =
nullptr;
1016 _reverseOne =
nullptr;
1017 _reverseTwo =
nullptr;
1018 _jacobian =
nullptr;
1020 _sparseForwardOne =
nullptr;
1021 _sparseReverseOne =
nullptr;
1022 _sparseReverseTwo =
nullptr;
1023 _sparseJacobian =
nullptr;
1024 _sparseHessian =
nullptr;
1025 _forwardOneSparsity =
nullptr;
1026 _reverseOneSparsity =
nullptr;
1027 _reverseTwoSparsity =
nullptr;
1028 _jacobianSparsity =
nullptr;
1029 _hessianSparsity =
nullptr;
1030 _hessianSparsity2 =
nullptr;
1035 template<
class ExtFunc,
class Wrapper>
1036 inline bool addExternalFunction(ExtFunc& atomic,
1037 const std::string& name) {
1038 size_t n = _atomicNames.size();
1039 for (
size_t i = 0; i < n; i++) {
1040 if (name == _atomicNames[i]) {
1041 if (_atomic[i] ==
nullptr) {
1042 _missingAtomicFunctions--;
1046 _atomic[i] =
new Wrapper(atomic);
1053 static int atomicForward(
void* libModelIn,
1062 return externalFunc->forward(*libModel, q, p, tx, *ty);
1065 static int atomicReverse(
void* libModelIn,
1074 return externalFunc->reverse(*libModel, p, tx, *px, py);
1076 #ifdef CPPAD_CG_SYSTEM_LINUX 1077 friend class LinuxDynamicLib<Base>;
void ForwardZero(const std::vector< const Base *> &x, ArrayView< Base > dep) override
bool isJacobianAvailable() override
const std::vector< std::string > & getAtomicFunctionNames() override
FunctorGenericModel(const std::string &name)
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)
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
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< const Base *> &x, ArrayView< const Base > w, ArrayView< Base > hess, 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