SCIP

    Solving Constraint Integer Programs

    nlpioracle.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file nlpioracle.c
    26 * @ingroup OTHER_CFILES
    27 * @brief implementation of NLPI oracle
    28 * @author Stefan Vigerske
    29 *
    30 * @todo jacobi evaluation should be sparse
    31 */
    32
    33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    34
    35#include "scip/scip.h"
    36#include "scip/nlpioracle.h"
    37#include "scip/exprinterpret.h"
    38#include "scip/expr_pow.h"
    39#include "scip/expr_varidx.h"
    40
    41#include <string.h> /* for strlen */
    42
    43/**@name NLPI Oracle data structures */
    44/**@{ */
    45
    47{
    48 SCIP_Real lhs; /**< left hand side (for constraint) or constant (for objective) */
    49 SCIP_Real rhs; /**< right hand side (for constraint) or constant (for objective) */
    50
    51 int linsize; /**< length of linidxs and lincoefs arrays */
    52 int nlinidxs; /**< number of linear variable indices and coefficients */
    53 int* linidxs; /**< variable indices in linear part, or NULL if none */
    54 SCIP_Real* lincoefs; /**< variable coefficients in linear part, of NULL if none */
    55
    56 SCIP_EXPR* expr; /**< expression for nonlinear part, or NULL if none */
    57 SCIP_EXPRINTDATA* exprintdata; /**< expression interpret data for expression, or NULL if no expr or not compiled yet */
    58
    59 char* name; /**< name of constraint */
    60};
    62
    64{
    65 char* name; /**< name of problem */
    66
    67 /* variables */
    68 int varssize; /**< length of variables related arrays */
    69 int nvars; /**< number of variables */
    70 SCIP_Real* varlbs; /**< array with variable lower bounds */
    71 SCIP_Real* varubs; /**< array with variable upper bounds */
    72 char** varnames; /**< array with variable names */
    73 int* varlincount; /**< array with number of appearances of variable in linear part of objective or constraints */
    74 int* varnlcount; /**< array with number of appearances of variable in nonlinear part of objective or constraints */
    75
    76 /* constraints */
    77 int consssize; /**< length of constraints related arrays */
    78 int nconss; /**< number of constraints */
    79 SCIP_NLPIORACLECONS** conss; /**< constraints, or NULL if none */
    80
    81 /* objective */
    82 SCIP_NLPIORACLECONS* objective; /**< objective */
    83
    84 /* Jacobian */
    85 int njacnlnz; /**< number of entries in the Jacobian corresponding to nonlinear terms */
    86
    87 /* rowwise Jacobian structure */
    88 int* jacrowoffsets; /**< rowwise jacobi sparsity pattern: constraint offsets in jaccols */
    89 int* jaccols; /**< rowwise jacobi sparsity pattern: indices of variables appearing in constraints */
    90 SCIP_Bool* jaccolnlflags; /**< flags indicating whether a Jacobian entry corresponds to a nonlinear variable; sorted rowwise */
    91
    92 /* columnwise Jacobian structure */
    93 int* jaccoloffsets; /**< columnwise jacobi sparsity pattern: variable offsets in jacrows */
    94 int* jacrows; /**< columnwise jacobi sparsity pattern: indices of constraints where corresponding variables appear */
    95 SCIP_Bool* jacrownlflags; /**< flags indicating whether a Jacobian entry corresponds to a nonlinear variable; sorted column-wise */
    96
    97 /* objective gradient sparsity */
    98 int* objgradnz; /**< indices of nonzeroes in the objective gradient */
    99 SCIP_Bool* objnlflags; /**< flags of nonlinear nonzeroes in the objective gradient */
    100 int nobjgradnz; /**< number of nonzeroes in the objective gradient */
    101 int nobjgradnlnz; /**< number of nonlinear nonzeroes in the objective gradient */
    102
    103 /* sparsity pattern of the Hessian of the Lagrangian */
    104 int* heslagoffsets; /**< column (if colwise==TRUE) or row offsets in heslagnzs */
    105 int* heslagnzs; /**< row (if colwise==TRUE) or column indices; sorted for each column (if colwise==TRUE) or row */
    106 SCIP_Bool hescolwise; /**< indicates whether the Hessian entries are first sorted column-wise (TRUE) or row-wise */
    107
    108 SCIP_EXPRINT* exprinterpreter; /**< interpreter for expressions: evaluation and derivatives */
    109 SCIP_CLOCK* evalclock; /**< clock measuring evaluation time */
    110};
    111
    112/**@} */
    113
    114/*lint -e440*/
    115/*lint -e441*/
    116/*lint -e866*/
    117
    118/**@name Local functions */
    119/**@{ */
    120
    121/** ensures that those arrays in oracle that store information on variables have at least a given length */
    122static
    124 SCIP* scip, /**< SCIP data structure */
    125 SCIP_NLPIORACLE* oracle, /**< NLPIORACLE data structure */
    126 int minsize /**< minimal required size */
    127 )
    128{
    129 assert(oracle != NULL);
    130
    131 if( minsize > oracle->varssize )
    132 {
    133 int newsize;
    134
    135 newsize = SCIPcalcMemGrowSize(scip, minsize);
    136 assert(newsize >= minsize);
    137
    138 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &oracle->varlbs, oracle->varssize, newsize) );
    139 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &oracle->varubs, oracle->varssize, newsize) );
    140 if( oracle->varnames != NULL )
    141 {
    142 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &oracle->varnames, oracle->varssize, newsize) );
    143 }
    144 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &oracle->varlincount, oracle->varssize, newsize) );
    145 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &oracle->varnlcount, oracle->varssize, newsize) );
    146
    147 oracle->varssize = newsize;
    148 }
    149 assert(oracle->varssize >= minsize);
    150
    151 return SCIP_OKAY;
    152}
    153
    154/** ensures that constraints array in oracle has at least a given length */
    155static
    157 SCIP* scip, /**< SCIP data structure */
    158 SCIP_NLPIORACLE* oracle, /**< NLPIORACLE data structure */
    159 int minsize /**< minimal required size */
    160 )
    161{
    162 assert(oracle != NULL);
    163
    164 SCIP_CALL( SCIPensureBlockMemoryArray(scip, &oracle->conss, &oracle->consssize, minsize) );
    165 assert(oracle->consssize >= minsize);
    166
    167 return SCIP_OKAY;
    168}
    169
    170/** ensures that arrays for linear part in a oracle constraints have at least a given length */
    171static
    173 SCIP* scip, /**< SCIP data structure */
    174 SCIP_NLPIORACLECONS* cons, /**< oracle constraint */
    175 int minsize /**< minimal required size */
    176 )
    177{
    178 assert(cons != NULL);
    179
    180 if( minsize > cons->linsize )
    181 {
    182 int newsize;
    183
    184 newsize = SCIPcalcMemGrowSize(scip, minsize);
    185 assert(newsize >= minsize);
    186
    187 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &cons->linidxs, cons->linsize, newsize) );
    188 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &cons->lincoefs, cons->linsize, newsize) );
    189 cons->linsize = newsize;
    190 }
    191 assert(cons->linsize >= minsize);
    192
    193 return SCIP_OKAY;
    194}
    195
    196/** ensures that a given array of integers has at least a given length */
    197static
    199 SCIP* scip, /**< SCIP data structure */
    200 int** intarray, /**< array of integers */
    201 int* len, /**< length of array (modified if reallocated) */
    202 int minsize /**< minimal required array length */
    203 )
    204{
    205 assert(intarray != NULL);
    206 assert(len != NULL);
    207
    208 SCIP_CALL( SCIPensureBlockMemoryArray(scip, intarray, len, minsize) );
    209 assert(*len >= minsize);
    210
    211 return SCIP_OKAY;
    212}
    213
    214/** ensures that a given array of booleans has at least a given length, and clears the newly allocated memory */
    215static
    217 SCIP* scip, /**< SCIP data structure */
    218 SCIP_Bool** boolarray, /**< array of bools */
    219 int* len, /**< length of array (modified if reallocated) */
    220 int minsize /**< minimal required array length */
    221 )
    222{
    223 int oldlen = *len;
    224
    225 assert(boolarray != NULL);
    226 assert(len != NULL);
    227
    228 SCIP_CALL( SCIPensureBlockMemoryArray(scip, boolarray, len, minsize) );
    229 assert(*len >= minsize);
    230
    231 BMSclearMemoryArray((*boolarray)+oldlen, *len-oldlen);
    232
    233 return SCIP_OKAY;
    234}
    235
    236/** Invalidates the sparsity pattern of the Jacobian.
    237 * Should be called when constraints are added or deleted.
    238 */
    239static
    241 SCIP* scip, /**< SCIP data structure */
    242 SCIP_NLPIORACLE* oracle /**< pointer to store NLPIORACLE data structure */
    243 )
    244{
    245 assert(oracle != NULL);
    246
    247 SCIPdebugMessage("%p invalidate jacobian sparsity\n", (void*)oracle);
    248
    249 oracle->njacnlnz = 0;
    250
    251 if( oracle->jacrowoffsets == NULL )
    252 { /* nothing to do for the row representation */
    253 assert(oracle->jaccols == NULL);
    254 assert(oracle->jaccolnlflags == NULL);
    255 }
    256 else
    257 {
    258 assert(oracle->jaccols != NULL);
    260 SCIPfreeBlockMemoryArray(scip, &oracle->jaccols, oracle->jacrowoffsets[oracle->nconss]);
    261 SCIPfreeBlockMemoryArray(scip, &oracle->jacrowoffsets, oracle->nconss + 1);
    262 }
    263
    264 if( oracle->jaccoloffsets == NULL )
    265 { /* nothing to do for the column representation */
    266 assert(oracle->jacrows == NULL);
    267 assert(oracle->jacrownlflags == NULL);
    268 }
    269 else
    270 {
    271 assert(oracle->jacrows != NULL);
    273 SCIPfreeBlockMemoryArray(scip, &oracle->jacrows, oracle->jaccoloffsets[oracle->nvars]);
    274 SCIPfreeBlockMemoryArray(scip, &oracle->jaccoloffsets, oracle->nvars + 1);
    275 }
    276
    277 if( oracle->objgradnz == NULL )
    278 {
    279 /* nothing to do for objective gradient structure */
    280 assert(oracle->objnlflags == NULL);
    281 assert(oracle->nobjgradnz == 0);
    282 assert(oracle->nobjgradnlnz == 0);
    283 return;
    284 }
    285
    288 oracle->nobjgradnz = 0;
    289 oracle->nobjgradnlnz = 0;
    290}
    291
    292/** Invalidates the sparsity pattern of the Hessian of the Lagragian.
    293 * Should be called when the objective is set or constraints are added or deleted.
    294 */
    295static
    297 SCIP* scip, /**< SCIP data structure */
    298 SCIP_NLPIORACLE* oracle /**< pointer to store NLPIORACLE data structure */
    299 )
    300{
    301 assert(oracle != NULL);
    302
    303 SCIPdebugMessage("%p invalidate hessian lag sparsity\n", (void*)oracle);
    304
    305 if( oracle->heslagoffsets == NULL )
    306 {
    307 /* nothing to do */
    308 assert(oracle->heslagnzs == NULL);
    309 return;
    310 }
    311
    312 assert(oracle->heslagnzs != NULL);
    313 SCIPfreeBlockMemoryArray(scip, &oracle->heslagnzs, oracle->heslagoffsets[oracle->nvars]);
    314 SCIPfreeBlockMemoryArray(scip, &oracle->heslagoffsets, oracle->nvars + 1);
    315}
    316
    317/** increases or decreases variable counts in oracle w.r.t. linear and nonlinear appearance */
    318static
    320 SCIP* scip, /**< SCIP data structure */
    321 SCIP_NLPIORACLE* oracle, /**< oracle data structure */
    322 int factor, /**< whether to add (factor=1) or remove (factor=-1) variable counts */
    323 int nlinidxs, /**< number of linear indices */
    324 const int* linidxs, /**< indices of variables in linear part */
    325 SCIP_EXPR* expr /**< expression */
    326 )
    327{
    328 int j;
    329
    330 assert(oracle != NULL);
    331 assert(oracle->varlincount != NULL || (nlinidxs == 0 && expr == NULL));
    332 assert(oracle->varnlcount != NULL || (nlinidxs == 0 && expr == NULL));
    333 assert(factor == 1 || factor == -1);
    334 assert(nlinidxs == 0 || linidxs != NULL);
    335
    336 for( j = 0; j < nlinidxs; ++j )
    337 {
    338 oracle->varlincount[linidxs[j]] += factor;
    339 assert(oracle->varlincount[linidxs[j]] >= 0);
    340 }
    341
    342 if( expr != NULL )
    343 {
    344 SCIP_EXPRITER* it;
    345
    348
    349 for( ; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    350 if( SCIPisExprVaridx(scip, expr) )
    351 {
    352 oracle->varnlcount[SCIPgetIndexExprVaridx(expr)] += factor;
    353 assert(oracle->varnlcount[SCIPgetIndexExprVaridx(expr)] >= 0);
    354 }
    355
    356 SCIPfreeExpriter(&it);
    357 }
    358
    359 return SCIP_OKAY;
    360}
    361
    362/** sorts a linear term, merges duplicate entries and removes entries with coefficient 0.0 */
    363static
    365 int* nidxs, /**< number of variables */
    366 int* idxs, /**< indices of variables */
    367 SCIP_Real* coefs /**< coefficients of variables */
    368 )
    369{
    370 int offset;
    371 int j;
    372
    373 assert(nidxs != NULL);
    374 assert(idxs != NULL || *nidxs == 0);
    375 assert(coefs != NULL || *nidxs == 0);
    376
    377 if( *nidxs == 0 )
    378 return;
    379
    380 SCIPsortIntReal(idxs, coefs, *nidxs);
    381
    382 offset = 0;
    383 j = 0;
    384 while( j+offset < *nidxs )
    385 {
    386 assert(idxs[j] >= 0); /*lint !e613*/
    387
    388 /* move j+offset to j, if different */
    389 if( offset > 0 )
    390 {
    391 idxs[j] = idxs[j+offset]; /*lint !e613*/
    392 coefs[j] = coefs[j+offset]; /*lint !e613*/
    393 }
    394
    395 /* add up coefs for j+offset+1... as long as they have the same index */
    396 while( j+offset+1 < *nidxs && idxs[j] == idxs[j+offset+1] ) /*lint !e613*/
    397 {
    398 coefs[j] += coefs[j+offset+1]; /*lint !e613*/
    399 ++offset;
    400 }
    401
    402 /* if j'th element is 0, increase offset, otherwise increase j */
    403 if( coefs[j] == 0.0 ) /*lint !e613*/
    404 ++offset;
    405 else
    406 ++j;
    407 }
    408 *nidxs -= offset;
    409}
    410
    411/** creates a NLPI constraint from given constraint data */
    412static
    414 SCIP* scip, /**< SCIP data structure */
    415 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    416 SCIP_NLPIORACLECONS** cons, /**< buffer where to store pointer to constraint */
    417 int nlinidxs, /**< length of linear part */
    418 const int* linidxs, /**< indices of linear part, or NULL if nlinidxs == 0 */
    419 const SCIP_Real* lincoefs, /**< coefficients of linear part, or NULL if nlinidxs == 0 */
    420 SCIP_EXPR* expr, /**< expression, or NULL */
    421 SCIP_Real lhs, /**< left-hand-side of constraint */
    422 SCIP_Real rhs, /**< right-hand-side of constraint */
    423 const char* name /**< name of constraint, or NULL */
    424 )
    425{
    426 assert(cons != NULL);
    427 assert(nlinidxs >= 0);
    428 assert(linidxs != NULL || nlinidxs == 0);
    429 assert(lincoefs != NULL || nlinidxs == 0);
    430 assert(EPSLE(lhs, rhs, SCIP_DEFAULT_EPSILON));
    431
    433 assert(*cons != NULL);
    434
    435 if( nlinidxs > 0 )
    436 {
    437 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*cons)->linidxs, linidxs, nlinidxs) );
    438 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*cons)->lincoefs, lincoefs, nlinidxs) );
    439 (*cons)->linsize = nlinidxs;
    440 (*cons)->nlinidxs = nlinidxs;
    441
    442 /* sort, merge duplicates, remove zero's */
    443 sortLinearCoefficients(&(*cons)->nlinidxs, (*cons)->linidxs, (*cons)->lincoefs);
    444 assert((*cons)->linidxs[0] >= 0);
    445 }
    446
    447 if( expr != NULL )
    448 {
    449 (*cons)->expr = expr;
    450 SCIPcaptureExpr(expr);
    451
    452 SCIP_CALL( SCIPexprintCompile(scip, oracle->exprinterpreter, (*cons)->expr, &(*cons)->exprintdata) );
    453 }
    454
    455 if( lhs > rhs )
    456 {
    457 assert(EPSEQ(lhs, rhs, SCIP_DEFAULT_EPSILON));
    458 lhs = rhs;
    459 }
    460 (*cons)->lhs = lhs;
    461 (*cons)->rhs = rhs;
    462
    463 if( name != NULL )
    464 {
    465 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*cons)->name, name, strlen(name)+1) );
    466 }
    467
    468 /* add variable counts */
    469 SCIP_CALL( updateVariableCounts(scip, oracle, 1, (*cons)->nlinidxs, (*cons)->linidxs, (*cons)->expr) );
    470
    471 return SCIP_OKAY;
    472}
    473
    474/** frees a constraint */
    475static
    477 SCIP* scip, /**< SCIP data structure */
    478 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    479 SCIP_NLPIORACLECONS** cons, /**< pointer to constraint that should be freed */
    480 SCIP_Bool updatevarcount /**< whether the update variable counts (typically TRUE) */
    481 )
    482{
    483 assert(oracle != NULL);
    484 assert(cons != NULL);
    485 assert(*cons != NULL);
    486
    487 SCIPdebugMessage("free constraint %p\n", (void*)*cons);
    488
    489 /* remove variable counts */
    490 if( updatevarcount )
    491 {
    492 SCIP_CALL( updateVariableCounts(scip, oracle, -1, (*cons)->nlinidxs, (*cons)->linidxs, (*cons)->expr) );
    493 }
    494
    495 SCIPfreeBlockMemoryArrayNull(scip, &(*cons)->linidxs, (*cons)->linsize);
    496 SCIPfreeBlockMemoryArrayNull(scip, &(*cons)->lincoefs, (*cons)->linsize);
    497
    498 if( (*cons)->expr != NULL )
    499 {
    500 SCIP_CALL( SCIPexprintFreeData(scip, oracle->exprinterpreter, (*cons)->expr, &(*cons)->exprintdata) );
    501 SCIP_CALL( SCIPreleaseExpr(scip, &(*cons)->expr) );
    502 }
    503
    504 if( (*cons)->name != NULL )
    505 {
    506 SCIPfreeBlockMemoryArrayNull(scip, &(*cons)->name, strlen((*cons)->name)+1);
    507 }
    508
    510 assert(*cons == NULL);
    511
    512 return SCIP_OKAY;
    513}
    514
    515/** frees all constraints
    516 *
    517 * \attention This omits updating the variable counts in the oracle.
    518 */
    519static
    521 SCIP* scip, /**< SCIP data structure */
    522 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    523 )
    524{
    525 int i;
    526
    527 assert(oracle != NULL);
    528
    529 SCIPdebugMessage("%p free constraints\n", (void*)oracle);
    530
    531 for( i = 0; i < oracle->nconss; ++i )
    532 {
    533 SCIP_CALL( freeConstraint(scip, oracle, &oracle->conss[i], FALSE) );
    534 assert(oracle->conss[i] == NULL);
    535 }
    536 oracle->nconss = 0;
    537
    539 oracle->consssize = 0;
    540
    541 return SCIP_OKAY;
    542}
    543
    544/** moves one variable
    545 * The place where it moves to need to be empty (all NULL) but allocated.
    546 * Note that this function does not update the variable indices in the constraints!
    547 */
    548static
    550 SCIP* scip, /**< SCIP data structure */
    551 SCIP_NLPIORACLE* oracle, /**< pointer to store NLPIORACLE data structure */
    552 int fromidx, /**< index of variable to move */
    553 int toidx /**< index of place where to move variable to */
    554 )
    555{
    556 assert(oracle != NULL);
    557
    558 SCIPdebugMessage("%p move variable\n", (void*)oracle);
    559
    560 assert(0 <= fromidx);
    561 assert(0 <= toidx);
    562 assert(fromidx < oracle->nvars);
    563 assert(toidx < oracle->nvars);
    564
    565 assert(oracle->varnames == NULL || oracle->varnames[toidx] == NULL);
    566
    567 oracle->varlbs[toidx] = oracle->varlbs[fromidx];
    568 oracle->varubs[toidx] = oracle->varubs[fromidx];
    569 oracle->varlbs[fromidx] = -SCIPinfinity(scip);
    570 oracle->varubs[fromidx] = SCIPinfinity(scip);
    571
    572 oracle->varlincount[toidx] = oracle->varlincount[fromidx];
    573 oracle->varnlcount[toidx] = oracle->varnlcount[fromidx];
    574 oracle->varlincount[fromidx] = 0;
    575 oracle->varnlcount[fromidx] = 0;
    576
    577 if( oracle->varnames != NULL )
    578 {
    579 oracle->varnames[toidx] = oracle->varnames[fromidx];
    580 oracle->varnames[fromidx] = NULL;
    581 }
    582
    583 return SCIP_OKAY;
    584}
    585
    586/** frees all variables */
    587static
    589 SCIP* scip, /**< SCIP data structure */
    590 SCIP_NLPIORACLE* oracle /**< pointer to store NLPIORACLE data structure */
    591 )
    592{
    593 int i;
    594
    595 assert(oracle != NULL);
    596
    597 SCIPdebugMessage("%p free variables\n", (void*)oracle);
    598
    599 if( oracle->varnames != NULL )
    600 {
    601 for( i = 0; i < oracle->nvars; ++i )
    602 {
    603 if( oracle->varnames[i] != NULL )
    604 {
    605 SCIPfreeBlockMemoryArray(scip, &oracle->varnames[i], strlen(oracle->varnames[i])+1); /*lint !e866*/
    606 }
    607 }
    609 }
    610 oracle->nvars = 0;
    611
    616
    617 oracle->varssize = 0;
    618}
    619
    620/** applies a mapping of indices to one array of indices */
    621static
    623 int* indexmap, /**< mapping from old variable indices to new indices */
    624 int nindices, /**< number of indices in indices1 and indices2 */
    625 int* indices /**< array of indices to adjust */
    626 )
    627{
    628 assert(indexmap != NULL);
    629 assert(nindices == 0 || indices != NULL);
    630
    631 for( ; nindices ; --nindices, ++indices )
    632 {
    633 assert(indexmap[*indices] >= 0);
    634 *indices = indexmap[*indices];
    635 }
    636}
    637
    638/** removes entries with index -1 (marked as deleted) from array of linear elements
    639 * assumes that array is sorted by index, i.e., all -1 are at the beginning
    640 */
    641static
    643 int** linidxs, /**< variable indices */
    644 SCIP_Real** coefs, /**< variable coefficients */
    645 int* nidxs /**< number of indices */
    646 )
    647{
    648 int i;
    649 int offset;
    650
    651 SCIPdebugMessage("clear deleted linear elements\n");
    652
    653 assert(linidxs != NULL);
    654 assert(*linidxs != NULL);
    655 assert(coefs != NULL);
    656 assert(*coefs != NULL);
    657 assert(nidxs != NULL);
    658 assert(*nidxs > 0);
    659
    660 /* search for beginning of non-delete entries @todo binary search? */
    661 for( offset = 0; offset < *nidxs; ++offset )
    662 if( (*linidxs)[offset] >= 0 )
    663 break;
    664
    665 /* nothing was deleted */
    666 if( offset == 0 )
    667 return;
    668
    669 /* some or all elements were deleted -> move remaining ones front */
    670 for( i = 0; i < *nidxs - offset; ++i )
    671 {
    672 (*linidxs)[i] = (*linidxs)[i+offset];
    673 (*coefs)[i] = (*coefs) [i+offset];
    674 }
    675 *nidxs -= offset;
    676}
    677
    678/** computes the value of a function */
    679static
    681 SCIP* scip, /**< SCIP data structure */
    682 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    683 SCIP_NLPIORACLECONS* cons, /**< oracle constraint */
    684 const SCIP_Real* x, /**< the point where to evaluate */
    685 SCIP_Real* val /**< pointer to store function value */
    686 )
    687{ /*lint --e{715}*/
    688 assert(oracle != NULL);
    689 assert(cons != NULL);
    690 assert(x != NULL || oracle->nvars == 0);
    691 assert(val != NULL);
    692
    693 SCIPdebugMessage("%p eval function value\n", (void*)oracle);
    694
    695 *val = 0.0;
    696
    697 if( cons->nlinidxs > 0 )
    698 {
    699 int* linidxs;
    700 SCIP_Real* lincoefs;
    701 int nlin;
    702
    703 nlin = cons->nlinidxs;
    704 linidxs = cons->linidxs;
    705 lincoefs = cons->lincoefs;
    706 assert(linidxs != NULL);
    707 assert(lincoefs != NULL);
    708 assert(x != NULL);
    709
    710 for( ; nlin > 0; --nlin, ++linidxs, ++lincoefs )
    711 *val += *lincoefs * x[*linidxs];
    712 }
    713
    714 if( cons->expr != NULL )
    715 {
    716 SCIP_Real nlval;
    717
    718 SCIP_CALL( SCIPexprintEval(scip, oracle->exprinterpreter, cons->expr, cons->exprintdata, (SCIP_Real*)x, &nlval) );
    719 if( !SCIPisFinite(nlval) || SCIPisInfinity(scip, ABS(nlval)) )
    720 *val = nlval;
    721 else
    722 *val += nlval;
    723 }
    724
    725 return SCIP_OKAY;
    726}
    727
    728/** computes an interval for a function */
    729static
    731 SCIP* scip, /**< SCIP data structure */
    732 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    733 SCIP_NLPIORACLECONS* cons, /**< oracle constraint */
    734 SCIP_Real infinity, /**< value for infinity */
    735 const SCIP_Real* xmin, /**< lower bound on variable interval */
    736 const SCIP_Real* xmax, /**< upper bound on variable interval */
    737 SCIP_Real* valmin, /**< buffer to store lower bound of function */
    738 SCIP_Real* valmax /**< buffer to store upper bound of function */
    739 )
    740{
    741 SCIP_INTERVAL val;
    742 int i;
    743
    744 assert(oracle != NULL);
    745 assert(cons != NULL);
    746 assert(xmin != NULL || oracle->nvars == 0);
    747 assert(xmax != NULL || oracle->nvars == 0);
    748 assert(valmin != NULL);
    749 assert(valmax != NULL);
    750
    751 SCIPdebugMessage("%p eval function interval\n", (void*)oracle);
    752
    753 if( cons->expr != NULL )
    754 {
    755 SCIP_EXPRITER* it;
    756 SCIP_EXPR* expr;
    757 SCIP_INTERVAL exprval;
    758
    759 /* Iterate through the expression in DFS.
    760 * Each time when an expression node is left, its interval (or activity) is evaluated by the
    761 * exprhdlrs interval evaluator (no nlhdlrs here), using the values in the children.
    762 * For variables, which are given by an index here, the values from xmin/xmax are used.
    763 */
    767
    768 for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    769 {
    770 if( SCIPisExprVaridx(scip, expr) )
    771 {
    772 int varidx = SCIPgetIndexExprVaridx(expr);
    773 assert(varidx >= 0);
    774 assert(varidx < SCIPnlpiOracleGetNVars(oracle));
    775
    776 SCIPintervalSetBounds(&exprval, xmin[varidx] == -infinity ? -SCIP_INTERVAL_INFINITY : xmin[varidx], /*lint !e777 */
    777 xmax[varidx] == infinity ? SCIP_INTERVAL_INFINITY : xmax[varidx]); /*lint !e777 */
    778 }
    779 else
    780 {
    781 /* call the inteval callback of the exprhdlr */
    782 SCIP_CALL( SCIPcallExprInteval(scip, expr, &exprval, NULL, NULL) );
    783 }
    784
    786 {
    787 /* abort with empty interval if domain error */
    788 *valmin = 1.0;
    789 *valmax = -1.0;
    790
    791 SCIPfreeExpriter(&it);
    792 return SCIP_OKAY;
    793 }
    794
    795 /* set exprval as activity in expr, so it will be used by SCIPcallExprInteval() in parents */
    796 SCIPexprSetActivity(expr, exprval, 0LL);
    797 }
    798
    799 SCIPfreeExpriter(&it);
    800
    801 val = SCIPexprGetActivity(cons->expr);
    802 }
    803 else
    804 {
    805 SCIPintervalSet(&val, 0.0);
    806 }
    807
    808 /* add the activity of the linear terms */
    809 for( i = 0; i < cons->nlinidxs; ++i )
    810 {
    811 SCIP_INTERVAL interval;
    812
    813 SCIPintervalSetBounds(&interval, xmin[cons->linidxs[i]] == -infinity ? -SCIP_INTERVAL_INFINITY : xmin[cons->linidxs[i]], /*lint !e777 */
    814 xmax[cons->linidxs[i]] == infinity ? SCIP_INTERVAL_INFINITY : xmax[cons->linidxs[i]]); /*lint !e777 */
    815 SCIPintervalMulScalar(SCIP_INTERVAL_INFINITY, &interval, interval, cons->lincoefs[i]);
    816 SCIPintervalAdd(SCIP_INTERVAL_INFINITY, &val, val, interval);
    817 }
    818
    819 *valmin = val.inf <= -SCIP_INTERVAL_INFINITY ? -infinity : val.inf;
    820 *valmax = val.sup >= SCIP_INTERVAL_INFINITY ? infinity : val.sup;
    821
    822 return SCIP_OKAY;
    823}
    824
    825/** computes the value and gradient of a function
    826 *
    827 * @return SCIP_INVALIDDATA, if the function or its gradient could not be evaluated (domain error, etc.)
    828 */
    829static
    831 SCIP* scip, /**< SCIP data structure */
    832 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    833 SCIP_NLPIORACLECONS* cons, /**< oracle constraint */
    834 const SCIP_Real* x, /**< the point where to evaluate */
    835 SCIP_Bool isnewx, /**< has the point x changed since the last call to some evaluation function? */
    836 SCIP_Real* RESTRICT val, /**< pointer to store function value */
    837 SCIP_Real* RESTRICT grad /**< pointer to store function gradient */
    838 )
    839{ /*lint --e{715}*/
    840 assert(oracle != NULL);
    841 assert(x != NULL || oracle->nvars == 0);
    842 assert(val != NULL);
    843 assert(grad != NULL);
    844
    845 SCIPdebugMessage("%p eval function gradient\n", (void*)oracle);
    846
    847 *val = 0.0;
    848 BMSclearMemoryArray(grad, oracle->nvars);
    849
    850 if( cons->expr != NULL )
    851 {
    852 SCIP_Real nlval;
    853 int i;
    854
    855 SCIPdebugMsg(scip, "eval gradient of ");
    856 SCIPdebug( if( isnewx ) {printf("\nx ="); for( i = 0; i < oracle->nvars; ++i) printf(" %g", x[i]); printf("\n");} )
    857
    858 SCIP_CALL( SCIPexprintGrad(scip, oracle->exprinterpreter, cons->expr, cons->exprintdata, (SCIP_Real*)x, isnewx, &nlval, grad) );
    859
    860 SCIPdebug( printf("g ="); for( i = 0; i < oracle->nvars; ++i) printf(" %g", grad[i]); printf("\n"); )
    861
    862 /* check for eval error */
    863 if( !SCIPisFinite(nlval) || SCIPisInfinity(scip, ABS(nlval)) )
    864 {
    865 SCIPdebugMessage("gradient evaluation yield invalid function value %g\n", nlval);
    866 return SCIP_INVALIDDATA; /* indicate that the function could not be evaluated at given point */
    867 }
    868 for( i = 0; i < oracle->nvars; ++i )
    869 if( !SCIPisFinite(grad[i]) )
    870 {
    871 SCIPdebugMessage("gradient evaluation yield invalid gradient value %g\n", grad[i]);
    872 return SCIP_INVALIDDATA; /* indicate that the function could not be evaluated at given point */
    873 }
    874
    875 *val += nlval;
    876 }
    877
    878 if( cons->nlinidxs > 0 )
    879 {
    880 int* linidxs;
    881 SCIP_Real* lincoefs;
    882 int nlin;
    883
    884 nlin = cons->nlinidxs;
    885 linidxs = cons->linidxs;
    886 lincoefs = cons->lincoefs;
    887 assert(linidxs != NULL);
    888 assert(lincoefs != NULL);
    889 assert(x != NULL);
    890
    891 for( ; nlin > 0; --nlin, ++linidxs, ++lincoefs )
    892 {
    893 *val += *lincoefs * x[*linidxs];
    894 grad[*linidxs] += *lincoefs;
    895 }
    896 }
    897
    898 return SCIP_OKAY;
    899}
    900
    901/** compute rowwise sparsity of the Jacobian */
    903 SCIP* scip, /**< SCIP data structure */
    904 SCIP_NLPIORACLE* oracle, /**< NLPI oracle */
    905 int* nnz, /**< counter for the number of nonzeroes */
    906 int* nvarnnz /**< for each variable, number of constraints it has a nonzero in; can be NULL if not needed */
    907 )
    908{
    909 int maxcols;
    910 int maxflags;
    911 SCIP_Bool* nzflag;
    912 SCIP_Bool* nlflag;
    913 SCIP_EXPRITER* it;
    915 SCIP_EXPR* expr;
    916
    917 assert(scip != NULL);
    918 assert(oracle != NULL);
    919
    920 maxcols = MIN(oracle->nvars, 10) * oracle->nconss; /* initial guess */
    921 maxflags = maxcols; /* since array extension functions change the length variable, have one variable for each array */
    922
    924 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &oracle->jaccols, maxcols) );
    926
    927 (*nnz) = 0;
    928
    929 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &nzflag, oracle->nvars) );
    930 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &nlflag, oracle->nvars) );
    931
    934
    935 for( int i = 0; i < oracle->nconss; ++i )
    936 {
    937 oracle->jacrowoffsets[i] = *nnz;
    938
    939 cons = oracle->conss[i];
    940 assert(cons != NULL);
    941
    942 if( cons->expr == NULL )
    943 {
    944 /* for a linear constraint, we can just copy the linear indices from the constraint into the sparsity pattern */
    945 if( cons->nlinidxs > 0 )
    946 {
    947 SCIP_CALL( ensureIntArraySize(scip, &oracle->jaccols, &maxcols, *nnz + cons->nlinidxs) );
    948 SCIP_CALL( ensureClearBoolArraySize(scip, &oracle->jaccolnlflags, &maxflags, *nnz + cons->nlinidxs) );
    949 BMScopyMemoryArray(&oracle->jaccols[*nnz], cons->linidxs, cons->nlinidxs);
    950 (*nnz) += cons->nlinidxs;
    951
    952 if( nvarnnz != NULL )
    953 for( int j = 0; j < cons->nlinidxs; ++j )
    954 ++nvarnnz[cons->linidxs[j]];
    955 }
    956 continue;
    957 }
    958
    959 /* check which variables appear in constraint i
    960 * @todo this could be done faster for very sparse constraint by assembling all appearing variables, sorting, and removing duplicates
    961 */
    962 BMSclearMemoryArray(nzflag, oracle->nvars);
    963 BMSclearMemoryArray(nlflag, oracle->nvars);
    964
    965 for( int j = 0; j < cons->nlinidxs; ++j )
    966 nzflag[cons->linidxs[j]] = TRUE;
    967
    968 for( expr = SCIPexpriterRestartDFS(it, cons->expr); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    969 if( SCIPisExprVaridx(scip, expr) )
    970 {
    971 assert(SCIPgetIndexExprVaridx(expr) < oracle->nvars);
    972 nzflag[SCIPgetIndexExprVaridx(expr)] = TRUE;
    973 nlflag[SCIPgetIndexExprVaridx(expr)] = TRUE;
    974 }
    975
    976 /* store variables indices in jaccols and increase coloffsets */
    977 for( int j = 0; j < oracle->nvars; ++j )
    978 {
    979 if( nzflag[j] == FALSE )
    980 continue;
    981
    982 SCIP_CALL( ensureIntArraySize(scip, &oracle->jaccols, &maxcols, (*nnz) + 1) );
    983 SCIP_CALL( ensureClearBoolArraySize(scip, &oracle->jaccolnlflags, &maxflags, (*nnz) + 1) );
    984 oracle->jaccols[*nnz] = j;
    985 if( nlflag[j] )
    986 {
    987 oracle->jaccolnlflags[*nnz] = TRUE;
    988 ++(oracle->njacnlnz);
    989 }
    990 ++(*nnz);
    991 if( nvarnnz != NULL )
    992 ++nvarnnz[j]; /* increase the counter of the variable's nonzeroes */
    993 }
    994 }
    995
    996 SCIPfreeExpriter(&it);
    997
    998 oracle->jacrowoffsets[oracle->nconss] = *nnz;
    999
    1000 /* shrink jaccols and jaccolnlflags arrays to nnz */
    1001 if( *nnz < maxcols )
    1002 {
    1003 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &oracle->jaccols, maxcols, *nnz) );
    1004 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &oracle->jaccolnlflags, maxflags, *nnz) );
    1005 }
    1006
    1007 SCIPfreeBlockMemoryArray(scip, &nlflag, oracle->nvars);
    1008 SCIPfreeBlockMemoryArray(scip, &nzflag, oracle->nvars);
    1009
    1010 return SCIP_OKAY;
    1011}
    1012
    1013/** collects indices of nonzero entries in the lower-left part of the hessian matrix of an expression
    1014 * adds the indices to a given set of indices, avoiding duplicates */
    1015static
    1017 SCIP* scip, /**< SCIP data structure */
    1018 SCIP_NLPIORACLE* oracle, /**< NLPI oracle */
    1019 int** nz, /**< indices of nonzero entries for each column (if col) or row */
    1020 int* len, /**< space allocated to store indices of nonzeros for each column (if col) or row */
    1021 int* nnz, /**< number of nonzero entries for each column (if col) or row */
    1022 int* nzcount, /**< counter for total number of nonzeros; should be increased when nzflag is set to 1 the first time */
    1023 SCIP_EXPR* expr, /**< expression */
    1024 SCIP_EXPRINTDATA* exprintdata, /**< expression interpreter data for expression */
    1025 int dim, /**< dimension of matrix */
    1026 SCIP_Bool colwise /**< tells the function whether a column-wise (TRUE) or row-wise representation is needed */
    1027 )
    1028{
    1029 SCIP_Real* x;
    1030 int* rowidxs;
    1031 int* colidxs;
    1032 int ntotalnz;
    1033 int row;
    1034 int col;
    1035 int pos;
    1036 int i;
    1037
    1038 assert(oracle != NULL);
    1039 assert(nz != NULL);
    1040 assert(len != NULL);
    1041 assert(nnz != NULL);
    1042 assert(nzcount != NULL);
    1043 assert(expr != NULL);
    1044 assert(dim >= 0);
    1045
    1046 SCIPdebugMessage("%p hess lag sparsity set nzflag for expr\n", (void*)oracle);
    1047
    1048 SCIP_CALL( SCIPallocBufferArray(scip, &x, oracle->nvars) );
    1049 for( i = 0; i < oracle->nvars; ++i )
    1050 x[i] = 2.0; /* hope that this value does not make much trouble for the evaluation routines */
    1051
    1052 SCIP_CALL( SCIPexprintHessianSparsity(scip, oracle->exprinterpreter, expr, exprintdata, x, &rowidxs, &colidxs, &ntotalnz) );
    1053
    1054 for( i = 0; i < ntotalnz; ++i )
    1055 {
    1056 row = rowidxs[i];
    1057 col = colidxs[i];
    1058
    1059 assert(row < oracle->nvars);
    1060 assert(col <= row);
    1061
    1062 if( !colwise )
    1063 { /* rowwise representation */
    1064 if( nz[row] == NULL || !SCIPsortedvecFindInt(nz[row], col, nnz[row], &pos) )
    1065 {
    1066 SCIP_CALL( ensureIntArraySize(scip, &nz[row], &len[row], nnz[row]+1) );
    1067 SCIPsortedvecInsertInt(nz[row], col, &nnz[row], NULL);
    1068 ++*nzcount;
    1069 }
    1070 }
    1071 else
    1072 { /* columnwise representation */
    1073 if( nz[col] == NULL || !SCIPsortedvecFindInt(nz[col], row, nnz[col], &pos) )
    1074 {
    1075 SCIP_CALL( ensureIntArraySize(scip, &nz[col], &len[col], nnz[col]+1) );
    1076 SCIPsortedvecInsertInt(nz[col], row, &nnz[col], NULL);
    1077 ++*nzcount;
    1078 }
    1079 }
    1080 }
    1081
    1083
    1084 return SCIP_OKAY;
    1085}
    1086
    1087/** adds hessian of an expression into hessian structure */
    1088static
    1090 SCIP* scip, /**< SCIP data structure */
    1091 SCIP_NLPIORACLE* oracle, /**< oracle */
    1092 SCIP_Real weight, /**< weight of quadratic part */
    1093 const SCIP_Real* x, /**< point for which hessian should be returned */
    1094 SCIP_Bool new_x, /**< whether point has been evaluated before */
    1095 SCIP_EXPR* expr, /**< expression */
    1096 SCIP_EXPRINTDATA* exprintdata, /**< expression interpreter data for expression */
    1097 int* hesoffset, /**< column (if colwise = TRUE) or row offsets in sparse matrix that is to be filled */
    1098 int* hesnzidcs, /**< row (if colwise = TRUE) or column indices in sparse matrix that is to be filled */
    1099 SCIP_Real* values, /**< buffer for values of sparse matrix that is to be filled */
    1100 SCIP_Bool colwise /**< whether the entries should be first sorted column-wise (TRUE) or row-wise */
    1101 )
    1102{
    1103 SCIP_Real val;
    1104 SCIP_Real* h;
    1105 int* rowidxs;
    1106 int* colidxs;
    1107 int nnz;
    1108 int row;
    1109 int col;
    1110 int pos;
    1111 int i;
    1112
    1113 SCIPdebugMessage("%p hess lag add expr\n", (void*)oracle);
    1114
    1115 assert(oracle != NULL);
    1116 assert(x != NULL || new_x == FALSE);
    1117 assert(expr != NULL);
    1118 assert(hesoffset != NULL);
    1119 assert(hesnzidcs != NULL);
    1120 assert(values != NULL);
    1121
    1122 SCIP_CALL( SCIPexprintHessian(scip, oracle->exprinterpreter, expr, exprintdata, (SCIP_Real*)x, new_x, &val,
    1123 &rowidxs, &colidxs, &h, &nnz) );
    1124
    1125 if( !SCIPisFinite(val) )
    1126 {
    1127 SCIPdebugMessage("hessian evaluation yield invalid function value %g\n", val);
    1128 return SCIP_INVALIDDATA; /* indicate that the function could not be evaluated at given point */
    1129 }
    1130
    1131 for( i = 0; i < nnz; ++i )
    1132 {
    1133 if( !SCIPisFinite(h[i]) )
    1134 {
    1135 SCIPdebugMessage("hessian evaluation yield invalid hessian value %g\n", *h);
    1136 return SCIP_INVALIDDATA; /* indicate that the function could not be evaluated at given point */
    1137 }
    1138
    1139 if( h[i] == 0.0 )
    1140 continue;
    1141
    1142 row = rowidxs[i];
    1143 col = colidxs[i];
    1144
    1145 if( !colwise )
    1146 {
    1147 if( !SCIPsortedvecFindInt(&hesnzidcs[hesoffset[row]], col, hesoffset[row+1] - hesoffset[row], &pos) )
    1148 {
    1149 SCIPerrorMessage("Could not find entry (%d, %d) in hessian sparsity\n", row, col);
    1150 return SCIP_ERROR;
    1151 }
    1152
    1153 values[hesoffset[row] + pos] += weight * h[i];
    1154 }
    1155 else
    1156 {
    1157 if( !SCIPsortedvecFindInt(&hesnzidcs[hesoffset[col]], row, hesoffset[col+1] - hesoffset[col], &pos) )
    1158 {
    1159 SCIPerrorMessage("Could not find entry (%d, %d) in hessian sparsity\n", row, col);
    1160 return SCIP_ERROR;
    1161 }
    1162
    1163 values[hesoffset[col] + pos] += weight * h[i];
    1164 }
    1165 }
    1166
    1167 return SCIP_OKAY;
    1168}
    1169
    1170/** prints a name, if available, makes sure it has not more than 64 characters, and adds a unique prefix if the longnames flag is set */
    1171static
    1173 char* buffer, /**< buffer to print to, has to be not NULL and should be at least 65 bytes */
    1174 char* name, /**< name, or NULL */
    1175 int idx, /**< index of var or cons which the name corresponds to */
    1176 char prefix, /**< a letter (typically 'x' or 'e') to distinguish variable and equation names, if names[idx] is not available */
    1177 const char* suffix, /**< a suffer to add to the name, or NULL */
    1178 SCIP_Bool longnames /**< whether prefixes for long names should be added */
    1179 )
    1180{
    1181 assert(idx >= 0 && idx < 100000); /* to ensure that we do not exceed the size of the buffer */
    1182
    1183 if( longnames )
    1184 {
    1185 if( name != NULL )
    1186 (void) SCIPsnprintf(buffer, 64, "%c%05d%.*s%s", prefix, idx, suffix != NULL ? (int)(57-strlen(suffix)) : 57, name, suffix ? suffix : "");
    1187 else
    1188 (void) SCIPsnprintf(buffer, 64, "%c%05d", prefix, idx);
    1189 }
    1190 else
    1191 {
    1192 if( name != NULL )
    1193 {
    1194 assert(strlen(name) + (suffix != NULL ? strlen(suffix) : 0) <= 64);
    1195 (void) SCIPsnprintf(buffer, 64, "%s%s", name, suffix != NULL ? suffix : "");
    1196 }
    1197 else
    1198 {
    1199 assert(1 + 5 + (suffix != NULL ? strlen(suffix) : 0) <= 64);
    1200 (void) SCIPsnprintf(buffer, 64, "%c%d%s", prefix, idx, suffix != NULL ? suffix : "");
    1201 }
    1202 }
    1203}
    1204
    1205/** prints a function */
    1206static
    1208 SCIP* scip, /**< SCIP data structure */
    1209 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1210 FILE* file, /**< file to print to, has to be not NULL */
    1211 SCIP_NLPIORACLECONS* cons, /**< constraint which function to print */
    1212 SCIP_Bool longvarnames /**< whether variable names need to be shorten to 64 characters */
    1213 )
    1214{ /*lint --e{715}*/
    1215 int i;
    1216 char namebuf[70];
    1217
    1218 SCIPdebugMessage("%p print function\n", (void*)oracle);
    1219
    1220 assert(oracle != NULL);
    1221 assert(file != NULL);
    1222 assert(cons != NULL);
    1223
    1224 for( i = 0; i < cons->nlinidxs; ++i )
    1225 {
    1226 printName(namebuf, oracle->varnames != NULL ? oracle->varnames[cons->linidxs[i]] : NULL, cons->linidxs[i], 'x', NULL, longvarnames);
    1227 SCIPinfoMessage(scip, file, "%+.15g*%s", cons->lincoefs[i], namebuf);
    1228 if( i % 10 == 9 )
    1229 SCIPinfoMessage(scip, file, "\n");
    1230 }
    1231
    1232 if( cons->expr != NULL )
    1233 {
    1234 /* TODO SCIPprintExpr does not use the variable names in oracle->varnames, probably that should be changed */
    1235 SCIPinfoMessage(scip, file, " +");
    1236 SCIP_CALL( SCIPprintExpr(scip, cons->expr, file) );
    1237 }
    1238
    1239 return SCIP_OKAY;
    1240}
    1241
    1242/** returns whether an expression contains nonsmooth operands (min, max, abs, ...) */
    1243static
    1245 SCIP* scip, /**< SCIP data structure */
    1246 SCIP_EXPR* expr, /**< expression */
    1247 SCIP_Bool* nonsmooth /**< buffer to store whether expression seems nonsmooth */
    1248 )
    1249{
    1250 SCIP_EXPRITER* it;
    1251
    1252 assert(expr != NULL);
    1253 assert(nonsmooth != NULL);
    1254
    1255 *nonsmooth = FALSE;
    1256
    1259
    1260 for( ; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    1261 {
    1262 const char* hdlrname;
    1263 if( SCIPisExprSignpower(scip, expr) )
    1264 {
    1265 *nonsmooth = TRUE;
    1266 break;
    1267 }
    1268 hdlrname = SCIPexprhdlrGetName(SCIPexprGetHdlr(expr));
    1269 if( strcmp(hdlrname, "abs") == 0 )
    1270 {
    1271 *nonsmooth = TRUE;
    1272 break;
    1273 }
    1274 if( strcmp(hdlrname, "min") == 0 )
    1275 {
    1276 *nonsmooth = TRUE;
    1277 break;
    1278 }
    1279 if( strcmp(hdlrname, "max") == 0 )
    1280 {
    1281 *nonsmooth = TRUE;
    1282 break;
    1283 }
    1284 }
    1285
    1286 SCIPfreeExpriter(&it);
    1287
    1288 return SCIP_OKAY;
    1289}
    1290
    1291/**@} */
    1292
    1293/**@name public function */
    1294/**@{ */
    1295
    1296/** creates an NLPIORACLE data structure */
    1298 SCIP* scip, /**< SCIP data structure */
    1299 SCIP_NLPIORACLE** oracle /**< pointer to store NLPIORACLE data structure */
    1300 )
    1301{
    1302 SCIP_Bool nlpieval;
    1303
    1304 assert(oracle != NULL);
    1305
    1306 SCIPdebugMessage("%p oracle create\n", (void*)oracle);
    1307
    1308 SCIP_CALL( SCIPallocMemory(scip, oracle) );
    1309 BMSclearMemory(*oracle);
    1310
    1311 SCIPdebugMessage("Oracle initializes expression interpreter %s\n", SCIPexprintGetName());
    1312 SCIP_CALL( SCIPexprintCreate(scip, &(*oracle)->exprinterpreter) );
    1313
    1314 SCIP_CALL( SCIPcreateClock(scip, &(*oracle)->evalclock) );
    1315
    1316 SCIP_CALL( SCIPgetBoolParam(scip, "timing/nlpieval", &nlpieval) );
    1317 if( !nlpieval )
    1318 SCIPsetClockEnabled((*oracle)->evalclock, FALSE);
    1319
    1320 /* create zero objective function */
    1321 SCIP_CALL( createConstraint(scip, *oracle, &(*oracle)->objective, 0, NULL, NULL, NULL, 0.0, 0.0, NULL) );
    1322
    1323 return SCIP_OKAY;
    1324}
    1325
    1326/** frees an NLPIORACLE data structure */
    1328 SCIP* scip, /**< SCIP data structure */
    1329 SCIP_NLPIORACLE** oracle /**< pointer to NLPIORACLE data structure */
    1330 )
    1331{
    1332 assert(oracle != NULL);
    1333 assert(*oracle != NULL);
    1334
    1335 SCIPdebugMessage("%p oracle free\n", (void*)oracle);
    1336
    1339
    1340 SCIP_CALL( freeConstraint(scip, *oracle, &(*oracle)->objective, FALSE) );
    1341 SCIP_CALL( freeConstraints(scip, *oracle) );
    1342 freeVariables(scip, *oracle);
    1343
    1344 SCIP_CALL( SCIPfreeClock(scip, &(*oracle)->evalclock) );
    1345
    1346 SCIP_CALL( SCIPexprintFree(scip, &(*oracle)->exprinterpreter) );
    1347
    1348 if( (*oracle)->name != NULL )
    1349 {
    1351 }
    1352
    1353 BMSfreeMemory(oracle);
    1354
    1355 return SCIP_OKAY;
    1356}
    1357
    1358/** sets the problem name (used for printing) */
    1360 SCIP* scip, /**< SCIP data structure */
    1361 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1362 const char* name /**< name of problem */
    1363 )
    1364{
    1365 assert(oracle != NULL);
    1366
    1367 SCIPdebugMessage("%p set problem name\n", (void*)oracle);
    1368
    1369 if( oracle->name != NULL )
    1370 {
    1371 SCIPfreeBlockMemoryArray(scip, &oracle->name, strlen(oracle->name)+1);
    1372 }
    1373
    1374 if( name != NULL )
    1375 {
    1376 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &oracle->name, name, strlen(name)+1) );
    1377 }
    1378
    1379 return SCIP_OKAY;
    1380}
    1381
    1382/** gets the problem name, or NULL if none set */
    1384 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    1385 )
    1386{
    1387 assert(oracle != NULL);
    1388
    1389 SCIPdebugMessage("%p get problem name\n", (void*)oracle);
    1390
    1391 return oracle->name;
    1392}
    1393
    1394/** adds variables */
    1396 SCIP* scip, /**< SCIP data structure */
    1397 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1398 int nvars, /**< number of variables to add */
    1399 const SCIP_Real* lbs, /**< array with lower bounds of new variables, or NULL if all -infinity */
    1400 const SCIP_Real* ubs, /**< array with upper bounds of new variables, or NULL if all +infinity */
    1401 const char** varnames /**< array with names of new variables, or NULL if no names should be stored */
    1402 )
    1403{
    1404 int i;
    1405
    1406 assert(oracle != NULL);
    1407
    1408 SCIPdebugMessage("%p add vars\n", (void*)oracle);
    1409
    1410 if( nvars == 0 )
    1411 return SCIP_OKAY;
    1412
    1413 assert(nvars > 0);
    1414
    1415 SCIP_CALL( ensureVarsSize(scip, oracle, oracle->nvars + nvars) );
    1416
    1417 if( lbs != NULL )
    1418 {
    1419 BMScopyMemoryArray(&oracle->varlbs[oracle->nvars], lbs, nvars);
    1420 }
    1421 else
    1422 for( i = 0; i < nvars; ++i )
    1423 oracle->varlbs[oracle->nvars+i] = -SCIPinfinity(scip);
    1424
    1425 if( ubs != NULL )
    1426 {
    1427 BMScopyMemoryArray(&oracle->varubs[oracle->nvars], ubs, nvars);
    1428
    1429 /* ensure variable bounds are consistent */
    1430 for( i = oracle->nvars; i < oracle->nvars + nvars; ++i )
    1431 {
    1432 if( oracle->varlbs[i] > oracle->varubs[i] )
    1433 {
    1434 assert(EPSEQ(oracle->varlbs[i], oracle->varubs[i], SCIP_DEFAULT_EPSILON));
    1435 oracle->varlbs[i] = oracle->varubs[i];
    1436 }
    1437 }
    1438 }
    1439 else
    1440 for( i = 0; i < nvars; ++i )
    1441 oracle->varubs[oracle->nvars+i] = SCIPinfinity(scip);
    1442
    1443 if( varnames != NULL )
    1444 {
    1445 if( oracle->varnames == NULL )
    1446 {
    1448 }
    1449
    1450 for( i = 0; i < nvars; ++i )
    1451 {
    1452 if( varnames[i] != NULL )
    1453 {
    1454 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &oracle->varnames[oracle->nvars+i], varnames[i], strlen(varnames[i])+1) );
    1455 }
    1456 else
    1457 oracle->varnames[oracle->nvars+i] = NULL;
    1458 }
    1459 }
    1460 else if( oracle->varnames != NULL )
    1461 {
    1462 BMSclearMemoryArray(&oracle->varnames[oracle->nvars], nvars);
    1463 }
    1464
    1465 BMSclearMemoryArray(&oracle->varlincount[oracle->nvars], nvars);
    1466 BMSclearMemoryArray(&oracle->varnlcount[oracle->nvars], nvars);
    1467
    1468 /* @TODO update sparsity pattern by extending heslagoffsets */
    1470
    1471 oracle->nvars += nvars;
    1472
    1473 return SCIP_OKAY;
    1474}
    1475
    1476/** adds constraints
    1477 *
    1478 * linear coefficients: row(=constraint) oriented matrix;
    1479 * quadratic coefficients: row oriented matrix for each constraint
    1480 */
    1482 SCIP* scip, /**< SCIP data structure */
    1483 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1484 int nconss, /**< number of constraints to add */
    1485 const SCIP_Real* lhss, /**< array with left-hand sides of constraints, or NULL if all -infinity */
    1486 const SCIP_Real* rhss, /**< array with right-hand sides of constraints, or NULL if all +infinity */
    1487 const int* nlininds, /**< number of linear coefficients for each constraint, may be NULL in case of no linear part */
    1488 int* const* lininds, /**< indices of variables for linear coefficients for each constraint, may be NULL in case of no linear part */
    1489 SCIP_Real* const* linvals, /**< values of linear coefficient for each constraint, may be NULL in case of no linear part */
    1490 SCIP_EXPR** exprs, /**< NULL if no nonlinear parts, otherwise exprs[.] gives nonlinear part,
    1491 * or NULL if no nonlinear part in this constraint */
    1492 const char** consnames /**< names of new constraints, or NULL if no names should be stored */
    1493 )
    1494{ /*lint --e{715}*/
    1495 SCIP_NLPIORACLECONS* cons;
    1496 SCIP_Bool addednlcon; /* whether a nonlinear constraint was added */
    1497 int c;
    1498
    1499 assert(oracle != NULL);
    1500
    1501 SCIPdebugMessage("%p add constraints\n", (void*)oracle);
    1502
    1503 if( nconss == 0 )
    1504 return SCIP_OKAY;
    1505
    1506 assert(nconss > 0);
    1507
    1508 addednlcon = FALSE;
    1509
    1510 invalidateJacobiSparsity(scip, oracle); /* @TODO we could also update (extend) the sparsity pattern */
    1511
    1512 SCIP_CALL( ensureConssSize(scip, oracle, oracle->nconss + nconss) );
    1513 for( c = 0; c < nconss; ++c )
    1514 {
    1515 SCIP_CALL( createConstraint(scip, oracle, &cons,
    1516 nlininds != NULL ? nlininds[c] : 0,
    1517 lininds != NULL ? lininds[c] : NULL,
    1518 linvals != NULL ? linvals[c] : NULL,
    1519 exprs != NULL ? exprs[c] : NULL,
    1520 lhss != NULL ? lhss[c] : -SCIPinfinity(scip),
    1521 rhss != NULL ? rhss[c] : SCIPinfinity(scip),
    1522 consnames != NULL ? consnames[c] : NULL
    1523 ) );
    1524
    1525 if( cons->expr != NULL )
    1526 addednlcon = TRUE;
    1527
    1528 oracle->conss[oracle->nconss+c] = cons;
    1529 }
    1530 oracle->nconss += nconss;
    1531
    1532 if( addednlcon == TRUE )
    1534
    1535 return SCIP_OKAY;
    1536}
    1537
    1538/** sets or overwrites objective, a minimization problem is expected
    1539 *
    1540 * May change sparsity pattern.
    1541 */
    1543 SCIP* scip, /**< SCIP data structure */
    1544 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1545 const SCIP_Real constant, /**< constant part of objective */
    1546 int nlin, /**< number of linear variable coefficients */
    1547 const int* lininds, /**< indices of linear variables, or NULL if no linear part */
    1548 const SCIP_Real* linvals, /**< coefficients of linear variables, or NULL if no linear part */
    1549 SCIP_EXPR* expr /**< expression of nonlinear part, or NULL if no nonlinear part */
    1550 )
    1551{ /*lint --e{715}*/
    1552 assert(oracle != NULL);
    1553 assert(!SCIPisInfinity(scip, REALABS(constant)));
    1554
    1555 SCIPdebugMessage("%p set objective\n", (void*)oracle);
    1556
    1557 if( expr != NULL || oracle->objective->expr != NULL )
    1559
    1560 /* clear previous objective */
    1561 SCIP_CALL( freeConstraint(scip, oracle, &oracle->objective, TRUE) );
    1562
    1563 /* create new objective */
    1564 SCIP_CALL( createConstraint(scip, oracle, &oracle->objective,
    1565 nlin, lininds, linvals, expr, constant, constant, NULL) );
    1566
    1567 return SCIP_OKAY;
    1568}
    1569
    1570/** change variable bounds */
    1572 SCIP* scip, /**< SCIP data structure */
    1573 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1574 int nvars, /**< number of variables to change bounds */
    1575 const int* indices, /**< indices of variables to change bounds */
    1576 const SCIP_Real* lbs, /**< new lower bounds, or NULL if all should be -infty */
    1577 const SCIP_Real* ubs /**< new upper bounds, or NULL if all should be +infty */
    1578 )
    1579{
    1580 int i;
    1581
    1582 assert(oracle != NULL);
    1583 assert(indices != NULL || nvars == 0);
    1584
    1585 SCIPdebugMessage("%p chg var bounds\n", (void*)oracle);
    1586
    1587 for( i = 0; i < nvars; ++i )
    1588 {
    1589 assert(indices != NULL);
    1590 assert(indices[i] >= 0);
    1591 assert(indices[i] < oracle->nvars);
    1592
    1593 oracle->varlbs[indices[i]] = (lbs != NULL ? lbs[i] : -SCIPinfinity(scip));
    1594 oracle->varubs[indices[i]] = (ubs != NULL ? ubs[i] : SCIPinfinity(scip));
    1595
    1596 if( oracle->varlbs[indices[i]] > oracle->varubs[indices[i]] )
    1597 {
    1598 /* inconsistent bounds; let's assume it's due to rounding and make them equal */
    1599 assert(EPSEQ(oracle->varlbs[indices[i]], oracle->varubs[indices[i]], SCIP_DEFAULT_EPSILON));
    1600 oracle->varlbs[indices[i]] = oracle->varubs[indices[i]];
    1601 }
    1602 }
    1603
    1604 return SCIP_OKAY;
    1605}
    1606
    1607/** change constraint sides */
    1609 SCIP* scip, /**< SCIP data structure */
    1610 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1611 int nconss, /**< number of constraints to change bounds */
    1612 const int* indices, /**< indices of constraints to change bounds */
    1613 const SCIP_Real* lhss, /**< new left-hand sides, or NULL if all should be -infty */
    1614 const SCIP_Real* rhss /**< new right-hand sides, or NULL if all should be +infty */
    1615 )
    1616{
    1617 int i;
    1618
    1619 assert(oracle != NULL);
    1620 assert(indices != NULL || nconss == 0);
    1621
    1622 SCIPdebugMessage("%p chg cons sides\n", (void*)oracle);
    1623
    1624 for( i = 0; i < nconss; ++i )
    1625 {
    1626 assert(indices != NULL);
    1627 assert(indices[i] >= 0);
    1628 assert(indices[i] < oracle->nconss);
    1629
    1630 oracle->conss[indices[i]]->lhs = (lhss != NULL ? lhss[i] : -SCIPinfinity(scip));
    1631 oracle->conss[indices[i]]->rhs = (rhss != NULL ? rhss[i] : SCIPinfinity(scip));
    1632 if( oracle->conss[indices[i]]->lhs > oracle->conss[indices[i]]->rhs )
    1633 {
    1634 assert(EPSEQ(oracle->conss[indices[i]]->lhs, oracle->conss[indices[i]]->rhs, SCIP_DEFAULT_EPSILON));
    1635 oracle->conss[indices[i]]->lhs = oracle->conss[indices[i]]->rhs;
    1636 }
    1637 }
    1638
    1639 return SCIP_OKAY;
    1640}
    1641
    1642/** deletes a set of variables */
    1644 SCIP* scip, /**< SCIP data structure */
    1645 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1646 int* delstats /**< deletion status of vars in input (1 if var should be deleted, 0 if not);
    1647 * new position of var in output (-1 if var was deleted) */
    1648 )
    1649{ /*lint --e{715}*/
    1650 int c;
    1651 int lastgood; /* index of the last variable that should be kept */
    1652 SCIP_NLPIORACLECONS* cons;
    1653 SCIP_EXPRITER* it;
    1654
    1655 assert(oracle != NULL);
    1656
    1657 SCIPdebugMessage("%p del var set\n", (void*)oracle);
    1658
    1661
    1662 lastgood = oracle->nvars - 1;
    1663 while( lastgood >= 0 && delstats[lastgood] == 1 )
    1664 --lastgood;
    1665 if( lastgood < 0 )
    1666 {
    1667 /* all variables should be deleted */
    1668 assert(oracle->nconss == 0); /* we could relax this by checking that all constraints are constant */
    1669 oracle->objective->nlinidxs = 0;
    1670 for( c = 0; c < oracle->nvars; ++c )
    1671 delstats[c] = -1;
    1672 freeVariables(scip, oracle);
    1673 return SCIP_OKAY;
    1674 }
    1675
    1676 /* delete variables at the end */
    1677 for( c = oracle->nvars - 1; c > lastgood; --c )
    1678 {
    1679 if( oracle->varnames && oracle->varnames[c] != NULL )
    1680 {
    1681 SCIPfreeBlockMemoryArray(scip, &oracle->varnames[c], strlen(oracle->varnames[c])+1);
    1682 }
    1683 delstats[c] = -1;
    1684 }
    1685
    1686 /* go through variables from the beginning on
    1687 * if variable should be deleted, free it and move lastgood variable to this position
    1688 * then update lastgood */
    1689 for( c = 0; c <= lastgood; ++c )
    1690 {
    1691 if( delstats[c] == 0 )
    1692 { /* variable should not be deleted and is kept on position c */
    1693 delstats[c] = c;
    1694 continue;
    1695 }
    1696 assert(delstats[c] == 1); /* variable should be deleted */
    1697
    1698 if( oracle->varnames != NULL && oracle->varnames[c] != NULL )
    1699 {
    1700 SCIPfreeBlockMemoryArray(scip, &oracle->varnames[c], strlen(oracle->varnames[c])+1);
    1701 }
    1702 delstats[c] = -1;
    1703
    1704 /* move variable at position lastgood to position c */
    1705 SCIP_CALL( moveVariable(scip, oracle, lastgood, c) );
    1706 delstats[lastgood] = c; /* mark that lastgood variable is now at position c */
    1707
    1708 /* move lastgood forward, delete variables on the way */
    1709 --lastgood;
    1710 while( lastgood > c && delstats[lastgood] == 1)
    1711 {
    1712 if( oracle->varnames && oracle->varnames[lastgood] != NULL )
    1713 {
    1714 SCIPfreeBlockMemoryArray(scip, &oracle->varnames[lastgood], strlen(oracle->varnames[lastgood])+1);
    1715 }
    1716 delstats[lastgood] = -1;
    1717 --lastgood;
    1718 }
    1719 }
    1720 assert(c == lastgood);
    1721
    1723
    1724 for( c = -1; c < oracle->nconss; ++c )
    1725 {
    1726 cons = c < 0 ? oracle->objective : oracle->conss[c];
    1727 assert(cons != NULL);
    1728
    1729 /* update indices in linear part, sort indices, and then clear elements that are marked as deleted */
    1730 mapIndices(delstats, cons->nlinidxs, cons->linidxs);
    1731 SCIPsortIntReal(cons->linidxs, cons->lincoefs, cons->nlinidxs);
    1732 clearDeletedLinearElements(&cons->linidxs, &cons->lincoefs, &cons->nlinidxs);
    1733
    1734 if( cons->expr != NULL )
    1735 {
    1736 /* update variable indices in varidx expressions */
    1737 SCIP_EXPR* expr;
    1738 SCIP_Bool keptvar = FALSE; /* whether any of the variables in expr was not deleted */
    1739#ifndef NDEBUG
    1740 SCIP_Bool delvar = FALSE; /* whether any of the variables in expr was deleted */
    1741#endif
    1742
    1744 for( expr = cons->expr; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    1745 {
    1746 if( !SCIPisExprVaridx(scip, expr) )
    1747 continue;
    1748
    1749 if( delstats[SCIPgetIndexExprVaridx(expr)] >= 0 )
    1750 {
    1751 /* if variable is not deleted, then set its new index */
    1752 keptvar = TRUE;
    1753 SCIPsetIndexExprVaridx(expr, delstats[SCIPgetIndexExprVaridx(expr)]);
    1754
    1755 /* if variable is kept, then there must not have been any variable that was deleted */
    1756 assert(!delvar);
    1757 }
    1758 else
    1759 {
    1760#ifndef NDEBUG
    1761 delvar = TRUE;
    1762#endif
    1763 /* if variable is deleted, then there must not have been any variable that was kept
    1764 * (either all variables are deleted, which removes the expr, or none)
    1765 */
    1766 assert(!keptvar);
    1767 }
    1768 }
    1769 if( !keptvar )
    1770 {
    1772 SCIP_CALL( SCIPreleaseExpr(scip, &cons->expr) );
    1773 }
    1774 }
    1775 }
    1776
    1777 SCIPfreeExpriter(&it);
    1778
    1779 oracle->nvars = lastgood+1;
    1780
    1781 return SCIP_OKAY;
    1782}
    1783
    1784/** deletes a set of constraints */
    1786 SCIP* scip, /**< SCIP data structure */
    1787 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1788 int* delstats /**< array with deletion status of rows in input (1 if row should be deleted, 0 if not);
    1789 * new position of row in output (-1 if row was deleted) */
    1790 )
    1791{ /*lint --e{715}*/
    1792 int c;
    1793 int lastgood; /* index of the last constraint that should be kept */
    1794
    1795 assert(oracle != NULL);
    1796
    1797 SCIPdebugMessage("%p del cons set\n", (void*)oracle);
    1798
    1801
    1802 lastgood = oracle->nconss - 1;
    1803 while( lastgood >= 0 && delstats[lastgood] == 1)
    1804 --lastgood;
    1805 if( lastgood < 0 )
    1806 {
    1807 /* all constraints should be deleted */
    1808 for( c = 0; c < oracle->nconss; ++c )
    1809 delstats[c] = -1;
    1810 SCIP_CALL( freeConstraints(scip, oracle) );
    1811
    1812 /* the previous call did not keep variable counts uptodate
    1813 * since we only have an objective function left, we reset the counts to the ones of the objective
    1814 */
    1815 BMSclearMemoryArray(oracle->varlincount, oracle->nvars);
    1816 BMSclearMemoryArray(oracle->varnlcount, oracle->nvars);
    1817 SCIP_CALL( updateVariableCounts(scip, oracle, 1, oracle->objective->nlinidxs, oracle->objective->linidxs, oracle->objective->expr) );
    1818
    1819 return SCIP_OKAY;
    1820 }
    1821
    1822 /* delete constraints at the end */
    1823 for( c = oracle->nconss - 1; c > lastgood; --c )
    1824 {
    1825 SCIP_CALL( freeConstraint(scip, oracle, &oracle->conss[c], TRUE) );
    1826 assert(oracle->conss[c] == NULL);
    1827 delstats[c] = -1;
    1828 }
    1829
    1830 /* go through constraint from the beginning on
    1831 * if constraint should be deleted, free it and move lastgood constraint to this position
    1832 * then update lastgood */
    1833 for( c = 0; c <= lastgood; ++c )
    1834 {
    1835 if( delstats[c] == 0 )
    1836 {
    1837 /* constraint should not be deleted and is kept on position c */
    1838 delstats[c] = c;
    1839 continue;
    1840 }
    1841 assert(delstats[c] == 1); /* constraint should be deleted */
    1842
    1843 SCIP_CALL( freeConstraint(scip, oracle, &oracle->conss[c], TRUE) );
    1844 assert(oracle->conss[c] == NULL);
    1845 delstats[c] = -1;
    1846
    1847 /* move constraint at position lastgood to position c */
    1848 oracle->conss[c] = oracle->conss[lastgood];
    1849 assert(oracle->conss[c] != NULL);
    1850 delstats[lastgood] = c; /* mark that lastgood constraint is now at position c */
    1851 oracle->conss[lastgood] = NULL;
    1852 --lastgood;
    1853
    1854 /* move lastgood forward, delete constraints on the way */
    1855 while( lastgood > c && delstats[lastgood] == 1)
    1856 {
    1857 SCIP_CALL( freeConstraint(scip, oracle, &oracle->conss[lastgood], TRUE) );
    1858 assert(oracle->conss[lastgood] == NULL);
    1859 delstats[lastgood] = -1;
    1860 --lastgood;
    1861 }
    1862 }
    1863 assert(c == lastgood+1);
    1864
    1865 oracle->nconss = lastgood+1;
    1866
    1867 return SCIP_OKAY;
    1868}
    1869
    1870/** changes (or adds) linear coefficients in one constraint or objective */
    1872 SCIP* scip, /**< SCIP data structure */
    1873 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1874 int considx, /**< index of constraint where linear coefficients should be changed, or -1 for objective */
    1875 int nentries, /**< number of coefficients to change */
    1876 const int* varidxs, /**< array with indices of variables which coefficients should be changed */
    1877 const SCIP_Real* newcoefs /**< array with new coefficients of variables */
    1878 )
    1879{ /*lint --e{715}*/
    1880 SCIP_NLPIORACLECONS* cons;
    1881 SCIP_Bool needsort;
    1882 int i;
    1883
    1884 SCIPdebugMessage("%p chg linear coefs\n", (void*)oracle);
    1885
    1886 assert(oracle != NULL);
    1887 assert(varidxs != NULL || nentries == 0);
    1888 assert(newcoefs != NULL || nentries == 0);
    1889 assert(considx >= -1);
    1890 assert(considx < oracle->nconss);
    1891
    1892 if( nentries == 0 )
    1893 return SCIP_OKAY;
    1894
    1895 SCIPdebugMessage("change %d linear coefficients in cons %d\n", nentries, considx);
    1896
    1897 needsort = FALSE;
    1898
    1899 cons = considx < 0 ? oracle->objective : oracle->conss[considx];
    1900
    1901 if( cons->linsize == 0 )
    1902 {
    1903 /* first time we have linear coefficients in this constraint (or objective) */
    1904 assert(cons->linidxs == NULL);
    1905 assert(cons->lincoefs == NULL);
    1906
    1907 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &cons->linidxs, varidxs, nentries) );
    1908 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &cons->lincoefs, newcoefs, nentries) );
    1909 cons->linsize = nentries;
    1910 cons->nlinidxs = nentries;
    1911
    1912 SCIP_CALL( updateVariableCounts(scip, oracle, 1, nentries, varidxs, NULL) );
    1913
    1914 needsort = TRUE;
    1915 }
    1916 else
    1917 {
    1918 int pos;
    1919
    1920 for( i = 0; i < nentries; ++i )
    1921 {
    1922 assert(varidxs[i] >= 0); /*lint !e613*/
    1923 assert(varidxs[i] < oracle->nvars); /*lint !e613*/
    1924
    1925 if( SCIPsortedvecFindInt(cons->linidxs, varidxs[i], cons->nlinidxs, &pos) ) /*lint !e613*/
    1926 {
    1927 SCIPdebugMessage("replace coefficient of var %d at pos %d by %g\n", varidxs[i], pos, newcoefs[i]); /*lint !e613*/
    1928
    1929 cons->lincoefs[pos] = newcoefs[i]; /*lint !e613*/
    1930
    1931 /* remember that we need to sort/merge/squeeze array if coefficient became zero here */
    1932 needsort |= (newcoefs[i] == 0.0); /*lint !e613 !e514*/
    1933
    1934 if( newcoefs[i] == 0.0 )
    1935 {
    1936 --oracle->varlincount[varidxs[i]];
    1937 assert(oracle->varlincount[varidxs[i]] >= 0);
    1938 }
    1939 }
    1940 else if( newcoefs[i] != 0.0 ) /*lint !e613*/
    1941 {
    1942 /* append new entry */
    1943 SCIPdebugMessage("add coefficient of var %d at pos %d, value %g\n", varidxs[i], cons->nlinidxs, newcoefs[i]); /*lint !e613*/
    1944
    1945 SCIP_CALL( ensureConsLinSize(scip, cons, cons->nlinidxs + (nentries-i)) );
    1946 cons->linidxs[cons->nlinidxs] = varidxs[i]; /*lint !e613*/
    1947 cons->lincoefs[cons->nlinidxs] = newcoefs[i]; /*lint !e613*/
    1948 ++cons->nlinidxs;
    1949
    1950 ++oracle->varlincount[varidxs[i]];
    1951
    1952 needsort = TRUE;
    1953 }
    1954 }
    1955 }
    1956
    1957 if( needsort )
    1958 {
    1960 sortLinearCoefficients(&cons->nlinidxs, cons->linidxs, cons->lincoefs);
    1961 }
    1962
    1963 return SCIP_OKAY;
    1964}
    1965
    1966/** replaces expression of one constraint or objective */
    1968 SCIP* scip, /**< SCIP data structure */
    1969 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    1970 int considx, /**< index of constraint where expression should be changed, or -1 for objective */
    1971 SCIP_EXPR* expr /**< new expression, or NULL */
    1972 )
    1973{
    1974 SCIP_NLPIORACLECONS* cons;
    1975
    1976 SCIPdebugMessage("%p chg expr\n", (void*)oracle);
    1977
    1978 assert(oracle != NULL);
    1979 assert(considx >= -1);
    1980 assert(considx < oracle->nconss);
    1981
    1984
    1985 cons = considx < 0 ? oracle->objective : oracle->conss[considx];
    1986
    1987 /* free previous expression */
    1988 if( cons->expr != NULL )
    1989 {
    1990 SCIP_CALL( updateVariableCounts(scip, oracle, -1, 0, NULL, cons->expr) );
    1992 SCIP_CALL( SCIPreleaseExpr(scip, &cons->expr) );
    1993 }
    1994
    1995 /* if user did not want to set new expr, then we are done */
    1996 if( expr == NULL )
    1997 return SCIP_OKAY;
    1998
    1999 assert(oracle->exprinterpreter != NULL);
    2000
    2001 /* install new expression */
    2002 cons->expr = expr;
    2003 SCIPcaptureExpr(cons->expr);
    2005
    2006 /* keep variable counts up to date */
    2007 SCIP_CALL( updateVariableCounts(scip, oracle, 1, 0, NULL, cons->expr) );
    2008
    2009 return SCIP_OKAY;
    2010}
    2011
    2012/** changes the constant value in the objective function */ /*lint -e{715}*/
    2014 SCIP* scip, /**< SCIP data structure */
    2015 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2016 SCIP_Real objconstant /**< new value for objective constant */
    2017 )
    2018{ /*lint --e{715}*/
    2019 assert(oracle != NULL);
    2020
    2021 SCIPdebugMessage("%p chg obj constant\n", (void*)oracle);
    2022
    2023 oracle->objective->lhs = objconstant;
    2024 oracle->objective->rhs = objconstant;
    2025
    2026 return SCIP_OKAY;
    2027}
    2028
    2029/** gives the current number of variables */
    2031 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    2032 )
    2033{
    2034 assert(oracle != NULL);
    2035
    2036 return oracle->nvars;
    2037}
    2038
    2039/** gives the current number of constraints */
    2041 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    2042 )
    2043{
    2044 assert(oracle != NULL);
    2045
    2046 return oracle->nconss;
    2047}
    2048
    2049/** gives the variables lower bounds */
    2051 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    2052 )
    2053{
    2054 assert(oracle != NULL);
    2055
    2056 return oracle->varlbs;
    2057}
    2058
    2059/** gives the variables upper bounds */
    2061 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    2062 )
    2063{
    2064 assert(oracle != NULL);
    2065
    2066 return oracle->varubs;
    2067}
    2068
    2069/** gives the variables names, or NULL if not set */
    2071 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    2072 )
    2073{
    2074 assert(oracle != NULL);
    2075
    2076 return oracle->varnames;
    2077}
    2078
    2079/** indicates whether variable appears nonlinear in any objective or constraint */ /*lint --e{715}*/
    2081 SCIP* scip, /**< SCIP data structure */
    2082 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2083 int varidx /**< the variable to check */
    2084 )
    2085{
    2086 assert(oracle != NULL);
    2087 assert(varidx >= 0);
    2088 assert(varidx < oracle->nvars);
    2089 assert(oracle->varnlcount != NULL);
    2090
    2091 return oracle->varnlcount[varidx] > 0;
    2092}
    2093
    2094/** returns number of linear and nonlinear appearances of variables in objective and constraints */ /*lint --e{715}*/
    2096 SCIP* scip, /**< SCIP data structure */
    2097 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2098 const int** lincounts, /**< buffer to return pointer to array of counts of linear appearances */
    2099 const int** nlcounts /**< buffer to return pointer to array of counts of nonlinear appearances */
    2100 )
    2101{
    2102 assert(oracle != NULL);
    2103 assert(lincounts != NULL);
    2104 assert(nlcounts != NULL);
    2105
    2106 *lincounts = oracle->varlincount;
    2107 *nlcounts = oracle->varnlcount;
    2108}
    2109
    2110/** gives constant term of objective */
    2112 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    2113 )
    2114{
    2115 assert(oracle != NULL);
    2116 assert(oracle->objective->lhs == oracle->objective->rhs); /*lint !e777*/
    2117
    2118 return oracle->objective->lhs;
    2119}
    2120
    2121/** gives left-hand side of a constraint */
    2123 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2124 int considx /**< constraint index */
    2125 )
    2126{
    2127 assert(oracle != NULL);
    2128 assert(considx >= 0);
    2129 assert(considx < oracle->nconss);
    2130
    2131 return oracle->conss[considx]->lhs;
    2132}
    2133
    2134/** gives right-hand side of a constraint */
    2136 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2137 int considx /**< constraint index */
    2138 )
    2139{
    2140 assert(oracle != NULL);
    2141 assert(considx >= 0);
    2142 assert(considx < oracle->nconss);
    2143
    2144 return oracle->conss[considx]->rhs;
    2145}
    2146
    2147/** gives name of a constraint, may be NULL */
    2149 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2150 int considx /**< constraint index */
    2151 )
    2152{
    2153 assert(oracle != NULL);
    2154 assert(considx >= 0);
    2155 assert(considx < oracle->nconss);
    2156
    2157 return oracle->conss[considx]->name;
    2158}
    2159
    2160/** gives linear coefficient of a given variable in a constraint */
    2162 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2163 int considx, /**< constraint index, or -1 for objective */
    2164 int varpos /**< position in the constraint's linear coefficient array */
    2165 )
    2166{
    2167 SCIP_NLPIORACLECONS* cons;
    2168
    2169 assert(oracle != NULL);
    2170 assert(considx >= -1);
    2171 assert(considx < oracle->nconss);
    2172 assert(varpos >= 0);
    2173
    2174 cons = considx == -1 ? oracle->objective : oracle->conss[considx];
    2175 assert(varpos < cons->nlinidxs);
    2176
    2177 return cons->lincoefs[varpos];
    2178}
    2179
    2180/** indicates whether constraint is nonlinear */
    2182 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2183 int considx /**< index of constraint for which nonlinearity status is returned, or -1 for objective */
    2184 )
    2185{
    2186 SCIP_NLPIORACLECONS* cons;
    2187
    2188 assert(oracle != NULL);
    2189 assert(considx >= -1);
    2190 assert(considx < oracle->nconss);
    2191
    2192 cons = considx < 0 ? oracle->objective : oracle->conss[considx];
    2193
    2194 return cons->expr != NULL;
    2195}
    2196
    2197/** gives the evaluation capabilities that are shared among all expressions in the problem */
    2199 SCIP* scip, /**< SCIP data structure */
    2200 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    2201 )
    2202{
    2203 int c;
    2204 SCIP_EXPRINTCAPABILITY evalcapability;
    2205
    2206 assert(oracle != NULL);
    2207
    2208 if( oracle->objective->expr != NULL )
    2209 evalcapability = SCIPexprintGetExprCapability(scip, oracle->exprinterpreter, oracle->objective->expr, oracle->objective->exprintdata);
    2210 else
    2211 evalcapability = SCIP_EXPRINTCAPABILITY_ALL;
    2212
    2213 for( c = 0; c < oracle->nconss; ++c )
    2214 if( oracle->conss[c]->expr != NULL )
    2215 evalcapability &= SCIPexprintGetExprCapability(scip, oracle->exprinterpreter, oracle->conss[c]->expr, oracle->conss[c]->exprintdata);
    2216
    2217 return evalcapability;
    2218}
    2219
    2220/** evaluates the objective function in a given point */
    2222 SCIP* scip, /**< SCIP data structure */
    2223 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2224 const SCIP_Real* x, /**< point where to evaluate */
    2225 SCIP_Real* objval /**< pointer to store objective value */
    2226 )
    2227{
    2228 SCIP_RETCODE retcode;
    2229
    2230 assert(oracle != NULL);
    2231
    2232 SCIPdebugMessage("%p eval obj value\n", (void*)oracle);
    2233
    2235 retcode = evalFunctionValue(scip, oracle, oracle->objective, x, objval);
    2237
    2238 assert(oracle->objective->lhs == oracle->objective->rhs); /*lint !e777*/
    2239 if( retcode == SCIP_OKAY )
    2240 *objval += oracle->objective->lhs;
    2241
    2242 return retcode;
    2243}
    2244
    2245/** evaluates one constraint function in a given point */
    2247 SCIP* scip, /**< SCIP data structure */
    2248 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2249 int considx, /**< index of constraint to evaluate */
    2250 const SCIP_Real* x, /**< point where to evaluate */
    2251 SCIP_Real* conval /**< pointer to store constraint value */
    2252 )
    2253{
    2254 SCIP_RETCODE retcode;
    2255
    2256 assert(oracle != NULL);
    2257 assert(x != NULL || oracle->nvars == 0);
    2258 assert(conval != NULL);
    2259
    2260 SCIPdebugMessage("%p eval cons value\n", (void*)oracle);
    2261
    2263 retcode = evalFunctionValue(scip, oracle, oracle->conss[considx], x, conval);
    2265
    2266 return retcode;
    2267}
    2268
    2269/** evaluates all constraint functions in a given point */
    2271 SCIP* scip, /**< SCIP data structure */
    2272 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2273 const SCIP_Real* x, /**< point where to evaluate */
    2274 SCIP_Real* convals /**< buffer to store constraint values */
    2275 )
    2276{
    2277 SCIP_RETCODE retcode = SCIP_OKAY;
    2278 int i;
    2279
    2280 SCIPdebugMessage("%p eval cons values\n", (void*)oracle);
    2281
    2282 assert(oracle != NULL);
    2283 assert(x != NULL || oracle->nvars == 0);
    2284 assert(convals != NULL);
    2285
    2287 for( i = 0; i < oracle->nconss; ++i )
    2288 {
    2289 retcode = evalFunctionValue(scip, oracle, oracle->conss[i], x, &convals[i]);
    2290 if( retcode != SCIP_OKAY )
    2291 break;
    2292 }
    2294
    2295 return retcode;
    2296}
    2297
    2298/** interval evaluate objective function for given variable bounds */
    2300 SCIP* scip, /**< SCIP data structure */
    2301 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2302 SCIP_Real infinity, /**< value for infinity */
    2303 const SCIP_Real* xmin, /**< lower bound on variable interval */
    2304 const SCIP_Real* xmax, /**< upper bound on variable interval */
    2305 SCIP_Real* objmin, /**< buffer to store lower bound of objective */
    2306 SCIP_Real* objmax /**< buffer to store upper bound of objective */
    2307 )
    2308{
    2309 SCIP_RETCODE retcode;
    2310
    2311 assert(oracle != NULL);
    2312 assert(xmin != NULL || oracle->nvars == 0);
    2313 assert(xmax != NULL || oracle->nvars == 0);
    2314 assert(objmin != NULL);
    2315 assert(objmax != NULL);
    2316
    2317 SCIPdebugMessage("%p eval obj interval\n", (void*)oracle);
    2318
    2320 retcode = evalFunctionInterval(scip, oracle, oracle->objective, infinity, xmin, xmax, objmin, objmax);
    2322
    2323 assert(oracle->objective->lhs == oracle->objective->rhs); /*lint !e777*/
    2324 if( retcode == SCIP_OKAY )
    2325 {
    2326 if( *objmin != -infinity ) /*lint !e777 */
    2327 *objmin += oracle->objective->lhs;
    2328 if( *objmax != infinity ) /*lint !e777 */
    2329 *objmax += oracle->objective->lhs;
    2330 }
    2331
    2332 return retcode;
    2333}
    2334
    2335/** interval evaluate one constraint function for given variable bounds */
    2337 SCIP* scip, /**< SCIP data structure */
    2338 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2339 SCIP_Real infinity, /**< value for infinity */
    2340 int considx, /**< index of constraint to evaluate */
    2341 const SCIP_Real* xmin, /**< lower bound on variable interval */
    2342 const SCIP_Real* xmax, /**< upper bound on variable interval */
    2343 SCIP_Real* conmin, /**< buffer to store lower bound of constraint */
    2344 SCIP_Real* conmax /**< buffer to store upper bound of constraint */
    2345 )
    2346{
    2347 SCIP_RETCODE retcode;
    2348
    2349 assert(oracle != NULL);
    2350 assert(xmin != NULL || oracle->nvars == 0);
    2351 assert(xmax != NULL || oracle->nvars == 0);
    2352 assert(conmin != NULL);
    2353 assert(conmax != NULL);
    2354
    2355 SCIPdebugMessage("%p eval cons interval\n", (void*)oracle);
    2356
    2358 retcode = evalFunctionInterval(scip, oracle, oracle->conss[considx], infinity, xmin, xmax, conmin, conmax);
    2360
    2361 return retcode;
    2362}
    2363
    2364/** computes the objective gradient in a given point
    2365 *
    2366 * @return SCIP_INVALIDDATA, if the function or its gradient could not be evaluated (domain error, etc.)
    2367 */
    2369 SCIP* scip, /**< SCIP data structure */
    2370 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2371 const SCIP_Real* x, /**< point where to evaluate */
    2372 SCIP_Bool isnewx, /**< has the point x changed since the last call to some evaluation function? */
    2373 SCIP_Real* objval, /**< pointer to store objective value */
    2374 SCIP_Real* objgrad /**< pointer to store (dense) objective gradient */
    2375 )
    2376{
    2377 SCIP_RETCODE retcode;
    2378 assert(oracle != NULL);
    2379
    2380 SCIPdebugMessage("%p eval obj grad\n", (void*)oracle);
    2381
    2383 retcode = evalFunctionGradient(scip, oracle, oracle->objective, x, isnewx, objval, objgrad);
    2385
    2386 assert(oracle->objective->lhs == oracle->objective->rhs); /*lint !e777*/
    2387 if( retcode == SCIP_OKAY )
    2388 *objval += oracle->objective->lhs;
    2389
    2390 return retcode;
    2391}
    2392
    2393/** computes a constraints gradient in a given point
    2394 *
    2395 * @return SCIP_INVALIDDATA, if the function or its gradient could not be evaluated (domain error, etc.)
    2396 */
    2398 SCIP* scip, /**< SCIP data structure */
    2399 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2400 const int considx, /**< index of constraint to compute gradient for */
    2401 const SCIP_Real* x, /**< point where to evaluate */
    2402 SCIP_Bool isnewx, /**< has the point x changed since the last call to some evaluation function? */
    2403 SCIP_Real* conval, /**< pointer to store constraint value */
    2404 SCIP_Real* congrad /**< pointer to store (dense) constraint gradient */
    2405 )
    2406{
    2407 SCIP_RETCODE retcode;
    2408
    2409 assert(oracle != NULL);
    2410 assert(x != NULL || oracle->nvars == 0);
    2411 assert(conval != NULL);
    2412
    2413 SCIPdebugMessage("%p eval cons grad\n", (void*)oracle);
    2414
    2416 retcode = evalFunctionGradient(scip, oracle, oracle->conss[considx], x, isnewx, conval, congrad);
    2418
    2419 return retcode;
    2420}
    2421
    2422/** gets sparsity pattern (rowwise) of Jacobian matrix
    2423 *
    2424 * Note that internal data is returned in *rowoffsets and *cols, thus the user does not need to allocate memory there.
    2425 * Adding or deleting constraints destroys the sparsity structure and make another call to this function necessary.
    2426 */
    2428 SCIP* scip, /**< SCIP data structure */
    2429 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2430 const int** rowoffsets, /**< pointer to store pointer that stores the offsets to each rows sparsity pattern in col, can be NULL */
    2431 const int** cols, /**< pointer to store pointer that stores the indices of variables that appear in each row,
    2432 * rowoffsets[nconss] gives length of col, can be NULL */
    2433 const SCIP_Bool** colnlflags, /**< flags indicating whether an entry in nonlinear (sorted row-wise), can be NULL */
    2434 int* nnlnz /**< number of nonlinear nonzeroes */
    2435 )
    2436{
    2437 int nnz;
    2438
    2439 assert(oracle != NULL);
    2440
    2441 SCIPdebugMessage("%p get jacobian sparsity\n", (void*)oracle);
    2442
    2443 if( oracle->jacrowoffsets != NULL || oracle->nvars == 0 || oracle->nconss == 0 )
    2444 {
    2445 /* sparsity already computed or no variables or no constraints */
    2446 assert(oracle->jaccols != NULL || oracle->nvars == 0 || oracle->nconss == 0);
    2447 if( rowoffsets != NULL )
    2448 *rowoffsets = oracle->jacrowoffsets;
    2449 if( cols != NULL )
    2450 *cols = oracle->jaccols;
    2451 if( colnlflags != NULL )
    2452 *colnlflags = oracle->jaccolnlflags;
    2453 if( nnlnz != NULL )
    2454 *nnlnz = oracle->njacnlnz;
    2455 return SCIP_OKAY;
    2456 }
    2457
    2459
    2460 SCIP_CALL( computeRowJacobianSparsity(scip, oracle, &nnz, NULL) );
    2461
    2462 if( rowoffsets != NULL )
    2463 *rowoffsets = oracle->jacrowoffsets;
    2464 if( cols != NULL )
    2465 *cols = oracle->jaccols;
    2466 if( colnlflags != NULL )
    2467 *colnlflags = oracle->jaccolnlflags;
    2468 if( nnlnz != NULL )
    2469 *nnlnz = oracle->njacnlnz;
    2470
    2472
    2473 return SCIP_OKAY;
    2474}
    2475
    2476/** gets sparsity pattern (columnwise) of Jacobian matrix
    2477 *
    2478 * Note that internal data is returned in *coloffsets, *rows, and *rownlflags, thus the user does not need to allocate memory there.
    2479 * Adding or deleting constraints destroys the sparsity structure and make another call to this function necessary.
    2480 */
    2482 SCIP* scip, /**< SCIP data structure */
    2483 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2484 const int** coloffsets, /**< pointer to store pointer that stores the offsets to each column's sparsity pattern in row, can be NULL */
    2485 const int** rows, /**< pointer to store pointer that stores the indices of rows that each variable participates in,
    2486 * coloffset[nvars] gives length of row, can be NULL */
    2487 const SCIP_Bool** rownlflags, /**< flags indicating whether an entry in nonlinear (sorted column-wise), can be NULL */
    2488 int* nnlnz /**< number of nonlinear nonzeroes */
    2489 )
    2490{
    2491 int* nvarnnz; /* for each variable, number of constraints it has a nonzero in */
    2492 int nnz;
    2493 int i;
    2494 int sumvarnnz; /* sum of nonzeroes for all columns, used in jaccoloffset computation */
    2495
    2496 assert(oracle != NULL);
    2497
    2498 SCIPdebugMessage("%p get jacobian sparsity\n", (void*)oracle);
    2499
    2500 if( oracle->jacrowoffsets != NULL || oracle->nvars == 0 || oracle->nconss == 0 )
    2501 {
    2502 assert(oracle->jacrows != NULL || oracle->nvars == 0 || oracle->nconss == 0);
    2503 if( coloffsets != NULL )
    2504 *coloffsets = oracle->jaccoloffsets;
    2505 if( rows != NULL )
    2506 *rows = oracle->jacrows;
    2507 if( rownlflags != NULL )
    2508 *rownlflags = oracle->jacrownlflags;
    2509 if( nnlnz != NULL )
    2510 *nnlnz = oracle->njacnlnz;
    2511
    2512 return SCIP_OKAY;
    2513 }
    2514
    2516
    2517 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &nvarnnz, oracle->nvars) );
    2518
    2519 /* row sparsity is more natural to compute with the structures we have - therefore, compute it first */
    2520 SCIP_CALL( computeRowJacobianSparsity(scip, oracle, &nnz, nvarnnz) );
    2521
    2522 /* compute the column representation */
    2526
    2527 /* use nvarnnz to compute jaccoloffsets */
    2528 sumvarnnz = 0;
    2529 for( i = 0; i < oracle->nvars; ++i )
    2530 {
    2531 oracle->jaccoloffsets[i] = sumvarnnz;
    2532 sumvarnnz += nvarnnz[i];
    2533 nvarnnz[i] = 0;
    2534 }
    2535 oracle->jaccoloffsets[oracle->nvars] = sumvarnnz;
    2536
    2537 /* use the row representation (jacrowoffsets, jaccols, jaccolnlflags) to fill in the
    2538 column representation nonzeroes (jacrows, jacrownlflags) */
    2539 int considx = 0;
    2540 for( i = 0; i < nnz; ++i )
    2541 {
    2542 int col = oracle->jaccols[i];
    2543 int coloffset = oracle->jaccoloffsets[col]; /* this gives us the offset corresponding to the index of the nnz variable */
    2544
    2545 if( i == oracle->jacrowoffsets[considx] )
    2546 ++considx;
    2547
    2548 oracle->jacrows[coloffset + nvarnnz[col]] = considx-1;
    2549 oracle->jacrownlflags[coloffset + nvarnnz[col]] = oracle->jaccolnlflags[i];
    2550 nvarnnz[col]++;
    2551 }
    2552
    2553 SCIPfreeBlockMemoryArray(scip, &nvarnnz, oracle->nvars);
    2554
    2555 if( coloffsets != NULL )
    2556 *coloffsets = oracle->jaccoloffsets;
    2557 if( rows != NULL )
    2558 *rows = oracle->jacrows;
    2559 if( rownlflags != NULL )
    2560 *rownlflags = oracle->jacrownlflags;
    2561 if( nnlnz != NULL )
    2562 *nnlnz = oracle->njacnlnz;
    2563
    2565
    2566 return SCIP_OKAY;
    2567}
    2568
    2569/** gets nonzero indices in the objective gradient
    2570 *
    2571 * Note that internal data is returned in *nz, thus the user does not need to allocate memory there.
    2572 */
    2574 SCIP* scip, /**< SCIP data structure */
    2575 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2576 const int** nz, /**< pointer to store pointer that stores the nonzeroes of the objective gradient */
    2577 const SCIP_Bool** nlnz, /**< flags marking nonlinear nonzeroes */
    2578 int* nnz, /**< number of nonzeroes */
    2579 int* nnlnz /**< number of nonlinear nonzeroes */
    2580 )
    2581{
    2583 SCIP_EXPRITER* it;
    2584 SCIP_EXPR* expr;
    2585 SCIP_Bool* nzflag;
    2586 SCIP_Bool* nlflag;
    2587 int j;
    2588
    2589 assert(oracle != NULL);
    2590
    2591 SCIPdebugMessage("%p get objective gradient sparsity\n", (void*)oracle);
    2592
    2593 if( oracle->objgradnz != NULL )
    2594 {
    2595 *nz = oracle->objgradnz;
    2596 *nlnz = oracle->objnlflags;
    2597 *nnz = oracle->nobjgradnz;
    2598 *nnlnz = oracle->nobjgradnlnz;
    2599 return SCIP_OKAY;
    2600 }
    2601
    2602 if( oracle->nvars == 0 )
    2603 {
    2604 /* TODO what happens with the fields in oracle? */
    2605 *nz = NULL;
    2606 *nlnz = NULL;
    2607 *nnz = 0;
    2608 *nnlnz = 0;
    2609 return SCIP_OKAY;
    2610 }
    2611
    2613
    2614 /* TODO this can be moved into a separate function */
    2615 obj = oracle->objective;
    2616 assert(obj != NULL);
    2617
    2618 if( obj->expr == NULL )
    2619 {
    2620 /* for a linear objective, we can just copy the linear indices from the objective into the sparsity pattern */
    2621 if( obj->nlinidxs > 0 )
    2622 {
    2625 oracle->nobjgradnz = obj->nlinidxs;
    2626 oracle->nobjgradnlnz = 0;
    2627 }
    2628 }
    2629 else
    2630 {
    2631 int maxnnz = 0; /* an upper bound on the number of nonzeroes */
    2632
    2633 /* check which variables appear in objective */
    2634 SCIP_CALL( SCIPallocCleanBufferArray(scip, &nzflag, oracle->nvars) );
    2635 SCIP_CALL( SCIPallocCleanBufferArray(scip, &nlflag, oracle->nvars) );
    2636
    2637 for( j = 0; j < obj->nlinidxs; ++j )
    2638 {
    2639 nzflag[obj->linidxs[j]] = TRUE;
    2640 ++maxnnz;
    2641 }
    2642
    2645
    2646 for( expr = SCIPexpriterRestartDFS(it, obj->expr); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    2647 {
    2648 if( SCIPisExprVaridx(scip, expr) )
    2649 {
    2650 int varidx = SCIPgetIndexExprVaridx(expr);
    2651
    2652 assert(varidx < oracle->nvars);
    2653 if( !nzflag[varidx] )
    2654 {
    2655 nzflag[varidx] = TRUE;
    2656 ++maxnnz;
    2657 }
    2658 nlflag[varidx] = TRUE;
    2659 }
    2660 }
    2661
    2662 SCIPfreeExpriter(&it);
    2663
    2666
    2667 /* store variables indices in objgradnz and increase nobjgradnz */
    2668 for( j = 0; j < oracle->nvars; ++j )
    2669 {
    2670 if( nzflag[j] == FALSE )
    2671 continue;
    2672
    2673 nzflag[j] = FALSE;
    2674 oracle->objgradnz[oracle->nobjgradnz] = j;
    2675
    2676 if( nlflag[j] )
    2677 {
    2678 oracle->objnlflags[oracle->nobjgradnz] = TRUE;
    2679 ++(oracle->nobjgradnlnz);
    2680 nlflag[j] = FALSE;
    2681 }
    2682 ++(oracle->nobjgradnz);
    2683 }
    2684
    2687 }
    2688
    2689 *nz = oracle->objgradnz;
    2690 *nlnz = oracle->objnlflags;
    2691 *nnz = oracle->nobjgradnz;
    2692 *nnlnz = oracle->nobjgradnlnz;
    2693
    2695
    2696 return SCIP_OKAY;
    2697}
    2698
    2699/** evaluates the Jacobian matrix in a given point
    2700 *
    2701 * The values in the Jacobian matrix are returned in the same order as specified by the offset and col arrays obtained by SCIPnlpiOracleGetJacobianRowSparsity().
    2702 * The user need to call SCIPnlpiOracleGetJacobianRowSparsity() at least ones before using this function.
    2703 *
    2704 * @return SCIP_INVALIDDATA, if the Jacobian could not be evaluated (domain error, etc.)
    2705 */
    2707 SCIP* scip, /**< SCIP data structure */
    2708 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2709 const SCIP_Real* x, /**< point where to evaluate */
    2710 SCIP_Bool isnewx, /**< has the point x changed since the last call to some evaluation function? */
    2711 SCIP_Real* convals, /**< pointer to store constraint values, can be NULL */
    2712 SCIP_Real* jacobi /**< pointer to store sparse jacobian values */
    2713 )
    2714{
    2715 SCIP_NLPIORACLECONS* cons;
    2716 SCIP_RETCODE retcode;
    2717 SCIP_Real* grad;
    2718 SCIP_Real nlval;
    2719 int i;
    2720 int j;
    2721 int k;
    2722 int l;
    2723
    2724 SCIPdebugMessage("%p eval jacobian\n", (void*)oracle);
    2725
    2726 assert(oracle != NULL);
    2727 assert(jacobi != NULL);
    2728
    2729 assert(oracle->jacrowoffsets != NULL);
    2730 assert(oracle->jaccols != NULL);
    2731
    2733
    2734 SCIP_CALL( SCIPallocCleanBufferArray(scip, &grad, oracle->nvars) );
    2735
    2736 retcode = SCIP_OKAY;
    2737
    2738 j = oracle->jacrowoffsets[0]; /* TODO isn't oracle->jacrowoffsets[0] == 0 and thus always j == k ? */
    2739 k = 0;
    2740 for( i = 0; i < oracle->nconss; ++i )
    2741 {
    2742 cons = oracle->conss[i];
    2743 assert(cons != NULL);
    2744
    2745 if( cons->expr == NULL )
    2746 {
    2747 if( convals != NULL )
    2748 convals[i] = 0.0;
    2749
    2750 /* for a linear constraint, we can just copy the linear coefs from the constraint into the jacobian */
    2751 if( cons->nlinidxs > 0 )
    2752 {
    2753 BMScopyMemoryArray(&jacobi[k], cons->lincoefs, cons->nlinidxs);
    2754 j += cons->nlinidxs;
    2755 k += cons->nlinidxs;
    2756 if( convals != NULL )
    2757 for( l = 0; l < cons->nlinidxs; ++l )
    2758 convals[i] += cons->lincoefs[l] * x[cons->linidxs[l]];
    2759 }
    2760 assert(j == oracle->jacrowoffsets[i+1]);
    2761 continue;
    2762 }
    2763
    2764 /* eval grad for nonlinear and add to jacobi */
    2765 SCIPdebugMsg(scip, "eval gradient of ");
    2766 SCIPdebug( if( isnewx ) {printf("\nx ="); for( l = 0; l < oracle->nvars; ++l) printf(" %g", x[l]); printf("\n");} )
    2767
    2768 SCIP_CALL( SCIPexprintGrad(scip, oracle->exprinterpreter, cons->expr, cons->exprintdata, (SCIP_Real*)x, isnewx, &nlval, grad) );
    2769
    2770 SCIPdebug( printf("g ="); for( l = oracle->jacoffsets[i]; l < oracle->jacoffsets[i+1]; ++l) printf(" %g", grad[oracle->jaccols[l]]); printf("\n"); )
    2771
    2772 if( !SCIPisFinite(nlval) || SCIPisInfinity(scip, ABS(nlval)) )
    2773 {
    2774 SCIPdebugMessage("gradient evaluation yield invalid function value %g\n", nlval);
    2775 retcode = SCIP_INVALIDDATA; /* indicate that the function could not be evaluated at given point */
    2776 goto TERMINATE;
    2777 }
    2778 if( convals != NULL )
    2779 convals[i] = nlval;
    2780
    2781 /* add linear part to grad */
    2782 for( l = 0; l < cons->nlinidxs; ++l )
    2783 {
    2784 if( convals != NULL )
    2785 convals[i] += cons->lincoefs[l] * x[cons->linidxs[l]];
    2786 /* if grad[cons->linidxs[l]] is not finite, then adding a finite value doesn't change that, so don't check that here */
    2787 grad[cons->linidxs[l]] += cons->lincoefs[l];
    2788 }
    2789
    2790 /* store complete gradient (linear + nonlinear) in jacobi
    2791 * use the already evaluated sparsity pattern to pick only elements from grad that could have been set
    2792 */
    2793 assert(j == oracle->jacrowoffsets[i]);
    2794 for( ; j < oracle->jacrowoffsets[i+1]; ++j )
    2795 {
    2796 if( !SCIPisFinite(grad[oracle->jaccols[j]]) )
    2797 {
    2798 SCIPdebugMessage("gradient evaluation yield invalid gradient value %g\n", grad[l]);
    2799 retcode = SCIP_INVALIDDATA; /* indicate that the function could not be evaluated at given point */
    2800 goto TERMINATE;
    2801 }
    2802 jacobi[k++] = grad[oracle->jaccols[j]];
    2803 /* reset to 0 for next constraint */
    2804 grad[oracle->jaccols[j]] = 0.0;
    2805 }
    2806
    2807#ifndef NDEBUG
    2808 /* check that exprint really wrote only into expected elements of grad
    2809 * TODO remove after some testing for better performance of debug runs */
    2810 for( l = 0; l < oracle->nvars; ++l )
    2811 assert(grad[l] == 0.0);
    2812#endif
    2813 }
    2814
    2815TERMINATE:
    2816 /* if there was an eval error, then we may have interrupted before cleaning up the grad buffer */
    2817 if( retcode == SCIP_INVALIDDATA )
    2818 BMSclearMemoryArray(grad, oracle->nvars);
    2819
    2821
    2823
    2824 return retcode;
    2825}
    2826
    2827/** gets sparsity pattern of the Hessian matrix of the Lagrangian
    2828 *
    2829 * Note that internal data is returned in *offset and *nzs, thus the user must not to allocate memory there.
    2830 * Adding or deleting variables, objective, or constraints may destroy the sparsity structure and make another call to this function necessary.
    2831 * Only elements of the lower left triangle and the diagonal are counted.
    2832 */
    2834 SCIP* scip, /**< SCIP data structure */
    2835 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2836 const int** offset, /**< pointer to store pointer that stores the offsets to each row's (or col's if colwise == TRUE) sparsity pattern in nzs, can be NULL */
    2837 const int** allnz, /**< pointer to store pointer that stores the indices of variables that appear in each row (or col if colwise = TRUE), offset[nvars] gives length of nzs, can be NULL */
    2838 SCIP_Bool colwise /**< tells whether a columnwise (TRUE) or rowwise representation is needed */
    2839 )
    2840{
    2841 int** nz; /* nonzeros in Hessian corresponding to one column (if colwise = TRUE) or row */
    2842 int* len; /* len[i] is length of array nz[i] */
    2843 int* nnz; /* nnz[i] is number of entries in nz[i] (<= len[i]) */
    2844 int totalnnz;
    2845 int i;
    2846 int j;
    2847 int cnt;
    2848
    2849 assert(oracle != NULL);
    2850
    2851 SCIPdebugMessage("%p get hessian lag sparsity\n", (void*)oracle);
    2852
    2853 if( oracle->heslagoffsets != NULL )
    2854 {
    2855 assert(oracle->hescolwise == colwise);
    2856 assert(oracle->heslagnzs != NULL);
    2857 if( offset != NULL )
    2858 *offset = oracle->heslagoffsets;
    2859 if( allnz != NULL )
    2860 *allnz = oracle->heslagnzs;
    2861 return SCIP_OKAY;
    2862 }
    2863
    2864 oracle->hescolwise = colwise;
    2865
    2867
    2868 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &oracle->heslagoffsets, oracle->nvars + 1) );
    2869
    2871 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &len, oracle->nvars) );
    2872 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &nnz, oracle->nvars) );
    2873 BMSclearMemoryArray(nz, oracle->nvars);
    2874 BMSclearMemoryArray(len, oracle->nvars);
    2875 BMSclearMemoryArray(nnz, oracle->nvars);
    2876 totalnnz = 0;
    2877
    2878 if( oracle->objective->expr != NULL )
    2879 {
    2880 SCIP_CALL( hessLagSparsitySetNzFlagForExpr(scip, oracle, nz, len, nnz, &totalnnz, oracle->objective->expr,
    2881 oracle->objective->exprintdata, oracle->nvars, colwise) );
    2882 }
    2883
    2884 for( i = 0; i < oracle->nconss; ++i )
    2885 {
    2886 if( oracle->conss[i]->expr != NULL )
    2887 {
    2888 SCIP_CALL( hessLagSparsitySetNzFlagForExpr(scip, oracle, nz, len, nnz, &totalnnz, oracle->conss[i]->expr,
    2889 oracle->conss[i]->exprintdata, oracle->nvars, colwise) );
    2890 }
    2891 }
    2892
    2893 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &oracle->heslagnzs, totalnnz) );
    2894
    2895 /* set hessian sparsity from nz, nnz */
    2896 cnt = 0;
    2897 for( i = 0; i < oracle->nvars; ++i )
    2898 {
    2899 oracle->heslagoffsets[i] = cnt;
    2900 for( j = 0; j < nnz[i]; ++j )
    2901 {
    2902 assert(cnt < totalnnz);
    2903 oracle->heslagnzs[cnt++] = nz[i][j];
    2904 }
    2905 SCIPfreeBlockMemoryArrayNull(scip, &nz[i], len[i]);
    2906 len[i] = 0;
    2907 }
    2908 oracle->heslagoffsets[oracle->nvars] = cnt;
    2909 assert(cnt == totalnnz);
    2910
    2911 SCIPfreeBlockMemoryArray(scip, &nz, oracle->nvars);
    2912 SCIPfreeBlockMemoryArray(scip, &nnz, oracle->nvars);
    2913 SCIPfreeBlockMemoryArray(scip, &len, oracle->nvars);
    2914
    2915 if( offset != NULL )
    2916 *offset = oracle->heslagoffsets;
    2917 if( allnz != NULL )
    2918 *allnz = oracle->heslagnzs;
    2919
    2921
    2922 return SCIP_OKAY;
    2923}
    2924
    2925/** evaluates the Hessian matrix of the Lagrangian in a given point
    2926 *
    2927 * The values in the Hessian matrix are returned in the same order as specified by the offset and col arrays obtained by SCIPnlpiOracleGetHessianLagSparsity().
    2928 * The user must call SCIPnlpiOracleGetHessianLagSparsity() at least ones before using this function.
    2929 * Only elements of the lower left triangle and the diagonal are computed.
    2930 *
    2931 * @return SCIP_INVALIDDATA, if the Hessian could not be evaluated (domain error, etc.)
    2932 */
    2934 SCIP* scip, /**< SCIP data structure */
    2935 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    2936 const SCIP_Real* x, /**< point where to evaluate */
    2937 SCIP_Bool isnewx_obj, /**< has the point x changed since the last call to an objective evaluation function? */
    2938 SCIP_Bool isnewx_cons, /**< has the point x changed since the last call to the constraint evaluation function? */
    2939 SCIP_Real objfactor, /**< weight for objective function */
    2940 const SCIP_Real* lambda, /**< weights (Lagrangian multipliers) for the constraints */
    2941 SCIP_Real* hessian, /**< pointer to store sparse hessian values */
    2942 SCIP_Bool colwise /**< whether the entries should be first sorted column-wise (TRUE) or row-wise */
    2943 )
    2944{ /*lint --e{715}*/
    2945 SCIP_RETCODE retcode = SCIP_OKAY;
    2946 int i;
    2947
    2948 assert(oracle != NULL);
    2949 assert(x != NULL);
    2950 assert(lambda != NULL || oracle->nconss == 0);
    2951 assert(hessian != NULL);
    2952
    2953 assert(oracle->heslagoffsets != NULL);
    2954 assert(oracle->heslagnzs != NULL);
    2955 assert(oracle->hescolwise == colwise);
    2956
    2957 SCIPdebugMessage("%p eval hessian lag\n", (void*)oracle);
    2958
    2960
    2961 BMSclearMemoryArray(hessian, oracle->heslagoffsets[oracle->nvars]);
    2962
    2963 if( objfactor != 0.0 && oracle->objective->expr != NULL )
    2964 {
    2965 retcode = hessLagAddExpr(scip, oracle, objfactor, x, isnewx_obj, oracle->objective->expr,
    2966 oracle->objective->exprintdata, oracle->heslagoffsets, oracle->heslagnzs, hessian, colwise);
    2967 }
    2968
    2969 for( i = 0; i < oracle->nconss && retcode == SCIP_OKAY; ++i )
    2970 {
    2971 assert( lambda != NULL ); /* for lint */
    2972 if( lambda[i] == 0.0 || oracle->conss[i]->expr == NULL )
    2973 continue;
    2974 retcode = hessLagAddExpr(scip, oracle, lambda[i], x, isnewx_cons, oracle->conss[i]->expr,
    2975 oracle->conss[i]->exprintdata, oracle->heslagoffsets, oracle->heslagnzs, hessian, colwise);
    2976 }
    2977
    2979
    2980 return retcode;
    2981}
    2982
    2983/** resets clock that measures evaluation time */
    2985 SCIP* scip, /**< SCIP data structure */
    2986 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    2987 )
    2988{
    2989 assert(oracle != NULL);
    2990
    2992
    2993 return SCIP_OKAY;
    2994}
    2995
    2996/** gives time spend in evaluation since last reset of clock
    2997 *
    2998 * Gives 0 if the eval clock is disabled.
    2999 */
    3001 SCIP* scip, /**< SCIP data structure */
    3002 SCIP_NLPIORACLE* oracle /**< pointer to NLPIORACLE data structure */
    3003 )
    3004{
    3005 assert(oracle != NULL);
    3006
    3007 return SCIPgetClockTime(scip, oracle->evalclock);
    3008}
    3009
    3010/** prints the problem to a file. */
    3012 SCIP* scip, /**< SCIP data structure */
    3013 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    3014 FILE* file /**< file to print to, or NULL for standard output */
    3015 )
    3016{ /*lint --e{777} */
    3017 int i;
    3018 SCIP_Real lhs;
    3019 SCIP_Real rhs;
    3020
    3021 assert(oracle != NULL);
    3022
    3023 SCIPdebugMessage("%p print problem\n", (void*)oracle);
    3024
    3025 if( file == NULL )
    3026 file = stdout;
    3027
    3028 SCIPinfoMessage(scip, file, "NLPI Oracle %s: %d variables and %d constraints\n", oracle->name ? oracle->name : "", oracle->nvars, oracle->nconss);
    3029 for( i = 0; i < oracle->nvars; ++i )
    3030 {
    3031 if( oracle->varnames != NULL && oracle->varnames[i] != NULL )
    3032 SCIPinfoMessage(scip, file, "%10s (x%d)", oracle->varnames[i], i); /* give also name x%d as it will be by expression-print (printFunction) */
    3033 else
    3034 SCIPinfoMessage(scip, file, "x%09d", i);
    3035 SCIPinfoMessage(scip, file, ": [%8g, %8g]", oracle->varlbs[i], oracle->varubs[i]);
    3036 SCIPinfoMessage(scip, file, "\t #linear: %d #nonlinear: %d\n", oracle->varlincount[i], oracle->varnlcount[i]);
    3037 }
    3038
    3039 SCIPinfoMessage(scip, file, "objective: ");
    3040 SCIP_CALL( printFunction(scip, oracle, file, oracle->objective, FALSE) );
    3041 if( oracle->objective->lhs != 0.0 )
    3042 SCIPinfoMessage(scip, file, "%+.15g", oracle->objective->lhs);
    3043 SCIPinfoMessage(scip, file, "\n");
    3044
    3045 for( i = 0; i < oracle->nconss; ++i )
    3046 {
    3047 if( oracle->conss[i]->name != NULL )
    3048 SCIPinfoMessage(scip, file, "%10s", oracle->conss[i]->name);
    3049 else
    3050 SCIPinfoMessage(scip, file, "con%07d", i);
    3051
    3052 lhs = oracle->conss[i]->lhs;
    3053 rhs = oracle->conss[i]->rhs;
    3054 SCIPinfoMessage(scip, file, ": ");
    3055 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && lhs != rhs )
    3056 SCIPinfoMessage(scip, file, "%.15g <= ", lhs);
    3057
    3058 SCIP_CALL( printFunction(scip, oracle, file, oracle->conss[i], FALSE) );
    3059
    3060 if( lhs == rhs )
    3061 SCIPinfoMessage(scip, file, " = %.15g", rhs);
    3062 else if( !SCIPisInfinity(scip, rhs) )
    3063 SCIPinfoMessage(scip, file, " <= %.15g", rhs);
    3064 else if( !SCIPisInfinity(scip, -lhs) )
    3065 SCIPinfoMessage(scip, file, " >= %.15g", lhs);
    3066
    3067 SCIPinfoMessage(scip, file, "\n");
    3068 }
    3069
    3070 return SCIP_OKAY;
    3071}
    3072
    3073/** prints the problem to a file in GAMS format
    3074 *
    3075 * If there are variable (equation, resp.) names with more than 9 characters, then variable (equation, resp.) names are prefixed with an unique identifier.
    3076 * This is to make it easier to identify variables solution output in the listing file.
    3077 * Names with more than 64 characters are shorten to 64 letters due to GAMS limits.
    3078 */
    3080 SCIP* scip, /**< SCIP data structure */
    3081 SCIP_NLPIORACLE* oracle, /**< pointer to NLPIORACLE data structure */
    3082 SCIP_Real* initval, /**< starting point values for variables or NULL */
    3083 FILE* file /**< file to print to, or NULL for standard output */
    3084 )
    3085{ /*lint --e{777} */
    3086 int i;
    3087 int nllevel; /* level of nonlinearity of problem: linear = 0, quadratic, smooth nonlinear, nonsmooth */
    3088 static const char* nllevelname[4] = { "LP", "QCP", "NLP", "DNLP" };
    3089 char problemname[SCIP_MAXSTRLEN];
    3090 char namebuf[70];
    3091 SCIP_Bool havelongvarnames;
    3092 SCIP_Bool havelongequnames;
    3093
    3094 SCIPdebugMessage("%p print problem gams\n", (void*)oracle);
    3095
    3096 assert(oracle != NULL);
    3097
    3098 if( file == NULL )
    3099 file = stdout;
    3100
    3101 nllevel = 0;
    3102
    3103 havelongvarnames = FALSE;
    3104 for( i = 0; i < oracle->nvars; ++i )
    3105 if( oracle->varnames != NULL && oracle->varnames[i] != NULL && strlen(oracle->varnames[i]) > 9 )
    3106 {
    3107 havelongvarnames = TRUE;
    3108 break;
    3109 }
    3110
    3111 havelongequnames = FALSE;
    3112 for( i = 0; i < oracle->nconss; ++i )
    3113 if( oracle->conss[i]->name && strlen(oracle->conss[i]->name) > 9 )
    3114 {
    3115 havelongequnames = TRUE;
    3116 break;
    3117 }
    3118
    3119 SCIPinfoMessage(scip, file, "$offlisting\n");
    3120 SCIPinfoMessage(scip, file, "$offdigit\n");
    3121 SCIPinfoMessage(scip, file, "* NLPI Oracle Problem %s\n", oracle->name ? oracle->name : "");
    3122 SCIPinfoMessage(scip, file, "Variables ");
    3123 for( i = 0; i < oracle->nvars; ++i )
    3124 {
    3125 printName(namebuf, oracle->varnames != NULL ? oracle->varnames[i] : NULL, i, 'x', NULL, havelongvarnames);
    3126 SCIPinfoMessage(scip, file, "%s, ", namebuf);
    3127 if( i % 10 == 9 )
    3128 SCIPinfoMessage(scip, file, "\n");
    3129 }
    3130 SCIPinfoMessage(scip, file, "NLPIORACLEOBJVAR;\n\n");
    3131 for( i = 0; i < oracle->nvars; ++i )
    3132 {
    3133 char* name;
    3134 name = oracle->varnames != NULL ? oracle->varnames[i] : NULL;
    3135 if( oracle->varlbs[i] == oracle->varubs[i] )
    3136 {
    3137 printName(namebuf, name, i, 'x', NULL, havelongvarnames);
    3138 SCIPinfoMessage(scip, file, "%s.fx = %.15g;\t", namebuf, oracle->varlbs[i]);
    3139 }
    3140 else
    3141 {
    3142 if( !SCIPisInfinity(scip, -oracle->varlbs[i]) )
    3143 {
    3144 printName(namebuf, name, i, 'x', NULL, havelongvarnames);
    3145 SCIPinfoMessage(scip, file, "%s.lo = %.15g;\t", namebuf, oracle->varlbs[i]);
    3146 }
    3147 if( !SCIPisInfinity(scip, oracle->varubs[i]) )
    3148 {
    3149 printName(namebuf, name, i, 'x', NULL, havelongvarnames);
    3150 SCIPinfoMessage(scip, file, "%s.up = %.15g;\t", namebuf, oracle->varubs[i]);
    3151 }
    3152 }
    3153 if( initval != NULL )
    3154 {
    3155 printName(namebuf, name, i, 'x', NULL, havelongvarnames);
    3156 SCIPinfoMessage(scip, file, "%s.l = %.15g;\t", namebuf, initval[i]);
    3157 }
    3158 SCIPinfoMessage(scip, file, "\n");
    3159 }
    3160 SCIPinfoMessage(scip, file, "\n");
    3161
    3162 SCIPinfoMessage(scip, file, "Equations ");
    3163 for( i = 0; i < oracle->nconss; ++i )
    3164 {
    3165 printName(namebuf, oracle->conss[i]->name, i, 'e', NULL, havelongequnames);
    3166 SCIPinfoMessage(scip, file, "%s, ", namebuf);
    3167
    3168 if( !SCIPisInfinity(scip, -oracle->conss[i]->lhs) && !SCIPisInfinity(scip, oracle->conss[i]->rhs) && oracle->conss[i]->lhs != oracle->conss[i]->rhs )
    3169 {
    3170 /* ranged row: add second constraint */
    3171 printName(namebuf, oracle->conss[i]->name, i, 'e', "_RNG", havelongequnames);
    3172 SCIPinfoMessage(scip, file, "%s, ", namebuf);
    3173 }
    3174 if( i % 10 == 9 )
    3175 SCIPinfoMessage(scip, file, "\n");
    3176 }
    3177 SCIPinfoMessage(scip, file, "NLPIORACLEOBJ;\n\n");
    3178
    3179 SCIPinfoMessage(scip, file, "NLPIORACLEOBJ.. NLPIORACLEOBJVAR =E= ");
    3180 SCIP_CALL( printFunction(scip, oracle, file, oracle->objective, havelongvarnames) );
    3181 if( oracle->objective->lhs != 0.0 )
    3182 SCIPinfoMessage(scip, file, "%+.15g", oracle->objective->lhs);
    3183 SCIPinfoMessage(scip, file, ";\n");
    3184
    3185 for( i = 0; i < oracle->nconss; ++i )
    3186 {
    3187 SCIP_Real lhs;
    3188 SCIP_Real rhs;
    3189
    3190 printName(namebuf, oracle->conss[i]->name, i, 'e', NULL, havelongequnames);
    3191 SCIPinfoMessage(scip, file, "%s.. ", namebuf);
    3192
    3193 SCIP_CALL( printFunction(scip, oracle, file, oracle->conss[i], havelongvarnames) );
    3194
    3195 lhs = oracle->conss[i]->lhs;
    3196 rhs = oracle->conss[i]->rhs;
    3197
    3198 if( lhs == rhs )
    3199 SCIPinfoMessage(scip, file, " =E= %.15g", rhs);
    3200 else if( !SCIPisInfinity(scip, rhs) )
    3201 SCIPinfoMessage(scip, file, " =L= %.15g", rhs);
    3202 else if( !SCIPisInfinity(scip, -lhs) )
    3203 SCIPinfoMessage(scip, file, " =G= %.15g", lhs);
    3204 else
    3205 SCIPinfoMessage(scip, file, " =N= 0");
    3206 SCIPinfoMessage(scip, file, ";\n");
    3207
    3208 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && lhs != rhs )
    3209 {
    3210 printName(namebuf, oracle->conss[i]->name, i, 'e', "_RNG", havelongequnames);
    3211 SCIPinfoMessage(scip, file, "%s.. ", namebuf);
    3212
    3213 SCIP_CALL( printFunction(scip, oracle, file, oracle->conss[i], havelongvarnames) );
    3214
    3215 SCIPinfoMessage(scip, file, " =G= %.15g;\n", lhs);
    3216 }
    3217
    3218 if( nllevel <= 1 && oracle->conss[i]->expr != NULL )
    3219 nllevel = 2;
    3220 if( nllevel <= 2 && oracle->conss[i]->expr != NULL )
    3221 {
    3222 SCIP_Bool nonsmooth;
    3223 SCIP_CALL( exprIsNonSmooth(scip, oracle->conss[i]->expr, &nonsmooth) );
    3224 if( nonsmooth )
    3225 nllevel = 3;
    3226 }
    3227 }
    3228
    3229 (void) SCIPsnprintf(problemname, SCIP_MAXSTRLEN, "%s", oracle->name ? oracle->name : "m");
    3230
    3231 SCIPinfoMessage(scip, file, "Model %s / all /;\n", problemname);
    3232 SCIPinfoMessage(scip, file, "option limrow = 0;\n");
    3233 SCIPinfoMessage(scip, file, "option limcol = 0;\n");
    3234 SCIPinfoMessage(scip, file, "Solve %s minimizing NLPIORACLEOBJVAR using %s;\n", problemname, nllevelname[nllevel]);
    3235
    3236 return SCIP_OKAY;
    3237}
    3238
    3239/**@} */
    SCIP_VAR * h
    Definition: circlepacking.c:68
    SCIP_VAR ** x
    Definition: circlepacking.c:63
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_INTERVAL_INFINITY
    Definition: def.h:189
    #define SCIP_Bool
    Definition: def.h:100
    #define SCIP_DEFAULT_EPSILON
    Definition: def.h:173
    #define EPSLE(x, y, eps)
    Definition: def.h:194
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_Real
    Definition: def.h:165
    #define ABS(x)
    Definition: def.h:225
    #define EPSEQ(x, y, eps)
    Definition: def.h:192
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define RESTRICT
    Definition: def.h:269
    #define REALABS(x)
    Definition: def.h:191
    #define SCIP_CALL(x)
    Definition: def.h:364
    power and signed power expression handlers
    handler for variable index expressions
    methods to interpret (evaluate) an expression "fast"
    #define infinity
    Definition: gastrans.c:80
    int SCIPgetIndexExprVaridx(SCIP_EXPR *expr)
    Definition: expr_varidx.c:267
    SCIP_Bool SCIPisExprVaridx(SCIP *scip, SCIP_EXPR *expr)
    Definition: expr_varidx.c:252
    void SCIPsetIndexExprVaridx(SCIP_EXPR *expr, int newindex)
    Definition: expr_varidx.c:279
    SCIP_Bool SCIPisExprSignpower(SCIP *scip, SCIP_EXPR *expr)
    Definition: expr_pow.c:3235
    SCIP_RETCODE SCIPexprintCompile(SCIP *scip, SCIP_EXPRINT *exprint, SCIP_EXPR *expr, SCIP_EXPRINTDATA **exprintdata)
    SCIP_RETCODE SCIPexprintFreeData(SCIP *scip, SCIP_EXPRINT *exprint, SCIP_EXPR *expr, SCIP_EXPRINTDATA **exprintdata)
    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)
    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,...)
    Definition: scip_message.c:208
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPnlpiOracleEvalObjectiveValue(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Real *objval)
    Definition: nlpioracle.c:2221
    SCIP_RETCODE SCIPnlpiOracleChgLinearCoefs(SCIP *scip, SCIP_NLPIORACLE *oracle, int considx, int nentries, const int *varidxs, const SCIP_Real *newcoefs)
    Definition: nlpioracle.c:1871
    SCIP_RETCODE SCIPnlpiOracleEvalConstraintInterval(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_Real infinity, int considx, const SCIP_Real *xmin, const SCIP_Real *xmax, SCIP_Real *conmin, SCIP_Real *conmax)
    Definition: nlpioracle.c:2336
    SCIP_RETCODE SCIPnlpiOracleGetJacobianRowSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **rowoffsets, const int **cols, const SCIP_Bool **colnlflags, int *nnlnz)
    Definition: nlpioracle.c:2427
    SCIP_RETCODE SCIPnlpiOracleGetHessianLagSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **offset, const int **allnz, SCIP_Bool colwise)
    Definition: nlpioracle.c:2833
    SCIP_RETCODE SCIPnlpiOracleChgVarBounds(SCIP *scip, SCIP_NLPIORACLE *oracle, int nvars, const int *indices, const SCIP_Real *lbs, const SCIP_Real *ubs)
    Definition: nlpioracle.c:1571
    SCIP_RETCODE SCIPnlpiOracleAddConstraints(SCIP *scip, SCIP_NLPIORACLE *oracle, int nconss, const SCIP_Real *lhss, const SCIP_Real *rhss, const int *nlininds, int *const *lininds, SCIP_Real *const *linvals, SCIP_EXPR **exprs, const char **consnames)
    Definition: nlpioracle.c:1481
    SCIP_Bool SCIPnlpiOracleIsConstraintNonlinear(SCIP_NLPIORACLE *oracle, int considx)
    Definition: nlpioracle.c:2181
    SCIP_RETCODE SCIPnlpiOracleDelVarSet(SCIP *scip, SCIP_NLPIORACLE *oracle, int *delstats)
    Definition: nlpioracle.c:1643
    SCIP_RETCODE SCIPnlpiOracleEvalConstraintValues(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Real *convals)
    Definition: nlpioracle.c:2270
    SCIP_RETCODE SCIPnlpiOracleCreate(SCIP *scip, SCIP_NLPIORACLE **oracle)
    Definition: nlpioracle.c:1297
    void SCIPnlpiOracleGetVarCounts(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **lincounts, const int **nlcounts)
    Definition: nlpioracle.c:2095
    char * SCIPnlpiOracleGetConstraintName(SCIP_NLPIORACLE *oracle, int considx)
    Definition: nlpioracle.c:2148
    SCIP_RETCODE SCIPnlpiOracleEvalObjectiveGradient(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *objval, SCIP_Real *objgrad)
    Definition: nlpioracle.c:2368
    SCIP_RETCODE SCIPnlpiOracleResetEvalTime(SCIP *scip, SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:2984
    SCIP_RETCODE SCIPnlpiOraclePrintProblem(SCIP *scip, SCIP_NLPIORACLE *oracle, FILE *file)
    Definition: nlpioracle.c:3011
    SCIP_RETCODE SCIPnlpiOracleSetObjective(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real constant, int nlin, const int *lininds, const SCIP_Real *linvals, SCIP_EXPR *expr)
    Definition: nlpioracle.c:1542
    SCIP_Real SCIPnlpiOracleGetConstraintRhs(SCIP_NLPIORACLE *oracle, int considx)
    Definition: nlpioracle.c:2135
    SCIP_Real SCIPnlpiOracleGetEvalTime(SCIP *scip, SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:3000
    SCIP_RETCODE SCIPnlpiOracleChgConsSides(SCIP *scip, SCIP_NLPIORACLE *oracle, int nconss, const int *indices, const SCIP_Real *lhss, const SCIP_Real *rhss)
    Definition: nlpioracle.c:1608
    SCIP_Real SCIPnlpiOracleGetConstraintLhs(SCIP_NLPIORACLE *oracle, int considx)
    Definition: nlpioracle.c:2122
    SCIP_RETCODE SCIPnlpiOracleGetJacobianColSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **coloffsets, const int **rows, const SCIP_Bool **rownlflags, int *nnlnz)
    Definition: nlpioracle.c:2481
    SCIP_RETCODE SCIPnlpiOracleAddVars(SCIP *scip, SCIP_NLPIORACLE *oracle, int nvars, const SCIP_Real *lbs, const SCIP_Real *ubs, const char **varnames)
    Definition: nlpioracle.c:1395
    SCIP_RETCODE SCIPnlpiOracleEvalHessianLag(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx_obj, SCIP_Bool isnewx_cons, SCIP_Real objfactor, const SCIP_Real *lambda, SCIP_Real *hessian, SCIP_Bool colwise)
    Definition: nlpioracle.c:2933
    SCIP_RETCODE SCIPnlpiOracleEvalConstraintGradient(SCIP *scip, SCIP_NLPIORACLE *oracle, const int considx, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *conval, SCIP_Real *congrad)
    Definition: nlpioracle.c:2397
    int SCIPnlpiOracleGetNVars(SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:2030
    int SCIPnlpiOracleGetNConstraints(SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:2040
    SCIP_RETCODE SCIPnlpiOracleGetObjGradientNnz(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **nz, const SCIP_Bool **nlnz, int *nnz, int *nnlnz)
    Definition: nlpioracle.c:2573
    SCIP_EXPRINTCAPABILITY SCIPnlpiOracleGetEvalCapability(SCIP *scip, SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:2198
    SCIP_Real SCIPnlpiOracleGetObjectiveConstant(SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:2111
    SCIP_RETCODE SCIPnlpiOraclePrintProblemGams(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_Real *initval, FILE *file)
    Definition: nlpioracle.c:3079
    SCIP_Bool SCIPnlpiOracleIsVarNonlinear(SCIP *scip, SCIP_NLPIORACLE *oracle, int varidx)
    Definition: nlpioracle.c:2080
    SCIP_RETCODE SCIPnlpiOracleEvalJacobian(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *convals, SCIP_Real *jacobi)
    Definition: nlpioracle.c:2706
    SCIP_RETCODE SCIPnlpiOracleDelConsSet(SCIP *scip, SCIP_NLPIORACLE *oracle, int *delstats)
    Definition: nlpioracle.c:1785
    SCIP_RETCODE SCIPnlpiOracleSetProblemName(SCIP *scip, SCIP_NLPIORACLE *oracle, const char *name)
    Definition: nlpioracle.c:1359
    SCIP_RETCODE SCIPnlpiOracleChgObjConstant(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_Real objconstant)
    Definition: nlpioracle.c:2013
    SCIP_RETCODE SCIPnlpiOracleEvalConstraintValue(SCIP *scip, SCIP_NLPIORACLE *oracle, int considx, const SCIP_Real *x, SCIP_Real *conval)
    Definition: nlpioracle.c:2246
    char ** SCIPnlpiOracleGetVarNames(SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:2070
    SCIP_Real SCIPnlpiOracleGetConstraintLinearCoef(SCIP_NLPIORACLE *oracle, int considx, int varpos)
    Definition: nlpioracle.c:2161
    SCIP_RETCODE SCIPnlpiOracleEvalObjectiveInterval(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_Real infinity, const SCIP_Real *xmin, const SCIP_Real *xmax, SCIP_Real *objmin, SCIP_Real *objmax)
    Definition: nlpioracle.c:2299
    const SCIP_Real * SCIPnlpiOracleGetVarLbs(SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:2050
    const SCIP_Real * SCIPnlpiOracleGetVarUbs(SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:2060
    SCIP_RETCODE SCIPnlpiOracleFree(SCIP *scip, SCIP_NLPIORACLE **oracle)
    Definition: nlpioracle.c:1327
    const char * SCIPnlpiOracleGetProblemName(SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:1383
    SCIP_RETCODE SCIPnlpiOracleChgExpr(SCIP *scip, SCIP_NLPIORACLE *oracle, int considx, SCIP_EXPR *expr)
    Definition: nlpioracle.c:1967
    SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
    Definition: scip_param.c:250
    const char * SCIPexprhdlrGetName(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:545
    void SCIPexprSetActivity(SCIP_EXPR *expr, SCIP_INTERVAL activity, SCIP_Longint activitytag)
    Definition: expr.c:4054
    SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
    Definition: expriter.c:969
    SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
    Definition: scip_expr.c:1443
    SCIP_EXPR * SCIPexpriterGetCurrent(SCIP_EXPRITER *iterator)
    Definition: expriter.c:683
    void SCIPexpriterSetStagesDFS(SCIP_EXPRITER *iterator, SCIP_EXPRITER_STAGE stopstages)
    Definition: expriter.c:664
    SCIP_EXPR * SCIPexpriterRestartDFS(SCIP_EXPRITER *iterator, SCIP_EXPR *expr)
    Definition: expriter.c:630
    SCIP_RETCODE SCIPcreateExpriter(SCIP *scip, SCIP_EXPRITER **iterator)
    Definition: scip_expr.c:2362
    SCIP_RETCODE SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
    Definition: scip_expr.c:1512
    SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
    Definition: expriter.c:858
    SCIP_INTERVAL SCIPexprGetActivity(SCIP_EXPR *expr)
    Definition: expr.c:4028
    void SCIPfreeExpriter(SCIP_EXPRITER **iterator)
    Definition: scip_expr.c:2376
    void SCIPcaptureExpr(SCIP_EXPR *expr)
    Definition: scip_expr.c:1435
    SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
    Definition: expriter.c:501
    SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
    Definition: expr.c:3895
    void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
    SCIP_Bool SCIPintervalIsEmpty(SCIP_Real infinity, SCIP_INTERVAL operand)
    void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
    void SCIPintervalMulScalar(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_Real operand2)
    void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
    #define SCIPfreeCleanBufferArray(scip, ptr)
    Definition: scip_mem.h:146
    #define SCIPallocCleanBufferArray(scip, ptr, num)
    Definition: scip_mem.h:142
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    #define SCIPallocClearBlockMemory(scip, ptr)
    Definition: scip_mem.h:91
    #define SCIPensureBlockMemoryArray(scip, ptr, arraysizeptr, minsize)
    Definition: scip_mem.h:107
    #define SCIPallocClearBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:97
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPallocMemory(scip, ptr)
    Definition: scip_mem.h:60
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    SCIP_RETCODE SCIPcreateClock(SCIP *scip, SCIP_CLOCK **clck)
    Definition: scip_timing.c:76
    SCIP_RETCODE SCIPresetClock(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:144
    void SCIPsetClockEnabled(SCIP_CLOCK *clck, SCIP_Bool enable)
    Definition: scip_timing.c:191
    SCIP_RETCODE SCIPstopClock(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:178
    SCIP_RETCODE SCIPfreeClock(SCIP *scip, SCIP_CLOCK **clck)
    Definition: scip_timing.c:127
    SCIP_Real SCIPgetClockTime(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:319
    SCIP_RETCODE SCIPstartClock(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:161
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPsortedvecFindInt(int *intarray, int val, int len, int *pos)
    void SCIPsortedvecInsertInt(int *intarray, int keyval, int *len, int *pos)
    void SCIPsortIntReal(int *intarray, SCIP_Real *realarray, int len)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSclearMemory(ptr)
    Definition: memory.h:129
    #define BMScopyMemoryArray(ptr, source, num)
    Definition: memory.h:134
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    static SCIP_RETCODE moveVariable(SCIP *scip, SCIP_NLPIORACLE *oracle, int fromidx, int toidx)
    Definition: nlpioracle.c:549
    static SCIP_RETCODE ensureIntArraySize(SCIP *scip, int **intarray, int *len, int minsize)
    Definition: nlpioracle.c:198
    static SCIP_RETCODE freeConstraint(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_NLPIORACLECONS **cons, SCIP_Bool updatevarcount)
    Definition: nlpioracle.c:476
    static SCIP_RETCODE hessLagAddExpr(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_Real weight, const SCIP_Real *x, SCIP_Bool new_x, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, int *hesoffset, int *hesnzidcs, SCIP_Real *values, SCIP_Bool colwise)
    Definition: nlpioracle.c:1089
    static SCIP_RETCODE updateVariableCounts(SCIP *scip, SCIP_NLPIORACLE *oracle, int factor, int nlinidxs, const int *linidxs, SCIP_EXPR *expr)
    Definition: nlpioracle.c:319
    static void freeVariables(SCIP *scip, SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:588
    static SCIP_RETCODE evalFunctionInterval(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_NLPIORACLECONS *cons, SCIP_Real infinity, const SCIP_Real *xmin, const SCIP_Real *xmax, SCIP_Real *valmin, SCIP_Real *valmax)
    Definition: nlpioracle.c:730
    static SCIP_RETCODE hessLagSparsitySetNzFlagForExpr(SCIP *scip, SCIP_NLPIORACLE *oracle, int **nz, int *len, int *nnz, int *nzcount, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, int dim, SCIP_Bool colwise)
    Definition: nlpioracle.c:1016
    static void clearDeletedLinearElements(int **linidxs, SCIP_Real **coefs, int *nidxs)
    Definition: nlpioracle.c:642
    static SCIP_RETCODE ensureConssSize(SCIP *scip, SCIP_NLPIORACLE *oracle, int minsize)
    Definition: nlpioracle.c:156
    static SCIP_RETCODE computeRowJacobianSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, int *nnz, int *nvarnnz)
    Definition: nlpioracle.c:902
    static SCIP_RETCODE createConstraint(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_NLPIORACLECONS **cons, int nlinidxs, const int *linidxs, const SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, const char *name)
    Definition: nlpioracle.c:413
    static void invalidateJacobiSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:240
    static void printName(char *buffer, char *name, int idx, char prefix, const char *suffix, SCIP_Bool longnames)
    Definition: nlpioracle.c:1172
    static SCIP_RETCODE exprIsNonSmooth(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool *nonsmooth)
    Definition: nlpioracle.c:1244
    static SCIP_RETCODE ensureConsLinSize(SCIP *scip, SCIP_NLPIORACLECONS *cons, int minsize)
    Definition: nlpioracle.c:172
    static void mapIndices(int *indexmap, int nindices, int *indices)
    Definition: nlpioracle.c:622
    static SCIP_RETCODE printFunction(SCIP *scip, SCIP_NLPIORACLE *oracle, FILE *file, SCIP_NLPIORACLECONS *cons, SCIP_Bool longvarnames)
    Definition: nlpioracle.c:1207
    static SCIP_RETCODE ensureVarsSize(SCIP *scip, SCIP_NLPIORACLE *oracle, int minsize)
    Definition: nlpioracle.c:123
    static SCIP_RETCODE evalFunctionValue(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_NLPIORACLECONS *cons, const SCIP_Real *x, SCIP_Real *val)
    Definition: nlpioracle.c:680
    static void invalidateHessianLagSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:296
    static void sortLinearCoefficients(int *nidxs, int *idxs, SCIP_Real *coefs)
    Definition: nlpioracle.c:364
    static SCIP_RETCODE ensureClearBoolArraySize(SCIP *scip, SCIP_Bool **boolarray, int *len, int minsize)
    Definition: nlpioracle.c:216
    static SCIP_RETCODE evalFunctionGradient(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_NLPIORACLECONS *cons, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *RESTRICT val, SCIP_Real *RESTRICT grad)
    Definition: nlpioracle.c:830
    static SCIP_RETCODE freeConstraints(SCIP *scip, SCIP_NLPIORACLE *oracle)
    Definition: nlpioracle.c:520
    methods to store an NLP and request function, gradient, and Hessian values
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    #define SCIPisFinite(x)
    Definition: pub_misc.h:82
    SCIP callable library.
    SCIP_Real sup
    Definition: intervalarith.h:57
    SCIP_Real inf
    Definition: intervalarith.h:56
    SCIP_Real * lincoefs
    Definition: nlpioracle.c:54
    SCIP_EXPRINTDATA * exprintdata
    Definition: nlpioracle.c:57
    SCIP_EXPR * expr
    Definition: nlpioracle.c:56
    SCIP_Real * varubs
    Definition: nlpioracle.c:71
    int * jaccoloffsets
    Definition: nlpioracle.c:93
    char ** varnames
    Definition: nlpioracle.c:72
    SCIP_Real * varlbs
    Definition: nlpioracle.c:70
    SCIP_Bool * jacrownlflags
    Definition: nlpioracle.c:95
    SCIP_Bool * objnlflags
    Definition: nlpioracle.c:99
    SCIP_Bool hescolwise
    Definition: nlpioracle.c:106
    SCIP_NLPIORACLECONS * objective
    Definition: nlpioracle.c:82
    SCIP_EXPRINT * exprinterpreter
    Definition: nlpioracle.c:108
    int * varlincount
    Definition: nlpioracle.c:73
    SCIP_NLPIORACLECONS ** conss
    Definition: nlpioracle.c:79
    int * varnlcount
    Definition: nlpioracle.c:74
    int * heslagoffsets
    Definition: nlpioracle.c:104
    SCIP_CLOCK * evalclock
    Definition: nlpioracle.c:109
    SCIP_Bool * jaccolnlflags
    Definition: nlpioracle.c:90
    int * jacrowoffsets
    Definition: nlpioracle.c:88
    @ SCIP_EXPRITER_DFS
    Definition: type_expr.h:718
    #define SCIP_EXPRITER_LEAVEEXPR
    Definition: type_expr.h:697
    struct SCIP_ExprIntData SCIP_EXPRINTDATA
    #define SCIP_EXPRINTCAPABILITY_ALL
    struct SCIP_ExprInt SCIP_EXPRINT
    unsigned int SCIP_EXPRINTCAPABILITY
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63