1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /*                                                                           */
3 /*                  This file is part of the program and library             */
4 /*         SCIP --- Solving Constraint Integer Programs                      */
5 /*                                                                           */
6 /*    Copyright (C) 2002-2021 Konrad-Zuse-Zentrum                            */
7 /*                            fuer Informationstechnik Berlin                */
8 /*                                                                           */
9 /*  SCIP is distributed under the terms of the ZIB Academic License.         */
10 /*                                                                           */
11 /*  You should have received a copy of the ZIB Academic License              */
12 /*  along with SCIP; see the file COPYING. If not visit scipopt.org.         */
13 /*                                                                           */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file   nlpi.c
17  * @ingroup OTHER_CFILES
18  * @brief  methods for handling nlp interface
19  * @author Stefan Vigerske
20  * @author Thorsten Gellermann
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #include <stdio.h>
26 #include <assert.h>
27 #include <string.h>
28 
29 #include "scip/pub_message.h"
30 #include "nlpi/nlpi.h"
31 #include "nlpi/struct_nlpi.h"
32 #include "blockmemshell/memory.h"
33 
34 /** compares two NLPIs w.r.t. their priority */
SCIP_DECL_SORTPTRCOMP(SCIPnlpiComp)35 SCIP_DECL_SORTPTRCOMP(SCIPnlpiComp)
36 {  /*lint --e{715}*/
37    return ((SCIP_NLPI*)elem2)->priority - ((SCIP_NLPI*)elem1)->priority;
38 }
39 
40 /** creates an NLP solver interface */
SCIPnlpiCreate(SCIP_NLPI ** nlpi,const char * name,const char * description,int priority,SCIP_DECL_NLPICOPY ((* nlpicopy)),SCIP_DECL_NLPIFREE ((* nlpifree)),SCIP_DECL_NLPIGETSOLVERPOINTER ((* nlpigetsolverpointer)),SCIP_DECL_NLPICREATEPROBLEM ((* nlpicreateproblem)),SCIP_DECL_NLPIFREEPROBLEM ((* nlpifreeproblem)),SCIP_DECL_NLPIGETPROBLEMPOINTER ((* nlpigetproblempointer)),SCIP_DECL_NLPIADDVARS ((* nlpiaddvars)),SCIP_DECL_NLPIADDCONSTRAINTS ((* nlpiaddconstraints)),SCIP_DECL_NLPISETOBJECTIVE ((* nlpisetobjective)),SCIP_DECL_NLPICHGVARBOUNDS ((* nlpichgvarbounds)),SCIP_DECL_NLPICHGCONSSIDES ((* nlpichgconssides)),SCIP_DECL_NLPIDELVARSET ((* nlpidelvarset)),SCIP_DECL_NLPIDELCONSSET ((* nlpidelconsset)),SCIP_DECL_NLPICHGLINEARCOEFS ((* nlpichglinearcoefs)),SCIP_DECL_NLPICHGQUADCOEFS ((* nlpichgquadcoefs)),SCIP_DECL_NLPICHGEXPRTREE ((* nlpichgexprtree)),SCIP_DECL_NLPICHGNONLINCOEF ((* nlpichgnonlincoef)),SCIP_DECL_NLPICHGOBJCONSTANT ((* nlpichgobjconstant)),SCIP_DECL_NLPISETINITIALGUESS ((* nlpisetinitialguess)),SCIP_DECL_NLPISOLVE ((* nlpisolve)),SCIP_DECL_NLPIGETSOLSTAT ((* nlpigetsolstat)),SCIP_DECL_NLPIGETTERMSTAT ((* nlpigettermstat)),SCIP_DECL_NLPIGETSOLUTION ((* nlpigetsolution)),SCIP_DECL_NLPIGETSTATISTICS ((* nlpigetstatistics)),SCIP_DECL_NLPIGETWARMSTARTSIZE ((* nlpigetwarmstartsize)),SCIP_DECL_NLPIGETWARMSTARTMEMO ((* nlpigetwarmstartmemo)),SCIP_DECL_NLPISETWARMSTARTMEMO ((* nlpisetwarmstartmemo)),SCIP_DECL_NLPIGETINTPAR ((* nlpigetintpar)),SCIP_DECL_NLPISETINTPAR ((* nlpisetintpar)),SCIP_DECL_NLPIGETREALPAR ((* nlpigetrealpar)),SCIP_DECL_NLPISETREALPAR ((* nlpisetrealpar)),SCIP_DECL_NLPIGETSTRINGPAR ((* nlpigetstringpar)),SCIP_DECL_NLPISETSTRINGPAR ((* nlpisetstringpar)),SCIP_DECL_NLPISETMESSAGEHDLR ((* nlpisetmessagehdlr)),SCIP_NLPIDATA * nlpidata)41 SCIP_RETCODE SCIPnlpiCreate(
42    SCIP_NLPI**                     nlpi,                        /**< pointer to NLP interface data structure */
43    const char*                     name,                        /**< name of NLP interface */
44    const char*                     description,                 /**< description of NLP interface */
45    int                             priority,                    /**< priority of NLP interface */
46    SCIP_DECL_NLPICOPY              ((*nlpicopy)),               /**< copying an NLPI */
47    SCIP_DECL_NLPIFREE              ((*nlpifree)),               /**< free NLPI user data */
48    SCIP_DECL_NLPIGETSOLVERPOINTER  ((*nlpigetsolverpointer)),   /**< get solver pointer */
49    SCIP_DECL_NLPICREATEPROBLEM     ((*nlpicreateproblem)),      /**< create a new problem instance */
50    SCIP_DECL_NLPIFREEPROBLEM       ((*nlpifreeproblem)),        /**< free a problem instance */
51    SCIP_DECL_NLPIGETPROBLEMPOINTER ((*nlpigetproblempointer)),  /**< get problem pointer */
52    SCIP_DECL_NLPIADDVARS           ((*nlpiaddvars)),            /**< add variables */
53    SCIP_DECL_NLPIADDCONSTRAINTS    ((*nlpiaddconstraints)),     /**< add constraints */
54    SCIP_DECL_NLPISETOBJECTIVE      ((*nlpisetobjective)),       /**< set objective */
55    SCIP_DECL_NLPICHGVARBOUNDS      ((*nlpichgvarbounds)),       /**< change variable bounds */
56    SCIP_DECL_NLPICHGCONSSIDES      ((*nlpichgconssides)),       /**< change constraint sides */
57    SCIP_DECL_NLPIDELVARSET         ((*nlpidelvarset)),          /**< delete a set of constraints */
58    SCIP_DECL_NLPIDELCONSSET        ((*nlpidelconsset)),         /**< delete a set of constraints */
59    SCIP_DECL_NLPICHGLINEARCOEFS    ((*nlpichglinearcoefs)),     /**< change coefficients in linear part of a constraint or objective */
60    SCIP_DECL_NLPICHGQUADCOEFS      ((*nlpichgquadcoefs)),       /**< change coefficients in quadratic part of a constraint or objective */
61    SCIP_DECL_NLPICHGEXPRTREE       ((*nlpichgexprtree)),        /**< change nonlinear expression a constraint or objective */
62    SCIP_DECL_NLPICHGNONLINCOEF     ((*nlpichgnonlincoef)),      /**< change one parameter in nonlinear expressions of a constraint or objective */
63    SCIP_DECL_NLPICHGOBJCONSTANT    ((*nlpichgobjconstant)),     /**< change the constant offset in the objective */
64    SCIP_DECL_NLPISETINITIALGUESS   ((*nlpisetinitialguess)),    /**< set initial guess for primal variables */
65    SCIP_DECL_NLPISOLVE             ((*nlpisolve)),              /**< solve NLP */
66    SCIP_DECL_NLPIGETSOLSTAT        ((*nlpigetsolstat)),         /**< get solution status */
67    SCIP_DECL_NLPIGETTERMSTAT       ((*nlpigettermstat)),        /**< get termination status */
68    SCIP_DECL_NLPIGETSOLUTION       ((*nlpigetsolution)),        /**< get solution */
69    SCIP_DECL_NLPIGETSTATISTICS     ((*nlpigetstatistics)),      /**< get solve statistics */
70    SCIP_DECL_NLPIGETWARMSTARTSIZE  ((*nlpigetwarmstartsize)),   /**< get size for warmstart object buffer */
71    SCIP_DECL_NLPIGETWARMSTARTMEMO  ((*nlpigetwarmstartmemo)),   /**< get warmstart object */
72    SCIP_DECL_NLPISETWARMSTARTMEMO  ((*nlpisetwarmstartmemo)),   /**< set warmstart object */
73    SCIP_DECL_NLPIGETINTPAR         ((*nlpigetintpar)),          /**< get value of integer parameter */
74    SCIP_DECL_NLPISETINTPAR         ((*nlpisetintpar)),          /**< set value of integer parameter */
75    SCIP_DECL_NLPIGETREALPAR        ((*nlpigetrealpar)),         /**< get value of floating point parameter */
76    SCIP_DECL_NLPISETREALPAR        ((*nlpisetrealpar)),         /**< set value of floating point parameter */
77    SCIP_DECL_NLPIGETSTRINGPAR      ((*nlpigetstringpar)),       /**< get value of string parameter */
78    SCIP_DECL_NLPISETSTRINGPAR      ((*nlpisetstringpar)),       /**< set value of string parameter */
79    SCIP_DECL_NLPISETMESSAGEHDLR    ((*nlpisetmessagehdlr)),     /**< set message handler */
80    SCIP_NLPIDATA*                  nlpidata                     /**< NLP interface local data */
81    )
82 {  /*lint --e{715}*/
83    assert(nlpi != NULL);
84 
85    assert(name != NULL);
86    assert(description != NULL);
87    assert(nlpicopy != NULL);
88    assert(nlpifree != NULL);
89    assert(nlpigetsolverpointer != NULL);
90    assert(nlpicreateproblem != NULL);
91    assert(nlpifreeproblem != NULL);
92    assert(nlpigetproblempointer != NULL);
93    assert(nlpiaddvars != NULL);
94    assert(nlpiaddconstraints != NULL);
95    assert(nlpisetobjective != NULL);
96    assert(nlpichgvarbounds != NULL);
97    assert(nlpichgconssides != NULL);
98    assert(nlpidelconsset != NULL);
99    assert(nlpichglinearcoefs != NULL);
100    assert(nlpichgquadcoefs != NULL);
101    assert(nlpichgexprtree != NULL);
102    assert(nlpichgnonlincoef != NULL);
103    assert(nlpichgobjconstant != NULL);
104    assert(nlpisetinitialguess != NULL);
105    assert(nlpisolve != NULL);
106    assert(nlpigetsolstat != NULL);
107    assert(nlpigettermstat != NULL);
108    assert(nlpigetsolution != NULL);
109    assert(nlpigetstatistics != NULL);
110    assert(nlpigetwarmstartsize != NULL);
111    assert(nlpigetwarmstartmemo != NULL);
112    assert(nlpisetwarmstartmemo != NULL);
113    assert(nlpigetintpar != NULL);
114    assert(nlpisetintpar != NULL);
115    assert(nlpigetrealpar != NULL);
116    assert(nlpisetrealpar != NULL);
117    assert(nlpigetstringpar != NULL);
118    assert(nlpisetstringpar != NULL);
119    assert(nlpisetmessagehdlr != NULL);
120 
121    SCIP_ALLOC( BMSallocMemory(nlpi) );
122 
123    SCIP_ALLOC( BMSduplicateMemoryArray(&(*nlpi)->name, name, strlen(name)+1) );
124    SCIP_ALLOC( BMSduplicateMemoryArray(&(*nlpi)->description, description, strlen(description)+1) );
125    (*nlpi)->priority = priority;
126    (*nlpi)->nlpicopy = nlpicopy;
127    (*nlpi)->nlpifree = nlpifree;
128    (*nlpi)->nlpigetsolverpointer = nlpigetsolverpointer;
129    (*nlpi)->nlpicreateproblem = nlpicreateproblem;
130    (*nlpi)->nlpifreeproblem = nlpifreeproblem;
131    (*nlpi)->nlpigetproblempointer = nlpigetproblempointer;
132    (*nlpi)->nlpiaddvars = nlpiaddvars;
133    (*nlpi)->nlpiaddconstraints = nlpiaddconstraints;
134    (*nlpi)->nlpisetobjective = nlpisetobjective;
135    (*nlpi)->nlpichgvarbounds = nlpichgvarbounds;
136    (*nlpi)->nlpichgconssides = nlpichgconssides;
137    (*nlpi)->nlpidelvarset = nlpidelvarset;
138    (*nlpi)->nlpidelconsset = nlpidelconsset;
139    (*nlpi)->nlpichglinearcoefs = nlpichglinearcoefs;
140    (*nlpi)->nlpichgquadcoefs = nlpichgquadcoefs;
141    (*nlpi)->nlpichgexprtree = nlpichgexprtree;
142    (*nlpi)->nlpichgnonlincoef = nlpichgnonlincoef;
143    (*nlpi)->nlpichgobjconstant = nlpichgobjconstant;
144    (*nlpi)->nlpisetinitialguess = nlpisetinitialguess;
145    (*nlpi)->nlpisolve = nlpisolve;
146    (*nlpi)->nlpigetsolstat = nlpigetsolstat;
147    (*nlpi)->nlpigettermstat = nlpigettermstat;
148    (*nlpi)->nlpigetsolution = nlpigetsolution;
149    (*nlpi)->nlpigetstatistics = nlpigetstatistics;
150    (*nlpi)->nlpigetwarmstartsize = nlpigetwarmstartsize;
151    (*nlpi)->nlpigetwarmstartmemo = nlpigetwarmstartmemo;
152    (*nlpi)->nlpisetwarmstartmemo = nlpisetwarmstartmemo;
153    (*nlpi)->nlpigetintpar = nlpigetintpar;
154    (*nlpi)->nlpisetintpar = nlpisetintpar;
155    (*nlpi)->nlpigetrealpar = nlpigetrealpar;
156    (*nlpi)->nlpisetrealpar = nlpisetrealpar;
157    (*nlpi)->nlpigetstringpar = nlpigetstringpar;
158    (*nlpi)->nlpisetstringpar = nlpisetstringpar;
159    (*nlpi)->nlpisetmessagehdlr = nlpisetmessagehdlr;
160    (*nlpi)->nlpidata = nlpidata;
161 
162    return SCIP_OKAY;
163 }
164 
165 /** copies an NLPI */
SCIPnlpiCopy(BMS_BLKMEM * blkmem,SCIP_NLPI * sourcenlpi,SCIP_NLPI ** targetnlpi)166 SCIP_RETCODE SCIPnlpiCopy(
167    BMS_BLKMEM*           blkmem,             /**< block memory in target SCIP */
168    SCIP_NLPI*            sourcenlpi,         /**< pointer to NLPI data structure to copy */
169    SCIP_NLPI**           targetnlpi          /**< buffer to store pointer to copied NLPI data structure */
170    )
171 {
172    assert(blkmem     != NULL);
173    assert(sourcenlpi != NULL);
174    assert(targetnlpi != NULL);
175 
176    SCIP_CALL( (*sourcenlpi->nlpicopy)(blkmem, sourcenlpi, targetnlpi) );
177 
178    return SCIP_OKAY;
179 }
180 
181 /** frees NLPI user data */
SCIPnlpiFree(SCIP_NLPI ** nlpi)182 SCIP_RETCODE SCIPnlpiFree(
183    SCIP_NLPI**           nlpi                /**< pointer to NLPI data structure */
184    )
185 {
186    assert(nlpi  != NULL);
187    assert(*nlpi != NULL);
188 
189    SCIP_CALL( (*(*nlpi)->nlpifree)((*nlpi)) );
190    BMSfreeMemoryArray(&(*nlpi)->name);
191    BMSfreeMemoryArray(&(*nlpi)->description);
192    BMSfreeMemory(nlpi);
193 
194    assert(*nlpi == NULL);
195 
196    return SCIP_OKAY;
197 }
198 
199 /** gets pointer for NLP solver
200  * @return void pointer to solver
201  */
SCIPnlpiGetSolverPointer(SCIP_NLPI * nlpi)202 void* SCIPnlpiGetSolverPointer(
203    SCIP_NLPI*            nlpi                /**< pointer to NLPI datastructure */
204    )
205 {
206    assert(nlpi != NULL);
207 
208    return (*nlpi->nlpigetsolverpointer)(nlpi);
209 }
210 
211 /** creates a problem instance */
SCIPnlpiCreateProblem(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM ** problem,const char * name)212 SCIP_RETCODE SCIPnlpiCreateProblem(
213    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
214    SCIP_NLPIPROBLEM**    problem,            /**< pointer to store problem data */
215    const char*           name                /**< name of problem, can be NULL */
216    )
217 {
218    assert(nlpi    != NULL);
219    assert(problem != NULL);
220 
221    return (*nlpi->nlpicreateproblem)(nlpi, problem, name);
222 }
223 
224 /** frees a problem instance */
SCIPnlpiFreeProblem(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM ** problem)225 SCIP_RETCODE SCIPnlpiFreeProblem(
226    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
227    SCIP_NLPIPROBLEM**    problem             /**< pointer where problem data is stored */
228    )
229 {
230    assert(nlpi    != NULL);
231    assert(problem != NULL);
232 
233    return (*nlpi->nlpifreeproblem)(nlpi, problem);
234 }
235 
236 /** gets pointer to solver-internal problem instance
237  * @return void pointer to problem instance
238  */
SCIPnlpiGetProblemPointer(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem)239 void* SCIPnlpiGetProblemPointer(
240    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
241    SCIP_NLPIPROBLEM*     problem             /**< pointer where problem data is stored */
242    )
243 {
244    assert(nlpi    != NULL);
245    assert(problem != NULL);
246 
247    return (*nlpi->nlpigetproblempointer)(nlpi, problem);
248 }
249 
250 /** add variables to nlpi */
SCIPnlpiAddVars(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,int nvars,const SCIP_Real * lbs,const SCIP_Real * ubs,const char ** varnames)251 SCIP_RETCODE SCIPnlpiAddVars(
252    SCIP_NLPI*            nlpi,               /**< pointer to NLPI data structure */
253    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
254    int                   nvars,              /**< number of variables */
255    const SCIP_Real*      lbs,                /**< lower bounds of variables, can be NULL if -infinity */
256    const SCIP_Real*      ubs,                /**< ubs upper bounds of variables, can be NULL if +infinity */
257    const char**          varnames            /**< varnames names of variables, can be NULL */
258    )
259 {
260    assert(nlpi    != NULL);
261    assert(problem != NULL);
262 
263    SCIP_CALL( (*nlpi->nlpiaddvars)(nlpi, problem, nvars, lbs, ubs, varnames) );
264 
265    return SCIP_OKAY;
266 }
267 
268 /** add constraints to nlpi */
SCIPnlpiAddConstraints(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,int nconss,const SCIP_Real * lhss,const SCIP_Real * rhss,const int * nlininds,int * const * lininds,SCIP_Real * const * linvals,const int * nquadelems,SCIP_QUADELEM * const * quadelems,int * const * exprvaridxs,SCIP_EXPRTREE * const * exprtrees,const char ** names)269 SCIP_RETCODE SCIPnlpiAddConstraints(
270    SCIP_NLPI*            nlpi,               /**< pointer to NLPI data structure */
271    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
272    int                   nconss,             /**< number of added constraints */
273    const SCIP_Real*      lhss,               /**< left hand sides of constraints */
274    const SCIP_Real*      rhss,               /**< right hand sides of constraints */
275    const int*            nlininds,           /**< number of linear coefficients for each constraint, may be NULL in case of no linear part */
276    int* const*           lininds,            /**< indices of variables for linear coefficients for each constraint, may be NULL in case of no linear part */
277    SCIP_Real* const*     linvals,            /**< values of linear coefficient for each constraint, may be NULL in case of no linear part */
278    const int*            nquadelems,         /**< number of elements in matrix of quadratic part for each constraint,
279                                               * may be NULL in case of no quadratic part in any constraint */
280    SCIP_QUADELEM* const* quadelems,          /**< quadratic elements specifying quadratic part for each constraint, entry of array may be NULL in case of no quadratic part,
281                                               * may be NULL in case of no quadratic part in any constraint */
282    int* const*           exprvaridxs,        /**< indices of variables in expression tree, maps variable indices in expression
283                                               * tree to indices in nlp, entry of array may be NULL in case of no expression
284                                               * tree, may be NULL in case of no expression tree in any constraint */
285    SCIP_EXPRTREE* const* exprtrees,          /**< exprtrees expression tree for nonquadratic part of constraints, entry of
286                                               * array may be NULL in case of no nonquadratic part, may be NULL in case of no
287                                               * nonquadratic part in any constraint */
288    const char**          names               /**< names of constraints, may be NULL or entries may be NULL */
289    )
290 {
291    assert(nlpi    != NULL);
292    assert(problem != NULL);
293 
294    SCIP_CALL( (*nlpi->nlpiaddconstraints)(nlpi, problem, nconss, lhss, rhss, nlininds, lininds, linvals,
295          nquadelems, quadelems, exprvaridxs, exprtrees, names) );
296 
297    return SCIP_OKAY;
298 }
299 
300 /** sets or overwrites objective, a minimization problem is expected */
SCIPnlpiSetObjective(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,int nlins,const int * lininds,const SCIP_Real * linvals,int nquadelems,const SCIP_QUADELEM * quadelems,const int * exprvaridxs,const SCIP_EXPRTREE * exprtree,const SCIP_Real constant)301 SCIP_RETCODE SCIPnlpiSetObjective(
302    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
303    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
304    int                   nlins,              /**< number of linear variables */
305    const int*            lininds,            /**< variable indices, may be NULL in case of no linear part */
306    const SCIP_Real*      linvals,            /**< coefficient values, may be NULL in case of no linear part */
307    int                   nquadelems,         /**< number of entries in matrix of quadratic part */
308    const SCIP_QUADELEM*  quadelems,          /**< entries in matrix of quadratic part, may be NULL in case of no quadratic part */
309    const int*            exprvaridxs,        /**< indices of variables in expression tree, maps variable indices in expression
310                                               * tree to indices in nlp, may be NULL in case of no expression tree */
311    const SCIP_EXPRTREE*  exprtree,           /**< expression tree for nonquadratic part of objective function, may be NULL in
312                                               * case of no nonquadratic part */
313    const SCIP_Real       constant            /**< objective value offset*/
314    )
315 {
316    assert(nlpi    != NULL);
317    assert(problem != NULL);
318 
319    SCIP_CALL( (*nlpi->nlpisetobjective)(nlpi, problem, nlins, lininds, linvals, nquadelems, quadelems,
320          exprvaridxs, exprtree, constant) );
321 
322    return SCIP_OKAY;
323 }
324 
325 /** change variable bounds */
SCIPnlpiChgVarBounds(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,int nvars,const int * indices,const SCIP_Real * lbs,const SCIP_Real * ubs)326 SCIP_RETCODE SCIPnlpiChgVarBounds(
327    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
328    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
329    int                   nvars,              /**< number of variables to change bounds */
330    const int*            indices,            /**< indices of variables to change bounds */
331    const SCIP_Real*      lbs,                /**< new lower bounds */
332    const SCIP_Real*      ubs                 /**< new upper bounds */
333    )
334 {
335    assert(nlpi    != NULL);
336    assert(problem != NULL);
337 
338    SCIP_CALL( (*nlpi->nlpichgvarbounds)(nlpi, problem, nvars, indices, lbs, ubs) );
339 
340    return SCIP_OKAY;
341 }
342 
343 /** change constraint bounds */
SCIPnlpiChgConsSides(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,int nconss,const int * indices,const SCIP_Real * lhss,const SCIP_Real * rhss)344 SCIP_RETCODE SCIPnlpiChgConsSides(
345    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
346    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
347    int                   nconss,             /**< number of constraints to change sides */
348    const int*            indices,            /**< indices of constraints to change sides */
349    const SCIP_Real*      lhss,               /**< new left hand sides */
350    const SCIP_Real*      rhss                /**< new right hand sides */
351    )
352 {
353    assert(nlpi    != NULL);
354    assert(problem != NULL);
355 
356    SCIP_CALL( (*nlpi->nlpichgconssides)(nlpi, problem, nconss, indices, lhss, rhss) );
357 
358    return SCIP_OKAY;
359 }
360 
361 /** delete a set of variables */
SCIPnlpiDelVarSet(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,int * dstats,int dstatssize)362 SCIP_RETCODE SCIPnlpiDelVarSet(
363    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
364    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
365    int*                  dstats,             /**< deletion status of vars; 1 if var should be deleted, 0 if not; afterwards -1
366                                               * if var was deleted */
367    int                   dstatssize          /**< size of the dstats array */
368    )
369 {
370    assert(nlpi    != NULL);
371    assert(problem != NULL);
372 
373    SCIP_CALL( (*nlpi->nlpidelvarset)(nlpi, problem, dstats, dstatssize) );
374 
375    return SCIP_OKAY;
376 }
377 
378 /** delete a set of constraints */
SCIPnlpiDelConsSet(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,int * dstats,int dstatssize)379 SCIP_RETCODE SCIPnlpiDelConsSet(
380    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
381    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
382    int*                  dstats,             /**< deletion status of rows; 1 if row should be deleted, 0 if not; afterwards -1
383                                               * if row was deleted */
384    int                   dstatssize          /**< size of the dstats array */
385    )
386 {
387    assert(nlpi    != NULL);
388    assert(problem != NULL);
389 
390    SCIP_CALL( (*nlpi->nlpidelconsset)(nlpi, problem, dstats, dstatssize) );
391 
392    return SCIP_OKAY;
393 }
394 
395 /** changes or adds linear coefficients in a constraint or objective */
SCIPnlpiChgLinearCoefs(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,const int idx,int nvals,const int * varidxs,const SCIP_Real * vals)396 SCIP_RETCODE SCIPnlpiChgLinearCoefs(
397    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
398    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
399    const int             idx,                /**< index of constraint or -1 for objective */
400    int                   nvals,              /**< number of values in linear constraint */
401    const int*            varidxs,            /**< indices of variable */
402    const SCIP_Real*      vals                /**< new values for coefficient */
403    )
404 {
405    assert(nlpi    != NULL);
406    assert(problem != NULL);
407 
408    SCIP_CALL( (*nlpi->nlpichglinearcoefs)(nlpi, problem, idx, nvals, varidxs, vals) );
409 
410    return SCIP_OKAY;
411 }
412 
413 /** changes or adds coefficients in the quadratic part of a constraint or objective */
SCIPnlpiChgQuadCoefs(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,int idx,int nquadelems,const SCIP_QUADELEM * quadelems)414 SCIP_RETCODE SCIPnlpiChgQuadCoefs(
415    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
416    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
417    int                   idx,                /**< index of constraint or -1 for objective */
418    int                   nquadelems,         /**< number of entries in quadratic constraint to change */
419    const SCIP_QUADELEM*  quadelems           /**< new elements in quadratic matrix (replacing already existing ones or adding new ones) */
420    )
421 {
422    assert(nlpi    != NULL);
423    assert(problem != NULL);
424 
425    SCIP_CALL( (*nlpi->nlpichgquadcoefs)(nlpi, problem, idx, nquadelems, quadelems) );
426 
427    return SCIP_OKAY;
428 }
429 
430 /** change the expression tree in the nonlinear part */
SCIPnlpiChgExprtree(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,int idxcons,const int * exprvaridxs,const SCIP_EXPRTREE * exprtree)431 SCIP_RETCODE SCIPnlpiChgExprtree(
432    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
433    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
434    int                   idxcons,            /**< index of constraint or -1 for objective */
435    const int*            exprvaridxs,        /**< indices of variables in expression tree, maps variable indices in expression tree to indices in nlp, or NULL */
436    const SCIP_EXPRTREE*  exprtree            /**< new expression tree, or NULL for no tree */
437    )
438 {
439    assert(nlpi    != NULL);
440    assert(problem != NULL);
441 
442    SCIP_CALL( (*nlpi->nlpichgexprtree)(nlpi, problem, idxcons, exprvaridxs, exprtree) );
443 
444    return SCIP_OKAY;
445 }
446 
447 /** change the value of one parameter in the nonlinear part */
SCIPnlpiChgNonlinCoef(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,int considx,int paramidx,SCIP_Real value)448 SCIP_RETCODE SCIPnlpiChgNonlinCoef(
449    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
450    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
451    int                   considx,            /**< index of constraint or -1 for objective */
452    int                   paramidx,           /**< index of parameter */
453    SCIP_Real             value               /**< new value for nonlinear parameter */
454    )
455 {
456    assert(nlpi    != NULL);
457    assert(problem != NULL);
458 
459    SCIP_CALL( (*nlpi->nlpichgnonlincoef)(nlpi, problem, considx, paramidx, value) );
460 
461    return SCIP_OKAY;
462 }
463 
464 /** change the constant offset in the objective */
SCIPnlpiChgObjConstant(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,SCIP_Real objconstant)465 SCIP_RETCODE SCIPnlpiChgObjConstant(
466    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
467    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
468    SCIP_Real             objconstant         /**< new value for objective constant */
469    )
470 {
471    assert(nlpi    != NULL);
472    assert(problem != NULL);
473 
474    SCIP_CALL( (*nlpi->nlpichgobjconstant)(nlpi, problem, objconstant) );
475 
476    return SCIP_OKAY;
477 }
478 
479 /** sets initial guess for primal variables */
SCIPnlpiSetInitialGuess(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,SCIP_Real * primalvalues,SCIP_Real * consdualvalues,SCIP_Real * varlbdualvalues,SCIP_Real * varubdualvalues)480 SCIP_RETCODE SCIPnlpiSetInitialGuess(
481    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
482    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
483    SCIP_Real*            primalvalues,       /**< initial primal values for variables, or NULL to clear previous values */
484    SCIP_Real*            consdualvalues,     /**< initial dual values for constraints, or NULL to clear previous values */
485    SCIP_Real*            varlbdualvalues,    /**< initial dual values for variable lower bounds, or NULL to clear previous values */
486    SCIP_Real*            varubdualvalues     /**< initial dual values for variable upper bounds, or NULL to clear previous values */
487    )
488 {
489    assert(nlpi    != NULL);
490    assert(problem != NULL);
491 
492    SCIP_CALL( (*nlpi->nlpisetinitialguess)(nlpi, problem, primalvalues, consdualvalues, varlbdualvalues, varubdualvalues) );
493 
494    return SCIP_OKAY;
495 }
496 
497 /** tries to solve NLP */
SCIPnlpiSolve(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem)498 SCIP_RETCODE SCIPnlpiSolve(
499    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
500    SCIP_NLPIPROBLEM*     problem             /**< pointer to problem data structure */
501    )
502 {
503    assert(nlpi    != NULL);
504    assert(problem != NULL);
505 
506    SCIP_CALL( (*nlpi->nlpisolve)(nlpi, problem) );
507 
508    return SCIP_OKAY;
509 }
510 
511 /** gives solution status, return: Solution Status */
SCIPnlpiGetSolstat(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem)512 SCIP_NLPSOLSTAT SCIPnlpiGetSolstat(
513    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
514    SCIP_NLPIPROBLEM*     problem             /**< pointer to problem data structure */
515    )
516 {
517    assert(nlpi    != NULL);
518    assert(problem != NULL);
519 
520    return (*nlpi->nlpigetsolstat)(nlpi, problem);
521 }
522 
523 /** gives termination reason; return: Termination Status */
SCIPnlpiGetTermstat(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem)524 SCIP_NLPTERMSTAT SCIPnlpiGetTermstat(
525    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
526    SCIP_NLPIPROBLEM*     problem             /**< pointer to problem data structure */
527    )
528 {
529    assert(nlpi    != NULL);
530    assert(problem != NULL);
531 
532    return (*nlpi->nlpigettermstat)(nlpi, problem);
533 }
534 
535 /** gives primal and dual solution
536   * for a ranged constraint, the dual variable is positive if the right hand side is active and negative if the left hand side is active
537   */
SCIPnlpiGetSolution(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,SCIP_Real ** primalvalues,SCIP_Real ** consdualvalues,SCIP_Real ** varlbdualvalues,SCIP_Real ** varubdualvalues,SCIP_Real * objval)538 SCIP_RETCODE SCIPnlpiGetSolution(
539    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
540    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
541    SCIP_Real**           primalvalues,       /**< buffer to store pointer to array to primal values, or NULL if not needed */
542    SCIP_Real**           consdualvalues,     /**< buffer to store pointer to array to dual values of constraints, or NULL if not needed */
543    SCIP_Real**           varlbdualvalues,    /**< buffer to store pointer to array to dual values of variable lower bounds, or NULL if not needed */
544    SCIP_Real**           varubdualvalues,    /**< buffer to store pointer to array to dual values of variable lower bounds, or NULL if not needed */
545    SCIP_Real*            objval              /**< buffer to store the objective value, or NULL if not needed */
546    )
547 {
548    assert(nlpi    != NULL);
549    assert(problem != NULL);
550 
551    SCIP_CALL( (*nlpi->nlpigetsolution)(nlpi, problem, primalvalues, consdualvalues, varlbdualvalues, varubdualvalues, objval) );
552 
553    return SCIP_OKAY;
554 }
555 
556 /** gives solve statistics */
SCIPnlpiGetStatistics(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,SCIP_NLPSTATISTICS * statistics)557 SCIP_RETCODE SCIPnlpiGetStatistics(
558    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
559    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
560    SCIP_NLPSTATISTICS*   statistics          /**< pointer to store statistics */
561    )
562 {
563    assert(nlpi    != NULL);
564    assert(problem != NULL);
565 
566    SCIP_CALL( (*nlpi->nlpigetstatistics)(nlpi, problem, statistics) );
567 
568    return SCIP_OKAY;
569 }
570 
571 /** gives required size of a buffer to store a warmstart object */
SCIPnlpiGetWarmstartSize(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,size_t * size)572 SCIP_RETCODE SCIPnlpiGetWarmstartSize(
573    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
574    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
575    size_t*               size                /**< pointer to store required size for warmstart buffer */
576    )
577 {
578    assert(nlpi    != NULL);
579    assert(problem != NULL);
580 
581    SCIP_CALL( (*nlpi->nlpigetwarmstartsize)(nlpi, problem, size) );
582 
583    return SCIP_OKAY;
584 }
585 
586 /** stores warmstart information in buffer */
SCIPnlpiGetWarmstartMemo(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,void * buffer)587 SCIP_RETCODE SCIPnlpiGetWarmstartMemo(
588    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
589    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
590    void*                 buffer              /**< memory to store warmstart information */
591    )
592 {
593    assert(nlpi    != NULL);
594    assert(problem != NULL);
595 
596    SCIP_CALL( (*nlpi->nlpigetwarmstartmemo)(nlpi, problem, buffer) );
597 
598    return SCIP_OKAY;
599 }
600 
601 /** sets warmstart information in solver */
SCIPnlpiSetWarmstartMemo(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,void * buffer)602 SCIP_RETCODE SCIPnlpiSetWarmstartMemo(
603    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
604    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
605    void*                 buffer              /**< warmstart information */
606    )
607 {
608    assert(nlpi    != NULL);
609    assert(problem != NULL);
610 
611    SCIP_CALL( (*nlpi->nlpisetwarmstartmemo)(nlpi, problem, buffer) );
612 
613    return SCIP_OKAY;
614 }
615 
616 /**@name Parameter Methods */
617 /**@{ */
618 
619 /** gets integer parameter of NLP */
SCIPnlpiGetIntPar(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,SCIP_NLPPARAM type,int * ival)620 SCIP_RETCODE SCIPnlpiGetIntPar(
621    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
622    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
623    SCIP_NLPPARAM         type,               /**< parameter number */
624    int*                  ival                /**< pointer to store the parameter value */
625    )
626 {
627    assert(nlpi    != NULL);
628    assert(problem != NULL);
629    assert(ival    != NULL);
630 
631    SCIP_CALL( (*nlpi->nlpigetintpar)(nlpi, problem, type, ival) );
632 
633    return SCIP_OKAY;
634 }
635 
636 /** sets integer parameter of NLP */
SCIPnlpiSetIntPar(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,SCIP_NLPPARAM type,int ival)637 SCIP_RETCODE SCIPnlpiSetIntPar(
638    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
639    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
640    SCIP_NLPPARAM         type,               /**< parameter number */
641    int                   ival                /**< parameter value */
642    )
643 {
644    assert(nlpi    != NULL);
645    assert(problem != NULL);
646 
647    SCIP_CALL( (*nlpi->nlpisetintpar)(nlpi, problem, type, ival) );
648 
649    return SCIP_OKAY;
650 }
651 
652 /** gets floating point parameter of NLP
653  * if problem is NULL and type == SCIP_NLPPAR_INFINITY, then gets solver-wide value for infinity */
SCIPnlpiGetRealPar(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,SCIP_NLPPARAM type,SCIP_Real * dval)654 SCIP_RETCODE SCIPnlpiGetRealPar(
655    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
656    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure, can be NULL only if type == SCIP_NLPPAR_INFINITY */
657    SCIP_NLPPARAM         type,               /**< parameter number */
658    SCIP_Real*            dval                /**< pointer to store the parameter value */
659    )
660 {
661    assert(nlpi    != NULL);
662    assert(problem != NULL || type == SCIP_NLPPAR_INFINITY);
663    assert(dval    != NULL);
664 
665    SCIP_CALL( (*nlpi->nlpigetrealpar)(nlpi, problem, type, dval) );
666 
667    return SCIP_OKAY;
668 }
669 
670 /** sets floating point parameter of NLP
671  * if problem is NULL and type == SCIP_NLPPAR_INFINITY, then sets solver-wide value for infinity */
SCIPnlpiSetRealPar(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,SCIP_NLPPARAM type,SCIP_Real dval)672 SCIP_RETCODE SCIPnlpiSetRealPar(
673    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
674    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure, can be NULL only if type == SCIP_NLPPAR_INFINITY */
675    SCIP_NLPPARAM         type,               /**< parameter number */
676    SCIP_Real             dval                /**< parameter value */
677    )
678 {
679    assert(nlpi    != NULL);
680    assert(problem != NULL || type == SCIP_NLPPAR_INFINITY);
681 
682    SCIP_CALL( (*nlpi->nlpisetrealpar)(nlpi, problem, type, dval) );
683 
684    return SCIP_OKAY;
685 }
686 
687 /** gets string parameter of NLP */
SCIPnlpiGetStringPar(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,SCIP_NLPPARAM type,const char ** sval)688 SCIP_RETCODE SCIPnlpiGetStringPar(
689    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
690    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
691    SCIP_NLPPARAM         type,               /**< parameter number */
692    const char**          sval                /**< pointer to store the parameter value, the user must not modify the string */
693    )
694 {
695    assert(nlpi    != NULL);
696    assert(problem != NULL);
697    assert(sval    != NULL);
698 
699    SCIP_CALL( (*nlpi->nlpigetstringpar)(nlpi, problem, type, sval) );
700 
701    return SCIP_OKAY;
702 }
703 
704 /** sets string parameter of NLP */
SCIPnlpiSetStringPar(SCIP_NLPI * nlpi,SCIP_NLPIPROBLEM * problem,SCIP_NLPPARAM type,const char * sval)705 SCIP_RETCODE SCIPnlpiSetStringPar(
706    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
707    SCIP_NLPIPROBLEM*     problem,            /**< pointer to problem data structure */
708    SCIP_NLPPARAM         type,               /**< parameter number */
709    const char*           sval                /**< parameter value */
710    )
711 {
712    assert(nlpi    != NULL);
713    assert(problem != NULL);
714 
715    SCIP_CALL( (*nlpi->nlpisetstringpar)(nlpi, problem, type, sval) );
716 
717    return SCIP_OKAY;
718 }
719 /**@} */
720 
721 /** sets message handler for message output */
SCIPnlpiSetMessageHdlr(SCIP_NLPI * nlpi,SCIP_MESSAGEHDLR * messagehdlr)722 SCIP_RETCODE SCIPnlpiSetMessageHdlr(
723    SCIP_NLPI*            nlpi,               /**< pointer to NLPI datastructure */
724    SCIP_MESSAGEHDLR*     messagehdlr         /**< pointer to message handler, or NULL to suppress all output */
725    )
726 {
727    assert(nlpi != NULL);
728 
729    SCIP_CALL( (*nlpi->nlpisetmessagehdlr)(nlpi, messagehdlr) );
730 
731    return SCIP_OKAY;
732 }
733 
734 /** gets data of an NLPI */
SCIPnlpiGetData(SCIP_NLPI * nlpi)735 SCIP_NLPIDATA* SCIPnlpiGetData(
736    SCIP_NLPI*            nlpi                /**< NLP interface structure */
737    )
738 {
739    assert(nlpi != NULL);
740 
741    return nlpi->nlpidata;
742 }
743 
744 /** gets NLP solver name */
SCIPnlpiGetName(SCIP_NLPI * nlpi)745 const char* SCIPnlpiGetName(
746    SCIP_NLPI*            nlpi                /**< NLP interface structure */
747    )
748 {
749    assert(nlpi != NULL);
750 
751    return nlpi->name;
752 }
753 
754 /** gets NLP solver descriptions */
SCIPnlpiGetDesc(SCIP_NLPI * nlpi)755 const char* SCIPnlpiGetDesc(
756    SCIP_NLPI*            nlpi                /**< NLP interface structure */
757    )
758 {
759    assert(nlpi != NULL);
760 
761    return nlpi->description;
762 }
763 
764 /** gets NLP solver priority */
SCIPnlpiGetPriority(SCIP_NLPI * nlpi)765 int SCIPnlpiGetPriority(
766    SCIP_NLPI*            nlpi                /**< NLP interface structure */
767    )
768 {
769    assert(nlpi != NULL);
770 
771    return nlpi->priority;
772 }
773 
774 /** sets NLP solver priority */
SCIPnlpiSetPriority(SCIP_NLPI * nlpi,int priority)775 void SCIPnlpiSetPriority(
776    SCIP_NLPI*            nlpi,               /**< NLP interface structure */
777    int                   priority            /**< new priority of NLPI */
778    )
779 {
780    assert(nlpi != NULL);
781 
782    nlpi->priority = priority;
783 }
784 
785 /** creates an NLP statistics structure */
SCIPnlpStatisticsCreate(BMS_BLKMEM * blkmem,SCIP_NLPSTATISTICS ** statistics)786 SCIP_RETCODE SCIPnlpStatisticsCreate(
787    BMS_BLKMEM*           blkmem,             /**< block memory */
788    SCIP_NLPSTATISTICS**  statistics          /**< pointer where to store NLP statistics structure */
789    )
790 {
791    assert(blkmem != NULL);
792    assert(statistics != NULL);
793 
794    SCIP_ALLOC( BMSallocBlockMemory(blkmem, statistics) );
795 
796    (*statistics)->niterations = -1;
797    (*statistics)->totaltime = -1.0;
798 
799    return SCIP_OKAY;
800 }
801 
802 /** frees an NLP statistics structure */
SCIPnlpStatisticsFree(BMS_BLKMEM * blkmem,SCIP_NLPSTATISTICS ** statistics)803 void SCIPnlpStatisticsFree(
804    BMS_BLKMEM*           blkmem,             /**< block memory */
805    SCIP_NLPSTATISTICS**  statistics          /**< pointer where to store NLP statistics structure */
806    )
807 {
808    assert(blkmem != NULL);
809    assert(statistics != NULL);
810    assert(*statistics != NULL);
811 
812    BMSfreeBlockMemory(blkmem, statistics);
813 
814    assert(*statistics == NULL);
815 }
816 
817 /** gets the number of iterations from an NLP statistics structure */
SCIPnlpStatisticsGetNIterations(SCIP_NLPSTATISTICS * statistics)818 int SCIPnlpStatisticsGetNIterations(
819    SCIP_NLPSTATISTICS*   statistics          /**< NLP statistics structure */
820    )
821 {
822    assert(statistics != NULL);
823 
824    return statistics->niterations;
825 }
826 
827 /** gets the total time from an NLP statistics structure */
SCIPnlpStatisticsGetTotalTime(SCIP_NLPSTATISTICS * statistics)828 SCIP_Real SCIPnlpStatisticsGetTotalTime(
829    SCIP_NLPSTATISTICS*   statistics          /**< NLP statistics structure */
830    )
831 {
832    assert(statistics != NULL);
833 
834    return statistics->totaltime;
835 }
836 
837 /** sets the number of iterations in an NLP statistics structure */
SCIPnlpStatisticsSetNIterations(SCIP_NLPSTATISTICS * statistics,int niterations)838 void SCIPnlpStatisticsSetNIterations(
839    SCIP_NLPSTATISTICS*   statistics,         /**< NLP statistics structure */
840    int                   niterations         /**< number of iterations to store */
841    )
842 {
843    assert(statistics != NULL);
844    statistics->niterations = niterations;
845 }
846 
847 /** sets the total time in an NLP statistics structure */
SCIPnlpStatisticsSetTotalTime(SCIP_NLPSTATISTICS * statistics,SCIP_Real totaltime)848 void SCIPnlpStatisticsSetTotalTime(
849    SCIP_NLPSTATISTICS*   statistics,         /**< NLP statistics structure */
850    SCIP_Real             totaltime           /**< solution time to store */
851    )
852 {
853    assert(statistics != NULL);
854    statistics->totaltime = totaltime;
855 }
856