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   cons_nonlinear.h
17  * @ingroup CONSHDLRS
18  * @brief  constraint handler for nonlinear constraints \f$\textrm{lhs} \leq \sum_{i=1}^n a_ix_i + \sum_{j=1}^m c_jf_j(x) \leq \textrm{rhs}\f$
19  * @author Stefan Vigerske
20  *
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #ifndef __SCIP_CONS_NONLINEAR_H__
26 #define __SCIP_CONS_NONLINEAR_H__
27 
28 #include "scip/def.h"
29 #include "scip/type_cons.h"
30 #include "nlpi/type_expr.h"
31 #include "scip/type_nlp.h"
32 #include "scip/type_retcode.h"
33 #include "scip/type_scip.h"
34 #include "scip/type_sol.h"
35 #include "scip/type_var.h"
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /** upgrading method for nonlinear constraints into more specific constraints
42  *
43  * the method might upgrade a nonlinear constraint into a set of upgrade constraints
44  * the caller provided an array upgdconss to store upgrade constraints
45  * the length of upgdconss is given by upgdconsssize
46  * if an upgrade is not possible, set *nupgdconss to zero
47  * if more than upgdconsssize many constraints shall replace cons, the function
48  * should return the required number as negated value in *nupgdconss
49  * i.e., if cons should be replaced by 3 constraints, the function should set
50  * *nupgdconss to -3 and return with SCIP_OKAY
51  *
52  *  input:
53  *  - scip            : SCIP main data structure
54  *  - cons            : the nonlinear constraint to upgrade
55  *  - nupgdconss      : pointer to store number of constraints that replace this constraint
56  *  - upgdconss       : array to store constraints that replace this constraint
57  *  - upgdconsssize   : length of the provided upgdconss array
58  */
59 #define SCIP_DECL_NONLINCONSUPGD(x) SCIP_RETCODE x (SCIP* scip, SCIP_CONS* cons, \
60       int* nupgdconss, SCIP_CONS** upgdconss, int upgdconsssize)
61 
62 /** reformulation method for expression graph nodes
63  *
64  * The method might reformulate a node in an expression graph by adding
65  * auxiliary constraints and/or variables.
66  * The caller provided an expression graph node which is to be reformulated.
67  * If the method takes action, it has to return the node that should replace
68  * the given node in *reformnode. The caller will then ensure that all parents of
69  * node will use *reformnode, so node may be freed.
70  * If the method does not do any reformulation, it shall return NULL in *reformnode.
71  * The counter naddcons can be used to setup the names of added variables/constraints.
72  * The method should increase this counter by the number of added constraints.
73  * The method has to ensure that the reformulated node, if still valid,
74  * has valid bound and curvature information.
75  *
76  *  input:
77  *  - scip            : SCIP main data structure
78  *  - exprgraph       : the expression graph which node to reformulate
79  *  - node            : the expression graph node to reformulate
80  *  - naddcons        : counter on number of added constraints so far
81  *
82  *  output:
83  *  - naddcons        : to be increased by number of additionally added constraints
84  *  - reformnode      : reformulated node to replace node with, or NULL if no reformulation
85  */
86 #define SCIP_DECL_EXPRGRAPHNODEREFORM(x) SCIP_RETCODE x (SCIP* scip,    \
87       SCIP_EXPRGRAPH* exprgraph, SCIP_EXPRGRAPHNODE* node,              \
88       int* naddcons, SCIP_EXPRGRAPHNODE** reformnode)
89 
90 /** creates the handler for nonlinear constraints and includes it in SCIP
91  *
92  * @ingroup ConshdlrIncludes
93  * */
94 SCIP_EXPORT
95 SCIP_RETCODE SCIPincludeConshdlrNonlinear(
96    SCIP*                 scip                /**< SCIP data structure */
97    );
98 
99 /**@addtogroup CONSHDLRS
100  *
101  * @{
102  *
103  * @name Nonlinear Constraints
104  *
105  * @{
106  *
107  * This constraint handler handles constraints of the form
108  * \f[
109  *   \textrm{lhs} \leq \sum_{i=1}^n a_ix_i + \sum_{j=1}^m c_jf_j(x) \leq \textrm{rhs},
110  * \f]
111  * where \f$a_i\f$ and \f$c_j\f$ are coefficients and
112  * \f$f_j(x)\f$ are nonlinear functions (given as expression tree).
113  *
114  * Constraints are enforced by separation, domain propagation, and spatial branching.
115  *
116  * For convex or concave \f$f_j(x)\f$, cuts that separate on the convex hull of the function graph are implemented.
117  * For \f$f_j(x)\f$ that are not known to be convex or concave, a simple variant of linear estimation based on interval gradients is implemented.
118  *
119  * Branching is performed for variables in nonconvex terms, if the relaxation solution cannot be separated.
120  *
121  * This header offers the upgrade functionality to upgrade a general nonlinear constraint into a more specific constraint
122  * via SCIP_DECL_NONLINCONSUPGD().
123  *
124  * Furthermore, the definition of callbacks used to reformulate an expression graph is offered by
125  * SCIP_DECL_EXPRGRAPHNODEREFORM().
126  *
127  * Further, the function representation is stored in an expression graph, which allows to propagate variable domains
128  * and constraint sides and offers a simple convexity check.
129  * During presolve, the expression graph is reformulated, whereby new variables and constraints are created
130  * such that for the remaining nonlinear constraints the functions \f$f_j(x)\f$ are known to be convex or concave.
131  * See also
132  *
133  * @par
134  * Stefan Vigerske@n
135  * Decomposition of Multistage Stochastic Programs and a Constraint Integer Programming Approach to Mixed-Integer Nonlinear Programming@n
136  * PhD Thesis, Humboldt-University Berlin, 2012, submitted.
137  */
138 
139 /** includes a nonlinear constraint upgrade method into the nonlinear constraint handler */
140 SCIP_EXPORT
141 SCIP_RETCODE SCIPincludeNonlinconsUpgrade(
142    SCIP*                 scip,               /**< SCIP data structure */
143    SCIP_DECL_NONLINCONSUPGD((*nonlinconsupgd)),/**< method to call for upgrading nonlinear constraint, or NULL */
144    SCIP_DECL_EXPRGRAPHNODEREFORM((*nodereform)),/**< method to call for reformulating expression graph node, or NULL */
145    int                   priority,           /**< priority of upgrading method */
146    SCIP_Bool             active,             /**< should the upgrading method by active by default? */
147    const char*           conshdlrname        /**< name of the constraint handler */
148    );
149 
150 /** creates and captures a nonlinear constraint
151  * this variant takes expression trees as input
152  *
153  *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
154  */
155 SCIP_EXPORT
156 SCIP_RETCODE SCIPcreateConsNonlinear(
157    SCIP*                 scip,               /**< SCIP data structure */
158    SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
159    const char*           name,               /**< name of constraint */
160    int                   nlinvars,           /**< number of linear variables in the constraint */
161    SCIP_VAR**            linvars,            /**< array with linear variables of constraint entries */
162    SCIP_Real*            lincoefs,           /**< array with coefficients of constraint linear entries */
163    int                   nexprtrees,         /**< number of expression trees for nonlinear part of constraint */
164    SCIP_EXPRTREE**       exprtrees,          /**< expression trees for nonlinear part of constraint */
165    SCIP_Real*            nonlincoefs,        /**< coefficients for expression trees for nonlinear part, or NULL if all 1.0 */
166    SCIP_Real             lhs,                /**< left hand side of constraint */
167    SCIP_Real             rhs,                /**< right hand side of constraint */
168    SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP?
169                                               *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
170    SCIP_Bool             separate,           /**< should the constraint be separated during LP processing?
171                                               *   Usually set to TRUE. */
172    SCIP_Bool             enforce,            /**< should the constraint be enforced during node processing?
173                                               *   TRUE for model constraints, FALSE for additional, redundant constraints. */
174    SCIP_Bool             check,              /**< should the constraint be checked for feasibility?
175                                               *   TRUE for model constraints, FALSE for additional, redundant constraints. */
176    SCIP_Bool             propagate,          /**< should the constraint be propagated during node processing?
177                                               *   Usually set to TRUE. */
178    SCIP_Bool             local,              /**< is constraint only valid locally?
179                                               *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
180    SCIP_Bool             modifiable,         /**< is constraint modifiable (subject to column generation)?
181                                               *   Usually set to FALSE. In column generation applications, set to TRUE if pricing
182                                               *   adds coefficients to this constraint. */
183    SCIP_Bool             dynamic,            /**< is constraint subject to aging?
184                                               *   Usually set to FALSE. Set to TRUE for own cuts which
185                                               *   are seperated as constraints. */
186    SCIP_Bool             removable,          /**< should the relaxation be removed from the LP due to aging or cleanup?
187                                               *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
188    SCIP_Bool             stickingatnode      /**< should the constraint always be kept at the node where it was added, even
189                                               *   if it may be moved to a more global node?
190                                               *   Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
191    );
192 
193 /** creates and captures a nonlinear constraint
194  *  in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
195  *  method SCIPcreateConsNonlinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
196  *
197  *  this variant takes expression trees as input
198  *
199  *  @see SCIPcreateConsNonlinear() for information about the basic constraint flag configuration
200  *
201  *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
202  */
203 SCIP_EXPORT
204 SCIP_RETCODE SCIPcreateConsBasicNonlinear(
205    SCIP*                 scip,               /**< SCIP data structure */
206    SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
207    const char*           name,               /**< name of constraint */
208    int                   nlinvars,           /**< number of linear variables in the constraint */
209    SCIP_VAR**            linvars,            /**< array with linear variables of constraint entries */
210    SCIP_Real*            lincoefs,           /**< array with coefficients of constraint linear entries */
211    int                   nexprtrees,         /**< number of expression trees for nonlinear part of constraint */
212    SCIP_EXPRTREE**       exprtrees,          /**< expression trees for nonlinear part of constraint */
213    SCIP_Real*            nonlincoefs,        /**< coefficients for expression trees for nonlinear part, or NULL if all 1.0 */
214    SCIP_Real             lhs,                /**< left hand side of constraint */
215    SCIP_Real             rhs                 /**< right hand side of constraint */
216    );
217 
218 /** creates and captures a nonlinear constraint
219  * this variant takes a node of the expression graph as input and can only be used during presolving
220  * it is assumed that the nonlinear constraint will be added to the transformed problem short after creation
221  * the given exprgraphnode is captured in this method
222  *
223  *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
224  */
225 SCIP_EXPORT
226 SCIP_RETCODE SCIPcreateConsNonlinear2(
227    SCIP*                 scip,               /**< SCIP data structure */
228    SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
229    const char*           name,               /**< name of constraint */
230    int                   nlinvars,           /**< number of linear variables in the constraint */
231    SCIP_VAR**            linvars,            /**< array with linear variables of constraint entries */
232    SCIP_Real*            lincoefs,           /**< array with coefficients of constraint linear entries */
233    SCIP_EXPRGRAPHNODE*   exprgraphnode,      /**< expression graph node associated to nonlinear expression */
234    SCIP_Real             lhs,                /**< left hand side of constraint */
235    SCIP_Real             rhs,                /**< right hand side of constraint */
236    SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP?
237                                               *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
238    SCIP_Bool             separate,           /**< should the constraint be separated during LP processing?
239                                               *   Usually set to TRUE. */
240    SCIP_Bool             enforce,            /**< should the constraint be enforced during node processing?
241                                               *   TRUE for model constraints, FALSE for additional, redundant constraints. */
242    SCIP_Bool             check,              /**< should the constraint be checked for feasibility?
243                                               *   TRUE for model constraints, FALSE for additional, redundant constraints. */
244    SCIP_Bool             propagate,          /**< should the constraint be propagated during node processing?
245                                               *   Usually set to TRUE. */
246    SCIP_Bool             local,              /**< is constraint only valid locally?
247                                               *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
248    SCIP_Bool             modifiable,         /**< is constraint modifiable (subject to column generation)?
249                                               *   Usually set to FALSE. In column generation applications, set to TRUE if pricing
250                                               *   adds coefficients to this constraint. */
251    SCIP_Bool             dynamic,            /**< is constraint subject to aging?
252                                               *   Usually set to FALSE. Set to TRUE for own cuts which
253                                               *   are seperated as constraints. */
254    SCIP_Bool             removable,          /**< should the relaxation be removed from the LP due to aging or cleanup?
255                                               *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
256    SCIP_Bool             stickingatnode      /**< should the constraint always be kept at the node where it was added, even
257                                               *   if it may be moved to a more global node?
258                                               *   Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
259    );
260 
261 /** creates and captures a nonlinear constraint
262  *  in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
263  *  method SCIPcreateConsNonlinear2(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
264  *
265  *  this variant takes a node of the expression graph as input and can only be used during presolving
266  *  it is assumed that the nonlinear constraint will be added to the transformed problem short after creation
267  *  the given exprgraphnode is captured in this method
268  *
269  *  @see SCIPcreateConsNonlinear2() for information about the basic constraint flag configuration
270  *
271  *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
272  */
273 SCIP_EXPORT
274 SCIP_RETCODE SCIPcreateConsBasicNonlinear2(
275    SCIP*                 scip,               /**< SCIP data structure */
276    SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
277    const char*           name,               /**< name of constraint */
278    int                   nlinvars,           /**< number of linear variables in the constraint */
279    SCIP_VAR**            linvars,            /**< array with linear variables of constraint entries */
280    SCIP_Real*            lincoefs,           /**< array with coefficients of constraint linear entries */
281    SCIP_EXPRGRAPHNODE*   exprgraphnode,      /**< expression graph node associated to nonlinear expression */
282    SCIP_Real             lhs,                /**< left hand side of constraint */
283    SCIP_Real             rhs                 /**< right hand side of constraint */
284    );
285 
286 /** adds a linear variable with coefficient to a nonlinear constraint */
287 SCIP_EXPORT
288 SCIP_RETCODE SCIPaddLinearVarNonlinear(
289    SCIP*                 scip,               /**< SCIP data structure */
290    SCIP_CONS*            cons,               /**< constraint */
291    SCIP_VAR*             var,                /**< variable */
292    SCIP_Real             coef                /**< coefficient of variable */
293    );
294 
295 /** sets the expression trees in a nonlinear constraint
296  * constraint must not be active yet
297  */
298 SCIP_EXPORT
299 SCIP_RETCODE SCIPsetExprtreesNonlinear(
300    SCIP*                 scip,               /**< SCIP data structure */
301    SCIP_CONS*            cons,               /**< constraint */
302    int                   nexprtrees,         /**< number of expression trees */
303    SCIP_EXPRTREE**       exprtrees,          /**< new expression trees, or NULL if nexprtrees is 0 */
304    SCIP_Real*            coefs               /**< coefficients of expression trees, or NULL if all 1.0 */
305    );
306 
307 /** adds expression trees to a nonlinear constraint
308  * constraint must not be active yet
309  */
310 SCIP_EXPORT
311 SCIP_RETCODE SCIPaddExprtreesNonlinear(
312    SCIP*                 scip,               /**< SCIP data structure */
313    SCIP_CONS*            cons,               /**< constraint */
314    int                   nexprtrees,         /**< number of expression trees */
315    SCIP_EXPRTREE**       exprtrees,          /**< new expression trees, or NULL if nexprtrees is 0 */
316    SCIP_Real*            coefs               /**< coefficients of expression trees, or NULL if all 1.0 */
317    );
318 
319 /** gets the nonlinear constraint as a nonlinear row representation */
320 SCIP_EXPORT
321 SCIP_RETCODE SCIPgetNlRowNonlinear(
322    SCIP*                 scip,               /**< SCIP data structure */
323    SCIP_CONS*            cons,               /**< constraint */
324    SCIP_NLROW**          nlrow               /**< pointer to store nonlinear row */
325    );
326 
327 /** gets the number of variables in the linear term of a nonlinear constraint */
328 SCIP_EXPORT
329 int SCIPgetNLinearVarsNonlinear(
330    SCIP*                 scip,               /**< SCIP data structure */
331    SCIP_CONS*            cons                /**< constraint */
332    );
333 
334 /** gets the variables in the linear part of a nonlinear constraint */
335 SCIP_EXPORT
336 SCIP_VAR** SCIPgetLinearVarsNonlinear(
337    SCIP*                 scip,               /**< SCIP data structure */
338    SCIP_CONS*            cons                /**< constraint */
339    );
340 
341 /** gets the coefficients in the linear part of a nonlinear constraint */
342 SCIP_EXPORT
343 SCIP_Real* SCIPgetLinearCoefsNonlinear(
344    SCIP*                 scip,               /**< SCIP data structure */
345    SCIP_CONS*            cons                /**< constraint */
346    );
347 
348 /** gets the number of expression trees of a nonlinear constraint */
349 SCIP_EXPORT
350 int SCIPgetNExprtreesNonlinear(
351    SCIP*                 scip,               /**< SCIP data structure */
352    SCIP_CONS*            cons                /**< constraint */
353    );
354 
355 /** gets the expression trees of a nonlinear constraint */
356 SCIP_EXPORT
357 SCIP_EXPRTREE** SCIPgetExprtreesNonlinear(
358    SCIP*                 scip,               /**< SCIP data structure */
359    SCIP_CONS*            cons                /**< constraint */
360    );
361 
362 /** gets the coefficients of the expression trees of a nonlinear constraint */
363 SCIP_EXPORT
364 SCIP_Real* SCIPgetExprtreeCoefsNonlinear(
365    SCIP*                 scip,               /**< SCIP data structure */
366    SCIP_CONS*            cons                /**< constraint */
367    );
368 
369 /** gets the expression graph node of a nonlinear constraint */
370 SCIP_EXPORT
371 SCIP_EXPRGRAPHNODE* SCIPgetExprgraphNodeNonlinear(
372    SCIP*                 scip,               /**< SCIP data structure */
373    SCIP_CONS*            cons                /**< constraint */
374    );
375 
376 /** gets the left hand side of a nonlinear constraint */
377 SCIP_EXPORT
378 SCIP_Real SCIPgetLhsNonlinear(
379    SCIP*                 scip,               /**< SCIP data structure */
380    SCIP_CONS*            cons                /**< constraint */
381    );
382 
383 /** gets the right hand side of a nonlinear constraint */
384 SCIP_EXPORT
385 SCIP_Real SCIPgetRhsNonlinear(
386    SCIP*                 scip,               /**< SCIP data structure */
387    SCIP_CONS*            cons                /**< constraint */
388    );
389 
390 /** check the function of a nonlinear constraint for convexity/concavity, if not done yet */
391 SCIP_EXPORT
392 SCIP_RETCODE SCIPcheckCurvatureNonlinear(
393    SCIP*                 scip,               /**< SCIP data structure */
394    SCIP_CONS*            cons                /**< constraint */
395    );
396 
397 /** gets the curvature of the nonlinear function of a nonlinear constraint
398  *
399  * The curvature is computed by summing up the curvature for each nonlinear summand.
400  * To get the curvature for single summands, use SCIPgetExprtreeCurvaturesNonlinear().
401  */
402 SCIP_EXPORT
403 SCIP_RETCODE SCIPgetCurvatureNonlinear(
404    SCIP*                 scip,               /**< SCIP data structure */
405    SCIP_CONS*            cons,               /**< constraint */
406    SCIP_Bool             checkcurv,          /**< whether to check constraint curvature, if not checked before */
407    SCIP_EXPRCURV*        curvature           /**< pointer to store curvature of constraint */
408    );
409 
410 /** gets the curvature of the expression trees (multiplied by their coefficient) of a nonlinear constraint */
411 SCIP_EXPORT
412 SCIP_RETCODE SCIPgetExprtreeCurvaturesNonlinear(
413    SCIP*                 scip,               /**< SCIP data structure */
414    SCIP_CONS*            cons,               /**< constraint */
415    SCIP_Bool             checkcurv,          /**< whether to check constraint curvature, if not checked before */
416    SCIP_EXPRCURV**       curvatures          /**< buffer to store curvatures of exprtrees */
417    );
418 
419 /** computes the violation of a nonlinear constraint by a solution */
420 SCIP_EXPORT
421 SCIP_RETCODE SCIPgetViolationNonlinear(
422    SCIP*                 scip,               /**< SCIP data structure */
423    SCIP_CONS*            cons,               /**< constraint */
424    SCIP_SOL*             sol,                /**< solution which violation to calculate, or NULL for LP solution */
425    SCIP_Real*            violation           /**< pointer to store violation of constraint */
426    );
427 
428 /** get index of a linear variable of a nonlinear constraint that may be decreased without making any other constraint infeasible, or -1 if none */
429 SCIP_EXPORT
430 int SCIPgetLinvarMayDecreaseNonlinear(
431    SCIP*                 scip,               /**< SCIP data structure */
432    SCIP_CONS*            cons                /**< constraint */
433    );
434 
435 /** get index of a linear variable of a nonlinear constraint that may be increased without making any other constraint infeasible, or -1 if none */
436 SCIP_EXPORT
437 int SCIPgetLinvarMayIncreaseNonlinear(
438    SCIP*                 scip,               /**< SCIP data structure */
439    SCIP_CONS*            cons                /**< constraint */
440    );
441 
442 /** gets expression graph of nonlinear constraint handler */
443 SCIP_EXPORT
444 SCIP_EXPRGRAPH* SCIPgetExprgraphNonlinear(
445    SCIP*                 scip,               /**< SCIP data structure */
446    SCIP_CONSHDLR*        conshdlr            /**< nonlinear constraint handler */
447    );
448 
449 /** given three points, constructs coefficient of equation for hyperplane generated by these three points
450  * Three points a, b, and c are given.
451  * Computes coefficients alpha, beta, gamma, and delta, such that a, b, and c, satisfy
452  * alpha * x1 + beta * x2 + gamma * x3 = delta and gamma >= 0.0.
453  */
454 SCIP_EXPORT
455 SCIP_RETCODE SCIPcomputeHyperplaneThreePoints(
456    SCIP*                 scip,               /**< SCIP data structure */
457    SCIP_Real             a1,                 /**< first coordinate of a */
458    SCIP_Real             a2,                 /**< second coordinate of a */
459    SCIP_Real             a3,                 /**< third coordinate of a */
460    SCIP_Real             b1,                 /**< first coordinate of b */
461    SCIP_Real             b2,                 /**< second coordinate of b */
462    SCIP_Real             b3,                 /**< third coordinate of b */
463    SCIP_Real             c1,                 /**< first coordinate of c */
464    SCIP_Real             c2,                 /**< second coordinate of c */
465    SCIP_Real             c3,                 /**< third coordinate of c */
466    SCIP_Real*            alpha,              /**< coefficient of first coordinate */
467    SCIP_Real*            beta,               /**< coefficient of second coordinate */
468    SCIP_Real*            gamma_,             /**< coefficient of third coordinate */
469    SCIP_Real*            delta               /**< constant right-hand side */
470    );
471 
472 /** @} */
473 
474 /** @} */
475 
476 #ifdef __cplusplus
477 }
478 #endif
479 
480 #endif
481