67#define NO_CPPAD_USER_ATOMIC
70#if __cplusplus < 201103L && defined(SCIP_THREADSAFE)
77#ifndef CPPAD_MAX_NUM_THREADS
79#define CPPAD_MAX_NUM_THREADS 64
81#define CPPAD_MAX_NUM_THREADS 1
91#pragma GCC diagnostic ignored "-Wshadow"
94#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
100#define log2(x) (log((double)x) / log(2.0))
103#include <cppad/cppad.hpp>
104#include <cppad/utility/error_handler.hpp>
111#ifdef SCIP_THREADSAFE
116static std::atomic_size_t ncurthreads{0};
117static thread_local int thread_number{-1};
121bool in_parallel(
void)
123 return ncurthreads > 1;
131size_t thread_num(
void)
137 if( thread_number == -1 )
139 thread_number =
static_cast<int>(ncurthreads.fetch_add(1, std::memory_order_relaxed));
142 threadnum =
static_cast<size_t>(thread_number);
152extern "C" SCIP_EXPORT
char SCIPexprintCppADInitParallel(
void);
154__attribute__((constructor))
156char SCIPexprintCppADInitParallel(
void)
159 CppAD::parallel_ad<double>();
164#if !defined(__GNUC__)
169static char init_parallel_return = SCIPexprintCppADInitParallel();
179struct SCIP_ExprIntData
186 need_retape_always(false),
204 assert(std::binary_search(varidxs.begin(), varidxs.end(),
varidx));
205 return std::lower_bound(varidxs.begin(), varidxs.end(),
varidx) - varidxs.begin();
208 vector< int > varidxs;
209 vector< AD<double> > X;
210 vector< AD<double> > Y;
211 CppAD::ADFun<double> f;
216 bool need_retape_always;
218 vector<atomic_userexpr*> userexprs;
223 vector<SCIP_Real> hesvalues;
225 SCIP_Bool hesconstant;
228 CppAD::local::internal_sparsity<bool>::pattern_type hessparsity_pattern;
229 CppAD::vector<size_t> hessparsity_row;
230 CppAD::vector<size_t> hessparsity_col;
231 CppAD::sparse_hessian_work heswork;
234#ifndef NO_CPPAD_USER_ATOMIC
242bool univariate_for_sparse_jac(
244 const CppAD::vector<bool>&
r,
245 CppAD::vector<bool>& s
262bool univariate_rev_sparse_jac(
264 const CppAD::vector<bool>&
r,
265 CppAD::vector<bool>& s
282bool univariate_rev_sparse_hes(
283 const CppAD::vector<bool>& vx,
284 const CppAD::vector<bool>& s,
285 CppAD::vector<bool>& t,
287 const CppAD::vector<bool>&
r,
288 const CppAD::vector<bool>& u,
289 CppAD::vector<bool>& v
305 for(
size_t j = 0; j < q; ++j )
321class atomic_posintpower :
public CppAD::atomic_base<Type>
325 : CppAD::atomic_base<
Type>(
"posintpower"),
329 this->option(CppAD::atomic_base<Type>::bool_sparsity_enum);
341 virtual void set_old(
size_t id)
361 const CppAD::vector<bool>& vx,
362 CppAD::vector<bool>& vy,
363 const CppAD::vector<Type>& tx,
364 CppAD::vector<Type>& ty
383 ty[0] = CppAD::pow(tx[0], exponent);
386 if( q <= 1 && 1 <= p )
388 ty[1] = CppAD::pow(tx[0], exponent-1) * tx[1];
389 ty[1] *= double(exponent);
392 if( q <= 2 && 2 <= p )
397 ty[2] = CppAD::pow(tx[0], exponent-2) * tx[1] * tx[1];
398 ty[2] *= (exponent-1) / 2.0;
399 ty[2] += CppAD::pow(tx[0], exponent-1) * tx[2];
406 ty[2] = tx[1] * tx[1] + 2.0 * tx[0] * tx[2];
449 const CppAD::vector<Type>& tx,
450 const CppAD::vector<Type>& ty,
451 CppAD::vector<Type>& px,
452 const CppAD::vector<Type>& py
464 px[0] = py[0] * CppAD::pow(tx[0], exponent-1);
470 px[0] = py[1] * tx[1] * CppAD::pow(tx[0], exponent-2);
472 px[0] += py[0] * CppAD::pow(tx[0], exponent-1);
475 px[1] = py[1] * CppAD::pow(tx[0], exponent-1);
486 using CppAD::atomic_base<
Type>::for_sparse_jac;
495 const CppAD::vector<bool>&
r,
496 CppAD::vector<bool>& s
499 return univariate_for_sparse_jac(q,
r, s);
502 using CppAD::atomic_base<
Type>::rev_sparse_jac;
511 const CppAD::vector<bool>&
r,
512 CppAD::vector<bool>& s
515 return univariate_rev_sparse_jac(q,
r, s);
518 using CppAD::atomic_base<
Type>::rev_sparse_hes;
526 const CppAD::vector<bool>& vx,
527 const CppAD::vector<bool>& s,
528 CppAD::vector<bool>& t,
530 const CppAD::vector<bool>&
r,
531 const CppAD::vector<bool>& u,
532 CppAD::vector<bool>& v
535 return univariate_rev_sparse_hes(vx, s, t, q,
r, u, v);
543 const vector<Type>& in,
548 static atomic_posintpower<typename Type::value_type> pip;
549 pip(in, out, exponent);
557 const vector<Type>& in,
562 out[0] = pow(in[0], (
int)exponent);
568#ifndef NO_CPPAD_USER_ATOMIC
574#define SIGN(x) ((x) >= 0.0 ? 1.0 : -1.0)
585class atomic_signpower :
public CppAD::atomic_base<Type>
589 : CppAD::atomic_base<
Type>(
"signpower"),
593 this->option(CppAD::atomic_base<Type>::bool_sparsity_enum);
605 virtual void set_old(
size_t id)
625 const CppAD::vector<bool>& vx,
626 CppAD::vector<bool>& vy,
627 const CppAD::vector<Type>& tx,
628 CppAD::vector<Type>& ty
647 ty[0] =
SIGN(tx[0]) * pow(
REALABS(tx[0]), exponent);
650 if( q <= 1 && 1 <= p )
652 ty[1] = pow(
REALABS(tx[0]), exponent - 1.0) * tx[1];
656 if( q <= 2 && 2 <= p )
658 if( exponent != 2.0 )
660 ty[2] =
SIGN(tx[0]) * pow(
REALABS(tx[0]), exponent - 2.0) * tx[1] * tx[1];
661 ty[2] *= (exponent - 1.0) / 2.0;
662 ty[2] += pow(
REALABS(tx[0]), exponent - 1.0) * tx[2];
668 ty[2] =
SIGN(tx[0]) * tx[1] * tx[1];
669 ty[2] += 2.0 *
REALABS(tx[0]) * tx[2];
712 const CppAD::vector<Type>& tx,
713 const CppAD::vector<Type>& ty,
714 CppAD::vector<Type>& px,
715 const CppAD::vector<Type>& py
727 px[0] = py[0] * pow(
REALABS(tx[0]), exponent - 1.0);
732 if( exponent != 2.0 )
735 px[0] = py[1] * tx[1] * pow(
REALABS(tx[0]), exponent - 2.0) *
SIGN(tx[0]);
736 px[0] *= exponent - 1.0;
737 px[0] += py[0] * pow(
REALABS(tx[0]), exponent - 1.0);
740 px[1] = py[1] * pow(
REALABS(tx[0]), exponent - 1.0);
746 px[0] = py[1] * tx[1] *
SIGN(tx[0]);
747 px[0] += py[0] *
REALABS(tx[0]);
750 px[1] = py[1] *
REALABS(tx[0]);
762 using CppAD::atomic_base<
Type>::for_sparse_jac;
771 const CppAD::vector<bool>&
r,
772 CppAD::vector<bool>& s
775 return univariate_for_sparse_jac(q,
r, s);
778 using CppAD::atomic_base<
Type>::rev_sparse_jac;
787 const CppAD::vector<bool>&
r,
788 CppAD::vector<bool>& s
791 return univariate_rev_sparse_jac(q,
r, s);
794 using CppAD::atomic_base<
Type>::rev_sparse_hes;
802 const CppAD::vector<bool>& vx,
803 const CppAD::vector<bool>& s,
804 CppAD::vector<bool>& t,
806 const CppAD::vector<bool>&
r,
807 const CppAD::vector<bool>& u,
808 CppAD::vector<bool>& v
811 return univariate_rev_sparse_hes(vx, s, t, q,
r, u, v);
825 vector<Type> in(1, arg);
828 static atomic_signpower<typename Type::value_type> sp;
829 sp(in, out, (
size_t)(
void*)expr);
841 CppAD::AD<Type>& resultant,
842 const CppAD::AD<Type>& arg,
854 resultant = CppAD::CondExpGe(arg, adzero, pow(arg, (
int)exponent), -pow(-arg, (
int)exponent));
861 resultant = CppAD::CondExpEq(arg, adzero, pow(arg+std::numeric_limits<SCIP_Real>::epsilon(), exponent)-pow(std::numeric_limits<SCIP_Real>::epsilon(), exponent),
862 CppAD::CondExpGe(arg, adzero, pow(arg, exponent), -pow(-arg, exponent)));
915 const CppAD::vector<bool>& vx,
916 CppAD::vector<bool>& vy,
917 const CppAD::vector<SCIP_Real>& tx,
918 CppAD::vector<SCIP_Real>& ty
926 size_t n = tx.size() / (p+1);
940 for(
size_t i = 0;
i < n; ++
i )
957 ty[0] = std::numeric_limits<double>::infinity();
969 SCIP_Real*
x =
new SCIP_Real[n];
970 SCIP_Real* dir =
new SCIP_Real[n];
971 for(
size_t i = 0;
i < n; ++
i )
973 x[
i] = tx[
i * (p+1) + 0];
974 dir[
i] = tx[
i * (p+1) + 1];
980 ty[0] = std::numeric_limits<double>::infinity();
982 ty[1] = std::numeric_limits<double>::infinity();
994#if SCIP_DISABLED_CODE
996 SCIP_Real* gradient =
NULL;
997 SCIP_Real* hessian =
NULL;
999 if( q <= 2 && 1 <= p )
1000 gradient =
new SCIP_Real[n];
1001 if( q <= 2 && 2 <= p )
1002 hessian =
new SCIP_Real[n*n];
1004 if( exprEvalUser(expr,
x, ty[0], gradient, hessian) !=
SCIP_OKAY )
1012 if( gradient !=
NULL )
1015 for(
size_t i = 0;
i < n; ++
i )
1016 ty[1] += gradient[
i] * tx[
i * (p+1) + 1];
1019 if( hessian !=
NULL )
1024 for(
size_t i = 0;
i < n; ++
i )
1026 for(
size_t j = 0; j < n; ++j )
1027 ty[2] += 0.5 * hessian[
i*n+j] * tx[
i * (p+1) + 1] * tx[j * (p+1) + 1];
1029 ty[2] += gradient[
i] * tx[
i * (p+1) + 2];
1104 const CppAD::vector<SCIP_Real>& tx,
1105 const CppAD::vector<SCIP_Real>& ty,
1106 CppAD::vector<SCIP_Real>& px,
1107 const CppAD::vector<SCIP_Real>& py
1111 assert(px.size() == tx.size());
1112 assert(py.size() == p+1);
1118#ifdef SCIP_DISABLED_CODE
1120 size_t n = tx.size() / (p+1);
1124 SCIP_Real*
x =
new SCIP_Real[n];
1126 SCIP_Real* gradient =
new SCIP_Real[n];
1127 SCIP_Real* hessian =
NULL;
1130 hessian =
new SCIP_Real[n*n];
1132 for(
size_t i = 0;
i < n; ++
i )
1133 x[
i] = tx[
i * (p+1) + 0];
1135 if( exprEvalUser(expr,
x, funcval, gradient, hessian) !=
SCIP_OKAY )
1147 for(
size_t i = 0;
i < n; ++
i )
1148 px[
i] = py[0] * gradient[
i];
1155 for(
size_t i = 0;
i < n; ++
i )
1157 px[
i*2+0] = py[0] * gradient[
i];
1158 for(
size_t j = 0; j < n; ++j )
1159 px[
i*2+0] += py[1] * hessian[
i+n*j] * tx[j*2+1];
1161 px[
i*2+1] = py[1] * gradient[
i];
1173 using CppAD::atomic_base<SCIP_Real>::for_sparse_jac;
1180 bool for_sparse_jac(
1182 const CppAD::vector<bool>&
r,
1183 CppAD::vector<bool>& s
1189 size_t n =
r.size() / q;
1193 for(
size_t j = 0; j < q; j++ )
1196 for(
size_t i = 0;
i < n;
i++ )
1197 s[j] |= (
bool)
r[
i * q + j];
1203 using CppAD::atomic_base<SCIP_Real>::rev_sparse_jac;
1210 bool rev_sparse_jac(
1212 const CppAD::vector<bool>& rt,
1213 CppAD::vector<bool>& st
1219 size_t n = st.size() / q;
1223 for(
size_t j = 0; j < q; j++ )
1224 for(
size_t i = 0;
i < n;
i++ )
1225 st[
i * q + j] = rt[j];
1230 using CppAD::atomic_base<SCIP_Real>::rev_sparse_hes;
1237 bool rev_sparse_hes(
1238 const CppAD::vector<bool>& vx,
1239 const CppAD::vector<bool>& s,
1240 CppAD::vector<bool>& t,
1242 const CppAD::vector<bool>&
r,
1243 const CppAD::vector<bool>& u,
1244 CppAD::vector<bool>& v
1248 size_t n = vx.size();
1254 assert(v.size() == n * q);
1259 for(
i = 0;
i < n; ++
i )
1267 for( j = 0; j < q; j++ )
1268 for(
i = 0;
i < n;
i++ )
1269 v[
i * q + j] = u[j];
1274 for( j = 0; j < q; j++ )
1275 for(
i = 0;
i < n;
i++ )
1276 for( k = 0; k < n; ++k )
1277 v[
i * q + j] |= (
bool)
r[ k * q + j];
1295 vector<Type> in(1, arg);
1296 vector<Type> out(1);
1306 vector<Type> in(1, arg);
1307 vector<Type> out(1);
1311 resultant =
Type(1.0)/out[0];
1323 resultant =
Type(1.0);
1328 resultant =
Type(1.0)/arg;
1338 const vector<Type>&
x,
1368#ifndef EVAL_USE_EXPRHDLR_ALWAYS
1386 else if( exponent == 0.5 )
1388 else if( exponent < 1.0 )
1394 AD<double> adzero(0.);
1395 val = CppAD::CondExpEq(buf[0], adzero, pow(buf[0]+std::numeric_limits<SCIP_Real>::epsilon(), exponent)-pow(std::numeric_limits<SCIP_Real>::epsilon(), exponent),
1396 pow(buf[0], exponent));
1434 val = CppAD::CondExpGt(buf[0], AD<double>(0.), -buf[0] * log(buf[0]), -sqrt(buf[0]));
1442 vector<Type> out(1);
1445 (*exprintdata->userexprs.back())(in, out);
1471 SCIPdebugMessage(
"ignore CppAD error from %sknown source %s:%d: msg: %s exp: %s\n", known ?
"" :
"un", file, line, msg, cond);
1480 return CPPAD_PACKAGE_STRING;
1486 return "Algorithmic Differentiation of C++ algorithms developed by B. Bell (github.com/coin-or/CppAD)";
1543 if( *exprintdata ==
NULL )
1550 (*exprintdata)->need_retape =
true;
1551 (*exprintdata)->need_retape_always =
false;
1552 (*exprintdata)->hesconstant =
false;
1558 std::set<int> varidxs;
1571#ifndef EVAL_USE_EXPRHDLR_ALWAYS
1603 (*exprintdata)->varidxs.reserve(varidxs.size());
1604 (*exprintdata)->varidxs.insert((*exprintdata)->varidxs.begin(), varidxs.begin(), varidxs.end());
1606 size_t n = (*exprintdata)->varidxs.size();
1607 (*exprintdata)->X.resize(n);
1608 (*exprintdata)->x.resize(n);
1609 (*exprintdata)->Y.resize(1);
1616 (*exprintdata)->hesconstant =
true;
1631 (*exprintdata)->hesconstant =
false;
1634 SCIPdebugMsg(
scip,
"Hessian found %sconstant\n", (*exprintdata)->hesconstant ?
"" :
"not ");
1654 delete *exprintdata;
1655 *exprintdata =
NULL;
1676 return exprintdata->userevalcapability;
1694 size_t n = exprintdata->varidxs.size();
1703 if( exprintdata->need_retape_always || exprintdata->need_retape )
1708 exprintdata->hesvalues.clear();
1709 exprintdata->hesnnz = 0;
1711 for(
size_t i = 0;
i < n; ++
i )
1713 int idx = exprintdata->varidxs[
i];
1714 exprintdata->X[
i] = varvals[idx];
1715 exprintdata->x[
i] = varvals[idx];
1719 for( vector<atomic_userexpr*>::iterator it(exprintdata->userexprs.begin()); it != exprintdata->userexprs.end(); ++it )
1721 exprintdata->userexprs.clear();
1723 CppAD::Independent(exprintdata->X);
1727 exprintdata->f.Dependent(exprintdata->X, exprintdata->Y);
1729 exprintdata->val = Value(exprintdata->Y[0]);
1730 SCIPdebugMessage(
"Eval retaped and computed value %g\n", exprintdata->val);
1736 exprintdata->f.optimize();
1738 exprintdata->need_retape =
false;
1742 assert(exprintdata->x.size() >= n);
1743 for(
size_t i = 0;
i < n; ++
i )
1744 exprintdata->x[
i] = varvals[exprintdata->varidxs[
i]];
1746 exprintdata->val = exprintdata->f.Forward(0, exprintdata->x)[0];
1747 SCIPdebugMessage(
"Eval used forward sweep to compute value %g\n", exprintdata->val);
1750 *val = exprintdata->val;
1762 SCIP_Bool new_varvals,
1778 *val = exprintdata->val;
1780 size_t n = exprintdata->varidxs.size();
1786 if( exprintdata->userexprs.empty() )
1787 jac = exprintdata->f.Jacobian(exprintdata->x);
1792 exprintdata->f.Forward(0, exprintdata->x);
1794 CppAD::JacobianFor(exprintdata->f, exprintdata->x, jac);
1797 for(
size_t i = 0;
i < n; ++
i )
1798 gradient[exprintdata->varidxs[
i]] = jac[
i];
1804 for(
size_t i = 0;
i < n; ++
i )
1809 for(
size_t i = 0;
i < n; ++
i )
1843 if( exprintdata->hesrowidxs ==
NULL )
1846 assert(exprintdata->hesvalues.size() == 0);
1847 assert(exprintdata->hesnnz == 0);
1849 size_t n = exprintdata->varidxs.size();
1858 if( exprintdata->need_retape_always )
1861 exprintdata->hesnnz = (n * (n+1))/2;
1866 for(
size_t i = 0;
i < n; ++
i )
1867 for(
size_t j = 0; j <=
i; ++j )
1869 exprintdata->hesrowidxs[k] = exprintdata->varidxs[
i];
1870 exprintdata->hescolidxs[k] = exprintdata->varidxs[j];
1880 *rowidxs = exprintdata->hesrowidxs;
1881 *colidxs = exprintdata->hescolidxs;
1882 *nnz = exprintdata->hesnnz;
1887 if( exprintdata->need_retape )
1897 vector<bool>
r(nn,
false);
1898 for(
size_t i = 0;
i < n; ++
i )
1900 (void) exprintdata->f.ForSparseJac(n,
r);
1909 vector<bool> hessparsity;
1910 exprintdata->f.RevSparseHesCase(
true,
false, n, vector<bool>(1,
true), hessparsity);
1913 exprintdata->hessparsity_pattern.resize(0, 0);
1914 exprintdata->hessparsity_pattern.resize(n, n);
1915 size_t hesnnz_full = 0;
1916 for(
size_t i = 0;
i < nn; ++
i )
1917 if( hessparsity[
i] )
1926 ++exprintdata->hesnnz;
1938 exprintdata->hessparsity_row.resize(hesnnz_full);
1939 exprintdata->hessparsity_col.resize(hesnnz_full);
1941 for(
size_t i = 0, j = 0, k = 0;
i < nn; ++
i )
1942 if( hessparsity[
i] )
1947 if( (
size_t)exprintdata->hesnnz <= nn/4 )
1950 exprintdata->hessparsity_pattern.add_element(row, col);
1957 assert(exprintdata->hesnnz + k < hesnnz_full);
1958 exprintdata->hessparsity_row[exprintdata->hesnnz + k] = row;
1959 exprintdata->hessparsity_col[exprintdata->hesnnz + k] = col;
1964 exprintdata->hessparsity_row[j] = row;
1965 exprintdata->hessparsity_col[j] = col;
1967 assert(j < (
size_t)exprintdata->hesnnz);
1968 exprintdata->hesrowidxs[j] = exprintdata->varidxs[row];
1969 exprintdata->hescolidxs[j] = exprintdata->varidxs[col];
1977 for(
int i = 0;
i < exprintdata->hesnnz; ++
i )
1985 *rowidxs = exprintdata->hesrowidxs;
1986 *colidxs = exprintdata->hescolidxs;
1987 *nnz = exprintdata->hesnnz;
2003 SCIP_Bool new_varvals,
2007 SCIP_Real** hessianvals,
2014 if( exprintdata->hesrowidxs ==
NULL )
2021 assert(exprintdata->hesvalues.size() == 0);
2022 assert(exprintdata->hesnnz == 0);
2026 new_varvals =
FALSE;
2034 *val = exprintdata->val;
2036 size_t n = exprintdata->varidxs.size();
2039 if( n > 0 && (!exprintdata->hesconstant || exprintdata->hesvalues.size() < (
size_t)exprintdata->hesnnz) )
2043 if( exprintdata->hesvalues.size() == 0 )
2046 exprintdata->hesvalues.resize(exprintdata->hessparsity_row.size());
2050 if( (
size_t)exprintdata->hesnnz > nn/4 )
2054 vector<double> hess = exprintdata->f.Hessian(exprintdata->x, 0);
2055 for(
int i = 0;
i < exprintdata->hesnnz; ++
i )
2056 exprintdata->hesvalues[
i] = hess[exprintdata->hessparsity_row[
i] * n + exprintdata->hessparsity_col[
i]];
2063 exprintdata->f.SparseHessianCompute(exprintdata->x, vector<double>(1, 1.0), exprintdata->hessparsity_pattern, exprintdata->hessparsity_row, exprintdata->hessparsity_col, exprintdata->hesvalues, exprintdata->heswork);
2067 exprintdata->hessparsity_row.clear();
2068 exprintdata->hessparsity_col.clear();
2069 exprintdata->hessparsity_pattern.resize(0,0);
2078 for(
size_t i = 0;
i < n; ++
i )
2083 for(
int i = 0;
i < exprintdata->hesnnz; ++
i )
2085 SCIPinfoMessage(
scip,
NULL,
" (%d,%d)=%g", exprintdata->hesrowidxs[
i], exprintdata->hescolidxs[
i], exprintdata->hesvalues[
i]);
2090 *rowidxs = exprintdata->hesrowidxs;
2091 *colidxs = exprintdata->hescolidxs;
2092 *hessianvals = exprintdata->hesvalues.data();
2093 *nnz = exprintdata->hesnnz;
atomic_userexpr(SCIP *scip_, SCIP_EXPR *expr_)
common defines and data types used in all packages of SCIP
exponential expression handler
logarithm expression handler
power and signed power expression handlers
handler for variable index expressions
methods to interpret (evaluate) an expression "fast"
#define CPPAD_MAX_NUM_THREADS
void posintpower(const vector< Type > &in, vector< Type > &out, size_t exponent)
static CppAD::ErrorHandler errorhandler(cppaderrorcallback)
static void cppaderrorcallback(bool known, int line, const char *file, const char *cond, const char *msg)
static void evalIntPower(Type &resultant, const Type &arg, const int exponent)
static void evalSignPower(CppAD::AD< Type > &resultant, const CppAD::AD< Type > &arg, SCIP_EXPR *expr)
static SCIP_RETCODE eval(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, const vector< Type > &x, Type &val)
int SCIPgetIndexExprVaridx(SCIP_EXPR *expr)
SCIP_Bool SCIPisExprVaridx(SCIP *scip, SCIP_EXPR *expr)
SCIP_Bool SCIPisExprLog(SCIP *scip, SCIP_EXPR *expr)
SCIP_Bool SCIPisExprExp(SCIP *scip, SCIP_EXPR *expr)
SCIP_Bool SCIPisExprSignpower(SCIP *scip, SCIP_EXPR *expr)
SCIP_RETCODE SCIPexprintCompile(SCIP *scip, SCIP_EXPRINT *exprint, SCIP_EXPR *rootexpr, SCIP_EXPRINTDATA **exprintdata)
SCIP_RETCODE SCIPexprintFreeData(SCIP *scip, SCIP_EXPRINT *exprint, SCIP_EXPR *expr, SCIP_EXPRINTDATA **exprintdata)
SCIP_EXPRINTCAPABILITY SCIPexprintGetCapability(void)
SCIP_RETCODE SCIPexprintHessianSparsity(SCIP *scip, SCIP_EXPRINT *exprint, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, SCIP_Real *varvals, int **rowidxs, int **colidxs, int *nnz)
SCIP_RETCODE SCIPexprintFree(SCIP *scip, SCIP_EXPRINT **exprint)
SCIP_RETCODE SCIPexprintEval(SCIP *scip, SCIP_EXPRINT *exprint, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, SCIP_Real *varvals, SCIP_Real *val)
const char * SCIPexprintGetName(void)
const char * SCIPexprintGetDesc(void)
SCIP_EXPRINTCAPABILITY SCIPexprintGetExprCapability(SCIP *scip, SCIP_EXPRINT *exprint, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata)
SCIP_RETCODE SCIPexprintHessian(SCIP *scip, SCIP_EXPRINT *exprint, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, SCIP_Real *varvals, SCIP_Bool new_varvals, SCIP_Real *val, int **rowidxs, int **colidxs, SCIP_Real **hessianvals, int *nnz)
SCIP_RETCODE SCIPexprintCreate(SCIP *scip, SCIP_EXPRINT **exprint)
SCIP_RETCODE SCIPexprintGrad(SCIP *scip, SCIP_EXPRINT *exprint, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, SCIP_Real *varvals, SCIP_Bool new_varvals, SCIP_Real *val, SCIP_Real *gradient)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
const char * SCIPexprhdlrGetName(SCIP_EXPRHDLR *exprhdlr)
SCIP_Bool SCIPexprhdlrHasFwdiff(SCIP_EXPRHDLR *exprhdlr)
SCIP_RETCODE SCIPevalExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag)
int SCIPexprGetNChildren(SCIP_EXPR *expr)
SCIP_Real SCIPgetExponentExprPow(SCIP_EXPR *expr)
SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
SCIP_Real * SCIPgetCoefsExprSum(SCIP_EXPR *expr)
SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
SCIP_Real SCIPgetCoefExprProduct(SCIP_EXPR *expr)
SCIP_EXPR * SCIPexpriterGetCurrent(SCIP_EXPRITER *iterator)
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
SCIP_RETCODE SCIPcallExprEval(SCIP *scip, SCIP_EXPR *expr, SCIP_Real *childrenvalues, SCIP_Real *val)
SCIP_RETCODE SCIPcreateExpriter(SCIP *scip, SCIP_EXPRITER **iterator)
SCIP_RETCODE SCIPcallExprEvalFwdiff(SCIP *scip, SCIP_EXPR *expr, SCIP_Real *childrenvalues, SCIP_Real *direction, SCIP_Real *val, SCIP_Real *dot)
SCIP_RETCODE SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
SCIP_Bool SCIPisExprPower(SCIP *scip, SCIP_EXPR *expr)
SCIP_Real SCIPexprGetEvalValue(SCIP_EXPR *expr)
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
SCIP_Real SCIPgetConstantExprSum(SCIP_EXPR *expr)
void SCIPfreeExpriter(SCIP_EXPRITER **iterator)
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
#define SCIPallocBufferArray(scip, ptr, num)
#define SCIPfreeBufferArray(scip, ptr)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
assert(minobj< SCIPgetCutoffbound(scip))
interval arithmetics for provable bounds
public functions to work with algebraic expressions
public functions to work with algebraic expressions
#define SCIP_EXPRINTCAPABILITY_GRADIENT
struct SCIP_ExprIntData SCIP_EXPRINTDATA
#define SCIP_EXPRINTCAPABILITY_HESSIAN
#define SCIP_EXPRINTCAPABILITY_FUNCVALUE
#define SCIP_EXPRINTCAPABILITY_ALL
struct SCIP_ExprInt SCIP_EXPRINT
unsigned int SCIP_EXPRINTCAPABILITY
enum SCIP_Retcode SCIP_RETCODE