Scippy

SCIP

Solving Constraint Integer Programs

lpi_xprs.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-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 lpi_xprs.c
17  * @ingroup LPIS
18  * @brief LP interface for Xpress-MP
19  * @author Tobias Achterberg
20  * @author Michael Perregaard
21  * @author Livio Bertacco
22  * @author Stefan Heinz
23  *
24  * This interface was revised for Xpress 26. Therefore, we removed all legacy code.
25  *
26  * Xpress requires that column and row names are unique. Since column and row names are not needed we ignore all column
27  * and row names to avoid the uniqueness issue.
28  */
29 
30 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31 
32 #include <assert.h>
33 #include <string.h>
34 #if defined(_WIN32) || defined(_WIN64)
35 #else
36 #include <strings.h> /*lint --e{766}*/
37 #endif
38 
39 #include "xprs.h"
40 #include "scip/bitencode.h"
41 #include "scip/pub_misc.h"
42 #include "scip/pub_message.h"
43 #include "lpi/lpi.h"
44 
45 #ifndef XPRS_LPQUICKPRESOLVE
46 #define XPRS_LPQUICKPRESOLVE 8207
47 #endif
48 
49 /* For SCIP we need an extra LP status which is optimal with scaled infeasibilities. */
50 #define XPRS_LP_OPTIMAL_SCALEDINFEAS 16
51 
52 #define CHECK_ZERO(messagehdlr, x) { int _restat_; \
53  if( (_restat_ = (x)) != 0 ) \
54  { \
55  SCIPmessagePrintWarning((messagehdlr), "%s:%d: LP Error: Xpress returned %d\n", __FILE__, __LINE__, _restat_); \
56  return SCIP_LPERROR; \
57  } \
58  }
59 
60 /* this macro is only called in functions returning SCIP_Bool; thus, we return retval if there is an error in optimized mode */
61 #define ABORT_ZERO(messagehdlr, retval, x) { int _restat_; \
62  if( (_restat_ = (x)) != 0 ) \
63  { \
64  SCIPmessagePrintWarning((messagehdlr), "LP Error: Xpress returned %d\n", _restat_); \
65  SCIPABORT(); \
66  return retval; \
67  } \
68  }
69 
70 
71 typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
72 #define COLS_PER_PACKET SCIP_DUALPACKETSIZE
73 typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
74 #define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
75 
76 /** LP interface */
77 struct SCIP_LPi
78 {
79  XPRSprob xprslp; /**< Xpress LP pointer */
80  char name[200]; /**< problem name */
81 
82  SCIP_PRICING pricing; /**< SCIP pricing setting */
83  int notfromscratch; /**< do we not want to solve the lp from scratch */
84  int solstat; /**< solution status of last optimization call */
85  char solmethod; /**< method used to solve the LP */
86 
87  char* larray; /**< array with 'L' entries for changing lower bounds */
88  char* uarray; /**< array with 'U' entries for changing upper bounds */
89  char* senarray; /**< array for storing row senses */
90  SCIP_Real* rhsarray; /**< array for storing rhs values */
91  SCIP_Real* rngarray; /**< array for storing range values */
92  SCIP_Real* valarray; /**< array for storing coefficient values */
93  int* cstat; /**< array for storing column basis status */
94  int* rstat; /**< array for storing row basis status (row status w.r.t. slack columns) */
95  int* indarray; /**< array for storing coefficient indices */
96 
97  int boundchgsize; /**< size of larray and uarray */
98  int sidechgsize; /**< size of senarray and rngarray */
99  int valsize; /**< size of valarray and indarray */
100  int cstatsize; /**< size of cstat array */
101  int rstatsize; /**< size of rstat array */
102 
103  int iterations; /**< number of iterations used in the last solving call */
104  SCIP_Bool solisbasic; /**< is current LP solution a basic solution? */
105  SCIP_Bool clearstate; /**< should the current basis be ignored with the next LP solve */
106 
107  SCIP_Real par_lobjlim; /**< objective lower bound */
108  SCIP_Real par_uobjlim; /**< objective upper bound */
109  int par_fastlp; /**< special meta parameter for making LP reoptimize go faster */
110  int par_presolve; /**< need to distinguish between the users setting and the optimizer setting of presolve */
111 
112  SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
113 };
114 
115 /** LPi state stores basis information */
116 struct SCIP_LPiState
117 {
118  int ncols; /**< number of LP columns */
119  int nrows; /**< number of LP rows */
120  COLPACKET* packcstat; /**< column basis status in compressed form */
121  ROWPACKET* packrstat; /**< row basis status in compressed form (row status w.r.t. slack columns) */
122 };
123 
124 /**@name Debug check methods
125  *
126  * @{
127  */
128 
129 #ifndef NDEBUG
130 
131 /** check that the column range fits */
132 static
134  SCIP_LPI* lpi, /**< LP interface structure */
135  int firstcol, /**< first column to be deleted */
136  int lastcol /**< last column to be deleted */
137  )
138 {
139  int ncols;
140 
141  (void)XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols);
142  assert(0 <= firstcol && firstcol <= lastcol && lastcol < ncols);
143 }
144 
145 /** check that the row range fits */
146 static
148  SCIP_LPI* lpi, /**< LP interface structure */
149  int firstrow, /**< first row to be deleted */
150  int lastrow /**< last row to be deleted */
151  )
152 {
153  int nrows;
154 
155  (void)XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows);
156  assert(0 <= firstrow && firstrow <= lastrow && lastrow < nrows);
157 }
158 
159 #else
160 
161 /* in optimized mode the checks are replaced with an empty command */
162 #define debugCheckColrang(lpi, firstcol, lastcol) /* */
163 #define debugCheckRowrang(lpi, firstrow, lastrow) /* */
164 #endif
165 
166 /**@} */
167 
168 
169 /**@name Dynamic memory arrays
170  *
171  * @{
172  */
173 
174 /** resizes larray and uarray to have at least num entries and fill it with 'L' and 'U' for the lower and upper bound
175  * markers
176  */
177 static
179  SCIP_LPI* lpi, /**< LP interface structure */
180  int num /**< minimal number of entries in array */
181  )
182 {
183  assert(lpi != NULL);
184 
185  if( num > lpi->boundchgsize )
186  {
187  int newsize;
188  int i;
189 
190  newsize = MAX(2*lpi->boundchgsize, num);
191  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->larray, newsize) );
192  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->uarray, newsize) );
193  for( i = lpi->boundchgsize; i < newsize; ++i )
194  {
195  lpi->larray[i] = 'L';
196  lpi->uarray[i] = 'U';
197  }
198  lpi->boundchgsize = newsize;
199  }
200  assert(num <= lpi->boundchgsize);
201 
202  return SCIP_OKAY;
203 }
204 
205 /** resizes senarray, rngarray, and rhsarray to have at least num entries */
206 static
208  SCIP_LPI* lpi, /**< LP interface structure */
209  int num /**< minimal number of entries in array */
210  )
211 {
212  assert(lpi != NULL);
213 
214  if( num > lpi->sidechgsize )
215  {
216  int newsize;
217 
218  newsize = MAX(2*lpi->sidechgsize, num);
219  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->senarray, newsize) );
220  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rhsarray, newsize) );
221  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngarray, newsize) );
222  lpi->sidechgsize = newsize;
223  }
224  assert(num <= lpi->sidechgsize);
225 
226  return SCIP_OKAY;
227 }
228 
229 /** resizes valarray and indarray to have at least num entries */
230 static
232  SCIP_LPI* lpi, /**< LP interface structure */
233  int num /**< minimal number of entries in array */
234  )
235 {
236  assert(lpi != NULL);
237 
238  if( num > lpi->valsize )
239  {
240  int newsize;
241 
242  newsize = MAX(2*lpi->valsize, num);
243  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->valarray, newsize) );
244  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->indarray, newsize) );
245  lpi->valsize = newsize;
246  }
247  assert(num <= lpi->valsize);
248 
249  return SCIP_OKAY;
250 }
251 
252 /** resizes cstat array to have at least num entries */
253 static
255  SCIP_LPI* lpi, /**< LP interface structure */
256  int num /**< minimal number of entries in array */
257  )
258 {
259  assert(lpi != NULL);
260 
261  if( num > lpi->cstatsize )
262  {
263  int newsize;
264 
265  newsize = MAX(2*lpi->cstatsize, num);
266  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
267  lpi->cstatsize = newsize;
268  }
269  assert(num <= lpi->cstatsize);
270 
271  return SCIP_OKAY;
272 }
273 
274 /** resizes rstat array to have at least num entries */
275 static
277  SCIP_LPI* lpi, /**< LP interface structure */
278  int num /**< minimal number of entries in array */
279  )
280 {
281  assert(lpi != NULL);
282 
283  if( num > lpi->rstatsize )
284  {
285  int newsize;
286 
287  newsize = MAX(2*lpi->rstatsize, num);
288  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
289  lpi->rstatsize = newsize;
290  }
291  assert(num <= lpi->rstatsize);
292 
293  return SCIP_OKAY;
294 }
295 
296 /**@} */
297 
298 
299 /**@name LPi state methods
300  *
301  * @{
302  */
303 
304 /** returns the number of packets needed to store column packet information */
305 static
307  int ncols /**< number of columns to store */
308  )
309 {
310  return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
311 }
312 
313 /** returns the number of packets needed to store row packet information */
314 static
316  int nrows /**< number of rows to store */
317  )
318 {
319  return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
320 }
321 
322 /** store row and column basis status in a packed LPi state object */
323 static
325  SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
326  const int* cstat, /**< basis status of columns in unpacked format */
327  const int* rstat /**< basis status of rows in unpacked format (row status w.r.t. slack columns) */
328  )
329 {
330  assert(lpistate != NULL);
331  assert(lpistate->packcstat != NULL);
332  assert(lpistate->packrstat != NULL);
333 
334  SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
335  SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
336 }
337 
338 /** unpacks row and column basis status from a packed LPi state object */
339 static
341  const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
342  int* cstat, /**< buffer for storing basis status of columns in unpacked format */
343  int* rstat /**< buffer for storing basis status of rows in unpacked format (row status w.r.t. slack columns) */
344  )
345 {
346  assert(lpistate != NULL);
347  assert(lpistate->packcstat != NULL);
348  assert(lpistate->packrstat != NULL);
349 
350  SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
351  SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
352 }
353 
354 /** creates LPi state information object */
355 static
357  SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
358  BMS_BLKMEM* blkmem, /**< block memory */
359  int ncols, /**< number of columns to store */
360  int nrows /**< number of rows to store */
361  )
362 {
363  assert(lpistate != NULL);
364  assert(blkmem != NULL);
365  assert(ncols >= 0);
366  assert(nrows >= 0);
367 
368  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
369  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum(ncols)) );
370  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum(nrows)) );
371 
372  return SCIP_OKAY;
373 }
374 
375 /** frees LPi state information */
376 static
378  SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
379  BMS_BLKMEM* blkmem /**< block memory */
380  )
381 {
382  assert(blkmem != NULL);
383  assert(lpistate != NULL);
384  assert(*lpistate != NULL);
385 
386  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum((*lpistate)->ncols));
387  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum((*lpistate)->nrows));
388  BMSfreeBlockMemory(blkmem, lpistate);
389 }
390 
391 /**@} */
392 
393 
394 /**@name Conversion methods
395  *
396  * @{
397  */
398 
399 /** converts SCIP's objective sense into CPLEX's objective sense */
400 static
402  SCIP_OBJSEN const objsen /**< objective sense */
403  )
404 {
405  switch( objsen )
406  {
408  return XPRS_OBJ_MAXIMIZE;
410  return XPRS_OBJ_MINIMIZE;
411  default:
412  SCIPerrorMessage("invalid objective sense\n");
413  SCIPABORT();
414  return 0; /*lint !e527*/
415  }
416 }
417 
418 /** converts SCIP's lhs/rhs pairs into Xpress' sen/rhs/rng */
419 static
421  SCIP_LPI* lpi, /**< LP interface structure */
422  int nrows, /**< number of rows */
423  const SCIP_Real* lhss, /**< left hand side vector */
424  const SCIP_Real* rhss /**< right hand side vector */
425  )
426 {
427  int i;
428 
429  assert(lpi != NULL);
430  assert(nrows >= 0);
431  assert(lhss != NULL);
432  assert(rhss != NULL);
433 
434  /* convert lhs/rhs into sen/rhs/rng */
435  for( i = 0; i < nrows; ++i )
436  {
437  assert(lhss[i] <= rhss[i]);
438  if( lhss[i] == rhss[i] ) /*lint !e777*/
439  {
440  assert(XPRS_MINUSINFINITY < rhss[i] && rhss[i] < XPRS_PLUSINFINITY);
441  lpi->senarray[i] = 'E';
442  lpi->rhsarray[i] = rhss[i];
443  lpi->rngarray[i] = 0.0;
444  }
445  else if( lhss[i] <= XPRS_MINUSINFINITY )
446  {
447  lpi->senarray[i] = 'L';
448  lpi->rhsarray[i] = rhss[i];
449  lpi->rngarray[i] = XPRS_PLUSINFINITY;
450  }
451  else if( rhss[i] >= XPRS_PLUSINFINITY )
452  {
453  lpi->senarray[i] = 'G';
454  lpi->rhsarray[i] = lhss[i];
455  lpi->rngarray[i] = XPRS_PLUSINFINITY;
456  }
457  else
458  {
459  /* Xpress defines a ranged row to be within rhs-rng and rhs. */
460  lpi->senarray[i] = 'R';
461  lpi->rhsarray[i] = rhss[i];
462  lpi->rngarray[i] = rhss[i] - lhss[i];
463  }
464  }
465 }
466 
467 /** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
468 static
470  SCIP_LPI* lpi, /**< LP interface structure */
471  int nrows, /**< number of rows */
472  SCIP_Real* lhss, /**< buffer to store the left hand side vector */
473  SCIP_Real* rhss /**< buffer to store the right hand side vector */
474  )
475 {
476  int i;
477 
478  assert(lpi != NULL);
479  assert(nrows >= 0);
480  assert(lhss != NULL);
481  assert(rhss != NULL);
482 
483  for( i = 0; i < nrows; ++i )
484  {
485  switch( lpi->senarray[i] )
486  {
487  case 'E':
488  lhss[i] = lpi->rhsarray[i];
489  rhss[i] = lpi->rhsarray[i];
490  break;
491 
492  case 'L':
493  lhss[i] = XPRS_MINUSINFINITY;
494  rhss[i] = lpi->rhsarray[i];
495  break;
496 
497  case 'G':
498  lhss[i] = lpi->rhsarray[i];
499  rhss[i] = XPRS_PLUSINFINITY;
500  break;
501 
502  case 'R':
503  assert(lpi->rngarray[i] >= 0.0);
504  rhss[i] = lpi->rhsarray[i];
505  lhss[i] = lpi->rhsarray[i] - lpi->rngarray[i];
506  break;
507 
508  default:
509  SCIPerrorMessage("invalid row sense\n");
510  SCIPABORT();
511  }
512  assert(lhss[i] <= rhss[i]);
513  }
514 }
515 
516 /** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the left hand side */
517 static
519  SCIP_LPI* lpi, /**< LP interface structure */
520  int nrows, /**< number of rows */
521  SCIP_Real* lhss /**< buffer to store the left hand side vector */
522  )
523 {
524  int i;
525 
526  assert(lpi != NULL);
527  assert(nrows >= 0);
528  assert(lhss != NULL);
529 
530  for( i = 0; i < nrows; ++i )
531  {
532  switch( lpi->senarray[i] )
533  {
534  case 'E':
535  assert(lpi->rngarray[i] == 0.0);
536  lhss[i] = lpi->rhsarray[i];
537  break;
538 
539  case 'L':
540  assert(lpi->rngarray[i] == 0.0);
541  lhss[i] = XPRS_MINUSINFINITY;
542  break;
543 
544  case 'G':
545  assert(lpi->rngarray[i] == 0.0);
546  lhss[i] = lpi->rhsarray[i];
547  break;
548 
549  case 'R':
550  assert(lpi->rngarray[i] >= 0.0);
551  lhss[i] = lpi->rhsarray[i] - lpi->rngarray[i];
552  break;
553 
554  default:
555  SCIPerrorMessage("invalid row sense\n");
556  SCIPABORT();
557  }
558  }
559 }
560 
561 /** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the right hand side */
562 static
564  SCIP_LPI* lpi, /**< LP interface structure */
565  int nrows, /**< number of rows */
566  SCIP_Real* rhss /**< buffer to store the right hand side vector */
567  )
568 {
569  int i;
570 
571  assert(lpi != NULL);
572  assert(nrows >= 0);
573  assert(rhss != NULL);
574 
575  for( i = 0; i < nrows; ++i )
576  {
577  switch( lpi->senarray[i] )
578  {
579  case 'E':
580  assert(lpi->rngarray[i] == 0.0);
581  rhss[i] = lpi->rhsarray[i];
582  break;
583 
584  case 'L':
585  assert(lpi->rngarray[i] == 0.0);
586  rhss[i] = lpi->rhsarray[i];
587  break;
588 
589  case 'G':
590  assert(lpi->rngarray[i] == 0.0);
591  rhss[i] = XPRS_PLUSINFINITY;
592  break;
593 
594  case 'R':
595  assert(lpi->rngarray[i] >= 0.0);
596  rhss[i] = lpi->rhsarray[i];
597  break;
598 
599  default:
600  SCIPerrorMessage("invalid row sense\n");
601  SCIPABORT();
602  }
603  }
604 }
605 
606 /** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
607 static
609  SCIP_LPI* lpi, /**< LP interface structure */
610  int nrows, /**< number of rows */
611  SCIP_Real* lhs, /**< buffer to store the left hand side vector, or NULL */
612  SCIP_Real* rhs /**< buffer to store the right hand side vector, or NULL */
613  )
614 {
615  if( lhs != NULL && rhs != NULL )
616  reconvertBothSides(lpi, nrows, lhs, rhs);
617  else if( lhs != NULL )
618  reconvertLhs(lpi, nrows, lhs);
619  else if( rhs != NULL )
620  reconvertRhs(lpi, nrows, rhs);
621 }
622 
623 /**@} */
624 
625 
626 /** marks the current LP to be unsolved */
627 static
629  SCIP_LPI* lpi
630  )
631 {
632  assert(lpi != NULL);
633  lpi->solstat = -1;
634 }
635 
636 /*
637  * LP Interface Methods
638  */
639 
640 /**@name Miscellaneous Methods
641  *
642  * @{
643  */
644 
645 static char xprsname[100];
646 
647 /** gets name and version of LP solver */
649  void
650  )
651 {
652  char version[16];
653 
654  /* get version of Xpress */
655  if( XPRSgetversion(version) == 0 )
656  (void) sprintf(xprsname, "Xpress %s", version);
657  else
658  (void) sprintf(xprsname, "Xpress %d", XPVERSION);
659 
660  return xprsname;
661 }
662 
663 /** gets description of LP solver (developer, webpage, ...) */
665  void
666  )
667 {
668  return "Linear Programming Solver developed by FICO (www.fico.com/xpress)";
669 }
670 
671 /** gets pointer for LP solver - use only with great care
672  *
673  * Here we return the pointer to the LP environment.
674  */
676  SCIP_LPI* lpi /**< pointer to an LP interface structure */
677  )
678 { /*lint --e{715}*/
679  return (void*) lpi->xprslp;
680 }
681 
682 /** pass integrality information to LP solver */
684  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
685  int ncols, /**< length of integrality array */
686  int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
687  )
688 { /*lint --e{715}*/
689  assert(lpi != NULL);
690  assert(ncols >= 0);
691  assert(ncols == 0 || intInfo != NULL);
692 
693  SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
694  return SCIP_LPERROR;
695 }
696 
697 /** informs about availability of a primal simplex solving method */
699  void
700  )
701 {
702  return TRUE;
703 }
704 
705 /** informs about availability of a dual simplex solving method */
707  void
708  )
709 {
710  return TRUE;
711 }
712 
713 /** informs about availability of a barrier solving method */
715  void
716  )
717 {
718  return TRUE;
719 }
720 
721 /**@} */
722 
723 
724 /**@name LPI Creation and Destruction Methods
725  *
726  * @{
727  */
728 
729 /** creates an LP problem object */
731  SCIP_LPI** lpi, /**< pointer to an LP interface structure */
732  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
733  const char* name, /**< problem name */
734  SCIP_OBJSEN objsen /**< objective sense */
735  )
736 {
737  int zero = 0;
738 
739  assert(sizeof(SCIP_Real) == sizeof(double)); /*lint !e506*/ /* Xpress only works with doubles as floating points */
740  assert(sizeof(SCIP_Bool) == sizeof(int)); /*lint !e506*/ /* Xpress only works with ints as bools */
741  assert(lpi != NULL);
742  assert(name != NULL);
743 
744  SCIPdebugMessage("SCIPlpiCreate()\n");
745 
746  /* the interface is revised for Xpress 26 or higher */
747  if( XPVERSION < 26 ) /*lint !e506 !e774*/
748  {
749  SCIPmessagePrintWarning(messagehdlr, "Please use Xpress version 26 or higher, you are using %d\n", XPVERSION);
750  return SCIP_LPERROR;
751  }
752 
753  /* initialize the Xpress library (licensing) */
754  CHECK_ZERO( messagehdlr, XPRSinit(NULL) );
755 
756  /* create LPi data structure */
757  SCIP_ALLOC( BMSallocMemory(lpi) );
758 
759  /* copy the problem name */
760  (void)strncpy((*lpi)->name, name, 199);
761  (*lpi)->name[199] = '\0';
762 
763  (*lpi)->larray = NULL;
764  (*lpi)->uarray = NULL;
765  (*lpi)->senarray = NULL;
766  (*lpi)->rhsarray = NULL;
767  (*lpi)->rngarray = NULL;
768  (*lpi)->indarray = NULL;
769  (*lpi)->valarray = NULL;
770  (*lpi)->cstat = NULL;
771  (*lpi)->rstat = NULL;
772  (*lpi)->boundchgsize = 0;
773  (*lpi)->sidechgsize = 0;
774  (*lpi)->valsize = 0;
775  (*lpi)->cstatsize = 0;
776  (*lpi)->rstatsize = 0;
777  (*lpi)->iterations = 0;
778  (*lpi)->solisbasic = TRUE;
779  (*lpi)->clearstate = FALSE;
780  (*lpi)->solmethod = ' ';
781  (*lpi)->par_lobjlim = -1e+40;
782  (*lpi)->par_uobjlim = +1e+40;
783  (*lpi)->par_fastlp = 0;
784  (*lpi)->par_presolve = 0;
785  (*lpi)->messagehdlr = messagehdlr;
786 
787  CHECK_ZERO( messagehdlr, XPRScreateprob(&(*lpi)->xprslp) );
788  invalidateSolution(*lpi);
789 
790  /* turn logging off until the user explicitly turns it on; this should prevent any unwanted Xpress output from
791  * appearing in the SCIP log.
792  */
793  CHECK_ZERO( messagehdlr, XPRSsetintcontrol((*lpi)->xprslp, XPRS_OUTPUTLOG, 0) );
794 
795  /* we need to create an empty LP in this prob since SCIP might attempt to add rows or columns to it */
796  CHECK_ZERO( messagehdlr, XPRSloadlp((*lpi)->xprslp, (*lpi)->name, 0, 0, NULL, NULL, NULL, NULL, &zero, NULL, NULL, NULL, NULL, NULL) );
797 
798  /* set objective sense */
799  SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
800 
801  return SCIP_OKAY;
802 }
803 
804 /** deletes an LP problem object */
806  SCIP_LPI** lpi /**< pointer to an LP interface structure */
807  )
808 {
809  assert(lpi != NULL);
810  assert(*lpi != NULL);
811  assert((*lpi)->xprslp != NULL);
812 
813  SCIPdebugMessage("SCIPlpiFree()\n");
814 
815  /* free LP */
816  CHECK_ZERO( (*lpi)->messagehdlr, XPRSdestroyprob(((*lpi)->xprslp)) );
817 
818  /* free environment */
819  CHECK_ZERO( (*lpi)->messagehdlr, XPRSfree() );
820 
821  /* free memory */
822  BMSfreeMemoryArrayNull(&(*lpi)->larray);
823  BMSfreeMemoryArrayNull(&(*lpi)->uarray);
824  BMSfreeMemoryArrayNull(&(*lpi)->senarray);
825  BMSfreeMemoryArrayNull(&(*lpi)->rhsarray);
826  BMSfreeMemoryArrayNull(&(*lpi)->rngarray);
827  BMSfreeMemoryArrayNull(&(*lpi)->indarray);
828  BMSfreeMemoryArrayNull(&(*lpi)->valarray);
829  BMSfreeMemoryArrayNull(&(*lpi)->cstat);
830  BMSfreeMemoryArrayNull(&(*lpi)->rstat);
831  BMSfreeMemory(lpi);
832 
833  return SCIP_OKAY;
834 }
835 
836 /**@} */
837 
838 
839 /**@name Modification Methods
840  *
841  * @{
842  */
843 
844 /** copies LP data with column matrix into LP solver */
846  SCIP_LPI* lpi, /**< LP interface structure */
847  SCIP_OBJSEN objsen, /**< objective sense */
848  int ncols, /**< number of columns */
849  const SCIP_Real* obj, /**< objective function values of columns */
850  const SCIP_Real* lb, /**< lower bounds of columns */
851  const SCIP_Real* ub, /**< upper bounds of columns */
852  char** colnames, /**< column names, or NULL */
853  int nrows, /**< number of rows */
854  const SCIP_Real* lhs, /**< left hand sides of rows */
855  const SCIP_Real* rhs, /**< right hand sides of rows */
856  char** rownames, /**< row names, or NULL */
857  int nnonz, /**< number of nonzero elements in the constraint matrix */
858  const int* beg, /**< start index of each column in ind- and val-array */
859  const int* ind, /**< row indices of constraint matrix entries */
860  const SCIP_Real* val /**< values of constraint matrix entries */
861  )
862 { /*lint --e{715}*/
863  int c;
864 
865 #ifndef NDEBUG
866  {
867  int j;
868  for( j = 0; j < nnonz; j++ )
869  assert( val[j] != 0 );
870  }
871 #endif
872 
873  assert(lpi != NULL);
874  assert(lpi->xprslp != NULL);
875  assert(obj != NULL);
876  assert(lb != NULL);
877  assert(ub != NULL);
878  assert(beg != NULL);
879  assert(ind != NULL);
880  assert(val != NULL);
881  SCIP_UNUSED(colnames);
882  SCIP_UNUSED(rownames);
883 
884  SCIPdebugMessage("loading LP in column format into Xpress: %d cols, %d rows\n", ncols, nrows);
885 
886  invalidateSolution(lpi);
887 
888  /* ensure that the temporary arrays for the side conversion are long enough */
889  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
890 
891  /* convert lhs/rhs into sen/rhs/range tuples the sen/rhs/range are stored in the temporary arrays in lpi structure */
892  convertSides(lpi, nrows, lhs, rhs);
893 
894  /* ensure that the temporary arrays are large enough */
895  SCIP_CALL( ensureValMem(lpi, ncols) );
896 
897  /* calculate column lengths */
898  for( c = 0; c < ncols-1; ++c )
899  {
900  lpi->indarray[c] = beg[c+1] - beg[c];
901  assert(lpi->indarray[c] >= 0);
902  }
903  lpi->indarray[ncols-1] = nnonz - beg[ncols-1];
904  assert(lpi->indarray[ncols-1] >= 0);
905 
906  /* copy data into Xpress */
907  CHECK_ZERO( lpi->messagehdlr, XPRSloadlp(lpi->xprslp, lpi->name, ncols, nrows, lpi->senarray, lpi->rhsarray,
908  lpi->rngarray, obj, beg, lpi->indarray, ind, val, lb, ub) );
909 
910  /* set objective sense */
911  SCIP_CALL( SCIPlpiChgObjsen(lpi, objsen) );
912 
913  return SCIP_OKAY;
914 }
915 
916 /** adds columns to the LP */
918  SCIP_LPI* lpi, /**< LP interface structure */
919  int ncols, /**< number of columns to be added */
920  const SCIP_Real* obj, /**< objective function values of new columns */
921  const SCIP_Real* lb, /**< lower bounds of new columns */
922  const SCIP_Real* ub, /**< upper bounds of new columns */
923  char** colnames, /**< column names, or NULL */
924  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
925  const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
926  const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
927  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
928  )
929 { /*lint --e{715}*/
930  int c;
931 
932  assert(lpi != NULL);
933  assert(lpi->xprslp != NULL);
934  assert(ncols > 0);
935  assert(obj != NULL);
936  assert(lb != NULL);
937  assert(ub != NULL);
938  assert(nnonz >= 0);
939  assert(nnonz == 0 || beg != NULL);
940  assert(nnonz == 0 || ind != NULL);
941  assert(nnonz == 0 || val != NULL);
942  SCIP_UNUSED(colnames);
943 
944  SCIPdebugMessage("adding %d columns with %d nonzeros to Xpress\n", ncols, nnonz);
945 
946  invalidateSolution(lpi);
947 
948  /* ensure that the temporary arrays are large enough */
949  SCIP_CALL( ensureValMem(lpi, ncols+1) );
950 
951 #ifndef NDEBUG
952  {
953  /* perform check that no new rows are added - this is forbidden */
954  int nrows;
955  int j;
956 
957  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
958  for (j = 0; j < nnonz; ++j)
959  {
960  assert( val[j] != 0.0 );
961  assert( 0 <= ind[j] && ind[j] < nrows );
962  }
963  }
964 #endif
965 
966  /* only collect the start array if we have at least one non-zero */
967  if( nnonz > 0 )
968  {
969  /* we need ncol+1 entries in the start array for Xpress */
970  for( c = 0; c < ncols; c++ )
971  lpi->indarray[c] = beg[c];
972  lpi->indarray[ncols] = nnonz;
973  }
974 
975  /* add the columns with (potential) non-zeros to the Xpress */
976  CHECK_ZERO( lpi->messagehdlr, XPRSaddcols(lpi->xprslp, ncols, nnonz, obj, lpi->indarray, ind, val, lb, ub) );
977 
978  return SCIP_OKAY;
979 }
980 
981 /** deletes all columns in the given range from LP */
983  SCIP_LPI* lpi, /**< LP interface structure */
984  int firstcol, /**< first column to be deleted */
985  int lastcol /**< last column to be deleted */
986  )
987 {
988  int c;
989 
990  assert(lpi != NULL);
991  assert(lpi->xprslp != NULL);
992 
993  debugCheckColrang(lpi, firstcol, lastcol);
994 
995  SCIPdebugMessage("deleting %d columns from Xpress\n", lastcol - firstcol + 1);
996 
997  invalidateSolution(lpi);
998 
999  /* ensure that the temporary arrays are large enough */
1000  SCIP_CALL( ensureValMem(lpi, lastcol-firstcol+1) );
1001 
1002  /* collect the columns indices to be deleted */
1003  for( c = firstcol; c <= lastcol; c++ )
1004  lpi->indarray[c-firstcol] = c;
1005 
1006  CHECK_ZERO( lpi->messagehdlr, XPRSdelcols(lpi->xprslp, lastcol-firstcol+1, lpi->indarray) );
1007 
1008  return SCIP_OKAY;
1009 }
1010 
1011 /** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
1013  SCIP_LPI* lpi, /**< LP interface structure */
1014  int* dstat /**< deletion status of columns
1015  * input: 1 if column should be deleted, 0 if not
1016  * output: new position of column, -1 if column was deleted */
1017  )
1018 {
1019  int nkeptcols;
1020  int ndelcols;
1021  int ncols;
1022  int c;
1023 
1024  assert(lpi != NULL);
1025  assert(lpi->xprslp != NULL);
1026  assert(dstat != NULL);
1027 
1028  SCIPdebugMessage("deleting a column set from Xpress\n");
1029 
1030  invalidateSolution(lpi);
1031 
1032  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
1033 
1034  nkeptcols = 0;
1035  ndelcols = 0;
1036 
1037  /* ensure that the temporary arrays are large enough */
1038  SCIP_CALL( ensureValMem(lpi, ncols) );
1039 
1040  /* collect the column indecies which should be deleted and create a the new column ordering */
1041  for( c = 0; c < ncols; c++ )
1042  {
1043  if( dstat[c] == 1 )
1044  {
1045  dstat[c] = -1;
1046  lpi->indarray[ndelcols] = c;
1047  ndelcols++;
1048  }
1049  else
1050  {
1051  dstat[c] = nkeptcols;
1052  nkeptcols++;
1053  }
1054  }
1055 
1056  CHECK_ZERO( lpi->messagehdlr, XPRSdelcols(lpi->xprslp, ndelcols, lpi->indarray) );
1057 
1058  return SCIP_OKAY;
1059 }
1060 
1061 /** adds rows to the LP */
1063  SCIP_LPI* lpi, /**< LP interface structure */
1064  int nrows, /**< number of rows to be added */
1065  const SCIP_Real* lhs, /**< left hand sides of new rows */
1066  const SCIP_Real* rhs, /**< right hand sides of new rows */
1067  char** rownames, /**< row names, or NULL */
1068  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1069  const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1070  const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1071  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1072  )
1073 { /*lint --e{715}*/
1074  int r;
1075 
1076  assert(lpi != NULL);
1077  assert(lpi->xprslp != NULL);
1078  assert(nrows >= 0);
1079  assert(lhs != NULL);
1080  assert(rhs != NULL);
1081  assert(nnonz >= 0);
1082  assert(nnonz == 0 || beg != NULL);
1083  assert(nnonz == 0 || ind != NULL);
1084  assert(nnonz == 0 || val != NULL);
1085  SCIP_UNUSED(rownames);
1086 
1087  SCIPdebugMessage("adding %d rows with %d nonzeros to Xpress\n", nrows, nnonz);
1088 
1089  invalidateSolution(lpi);
1090 
1091 #ifndef NDEBUG
1092  {
1093  /* perform check that no new cols are added - this is forbidden */
1094  int ncols;
1095  int j;
1096 
1097  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
1098  for (j = 0; j < nnonz; ++j)
1099  {
1100  assert( val[j] != 0.0 );
1101  assert( 0 <= ind[j] && ind[j] < ncols );
1102  }
1103  }
1104 #endif
1105 
1106  /* ensure that the temporary arrays are large enough */
1107  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1108  SCIP_CALL( ensureValMem(lpi, nrows+1) );
1109 
1110  /* convert lhs/rhs into sen/rhs/range tuples */
1111  convertSides(lpi, nrows, lhs, rhs);
1112 
1113  /* only collect the start array if we have at least one non-zero */
1114  if( nnonz > 0 )
1115  {
1116  for( r = 0; r < nrows; r++ )
1117  lpi->indarray[r] = beg[r];
1118  lpi->indarray[nrows] = nnonz;
1119  }
1120 
1121  CHECK_ZERO( lpi->messagehdlr, XPRSaddrows(lpi->xprslp, nrows, nnonz, lpi->senarray, lpi->rhsarray, lpi->rngarray, lpi->indarray, ind, val) );
1122 
1123  return SCIP_OKAY;
1124 }
1125 
1126 /** deletes all rows in the given range from LP */
1128  SCIP_LPI* lpi, /**< LP interface structure */
1129  int firstrow, /**< first row to be deleted */
1130  int lastrow /**< last row to be deleted */
1131  )
1132 {
1133  int r;
1134 
1135  assert(lpi != NULL);
1136  assert(lpi->xprslp != NULL);
1137 
1138  debugCheckRowrang(lpi, firstrow, lastrow);
1139 
1140  SCIPdebugMessage("deleting %d rows from Xpress\n", lastrow - firstrow + 1);
1141 
1142  invalidateSolution(lpi);
1143 
1144  /* ensure that the temporary arrays are large enough */
1145  SCIP_CALL( ensureValMem(lpi, lastrow-firstrow+1) );
1146 
1147  for( r = firstrow; r <= lastrow; r++ )
1148  lpi->indarray[r-firstrow] = r;
1149 
1150  CHECK_ZERO( lpi->messagehdlr, XPRSdelrows(lpi->xprslp, lastrow-firstrow+1, lpi->indarray) );
1151 
1152  return SCIP_OKAY;
1153 }
1154 
1155 /** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1157  SCIP_LPI* lpi, /**< LP interface structure */
1158  int* dstat /**< deletion status of rows
1159  * input: 1 if row should be deleted, 0 if not
1160  * output: new position of row, -1 if row was deleted */
1161  )
1162 {
1163  int nkeptrows;
1164  int ndelrows;
1165  int nrows;
1166  int r;
1167 
1168  assert(lpi != NULL);
1169  assert(lpi->xprslp != NULL);
1170 
1171  SCIPdebugMessage("deleting a row set from Xpress\n");
1172 
1173  invalidateSolution(lpi);
1174 
1175  nkeptrows = 0;
1176  ndelrows = 0;
1177 
1178  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
1179 
1180  /* ensure that the temporary arrays are large enough */
1181  SCIP_CALL( ensureValMem(lpi, nrows) );
1182 
1183  /* collect the row indecies which should be deleted and create a the new row ordering */
1184  for( r = 0; r < nrows; r++ )
1185  {
1186  if( dstat[r] == 1 )
1187  {
1188  dstat[r] = -1;
1189  lpi->indarray[ndelrows] = r;
1190  ndelrows++;
1191  }
1192  else
1193  {
1194  dstat[r] = nkeptrows;
1195  nkeptrows++;
1196  }
1197  }
1198 
1199  CHECK_ZERO( lpi->messagehdlr, XPRSdelrows(lpi->xprslp, ndelrows, lpi->indarray) );
1200 
1201  return SCIP_OKAY;
1202 }
1203 
1204 /** clears the whole LP */
1206  SCIP_LPI* lpi /**< LP interface structure */
1207  )
1208 {
1209  int zero = 0;
1210 
1211  assert(lpi != NULL);
1212  assert(lpi->xprslp != NULL);
1213 
1214  SCIPdebugMessage("clearing Xpress LP\n");
1215 
1216  invalidateSolution(lpi);
1217 
1218  /* create an empty LP in this */
1219  CHECK_ZERO( lpi->messagehdlr, XPRSloadlp(lpi->xprslp, lpi->name, 0, 0, NULL, NULL, NULL, NULL, &zero, NULL, NULL, NULL, NULL, NULL) );
1220 
1221  return SCIP_OKAY;
1222 }
1223 
1224 /** changes lower and upper bounds of columns */
1226  SCIP_LPI* lpi, /**< LP interface structure */
1227  int ncols, /**< number of columns to change bounds for */
1228  const int* ind, /**< column indices or NULL if ncols is zero */
1229  const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
1230  const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
1231  )
1232 {
1233  int j;
1234 
1235  assert(lpi != NULL);
1236  assert(lpi->xprslp != NULL);
1237  assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
1238 
1239  SCIPdebugMessage("changing %d bounds in Xpress\n", ncols);
1240  if( ncols <= 0 )
1241  return SCIP_OKAY;
1242 
1243  invalidateSolution(lpi);
1244 
1245  for (j = 0; j < ncols; ++j)
1246  {
1247  if ( SCIPlpiIsInfinity(lpi, lb[j]) )
1248  {
1249  SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[j]);
1250  return SCIP_LPERROR;
1251  }
1252  if ( SCIPlpiIsInfinity(lpi, -ub[j]) )
1253  {
1254  SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[j]);
1255  return SCIP_LPERROR;
1256  }
1257  }
1258 
1259  /* ensure that the temporary arrays are large enough */
1260  SCIP_CALL( ensureBoundchgMem(lpi, ncols) );
1261 
1262  CHECK_ZERO( lpi->messagehdlr, XPRSchgbounds(lpi->xprslp, ncols, ind, lpi->larray, (SCIP_Real*)lb) );
1263  CHECK_ZERO( lpi->messagehdlr, XPRSchgbounds(lpi->xprslp, ncols, ind, lpi->uarray, (SCIP_Real*)ub) );
1264 
1265  return SCIP_OKAY;
1266 }
1267 
1268 /** changes left and right hand sides of rows */
1270  SCIP_LPI* lpi, /**< LP interface structure */
1271  int nrows, /**< number of rows to change sides for */
1272  const int* ind, /**< row indices */
1273  const SCIP_Real* lhs, /**< new values for left hand sides */
1274  const SCIP_Real* rhs /**< new values for right hand sides */
1275  )
1276 {
1277  assert(lpi != NULL);
1278  assert(lpi->xprslp != NULL);
1279  assert(ind != NULL);
1280 
1281  SCIPdebugMessage("changing %d sides in Xpress\n", nrows);
1282  if( nrows <= 0 )
1283  return SCIP_OKAY;
1284 
1285  invalidateSolution(lpi);
1286 
1287  /* ensure that the temporary arrays are large enough */
1288  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1289 
1290  /* convert lhs/rhs into sen/rhs/range tuples */
1291  convertSides(lpi, nrows, lhs, rhs);
1292 
1293  /* change row sides */
1294  CHECK_ZERO( lpi->messagehdlr, XPRSchgrowtype(lpi->xprslp, nrows, ind, lpi->senarray) );
1295  CHECK_ZERO( lpi->messagehdlr, XPRSchgrhs(lpi->xprslp, nrows, ind, lpi->rhsarray) );
1296  CHECK_ZERO( lpi->messagehdlr, XPRSchgrhsrange(lpi->xprslp, nrows, ind, lpi->rngarray) );
1297 
1298  return SCIP_OKAY;
1299 }
1300 
1301 /** changes a single coefficient */
1303  SCIP_LPI* lpi, /**< LP interface structure */
1304  int row, /**< row number of coefficient to change */
1305  int col, /**< column number of coefficient to change */
1306  SCIP_Real newval /**< new value of coefficient */
1307  )
1308 {
1309  assert(lpi != NULL);
1310  assert(lpi->xprslp != NULL);
1311 
1312  SCIPdebugMessage("changing coefficient row %d, column %d in Xpress to %g\n", row, col, newval);
1313 
1314  invalidateSolution(lpi);
1315 
1316  CHECK_ZERO( lpi->messagehdlr, XPRSchgcoef(lpi->xprslp, row, col, newval) );
1317 
1318  return SCIP_OKAY;
1319 }
1320 
1321 /** changes the objective sense */
1323  SCIP_LPI* lpi, /**< LP interface structure */
1324  SCIP_OBJSEN objsense /**< new objective sense */
1325  )
1326 {
1327  assert(lpi != NULL);
1328  assert(lpi->xprslp != NULL);
1329 
1330  SCIPdebugMessage("changing objective sense in Xpress to %d\n", objsense);
1331 
1332  invalidateSolution(lpi);
1333 
1334  CHECK_ZERO( lpi->messagehdlr, XPRSchgobjsense(lpi->xprslp, xprsObjsen(objsense)) );
1335 
1336  return SCIP_OKAY;
1337 }
1338 
1339 /** changes objective values of columns in the LP */
1341  SCIP_LPI* lpi, /**< LP interface structure */
1342  int ncols, /**< number of columns to change objective value for */
1343  const int* ind, /**< column indices to change objective value for */
1344  const SCIP_Real* obj /**< new objective values for columns */
1345  )
1346 {
1347  assert(lpi != NULL);
1348  assert(lpi->xprslp != NULL);
1349  assert(ind != NULL);
1350  assert(obj != NULL);
1351 
1352  SCIPdebugMessage("changing %d objective values in Xpress\n", ncols);
1353 
1354  invalidateSolution(lpi);
1355 
1356  CHECK_ZERO( lpi->messagehdlr, XPRSchgobj(lpi->xprslp, ncols, ind, obj) );
1357 
1358  return SCIP_OKAY;
1359 }
1360 
1361 /** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1363  SCIP_LPI* lpi, /**< LP interface structure */
1364  int row, /**< row number to scale */
1365  SCIP_Real scaleval /**< scaling multiplier */
1366  )
1367 {
1368  SCIP_Real lhs;
1369  SCIP_Real rhs;
1370  int nnonz;
1371  int ncols;
1372  int i;
1373 
1374  assert(lpi != NULL);
1375  assert(lpi->xprslp != NULL);
1376  assert(scaleval != 0.0);
1377 
1378  SCIPdebugMessage("scaling row %d with factor %g in Xpress\n", row, scaleval);
1379 
1380  invalidateSolution(lpi);
1381 
1382  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
1383  SCIP_CALL( ensureValMem(lpi, ncols) );
1384 
1385  /* get the row */
1386  SCIP_CALL( SCIPlpiGetSides(lpi, row, row, &lhs, &rhs) );
1387  CHECK_ZERO( lpi->messagehdlr, XPRSgetrows(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, ncols, &nnonz, row, row) );
1388  assert(nnonz <= ncols);
1389 
1390  /* scale row coefficients */
1391  for( i = 0; i < nnonz; ++i )
1392  {
1393  SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
1394  }
1395 
1396  /* scale row sides */
1397  if( lhs > XPRS_MINUSINFINITY )
1398  lhs *= scaleval;
1399  else if( scaleval < 0.0 )
1400  lhs = XPRS_PLUSINFINITY;
1401  if( rhs < XPRS_PLUSINFINITY )
1402  rhs *= scaleval;
1403  else if( scaleval < 0.0 )
1404  rhs = XPRS_MINUSINFINITY;
1405 
1406  if( scaleval > 0.0 )
1407  {
1408  SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
1409  }
1410  else
1411  {
1412  SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
1413  }
1414 
1415  return SCIP_OKAY;
1416 }
1417 
1418 /** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1419  * are divided by the scalar; for negative scalars, the column's bounds are switched
1420  */
1422  SCIP_LPI* lpi, /**< LP interface structure */
1423  int col, /**< column number to scale */
1424  SCIP_Real scaleval /**< scaling multiplier */
1425  )
1426 {
1427  SCIP_Real lb;
1428  SCIP_Real ub;
1429  SCIP_Real obj;
1430  int nnonz;
1431  int nrows;
1432  int i;
1433 
1434  assert(lpi != NULL);
1435  assert(lpi->xprslp != NULL);
1436  assert(scaleval != 0.0);
1437 
1438  SCIPdebugMessage("scaling column %d with factor %g in Xpress\n", col, scaleval);
1439 
1440  invalidateSolution(lpi);
1441 
1442  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
1443  SCIP_CALL( ensureValMem(lpi, nrows) );
1444 
1445  /* get the column */
1446  CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, &lb, col, col) );
1447  CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, &ub, col, col) );
1448  CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, col, col) );
1449  assert(nnonz <= nrows);
1450 
1451  /* get objective coefficient */
1452  SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
1453 
1454  /* scale column coefficients */
1455  for( i = 0; i < nnonz; ++i )
1456  {
1457  SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
1458  }
1459 
1460  /* scale objective value */
1461  obj *= scaleval;
1462  SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
1463 
1464  /* scale column bounds */
1465  if( lb > XPRS_MINUSINFINITY )
1466  lb /= scaleval;
1467  else if( scaleval < 0.0 )
1468  lb = XPRS_PLUSINFINITY;
1469  if( ub < XPRS_PLUSINFINITY )
1470  ub /= scaleval;
1471  else if( scaleval < 0.0 )
1472  ub = XPRS_MINUSINFINITY;
1473 
1474  if( scaleval > 0.0 )
1475  {
1476  SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
1477  }
1478  else
1479  {
1480  SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
1481  }
1482 
1483  return SCIP_OKAY;
1484 }
1485 
1486 /**@} */
1487 
1488 
1489 /**@name Data Accessing Methods
1490  *
1491  * @{
1492  */
1493 
1494 /** gets the number of rows in the LP */
1496  SCIP_LPI* lpi, /**< LP interface structure */
1497  int* nrows /**< pointer to store the number of rows */
1498  )
1499 {
1500  assert(lpi != NULL);
1501  assert(lpi->xprslp != NULL);
1502  assert(nrows != NULL);
1503 
1504  SCIPdebugMessage("getting number of rows\n");
1505 
1506  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, nrows) );
1507 
1508  return SCIP_OKAY;
1509 }
1510 
1511 /** gets the number of columns in the LP */
1513  SCIP_LPI* lpi, /**< LP interface structure */
1514  int* ncols /**< pointer to store the number of cols */
1515  )
1516 {
1517  assert(lpi != NULL);
1518  assert(lpi->xprslp != NULL);
1519  assert(ncols != NULL);
1520 
1521  SCIPdebugMessage("getting number of columns\n");
1522 
1523  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, ncols) );
1524 
1525  return SCIP_OKAY;
1526 }
1527 
1528 /** gets the number of nonzero elements in the LP constraint matrix */
1530  SCIP_LPI* lpi, /**< LP interface structure */
1531  int* nnonz /**< pointer to store the number of nonzeros */
1532  )
1533 {
1534  assert(lpi != NULL);
1535  assert(lpi->xprslp != NULL);
1536  assert(nnonz != NULL);
1537 
1538  SCIPdebugMessage("getting number of non-zeros\n");
1539 
1540  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ELEMS, nnonz) );
1541 
1542  return SCIP_OKAY;
1543 }
1544 
1545 /** gets columns from LP problem object; the arrays have to be large enough to store all values
1546  * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1547  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1548  */
1550  SCIP_LPI* lpi, /**< LP interface structure */
1551  int firstcol, /**< first column to get from LP */
1552  int lastcol, /**< last column to get from LP */
1553  SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
1554  SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
1555  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1556  int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1557  int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1558  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1559  )
1560 {
1561  assert(lpi != NULL);
1562  assert(lpi->xprslp != NULL);
1563  assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
1564  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1565 
1566  debugCheckColrang(lpi, firstcol, lastcol);
1567 
1568  SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
1569 
1570  if( lb != NULL )
1571  {
1572  CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, lb, firstcol, lastcol) );
1573  CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, ub, firstcol, lastcol) );
1574  }
1575 
1576  if( nnonz != NULL )
1577  {
1578  int ntotalnonz;
1579  int c;
1580 
1581  /* ensure that the temporary buffer array is large enough */
1582  SCIP_CALL( ensureValMem(lpi, lastcol-firstcol+2) );
1583 
1584  /* get number of nonzero in the whole problem; needed to pass a proper size to XPRSgetcols() function call
1585  *
1586  * @note We are assuming that the arrays given by SCIP are large enough. Otherwise we are getting invalid writes
1587  */
1588  SCIP_CALL( SCIPlpiGetNNonz(lpi, &ntotalnonz) );
1589 
1590  /* get matrix entries */
1591  CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, lpi->indarray, ind, val, ntotalnonz, nnonz, firstcol, lastcol) );
1592  assert(*nnonz <= ntotalnonz);
1593  assert(lpi->indarray[lastcol-firstcol+1] == *nnonz);
1594 
1595  assert(beg != NULL); /* for lint */
1596  for( c = 0; c < lastcol-firstcol+1; c++ )
1597  beg[c] = lpi->indarray[c];
1598  }
1599 
1600  return SCIP_OKAY;
1601 }
1602 
1603 /** gets rows from LP problem object; the arrays have to be large enough to store all values.
1604  * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
1605  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1606  */
1608  SCIP_LPI* lpi, /**< LP interface structure */
1609  int firstrow, /**< first row to get from LP */
1610  int lastrow, /**< last row to get from LP */
1611  SCIP_Real* lhss, /**< buffer to store left hand side vector, or NULL */
1612  SCIP_Real* rhss, /**< buffer to store right hand side vector, or NULL */
1613  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1614  int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
1615  int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
1616  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1617  )
1618 {
1619  assert(lpi != NULL);
1620  assert(lpi->xprslp != NULL);
1621  assert((lhss != NULL && rhss != NULL) || (lhss == NULL && rhss == NULL));
1622  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1623 
1624  debugCheckRowrang(lpi, firstrow, lastrow);
1625 
1626  SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
1627 
1628  if( lhss != NULL )
1629  {
1630  /* get left and right sides */
1631  SCIP_CALL( SCIPlpiGetSides(lpi, firstrow, lastrow, lhss, rhss) );
1632  }
1633 
1634  if( nnonz != NULL )
1635  {
1636  int ntotalnonz;
1637  int r;
1638 
1639  /* ensure that the temporary buffer array is large enough */
1640  SCIP_CALL( ensureValMem(lpi, lastrow-firstrow+2) );
1641 
1642  /* get number of nonzero in the whole problem; needed to pass a proper size to XPRSgetrows() function call
1643  *
1644  * @note We are assuming that the arrays given by SCIP are large enough. Otherwise we are getting invalid writes
1645  */
1646  SCIP_CALL( SCIPlpiGetNNonz(lpi, &ntotalnonz) );
1647 
1648  /* get matrix entries */
1649  CHECK_ZERO( lpi->messagehdlr, XPRSgetrows(lpi->xprslp, lpi->indarray, ind, val, ntotalnonz, nnonz, firstrow, lastrow) );
1650  assert(*nnonz <= ntotalnonz);
1651  assert(lpi->indarray[lastrow-firstrow+1] == *nnonz);
1652 
1653  assert(beg != NULL); /* for lint */
1654  for( r = 0; r < lastrow-firstrow+1; r++ )
1655  beg[r] = lpi->indarray[r];
1656  }
1657 
1658  return SCIP_OKAY;
1659 }
1660 
1661 /** gets column names */
1663  SCIP_LPI* lpi, /**< LP interface structure */
1664  int firstcol, /**< first column to get name from LP */
1665  int lastcol, /**< last column to get name from LP */
1666  char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
1667  char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
1668  int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
1669  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
1670  )
1671 { /*lint --e{715}*/
1672  assert(lpi != NULL);
1673  assert(lpi->xprslp != NULL);
1674  assert(colnames != NULL || namestoragesize == 0);
1675  assert(namestorage != NULL || namestoragesize == 0);
1676  assert(namestoragesize >= 0);
1677  assert(storageleft != NULL);
1678  assert(0 <= firstcol && firstcol <= lastcol);
1679 
1680  SCIPerrorMessage("SCIPlpiGetColNames() has not been implemented yet.\n");
1681  return SCIP_LPERROR;
1682 }
1683 
1684 /** gets row names */
1686  SCIP_LPI* lpi, /**< LP interface structure */
1687  int firstrow, /**< first row to get name from LP */
1688  int lastrow, /**< last row to get name from LP */
1689  char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
1690  char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
1691  int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
1692  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
1693  )
1694 { /*lint --e{715}*/
1695  assert(lpi != NULL);
1696  assert(lpi->xprslp != NULL);
1697  assert(rownames != NULL || namestoragesize == 0);
1698  assert(namestorage != NULL || namestoragesize == 0);
1699  assert(namestoragesize >= 0);
1700  assert(storageleft != NULL);
1701  assert(0 <= firstrow && firstrow <= lastrow);
1702 
1703  SCIPerrorMessage("SCIPlpiGetRowNames() has not been implemented yet.\n");
1704  return SCIP_LPERROR;
1705 }
1706 
1707 /** gets the objective sense of the LP */
1709  SCIP_LPI* lpi, /**< LP interface structure */
1710  SCIP_OBJSEN* objsen /**< pointer to store objective sense */
1711  )
1712 {
1713  double xprsobjsen;
1714  assert(lpi != NULL);
1715  assert(lpi->xprslp != NULL);
1716  assert(objsen != NULL);
1717 
1718  /* check the objective sense attribute for the current objective sense set in Xpress */
1719  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_OBJSENSE, &xprsobjsen) );
1720 
1721  /* convert the Xpress objective sense attribute to a SCIP objective sense */
1722  if( xprsobjsen < 0.0 )
1723  (*objsen) = SCIP_OBJSEN_MAXIMIZE;
1724  else
1725  (*objsen) = SCIP_OBJSEN_MINIMIZE;
1726 
1727  return SCIP_OKAY;
1728 }
1729 
1730 /** gets objective coefficients from LP problem object */
1732  SCIP_LPI* lpi, /**< LP interface structure */
1733  int firstcol, /**< first column to get objective coefficient for */
1734  int lastcol, /**< last column to get objective coefficient for */
1735  SCIP_Real* vals /**< array to store objective coefficients */
1736  )
1737 {
1738  assert(lpi != NULL);
1739  assert(lpi->xprslp != NULL);
1740  assert(firstcol <= lastcol);
1741  assert(vals != NULL);
1742 
1743  SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
1744 
1745  CHECK_ZERO( lpi->messagehdlr, XPRSgetobj(lpi->xprslp, vals, firstcol, lastcol) );
1746 
1747  return SCIP_OKAY;
1748 }
1749 
1750 /** gets current bounds from LP problem object */
1752  SCIP_LPI* lpi, /**< LP interface structure */
1753  int firstcol, /**< first column to get bounds for */
1754  int lastcol, /**< last column to get bounds for */
1755  SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
1756  SCIP_Real* ubs /**< array to store upper bound values, or NULL */
1757  )
1758 {
1759  assert(lpi != NULL);
1760  assert(lpi->xprslp != NULL);
1761  assert(firstcol <= lastcol);
1762 
1763  SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
1764 
1765  if( lbs != NULL )
1766  {
1767  CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, lbs, firstcol, lastcol) );
1768  }
1769 
1770  if( ubs != NULL )
1771  {
1772  CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, ubs, firstcol, lastcol) );
1773  }
1774 
1775  return SCIP_OKAY;
1776 }
1777 
1778 /** gets current row sides from LP problem object */
1780  SCIP_LPI* lpi, /**< LP interface structure */
1781  int firstrow, /**< first row to get sides for */
1782  int lastrow, /**< last row to get sides for */
1783  SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
1784  SCIP_Real* rhss /**< array to store right hand side values, or NULL */
1785  )
1786 {
1787  assert(lpi != NULL);
1788  assert(lpi->xprslp != NULL);
1789  assert(firstrow <= lastrow);
1790 
1791  SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
1792 
1793  /* ensure the array size of the temporary buffers */
1794  SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
1795 
1796  /* get row sense, rhs, and ranges */
1797  CHECK_ZERO( lpi->messagehdlr, XPRSgetrowtype(lpi->xprslp, lpi->senarray, firstrow, lastrow) );
1798  CHECK_ZERO( lpi->messagehdlr, XPRSgetrhs(lpi->xprslp, lpi->rhsarray, firstrow, lastrow) );
1799  CHECK_ZERO( lpi->messagehdlr, XPRSgetrhsrange(lpi->xprslp, lpi->rngarray, firstrow, lastrow) );
1800 
1801  /* convert sen/rhs/range into lhs/rhs tuples */
1802  reconvertSides(lpi, lastrow - firstrow + 1, lhss, rhss);
1803 
1804  return SCIP_OKAY;
1805 }
1806 
1807 /** gets a single coefficient */
1809  SCIP_LPI* lpi, /**< LP interface structure */
1810  int row, /**< row number of coefficient */
1811  int col, /**< column number of coefficient */
1812  SCIP_Real* val /**< pointer to store the value of the coefficient */
1813  )
1814 {
1815  assert(lpi != NULL);
1816  assert(lpi->xprslp != NULL);
1817  assert(val != NULL);
1818 
1819  /* get the coefficient of the column in the corresponding row */
1820  CHECK_ZERO( lpi->messagehdlr, XPRSgetcoef(lpi->xprslp, row, col, val) );
1821 
1822  return SCIP_OKAY;
1823 }
1824 
1825 /**@} */
1826 
1827 
1828 /**@name Solving Methods
1829  *
1830  * @{
1831  */
1832 
1833 /** solve LP */
1835  SCIP_LPI* lpi, /**< LP interface structure */
1836  const char* method /**< indicates the method to use ('p' - primal, 'd' - dual, 'b' - barrier) */
1837  )
1838 {
1839  int primalinfeasible;
1840  int dualinfeasible;
1841  int state;
1842 
1843  assert(lpi != NULL);
1844  assert(lpi->xprslp != NULL);
1845 
1846  invalidateSolution(lpi);
1847 
1848  /* check if the current basis should be ignored */
1849  if( lpi->clearstate )
1850  {
1851  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, 0) );
1852  lpi->clearstate = FALSE;
1853  }
1854 
1855  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRESOLVE, 0) );
1856  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, (lpi->par_presolve) ? 1 : 0) );
1857 
1858  if( lpi->par_fastlp )
1859  {
1860  /* Don't refactorize at the end of the solve. */
1861  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_REFACTOR, 0) );
1862  }
1863  else
1864  {
1865  /* Use default settings for solving an lp (hopefully) robustly. */
1866  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_REFACTOR, 1) );
1867  }
1868 
1869  /* solve the LP */
1870  CHECK_ZERO( lpi->messagehdlr, XPRSlpoptimize(lpi->xprslp, method) );
1871 
1872  /* evaluate the result */
1873  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_LPSTATUS, &lpi->solstat) );
1874 
1875  /* Make sure the LP is postsolved in case it was interrupted. */
1876  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_PRESOLVESTATE, &state) );
1877 
1878  if( state & (2|4) )
1879  {
1880  /* Problem is in a presolve state - postsolve it. */
1881  CHECK_ZERO( lpi->messagehdlr, XPRSpostsolve(lpi->xprslp) );
1882  }
1883 
1884  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &lpi->iterations) );
1885  lpi->solisbasic = TRUE;
1886 
1887  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &primalinfeasible) );
1888  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_DUALINFEAS, &dualinfeasible) );
1889  SCIPdebugMessage(" -> Xpress returned solstat=%d, pinfeas=%d, dinfeas=%d (%d iterations)\n",
1890  lpi->solstat, primalinfeasible, dualinfeasible, lpi->iterations);
1891 
1892  /* Make sure that always a primal / dual ray exists */
1893  if( lpi->solstat == XPRS_LP_INFEAS || lpi->solstat == XPRS_LP_UNBOUNDED )
1894  {
1895  int hasray;
1896  int presolving;
1897 
1898  /* check whether a dual ray exists, in that case we don't need to resolve the LP w/o presolving */
1899  CHECK_ZERO( lpi->messagehdlr, XPRSgetdualray(lpi->xprslp, NULL, &hasray) );
1900 
1901  if( hasray == 1 )
1902  goto TERMINATE;
1903 
1904  /* get the current presolving setting */
1905  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, &presolving) );
1906 
1907  if( presolving != 0 )
1908  {
1909  int iterations;
1910 
1911  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
1912  SCIPdebugMessage("presolver may have solved the problem -> calling Xpress %s again without presolve\n",
1913  strcmp(method, "p") == 0 ? "primal simplex" : strcmp(method, "d") == 0 ? "dual simplex" : "barrier");
1914 
1915  /* switch off preprocessing */
1916  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, 0) );
1917 
1918  /* resolve w/o presolving */
1919  CHECK_ZERO( lpi->messagehdlr, XPRSlpoptimize(lpi->xprslp, method) );
1920 
1921  /* evaluate the result */
1922  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_LPSTATUS, &lpi->solstat) );
1923 
1924  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &iterations) );
1925  lpi->iterations += iterations;
1926  lpi->solisbasic = TRUE;
1927 
1928  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &primalinfeasible) );
1929  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_DUALINFEAS, &dualinfeasible) );
1930  SCIPdebugMessage(" -> Xpress returned solstat=%d, pinfeas=%d, dinfeas=%d (%d iterations)\n",
1931  lpi->solstat, primalinfeasible, dualinfeasible, lpi->iterations);
1932 
1933  /* reinstall the previous setting */
1934  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, presolving) );
1935  }
1936  }
1937 
1938  TERMINATE:
1939  if( (lpi->solstat == XPRS_LP_OPTIMAL) && (primalinfeasible || dualinfeasible) )
1941 
1942  return SCIP_OKAY;
1943 }
1944 
1945 /** calls primal simplex to solve the LP */
1947  SCIP_LPI* lpi /**< LP interface structure */
1948  )
1949 {
1950  assert(lpi != NULL);
1951  assert(lpi->xprslp != NULL);
1952 
1953  lpi->solmethod = 'p';
1954  return lpiSolve(lpi, "p");
1955 }
1956 
1957 /** calls dual simplex to solve the LP */
1959  SCIP_LPI* lpi /**< LP interface structure */
1960  )
1961 {
1962  assert(lpi != NULL);
1963  assert(lpi->xprslp != NULL);
1964 
1965  lpi->solmethod = 'd';
1966  return lpiSolve(lpi, "d");
1967 }
1968 
1969 /** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
1971  SCIP_LPI* lpi, /**< LP interface structure */
1972  SCIP_Bool crossover /**< perform crossover */
1973  )
1974 {
1975  SCIP_RETCODE retval;
1976 
1977  assert(lpi != NULL);
1978  assert(lpi->xprslp != NULL);
1979 
1980  lpi->solmethod = 'b';
1981 
1982  /* enable or disable cross over */
1983  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_CROSSOVER, crossover == TRUE ? -1 : 0) );
1984 
1985  retval = lpiSolve(lpi, "b");
1986  lpi->solisbasic = crossover;
1987 
1988  return retval;
1989 }
1990 
1991 /** start strong branching - call before any strong branching */
1993  SCIP_LPI* lpi /**< LP interface structure */
1994  )
1995 { /*lint --e{715}*/
1996  assert(lpi != NULL);
1997  assert(lpi->xprslp != NULL);
1998 
1999  /* currently do nothing */
2000  return SCIP_OKAY;
2001 }
2002 
2003 /** end strong branching - call after any strong branching */
2005  SCIP_LPI* lpi /**< LP interface structure */
2006  )
2007 { /*lint --e{715}*/
2008  assert(lpi != NULL);
2009  assert(lpi->xprslp != NULL);
2010 
2011  /* currently do nothing */
2012  return SCIP_OKAY;
2013 }
2014 
2015 /** performs strong branching iterations on one candidate */
2016 static
2018  SCIP_LPI* lpi, /**< LP interface structure */
2019  int col, /**< column to apply strong branching on */
2020  SCIP_Real psol, /**< current primal solution value of column */
2021  int itlim, /**< iteration limit for strong branchings */
2022  SCIP_Real* down, /**< stores dual bound after branching column down */
2023  SCIP_Real* up, /**< stores dual bound after branching column up */
2024  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2025  * otherwise, it can only be used as an estimate value */
2026  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2027  * otherwise, it can only be used as an estimate value */
2028  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2029  )
2030 {
2031  SCIP_OBJSEN objsen;
2032  double dbndval[2];
2033  double dobjval[2];
2034  char cbndtype[2];
2035  int mbndind[2];
2036  int mstatus[2];
2037 
2038  assert(lpi != NULL);
2039  assert(lpi->xprslp != NULL);
2040  assert(down != NULL);
2041  assert(up != NULL);
2042  assert(downvalid != NULL);
2043  assert(upvalid != NULL);
2044 
2045  SCIPdebugMessage("calling Xpress strong branching on variable %d (%d iterations)\n", col, itlim);
2046 
2047  /* results of Xpress are valid in any case */
2048  *downvalid = TRUE;
2049  *upvalid = TRUE;
2050 
2051  SCIPdebugMessage(" -> strong branching on integral variable\n");
2052 
2053  if( iter != NULL )
2054  *iter = 0;
2055 
2056  /* get objective sense of the current LP */
2057  SCIP_CALL( SCIPlpiGetObjsen(lpi, &objsen) );
2058 
2059  /* Set the branching bounds (down first, up second). */
2060  mbndind[0] = col;
2061  dbndval[0] = EPSCEIL(psol-1.0, 1e-06);
2062  cbndtype[0] = 'U';
2063  mbndind[1] = col;
2064  dbndval[1] = EPSFLOOR(psol+1.0, 1e-06);
2065  cbndtype[1] = 'L';
2066 
2067  /* Apply strong branching to the two branches. */
2068  CHECK_ZERO( lpi->messagehdlr, XPRSstrongbranch(lpi->xprslp, 2, mbndind, cbndtype, dbndval, itlim, dobjval, mstatus) );
2069 
2070  /* Get the objective of the down branch. */
2071  if( (mstatus[0] == XPRS_LP_INFEAS) || (mstatus[0] == XPRS_LP_CUTOFF_IN_DUAL) )
2072  *down = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
2073  else if( (mstatus[0] == XPRS_LP_OPTIMAL) || (mstatus[0] == XPRS_LP_UNFINISHED) )
2074  *down = dobjval[0];
2075  else
2076  {
2077  /* Something weird happened. */
2078  *downvalid = FALSE;
2079  }
2080 
2081  /* Get the objective of the up branch. */
2082  if( (mstatus[1] == XPRS_LP_INFEAS) || (mstatus[1] == XPRS_LP_CUTOFF_IN_DUAL) )
2083  *up = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
2084  else if( (mstatus[1] == XPRS_LP_OPTIMAL) || (mstatus[1] == XPRS_LP_UNFINISHED) )
2085  *up = dobjval[1];
2086  else
2087  {
2088  /* Something weird happened. */
2089  *upvalid = FALSE;
2090  }
2091 
2092  /* When using the XPRSstrongbranch function we are unable to provide an iteration count */
2093  if( iter != NULL )
2094  *iter = -1;
2095 
2096  return SCIP_OKAY;
2097 }
2098 
2099 /** performs strong branching iterations on given candidates */
2100 static
2102  SCIP_LPI* lpi, /**< LP interface structure */
2103  int* cols, /**< columns to apply strong branching on */
2104  int ncols, /**< number of columns */
2105  SCIP_Real* psols, /**< current primal solution values of columns (might be integral) */
2106  int itlim, /**< iteration limit for strong branchings */
2107  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2108  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2109  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2110  * otherwise, they can only be used as an estimate values */
2111  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2112  * otherwise, they can only be used as an estimate values */
2113  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2114  )
2115 {
2116  double* dbndval;
2117  double* dobjval;
2118  char* cbndtype;
2119  int* mbndind;
2120  int* mstatus;
2121  SCIP_OBJSEN objsen;
2122  int nbranches;
2123  int j;
2124 
2125  assert( lpi != NULL );
2126  assert( lpi->xprslp != NULL );
2127  assert( cols != NULL );
2128  assert( psols != NULL );
2129  assert( down != NULL );
2130  assert( up != NULL );
2131  assert( downvalid != NULL );
2132  assert( upvalid != NULL );
2133 
2134  SCIPdebugMessage("calling Xpress strong branching on %d variables (%d iterations)\n", ncols, itlim);
2135 
2136  if( iter != NULL )
2137  *iter = 0;
2138 
2139  /* compute the number of branches; for each column we have 2 branches */
2140  nbranches = 2*ncols;
2141 
2142  /* get objective sense of the current LP */
2143  SCIP_CALL( SCIPlpiGetObjsen(lpi, &objsen) );
2144 
2145  /* Set the branching bounds (down first, up second). */
2146  SCIP_ALLOC( BMSallocMemoryArray(&mbndind, nbranches) );
2147  SCIP_ALLOC( BMSallocMemoryArray(&dbndval, nbranches) );
2148  SCIP_ALLOC( BMSallocMemoryArray(&cbndtype, nbranches) );
2149  SCIP_ALLOC( BMSallocMemoryArray(&dobjval, nbranches) );
2150  SCIP_ALLOC( BMSallocMemoryArray(&mstatus, nbranches) );
2151 
2152  /* construct the bounds for the strong branches */
2153  for( j = 0; j < ncols; ++j )
2154  {
2155  mbndind[2*j] = cols[j];
2156  dbndval[2*j] = EPSCEIL(psols[j] - 1.0, 1e-06);
2157  cbndtype[2*j] = 'U';
2158 
2159  mbndind[2*j+1] = cols[j];
2160  dbndval[2*j+1] = EPSFLOOR(psols[j] + 1.0, 1e-06);
2161  cbndtype[2*j+1] = 'L';
2162  }
2163 
2164  /* apply strong branching to the 2*ncols branches. */
2165  CHECK_ZERO( lpi->messagehdlr, XPRSstrongbranch(lpi->xprslp, nbranches, mbndind, cbndtype, dbndval, itlim, dobjval, mstatus) );
2166 
2167  for( j = 0; j < ncols; ++j )
2168  {
2169  upvalid[j] = TRUE;
2170  downvalid[j] = TRUE;
2171 
2172  /* Get the objective of the down branch. */
2173  if( (mstatus[2*j] == XPRS_LP_INFEAS) || (mstatus[2*j] == XPRS_LP_CUTOFF_IN_DUAL) )
2174  down[j] = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
2175  else if( (mstatus[2*j] == XPRS_LP_OPTIMAL) || (mstatus[2*j] == XPRS_LP_UNFINISHED) )
2176  down[j] = dobjval[2*j];
2177  else
2178  {
2179  /* Something weird happened. */
2180  downvalid[j] = FALSE;
2181  }
2182 
2183  /* Get the objective of the up branch. */
2184  if( (mstatus[2*j+1] == XPRS_LP_INFEAS) || (mstatus[2*j+1] == XPRS_LP_CUTOFF_IN_DUAL) )
2185  up[j] = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
2186  else if( (mstatus[2*j+1] == XPRS_LP_OPTIMAL) || (mstatus[2*j+1] == XPRS_LP_UNFINISHED) )
2187  up[j] = dobjval[2*j+1];
2188  else
2189  {
2190  /* Something weird happened. */
2191  upvalid[j] = FALSE;
2192  }
2193  }
2194 
2195  /* When using the XPRSstrongbranch function we are unable to provide
2196  * an iteration count.
2197  */
2198  if( iter != NULL )
2199  *iter = -1;
2200 
2201  BMSfreeMemoryArray(&mstatus);
2202  BMSfreeMemoryArray(&dobjval);
2203  BMSfreeMemoryArray(&cbndtype);
2204  BMSfreeMemoryArray(&dbndval);
2205  BMSfreeMemoryArray(&mbndind);
2206 
2207  return SCIP_OKAY;
2208 }
2209 
2210 /** performs strong branching iterations on one @b fractional candidate */
2212  SCIP_LPI* lpi, /**< LP interface structure */
2213  int col, /**< column to apply strong branching on */
2214  SCIP_Real psol, /**< fractional current primal solution value of column */
2215  int itlim, /**< iteration limit for strong branchings */
2216  SCIP_Real* down, /**< stores dual bound after branching column down */
2217  SCIP_Real* up, /**< stores dual bound after branching column up */
2218  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2219  * otherwise, it can only be used as an estimate value */
2220  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2221  * otherwise, it can only be used as an estimate value */
2222  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2223  )
2224 {
2225  /* pass call on to lpiStrongbranch() */
2226  SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
2227 
2228  return SCIP_OKAY;
2229 }
2230 
2231 /** performs strong branching iterations on given @b fractional candidates */
2233  SCIP_LPI* lpi, /**< LP interface structure */
2234  int* cols, /**< columns to apply strong branching on */
2235  int ncols, /**< number of columns */
2236  SCIP_Real* psols, /**< fractional current primal solution values of columns */
2237  int itlim, /**< iteration limit for strong branchings */
2238  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2239  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2240  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2241  * otherwise, they can only be used as an estimate values */
2242  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2243  * otherwise, they can only be used as an estimate values */
2244  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2245  )
2246 {
2247  /* pass call on to lpiStrongbranches() */
2248  SCIP_CALL( lpiStrongbranches(lpi, cols, ncols, psols, itlim, down, up, downvalid, upvalid, iter) );
2249 
2250  return SCIP_OKAY;
2251 }
2252 
2253 /** performs strong branching iterations on one candidate with @b integral value */
2255  SCIP_LPI* lpi, /**< LP interface structure */
2256  int col, /**< column to apply strong branching on */
2257  SCIP_Real psol, /**< current integral primal solution value of column */
2258  int itlim, /**< iteration limit for strong branchings */
2259  SCIP_Real* down, /**< stores dual bound after branching column down */
2260  SCIP_Real* up, /**< stores dual bound after branching column up */
2261  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2262  * otherwise, it can only be used as an estimate value */
2263  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2264  * otherwise, it can only be used as an estimate value */
2265  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2266  )
2267 {
2268  /* pass call on to lpiStrongbranch() */
2269  SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
2270 
2271  return SCIP_OKAY;
2272 }
2273 
2274 /** performs strong branching iterations on given candidates with @b integral values */
2276  SCIP_LPI* lpi, /**< LP interface structure */
2277  int* cols, /**< columns to apply strong branching on */
2278  int ncols, /**< number of columns */
2279  SCIP_Real* psols, /**< current integral primal solution values of columns */
2280  int itlim, /**< iteration limit for strong branchings */
2281  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2282  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2283  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2284  * otherwise, they can only be used as an estimate values */
2285  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2286  * otherwise, they can only be used as an estimate values */
2287  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2288  )
2289 {
2290  /* pass call on to lpiStrongbranches() */
2291  SCIP_CALL( lpiStrongbranches(lpi, cols, ncols, psols, itlim, down, up, downvalid, upvalid, iter) );
2292 
2293  return SCIP_OKAY;
2294 }
2295 
2296 /**@} */
2297 
2298 
2299 /**@name Solution Information Methods
2300  *
2301  * @{
2302  */
2303 
2304 /** returns whether a solve method was called after the last modification of the LP */
2306  SCIP_LPI* lpi /**< LP interface structure */
2307  )
2308 {
2309  assert(lpi != NULL);
2310 
2311  return (lpi->solstat != -1);
2312 }
2313 
2314 /** gets information about primal and dual feasibility of the current LP solution
2315  *
2316  * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
2317  * returns true. If the LP is changed, this information might be invalidated.
2318  *
2319  * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
2320  * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
2321  * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
2322  * the problem might actually be feasible).
2323  */
2325  SCIP_LPI* lpi, /**< LP interface structure */
2326  SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
2327  SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
2328  )
2329 {
2330  assert(lpi != NULL);
2331  assert(lpi->xprslp != NULL);
2332  assert(primalfeasible != NULL);
2333  assert(dualfeasible != NULL);
2334 
2335  SCIPdebugMessage("getting solution feasibility\n");
2336 
2337  *primalfeasible = SCIPlpiIsPrimalFeasible(lpi);
2338  *dualfeasible = SCIPlpiIsDualFeasible(lpi);
2339 
2340  return SCIP_OKAY;
2341 }
2342 
2343 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
2344  * this does not necessarily mean, that the solver knows and can return the primal ray
2345  */
2347  SCIP_LPI* lpi /**< LP interface structure */
2348  )
2349 {
2350  assert(lpi != NULL);
2351  assert(lpi->xprslp != NULL);
2352  assert(lpi->solstat >= 0);
2353 
2354  return (lpi->solstat == XPRS_LP_UNBOUNDED);
2355 }
2356 
2357 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
2358  * and the solver knows and can return the primal ray
2359  */
2361  SCIP_LPI* lpi /**< LP interface structure */
2362  )
2363 {
2364  int hasRay;
2365 
2366  assert(lpi != NULL);
2367  assert(lpi->xprslp != NULL);
2368  assert(lpi->solstat >= 0);
2369 
2370  /* check if the LP solution status is unbounded and that primal was solving the LP */
2371  if (lpi->solstat != XPRS_LP_UNBOUNDED || lpi->solmethod != 'p')
2372  return FALSE;
2373 
2374  /* check if we can construct a primal ray */
2375  ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetprimalray(lpi->xprslp, NULL, &hasRay) );
2376 
2377  return (SCIP_Bool)hasRay;
2378 }
2379 
2380 /** returns TRUE iff LP is proven to be primal feasible and unbounded */
2382  SCIP_LPI* lpi /**< LP interface structure */
2383  )
2384 {
2385  assert(lpi != NULL);
2386  assert(lpi->xprslp != NULL);
2387  assert(lpi->solstat >= 0);
2388 
2389  SCIPdebugMessage("checking for primal unboundedness\n");
2390 
2391  /* If the solution status of Xpress is XPRS_LP_UNBOUNDED, it only means, there is an unbounded ray,
2392  * but not necessarily a feasible primal solution. If problem is declared LP_UNBOUNDED by dual,
2393  * we have no way to decide primal feasibility.
2394  */
2395 
2396  return lpi->solstat == XPRS_LP_UNBOUNDED && lpi->solmethod == 'p';
2397 }
2398 
2399 /** returns TRUE iff LP is proven to be primal infeasible */
2401  SCIP_LPI* lpi /**< LP interface structure */
2402  )
2403 {
2404  assert(lpi != NULL);
2405  assert(lpi->xprslp != NULL);
2406  assert(lpi->solstat >= 0);
2407 
2408  SCIPdebugMessage("checking for primal infeasibility\n");
2409 
2410  return (lpi->solstat == XPRS_LP_INFEAS);
2411 }
2412 
2413 /** returns TRUE iff LP is proven to be primal feasible */
2415  SCIP_LPI* lpi /**< LP interface structure */
2416  )
2417 {
2418  int nInfeasible;
2419  int nIter;
2420 
2421  assert(lpi != NULL);
2422  assert(lpi->xprslp != NULL);
2423  assert(lpi->solstat >= 0);
2424 
2425  SCIPdebugMessage("checking for primal feasibility\n");
2426 
2427  /* check if problem is solved to optimality */
2428  if (lpi->solstat == XPRS_LP_OPTIMAL || lpi->solstat == XPRS_LP_OPTIMAL_SCALEDINFEAS)
2429  return TRUE;
2430 
2431  /* check if problem is unbounded (found by primal) */
2432  if (lpi->solstat == XPRS_LP_UNBOUNDED && lpi->solmethod == 'p')
2433  return TRUE;
2434 
2435  /* get number of primal infeasibilities and number of simplex iterations */
2436  ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &nInfeasible) );
2437  ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &nIter) );
2438 
2439  /* check if the number of primal infeasibilities is zero
2440  * We need to make sure that the LP was indeed solved by primal, otherwise infeasibility might have been found
2441  * in setup (e.g. if conflicting bounds x >= 1, x <= 0 are present),
2442  */
2443  if (nInfeasible == 0 && nIter > 0 && lpi->solmethod == 'p')
2444  return TRUE;
2445 
2446  return FALSE;
2447 }
2448 
2449 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
2450  * this does not necessarily mean, that the solver knows and can return the dual ray
2451  */
2453  SCIP_LPI* lpi /**< LP interface structure */
2454  )
2455 {
2456  assert(lpi != NULL);
2457  assert(lpi->xprslp != NULL);
2458  assert(lpi->solstat >= 0);
2459 
2460  return (lpi->solstat == XPRS_LP_INFEAS);
2461 }
2462 
2463 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
2464  * and the solver knows and can return the dual ray
2465  */
2467  SCIP_LPI* lpi /**< LP interface structure */
2468  )
2469 {
2470  int hasRay;
2471 
2472  assert(lpi != NULL);
2473  assert(lpi->xprslp != NULL);
2474  assert(lpi->solstat >= 0);
2475 
2476  ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetdualray(lpi->xprslp, NULL, &hasRay) );
2477 
2478  return (SCIP_Bool) hasRay;
2479 }
2480 
2481 /** returns TRUE iff LP is proven to be dual unbounded */
2483  SCIP_LPI* lpi /**< LP interface structure */
2484  )
2485 {
2486  assert(lpi != NULL);
2487  assert(lpi->xprslp != NULL);
2488  assert(lpi->solstat >= 0);
2489 
2490  SCIPdebugMessage("checking for dual unboundedness\n");
2491 
2492  return ((lpi->solstat == XPRS_LP_INFEAS) && (lpi->solmethod == 'd'));
2493 }
2494 
2495 /** returns TRUE iff LP is proven to be dual infeasible */
2497  SCIP_LPI* lpi /**< LP interface structure */
2498  )
2499 {
2500  assert(lpi != NULL);
2501  assert(lpi->xprslp != NULL);
2502  assert(lpi->solstat >= 0);
2503 
2504  SCIPdebugMessage("checking for dual infeasibility\n");
2505 
2506  return (lpi->solstat == XPRS_LP_UNBOUNDED);
2507 }
2508 
2509 /** returns TRUE iff LP is proven to be dual feasible */
2511  SCIP_LPI* lpi /**< LP interface structure */
2512  )
2513 {
2514  int nInfeasible;
2515  int nIter;
2516 
2517  assert(lpi != NULL);
2518  assert(lpi->xprslp != NULL);
2519  assert(lpi->solstat >= 0);
2520 
2521  SCIPdebugMessage("checking for dual feasibility\n");
2522 
2523  /* check if problem solved to optimality */
2524  if (lpi->solstat == XPRS_LP_OPTIMAL || lpi->solstat == XPRS_LP_OPTIMAL_SCALEDINFEAS)
2525  return TRUE;
2526 
2527  /* check if problem infeasibility detected by dual */
2528  if (lpi->solstat == XPRS_LP_INFEAS && lpi->solmethod == 'd')
2529  return TRUE;
2530 
2531  /* get number of dual infeasibilities and number of simplex iterations */
2532  ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_DUALINFEAS, &nInfeasible) );
2533  ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &nIter) );
2534 
2535  /* check if the number of dual infeasibilities is zero
2536  * We need to make sure that the LP was indeed solved by primal, otherwise infeasibility might have been found
2537  * in setup (e.g. if conflicting bounds x >= 1, x <= 0 are present),
2538  */
2539  if (nInfeasible == 0 && nIter > 0 && lpi->solmethod == 'd')
2540  return TRUE;
2541 
2542  return FALSE;
2543 }
2544 
2545 /** returns TRUE iff LP was solved to optimality */
2547  SCIP_LPI* lpi /**< LP interface structure */
2548  )
2549 {
2550  assert(lpi != NULL);
2551  assert(lpi->xprslp != NULL);
2552  assert(lpi->solstat >= 0);
2553 
2554  return (lpi->solstat == XPRS_LP_OPTIMAL) || (lpi->solstat == XPRS_LP_OPTIMAL_SCALEDINFEAS);
2555 }
2556 
2557 /** returns TRUE iff current LP solution is stable
2558  *
2559  * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
2560  * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
2561  * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
2562  * SCIPlpiIsStable() should return false.
2563  */
2565  SCIP_LPI* lpi /**< LP interface structure */
2566  )
2567 {
2568  assert(lpi != NULL);
2569  assert(lpi->xprslp != NULL);
2570  assert(lpi->solstat >= 0);
2571 
2572  SCIPdebugMessage("checking for stability: Xpress solstat = %d\n", lpi->solstat);
2573 
2574 #ifdef SCIP_DISABLED_CODE
2575  /* The following workaround is not needed anymore for SCIP, since it tries to heuristically construct a feasible
2576  * solution or automatically resolves the problem if the status is "unbounded"; see SCIPlpGetUnboundedSol().
2577  */
2578 
2579  /* If the solution status of Xpress is XPRS_LP_UNBOUNDED, it only means, there is an unbounded ray,
2580  * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we interpret this
2581  * result as instability, s.t. the problem is resolved from scratch
2582  */
2583  if( lpi->solstat == XPRS_LP_UNBOUNDED )
2584  {
2585  int retcode;
2586  int pinfeas;
2587 
2588  retcode = XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &pinfeas);
2589 
2590  if( retcode != 0 || pinfeas )
2591  return FALSE;
2592  }
2593 #endif
2594 
2596  {
2597  /* presolved problem was solved to optimality but infeasibilities were introduced by postsolve */
2598  return FALSE;
2599  }
2600 
2601  return TRUE;
2602 }
2603 
2604 /** returns TRUE iff the objective limit was reached */
2606  SCIP_LPI* lpi /**< LP interface structure */
2607  )
2608 {
2609  assert(lpi != NULL);
2610  assert(lpi->xprslp != NULL);
2611  assert(lpi->solstat >= 0);
2612 
2613  return (lpi->solstat == XPRS_LP_CUTOFF || lpi->solstat == XPRS_LP_CUTOFF_IN_DUAL);
2614 }
2615 
2616 /** returns TRUE iff the iteration limit was reached */
2618  SCIP_LPI* lpi /**< LP interface structure */
2619  )
2620 {
2621  int lpiter;
2622  int lpiterlimit;
2623 
2624  assert(lpi != NULL);
2625  assert(lpi->xprslp != NULL);
2626  assert(lpi->solstat >= 0);
2627 
2628  ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &lpiter) );
2629  ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, &lpiterlimit) );
2630 
2631  if( (lpi->solstat == XPRS_LP_UNFINISHED) && (lpiter >= lpiterlimit) )
2632  return TRUE;
2633  else
2634  return FALSE;
2635 }
2636 
2637 /** returns TRUE iff the time limit was reached */
2639  SCIP_LPI* lpi /**< LP interface structure */
2640  )
2641 {
2642  int lpiter;
2643  int lpiterlimit;
2644 
2645  assert(lpi != NULL);
2646  assert(lpi->xprslp != NULL);
2647  assert(lpi->solstat >= 0);
2648 
2649  ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &lpiter) );
2650  ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, &lpiterlimit) );
2651 
2652  if( (lpi->solstat == XPRS_LP_UNFINISHED) && (lpiter < lpiterlimit) )
2653  return TRUE;
2654  else
2655  return FALSE;
2656 }
2657 
2658 /** returns the internal solution status of the solver */
2660  SCIP_LPI* lpi /**< LP interface structure */
2661  )
2662 {
2663  assert(lpi != NULL);
2664  assert(lpi->xprslp != NULL);
2665 
2666  return lpi->solstat;
2667 }
2668 
2669 /** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
2671  SCIP_LPI* lpi, /**< LP interface structure */
2672  SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
2673  )
2674 {
2675  assert(lpi != NULL);
2676  assert(lpi->xprslp != NULL);
2677  assert(success != NULL);
2678 
2679  /* Nothing to do here for Xpress. */
2680  *success = TRUE;
2681 
2682  return SCIP_OKAY;
2683 }
2684 
2685 /** gets objective value of solution */
2687  SCIP_LPI* lpi, /**< LP interface structure */
2688  SCIP_Real* objval /**< stores the objective value */
2689  )
2690 {
2691  assert(lpi != NULL);
2692  assert(lpi->xprslp != NULL);
2693  assert(objval != NULL);
2694 
2695  SCIPdebugMessage("getting solution's objective value\n");
2696 
2697  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_LPOBJVAL, objval) );
2698 
2699  return SCIP_OKAY;
2700 }
2701 
2702 /** gets primal and dual solution vectors for feasible LPs
2703  *
2704  * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
2705  * SCIPlpiIsOptimal() returns true.
2706  */
2708  SCIP_LPI* lpi, /**< LP interface structure */
2709  SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
2710  SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
2711  SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
2712  SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
2713  SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
2714  )
2715 {
2716  assert(lpi != NULL);
2717  assert(lpi->xprslp != NULL);
2718  assert(lpi->solstat >= 0);
2719 
2720  SCIPdebugMessage("getting solution\n");
2721 
2722  CHECK_ZERO( lpi->messagehdlr, XPRSgetsol(lpi->xprslp, primsol, activity, dualsol, redcost) );
2723 
2724  if( objval != NULL )
2725  {
2726  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_LPOBJVAL, objval) );
2727  }
2728 
2729  if( activity != NULL )
2730  {
2731  /* Convert the slack values into activity values. */
2732  int nrows;
2733  int r;
2734 
2735  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
2736 
2737  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
2738 
2739  CHECK_ZERO( lpi->messagehdlr, XPRSgetrhs(lpi->xprslp, lpi->rhsarray, 0, nrows-1) );
2740 
2741  for( r = 0; r < nrows; r++ )
2742  activity[r] = lpi->rhsarray[r] - activity[r];
2743  }
2744 
2745  return SCIP_OKAY;
2746 }
2747 
2748 /** gets primal ray for unbounded LPs */
2750  SCIP_LPI* lpi, /**< LP interface structure */
2751  SCIP_Real* ray /**< primal ray */
2752  )
2753 {
2754  int hasRay;
2755 
2756  assert(lpi != NULL);
2757  assert(lpi->xprslp != NULL);
2758  assert(ray != NULL);
2759  assert(lpi->solstat >= 0);
2760 
2761  CHECK_ZERO( lpi->messagehdlr, XPRSgetprimalray(lpi->xprslp, ray, &hasRay) );
2762 
2763  if( !hasRay )
2764  return SCIP_LPERROR;
2765 
2766  return SCIP_OKAY;
2767 }
2768 
2769 /** gets dual Farkas proof for infeasibility */
2771  SCIP_LPI* lpi, /**< LP interface structure */
2772  SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
2773  )
2774 {
2775  int hasRay;
2776 
2777  assert(lpi != NULL);
2778  assert(lpi->xprslp != NULL);
2779  assert(lpi->solstat >= 0);
2780  assert(dualfarkas != NULL);
2781 
2782  /**@note The Farkas proof might be numerically questionable which is indicated by "hasRay" use SCIPlpiHasDualRay() to
2783  * check that!
2784  */
2785  CHECK_ZERO( lpi->messagehdlr, XPRSgetdualray(lpi->xprslp, dualfarkas, &hasRay) );
2786 
2787  return SCIP_OKAY;
2788 }
2789 
2790 /** gets the number of LP iterations of the last solve call */
2792  SCIP_LPI* lpi, /**< LP interface structure */
2793  int* iterations /**< pointer to store the number of iterations of the last solve call */
2794  )
2795 {
2796  assert(lpi != NULL);
2797  assert(lpi->xprslp != NULL);
2798  assert(iterations != NULL);
2799 
2800  *iterations = lpi->iterations;
2801 
2802  return SCIP_OKAY;
2803 }
2804 
2805 /** gets information about the quality of an LP solution
2806  *
2807  * Such information is usually only available, if also a (maybe not optimal) solution is available.
2808  * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
2809  */
2811  SCIP_LPI* lpi, /**< LP interface structure */
2812  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
2813  SCIP_Real* quality /**< pointer to store quality number */
2814  )
2815 { /*lint --e{715}*/
2816  assert(lpi != NULL);
2817  assert(quality != NULL);
2818  SCIP_UNUSED(qualityindicator);
2819 
2820  *quality = SCIP_INVALID;
2821 
2822  return SCIP_OKAY;
2823 }
2824 
2825 /**@} */
2826 
2827 
2828 /**@name LP Basis Methods
2829  *
2830  * @{
2831  */
2832 
2833 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
2835  SCIP_LPI* lpi, /**< LP interface structure */
2836  int* cstat, /**< array to store column basis status, or NULL */
2837  int* rstat /**< array to store row basis status, or NULL (the status is need for the row and not for the slack column) */
2838  )
2839 {
2840  int nrows;
2841  int r;
2842 
2843  assert(lpi != NULL);
2844  assert(lpi->xprslp != NULL);
2845 
2846  /*lint --e{506}*/
2847  assert((int) SCIP_BASESTAT_LOWER == 0);
2848  assert((int) SCIP_BASESTAT_BASIC == 1);
2849  assert((int) SCIP_BASESTAT_UPPER == 2);
2850 
2851  SCIPdebugMessage("saving Xpress basis into %p/%p\n", (void*)rstat, (void*)cstat);
2852 
2853  /* get the basis status */
2854  CHECK_ZERO( lpi->messagehdlr, XPRSgetbasis(lpi->xprslp, rstat, cstat) );
2855 
2856  /* get the number of rows */
2857  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
2858 
2859  /* XPRSgetbasis collects the basis status for the column and the slack column, since SCIP request the basis for
2860  * columns and rows we need to convert slack column status to row status
2861  */
2862  for( r = 0; r < nrows; ++r )
2863  {
2864  if (rstat[r] == (int) SCIP_BASESTAT_LOWER)
2865  rstat[r] = (int) SCIP_BASESTAT_UPPER;
2866  else if (rstat[r] == (int) SCIP_BASESTAT_UPPER)
2867  rstat[r] = (int) SCIP_BASESTAT_LOWER;
2868  }
2869 
2870  return SCIP_OKAY;
2871 }
2872 
2873 /** sets current basis status for columns and rows */
2875  SCIP_LPI* lpi, /**< LP interface structure */
2876  const int* cstat, /**< array with column basis status */
2877  const int* rstat /**< array with row basis status */
2878  )
2879 {
2880  int* slackstats;
2881  int ncols;
2882  int nrows;
2883  int r;
2884 
2885  assert(lpi != NULL);
2886  assert(lpi->xprslp != NULL);
2887 
2888  /* get the number of rows/columns */
2889  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2890  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2891 
2892  assert(cstat != NULL || ncols == 0);
2893  assert(rstat != NULL || nrows == 0);
2894 
2895  /*lint --e{506}*/
2896  assert((int) SCIP_BASESTAT_LOWER == 0);
2897  assert((int) SCIP_BASESTAT_BASIC == 1);
2898  assert((int) SCIP_BASESTAT_UPPER == 2);
2899 
2900  SCIPdebugMessage("loading basis %p/%p into Xpress\n", (void*)rstat, (void*)cstat);
2901 
2902  invalidateSolution(lpi);
2903 
2904  SCIP_ALLOC( BMSallocMemoryArray(&slackstats, nrows) );
2905 
2906  /* XPRSloadbasis expects the basis status for the column and the slack column, since SCIP has the basis status for
2907  * columns and rows we need to convert row status to slack column status
2908  */
2909  for( r = 0; r < nrows; ++r )
2910  {
2911  if (rstat[r] == (int) SCIP_BASESTAT_LOWER) /*lint !e613*/
2912  slackstats[r] = (int) SCIP_BASESTAT_UPPER;
2913  else if (rstat[r] == (int) SCIP_BASESTAT_UPPER) /*lint !e613*/
2914  slackstats[r] = (int) SCIP_BASESTAT_LOWER;
2915  else
2916  slackstats[r] = rstat[r]; /*lint !e613*/
2917  }
2918 
2919  /* load basis information into Xpress
2920  *
2921  * @note Xpress expects the row status w.r.t. slack columns!
2922  */
2923  CHECK_ZERO( lpi->messagehdlr, XPRSloadbasis(lpi->xprslp, slackstats, cstat) );
2924 
2925  BMSfreeMemoryArray(&slackstats);
2926 
2927  lpi->clearstate = FALSE;
2928 
2929  return SCIP_OKAY;
2930 }
2931 
2932 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
2934  SCIP_LPI* lpi, /**< LP interface structure */
2935  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
2936  )
2937 {
2938  int irspace;
2939  int nrows;
2940  int r;
2941 
2942  /* In the basis methods we assume that xprs basis flags coincide with scip, so assert it */
2943  /*lint --e{506}*/
2944  assert((int) SCIP_BASESTAT_LOWER == 0);
2945  assert((int) SCIP_BASESTAT_BASIC == 1);
2946  assert((int) SCIP_BASESTAT_UPPER == 2);
2947  assert((int) SCIP_BASESTAT_ZERO == 3);
2948 
2949  assert(lpi != NULL);
2950  assert(lpi->xprslp != NULL);
2951  assert(bind != NULL);
2952 
2953  SCIPdebugMessage("getting basis information\n");
2954 
2955  CHECK_ZERO( lpi->messagehdlr, XPRSgetpivotorder(lpi->xprslp, bind) );
2956 
2957  /* Reindex variables to match those of SCIP. */
2958  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
2959  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_SPAREROWS, &irspace) );
2960  irspace += nrows;
2961 
2962  for( r = 0; r < nrows; r++ )
2963  {
2964  if( bind[r] < nrows )
2965  bind[r] = -bind[r]-1;
2966  else
2967  {
2968  assert(bind[r] >= irspace);
2969  bind[r] = bind[r] - irspace;
2970  }
2971  }
2972 
2973  return SCIP_OKAY;
2974 }
2975 
2976 /** get row of inverse basis matrix B^-1
2977  *
2978  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
2979  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
2980  * see also the explanation in lpi.h.
2981  *
2982  * @todo check that the result is in terms of the LP interface definition
2983  */
2985  SCIP_LPI* lpi, /**< LP interface structure */
2986  int row, /**< row number */
2987  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
2988  int* inds, /**< array to store the non-zero indices, or NULL */
2989  int* ninds /**< pointer to store the number of non-zero indices, or NULL
2990  * (-1: if we do not store sparsity information) */
2991  )
2992 { /*lint --e{715}*/
2993  int nrows;
2994 
2995  assert(lpi != NULL);
2996  assert(lpi->xprslp != NULL);
2997  assert(coef != NULL);
2998  SCIP_UNUSED(inds);
2999 
3000  SCIPdebugMessage("getting binv-row %d\n", row);
3001 
3002  /* can only return dense result */
3003  if ( ninds != NULL )
3004  *ninds = -1;
3005 
3006  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3007  BMSclearMemoryArray(coef, nrows);
3008  coef[row] = 1.0;
3009  CHECK_ZERO( lpi->messagehdlr, XPRSbtran(lpi->xprslp, coef) );
3010 
3011  return SCIP_OKAY;
3012 }
3013 
3014 /** get column of inverse basis matrix B^-1
3015  *
3016  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3017  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3018  * see also the explanation in lpi.h.
3019  *
3020  * @todo check that the result is in terms of the LP interface definition
3021  */
3023  SCIP_LPI* lpi, /**< LP interface structure */
3024  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3025  * you have to call SCIPlpiGetBasisInd() to get the array which links the
3026  * B^-1 column numbers to the row and column numbers of the LP!
3027  * c must be between 0 and nrows-1, since the basis has the size
3028  * nrows * nrows */
3029  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
3030  int* inds, /**< array to store the non-zero indices, or NULL */
3031  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3032  * (-1: if we do not store sparsity information) */
3033  )
3034 { /*lint --e{715}*/
3035  int nrows;
3036 
3037  assert(lpi != NULL);
3038  assert(lpi->xprslp != NULL);
3039  assert(coef != NULL);
3040  SCIP_UNUSED(inds);
3041 
3042  SCIPdebugMessage("getting binv-col %d\n", c);
3043 
3044  /* can only return dense result */
3045  if ( ninds != NULL )
3046  *ninds = -1;
3047 
3048  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3049  BMSclearMemoryArray(coef, nrows);
3050  coef[c] = 1.0;
3051  CHECK_ZERO( lpi->messagehdlr, XPRSftran(lpi->xprslp, coef) );
3052 
3053  return SCIP_OKAY;
3054 }
3055 
3056 /** get row of inverse basis matrix times constraint matrix B^-1 * A
3057  *
3058  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3059  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3060  * see also the explanation in lpi.h.
3061  *
3062  * @todo check that the result is in terms of the LP interface definition
3063  */
3065  SCIP_LPI* lpi, /**< LP interface structure */
3066  int r, /**< row number */
3067  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3068  SCIP_Real* coef, /**< vector to return coefficients of the row */
3069  int* inds, /**< array to store the non-zero indices, or NULL */
3070  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3071  * (-1: if we do not store sparsity information) */
3072  )
3073 { /*lint --e{715}*/
3074  SCIP_Real* binv;
3075  SCIP_Real* buffer;
3076  int ncols;
3077  int nrows;
3078  int nnonz;
3079  int c;
3080 
3081  assert(lpi != NULL);
3082  assert(lpi->xprslp != NULL);
3083  assert(coef != NULL);
3084 
3085  SCIPdebugMessage("getting binva-row %d\n", r);
3086 
3087  /* can only return dense result */
3088  if ( ninds != NULL )
3089  *ninds = -1;
3090 
3091  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3092  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
3093 
3094  buffer = NULL;
3095 
3096  /* get (or calculate) the row in B^-1 */
3097  if( binvrow == NULL )
3098  {
3099  SCIP_ALLOC( BMSallocMemoryArray(&buffer, nrows) );
3100  SCIP_CALL( SCIPlpiGetBInvRow(lpi, r, buffer, inds, ninds) );
3101  binv = buffer;
3102  }
3103  else
3104  binv = (double*) binvrow;
3105 
3106  /* We need space to extract a single column. */
3107  SCIP_CALL( ensureValMem(lpi, nrows) );
3108 
3109  for( c = 0; c < ncols; c++ )
3110  {
3111  int i;
3112 
3113  coef[c] = 0;
3114 
3115  /* Extract the column. */
3116  CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, c, c) );
3117  assert(nnonz <= nrows);
3118 
3119  /* Price out the column. */
3120  for( i = 0; i < nnonz; i++ )
3121  coef[c] += binv[lpi->indarray[i]] * lpi->valarray[i];
3122  }
3123 
3124  /* Free allocated memory. */
3125  BMSfreeMemoryArrayNull(&buffer);
3126 
3127  return SCIP_OKAY;
3128 }
3129 
3130 /** get column of inverse basis matrix times constraint matrix B^-1 * A
3131  *
3132  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3133  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3134  * see also the explanation in lpi.h.
3135  *
3136  * @todo check that the result is in terms of the LP interface definition
3137  */
3139  SCIP_LPI* lpi, /**< LP interface structure */
3140  int c, /**< column number */
3141  SCIP_Real* coef, /**< vector to return coefficients of the column */
3142  int* inds, /**< array to store the non-zero indices, or NULL */
3143  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3144  * (-1: if we do not store sparsity information) */
3145  )
3146 { /*lint --e{715}*/
3147  int nrows;
3148  int nnonz;
3149  int i;
3150 
3151  /* Ftran */
3152 
3153  assert(lpi != NULL);
3154  assert(lpi->xprslp != NULL);
3155  assert(coef != NULL);
3156  SCIP_UNUSED(inds);
3157 
3158  SCIPdebugMessage("getting binv-col %d\n", c);
3159 
3160  /* can only return dense result */
3161  if ( ninds != NULL )
3162  *ninds = -1;
3163 
3164  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3165 
3166  /* We need space to extract the column. */
3167  SCIP_CALL( ensureValMem(lpi, nrows) );
3168 
3169  /* Get the column to transform. */
3170  CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, c, c) );
3171  assert(nnonz <= nrows);
3172 
3173  /* Transform the column. */
3174  BMSclearMemoryArray(coef, nrows);
3175  for( i = 0; i < nnonz; i++ )
3176  coef[lpi->indarray[i]] = lpi->valarray[i];
3177 
3178  CHECK_ZERO( lpi->messagehdlr, XPRSftran(lpi->xprslp, coef) );
3179 
3180  return SCIP_OKAY;
3181 }
3182 
3183 /**@} */
3184 
3185 
3186 /**@name LP State Methods
3187  *
3188  * @{
3189  */
3190 
3191 /** stores LPi state (like basis information) into lpistate object */
3193  SCIP_LPI* lpi, /**< LP interface structure */
3194  BMS_BLKMEM* blkmem, /**< block memory */
3195  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3196  )
3197 {
3198  int ncols;
3199  int nrows;
3200 
3201  assert(blkmem != NULL);
3202  assert(lpi != NULL);
3203  assert(lpi->xprslp != NULL);
3204  assert(lpistate != NULL);
3205 
3206  /* if there is no basis information available (e.g. after barrier without crossover), or no state can be saved; if
3207  * SCIPlpiClearState() has been called, do not return the state
3208  */
3209  if( !lpi->solisbasic || lpi->clearstate )
3210  {
3211  *lpistate = NULL;
3212  return SCIP_OKAY;
3213  }
3214 
3215  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3216  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
3217  assert(ncols >= 0);
3218  assert(nrows >= 0);
3219 
3220  /* allocate lpistate data */
3221  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
3222 
3223  SCIPdebugMessage("storing Xpress LPI state in %p (%d cols, %d rows)\n", (void*)*lpistate, ncols, nrows);
3224 
3225  /* allocate enough memory for storing uncompressed basis information */
3226  SCIP_CALL( ensureCstatMem(lpi, ncols) );
3227  SCIP_CALL( ensureRstatMem(lpi, nrows) );
3228 
3229  /* get unpacked basis information from Xpress
3230  *
3231  * @note The row status is w.r.t. slack columns!
3232  */
3233  CHECK_ZERO( lpi->messagehdlr, XPRSgetbasis(lpi->xprslp, lpi->rstat, lpi->cstat) );
3234 
3235  /* pack LPi state data */
3236  (*lpistate)->ncols = ncols;
3237  (*lpistate)->nrows = nrows;
3238  lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
3239 
3240  return SCIP_OKAY;
3241 }
3242 
3243 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
3244  * columns and rows since the state was stored with SCIPlpiGetState()
3245  */
3247  SCIP_LPI* lpi, /**< LP interface structure */
3248  BMS_BLKMEM* blkmem, /**< block memory */
3249  const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
3250  )
3251 {
3252  int nrows;
3253  int ncols;
3254  int i;
3255 
3256  assert(blkmem != NULL);
3257  assert(lpi != NULL);
3258  assert(lpi->xprslp != NULL);
3259 
3260  /* if there was no basis information available, the LPI state was not stored */
3261  if( lpistate == NULL )
3262  return SCIP_OKAY;
3263 
3264  if( lpistate->ncols == 0 || lpistate->nrows == 0 )
3265  return SCIP_OKAY;
3266 
3267  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3268  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
3269 
3270  /* the dimension of the lpi state should not be larger than the current problem; it might be that columns and rows
3271  * are added since the saving of the lpi state
3272  */
3273  assert(lpistate->ncols <= ncols);
3274  assert(lpistate->nrows <= nrows);
3275 
3276  SCIPdebugMessage("loading LPI state %p (%d cols, %d rows) into Xpress\n", (void*)lpistate, lpistate->ncols, lpistate->nrows);
3277 
3278  /* allocate enough memory for storing uncompressed basis information */
3279  SCIP_CALL( ensureCstatMem(lpi, ncols) );
3280  SCIP_CALL( ensureRstatMem(lpi, nrows) );
3281 
3282  /* unpack LPi state data
3283  *
3284  * @note The row status is w.r.t. slack column!
3285  */
3286  lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
3287 
3288  /* extend the basis to the current LP beyond the previously existing columns */
3289  for( i = lpistate->ncols; i < ncols; ++i )
3290  {
3291  SCIP_Real bnd;
3292 
3293  CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, &bnd, i, i) );
3294 
3295  if( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3296  {
3297  /* if lower bound is +/- infinity -> try upper bound */
3298  CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, &bnd, i, i) );
3299 
3300  if( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3301  lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free */
3302  else
3303  lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
3304  }
3305  else
3306  lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
3307  }
3308  for( i = lpistate->nrows; i < nrows; ++i )
3309  lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
3310 
3311  /* load basis information into Xpress
3312  *
3313  * @note Xpress expects the row status w.r.t. slack columns!
3314  */
3315  CHECK_ZERO( lpi->messagehdlr, XPRSloadbasis(lpi->xprslp, lpi->rstat, lpi->cstat) );
3316 
3317  lpi->clearstate = FALSE;
3318 
3319  return SCIP_OKAY;
3320 }
3321 
3322 /** clears current LPi state (like basis information) of the solver */
3324  SCIP_LPI* lpi /**< LP interface structure */
3325  )
3326 {
3327  assert(lpi != NULL);
3328 
3329  /* set KEEPBASIS to 0 for the next solve */
3330  lpi->clearstate = TRUE;
3331 
3332  return SCIP_OKAY;
3333 }
3334 
3335 /** frees LPi state information */
3337  SCIP_LPI* lpi, /**< LP interface structure */
3338  BMS_BLKMEM* blkmem, /**< block memory */
3339  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3340  )
3341 {
3342  assert(lpi != NULL);
3343  assert(lpistate != NULL);
3344  assert(blkmem != NULL);
3345 
3346  if( *lpistate != NULL )
3347  {
3348  lpistateFree(lpistate, blkmem);
3349  }
3350 
3351  return SCIP_OKAY;
3352 }
3353 
3354 /** checks, whether the given LP state contains simplex basis information */
3356  SCIP_LPI* lpi, /**< LP interface structure */
3357  SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
3358  )
3359 { /*lint --e{715}*/
3360  assert(lpi != NULL);
3361  return (lpistate != NULL);
3362 }
3363 
3364 /** reads LP state (like basis information from a file */
3366  SCIP_LPI* lpi, /**< LP interface structure */
3367  const char* fname /**< file name */
3368  )
3369 {
3370  assert(lpi != NULL);
3371  assert(lpi->xprslp != NULL);
3372  assert(fname != NULL);
3373 
3374  SCIPdebugMessage("reading LP state from file <%s>\n", fname);
3375 
3376  CHECK_ZERO( lpi->messagehdlr, XPRSreadbasis(lpi->xprslp, fname, "") );
3377 
3378  return SCIP_OKAY;
3379 }
3380 
3381 /** writes LPi state (i.e. basis information) to a file */
3383  SCIP_LPI* lpi, /**< LP interface structure */
3384  const char* fname /**< file name */
3385  )
3386 {
3387  assert(lpi != NULL);
3388  assert(lpi->xprslp != NULL);
3389  assert(fname != NULL);
3390 
3391  SCIPdebugMessage("writing LP state to file <%s>\n", fname);
3392 
3393  CHECK_ZERO( lpi->messagehdlr, XPRSwritebasis(lpi->xprslp, fname, "") );
3394 
3395  return SCIP_OKAY;
3396 }
3397 
3398 /**@} */
3399 
3400 
3401 /**@name LP Pricing Norms Methods
3402  *
3403  * @{
3404  */
3405 
3406 /** stores LPi pricing norms information
3407  * @todo should we store norm information?
3408  */
3410  SCIP_LPI* lpi, /**< LP interface structure */
3411  BMS_BLKMEM* blkmem, /**< block memory */
3412  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
3413  )
3414 { /*lint --e{715}*/
3415  assert(lpi != NULL);
3416  assert(blkmem != NULL);
3417  assert(lpinorms != NULL);
3418 
3419  (*lpinorms) = NULL;
3420 
3421  return SCIP_OKAY;
3422 }
3423 
3424 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
3425  * columns and rows since the state was stored with SCIPlpiGetNorms()
3426  */
3428  SCIP_LPI* lpi, /**< LP interface structure */
3429  BMS_BLKMEM* blkmem, /**< block memory */
3430  const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
3431  )
3432 { /*lint --e{715}*/
3433  assert(lpi != NULL);
3434  assert(lpinorms == NULL);
3435  SCIP_UNUSED(blkmem);
3436 
3437  /* no work necessary */
3438  return SCIP_OKAY;
3439 }
3440 
3441 /** frees pricing norms information */
3443  SCIP_LPI* lpi, /**< LP interface structure */
3444  BMS_BLKMEM* blkmem, /**< block memory */
3445  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
3446  )
3447 { /*lint --e{715}*/
3448  assert(lpi != NULL);
3449  assert(lpinorms == NULL);
3450  SCIP_UNUSED(blkmem);
3451 
3452  /* no work necessary */
3453  return SCIP_OKAY;
3454 }
3455 
3456 /**@} */
3457 
3458 
3459 /**@name Parameter Methods
3460  *
3461  * @{
3462  */
3463 
3464 /** gets integer parameter of LP */
3466  SCIP_LPI* lpi, /**< LP interface structure */
3467  SCIP_LPPARAM type, /**< parameter number */
3468  int* ival /**< buffer to store the parameter value */
3469  )
3470 {
3471  int ictrlval;
3472 
3473  assert(lpi != NULL);
3474  assert(lpi->xprslp != NULL);
3475  assert(ival != NULL);
3476 
3477  SCIPdebugMessage("getting int parameter %d\n", type);
3478 
3479  switch( type )
3480  {
3481  case SCIP_LPPAR_PRICING:
3482  *ival = (int)lpi->pricing;
3483  break;
3485 #if 1
3486  *ival = (lpi->notfromscratch == 0);
3487 #else
3488  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, &ictrlval) );
3489  *ival = (ictrlval == 0);
3490 #endif
3491  break;
3492  case SCIP_LPPAR_SCALING:
3493  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_SCALING, &ictrlval) );
3494  if( ictrlval == 0 )
3495  *ival = 0;
3496  else if( ictrlval == 16 )
3497  *ival = 2;
3498  else
3499  *ival = 1;
3500  break;
3501  case SCIP_LPPAR_PRESOLVING:
3502  *ival = lpi->par_presolve;
3503  break;
3504  case SCIP_LPPAR_LPINFO:
3505  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_OUTPUTLOG, &ictrlval) );
3506  *ival = (ictrlval != 0);
3507  break;
3508  case SCIP_LPPAR_LPITLIM:
3509  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, &ictrlval) );
3510  *ival = ictrlval;
3511  if( *ival >= XPRS_MAXINT )
3512  *ival = XPRS_MAXINT;
3513  break;
3514  case SCIP_LPPAR_THREADS:
3515  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_THREADS, &ictrlval) );
3516  *ival = ictrlval;
3517  break;
3518  default:
3519  return SCIP_PARAMETERUNKNOWN;
3520  } /*lint !e788*/
3521 
3522  return SCIP_OKAY;
3523 }
3524 
3525 /** sets integer parameter of LP */
3527  SCIP_LPI* lpi, /**< LP interface structure */
3528  SCIP_LPPARAM type, /**< parameter number */
3529  int ival /**< parameter value */
3530  )
3531 {
3532  assert(lpi != NULL);
3533  assert(lpi->xprslp != NULL);
3534 
3535  SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
3536 
3537  switch( type )
3538  {
3539  case SCIP_LPPAR_PRICING:
3540  /* every non-supported pricing strategy is promoted to the default pricing strategy */
3541  lpi->pricing = (SCIP_PRICING)ival; /* store pricing method in LPI struct */
3542  switch( lpi->pricing )
3543  {
3544  case SCIP_PRICING_PARTIAL:
3545  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_PARTIAL) );
3546  break;
3547  case SCIP_PRICING_DEVEX:
3548  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_DEVEX) );
3549  break;
3550  case SCIP_PRICING_AUTO:
3551  case SCIP_PRICING_FULL:
3553  case SCIP_PRICING_STEEP:
3555  default:
3556  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_DEFAULT) );
3557  break;
3558  }
3559  break;
3561  assert(ival == TRUE || ival == FALSE);
3562  lpi->notfromscratch = (int)(!ival);
3563  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, (ival == FALSE) ? 1 : 0) );
3564  break;
3565  case SCIP_LPPAR_SCALING:
3566  assert(ival >= 0 && ival <= 2);
3567  if( ival == 0 )
3568  {
3569  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 0) );
3570  }
3571  else if( ival == 1 )
3572  {
3573  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 163) );
3574  }
3575  else
3576  {
3577  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 16) );
3578  }
3579 
3580  break;
3581  case SCIP_LPPAR_PRESOLVING:
3582  assert(ival == TRUE || ival == FALSE);
3583  lpi->par_presolve = ival;
3584  break;
3585  case SCIP_LPPAR_LPINFO:
3586  assert(ival == TRUE || ival == FALSE);
3587  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_OUTPUTLOG, (ival == TRUE) ? 1 : 0) );
3588  break;
3589  case SCIP_LPPAR_LPITLIM:
3590  assert( ival >= 0 );
3591  /* 0 <= ival, 0 stopping immediately */
3592  ival = MIN(ival, XPRS_MAXINT); /*lint !e685*//*lint !e2650*//*lint !e587*/
3593  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, ival) );
3594  break;
3595  case SCIP_LPPAR_THREADS:
3596  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_THREADS, ival) );
3597  break;
3598  default:
3599  return SCIP_PARAMETERUNKNOWN;
3600  } /*lint !e788*/
3601 
3602  return SCIP_OKAY;
3603 }
3604 
3605 /** gets floating point parameter of LP */
3607  SCIP_LPI* lpi, /**< LP interface structure */
3608  SCIP_LPPARAM type, /**< parameter number */
3609  SCIP_Real* dval /**< buffer to store the parameter value */
3610  )
3611 {
3612  int ictrlval;
3613  double dctrlval;
3614 
3615  assert(lpi != NULL);
3616  assert(lpi->xprslp != NULL);
3617  assert(dval != NULL);
3618 
3619  SCIPdebugMessage("getting real parameter %d\n", type);
3620 
3621  switch( type )
3622  {
3623  case SCIP_LPPAR_FEASTOL:
3624  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_FEASTOL, &dctrlval) );
3625  *dval = dctrlval;
3626  break;
3628  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_OPTIMALITYTOL, &dctrlval) );
3629  *dval = dctrlval;
3630  break;
3632  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_BARGAPSTOP, &dctrlval) );
3633  *dval = dctrlval;
3634  break;
3635  case SCIP_LPPAR_LPTILIM:
3636  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_MAXTIME, &ictrlval) );
3637  /* ictrlval is the negative of the timelimit (see SCIPlpiSetRealpar) */
3638  *dval = (double) -ictrlval;
3639  break;
3640  case SCIP_LPPAR_MARKOWITZ:
3641  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_MARKOWITZTOL, &dctrlval) );
3642  *dval = dctrlval;
3643  break;
3644  case SCIP_LPPAR_OBJLIM:
3645  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_MIPABSCUTOFF, &dctrlval) );
3646  *dval = dctrlval;
3647  break;
3648  default:
3649  return SCIP_PARAMETERUNKNOWN;
3650  } /*lint !e788*/
3651 
3652  return SCIP_OKAY;
3653 }
3654 
3655 /** sets floating point parameter of LP */
3657  SCIP_LPI* lpi, /**< LP interface structure */
3658  SCIP_LPPARAM type, /**< parameter number */
3659  SCIP_Real dval /**< parameter value */
3660  )
3661 {
3662  assert(lpi != NULL);
3663  assert(lpi->xprslp != NULL);
3664 
3665  SCIPdebugMessage("setting real parameter %d to %g\n", type, dval);
3666 
3667  switch( type )
3668  {
3669  case SCIP_LPPAR_FEASTOL:
3670  /* Xpress does not pose any restriction on dval, its absolute value is used as tolerance.
3671  * For consistency we assert it to be strictly positive.
3672  */
3673  assert( dval > 0.0 );
3674  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_FEASTOL, dval) );
3675  break;
3677  /* Xpress does not pose any restriction on dval,
3678  * however for consistency we assert it to be strictly positive.
3679  */
3680  assert( dval > 0.0 );
3681  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_OPTIMALITYTOL, dval) );
3682  break;
3684  assert( dval >= 0.0 );
3685  /* Xpress poses no restriction on dval
3686  * However for consistency we assert it to be nonnegative.
3687  */
3688  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_BARGAPSTOP, dval) );
3689  break;
3690  case SCIP_LPPAR_LPTILIM:
3691  {
3692  int ival;
3693 
3694  /* From the Xpress documentation:
3695  * dval>0 If an integer solution has been found, stop MIP search after dval seconds,
3696  * otherwise continue until an integer solution is finally found.
3697  * dval<0 Stop in LP or MIP search after dval seconds.
3698  * dval=0 No time limit
3699  */
3700  assert( dval > 0.0 );
3701  if( dval >= INT_MAX )
3702  ival = 0;
3703  else
3704  ival = (int) -floor(dval);
3705 
3706  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_MAXTIME, ival) );
3707  break;
3708  }
3709  case SCIP_LPPAR_MARKOWITZ:
3710  /* no restriction on dval */
3711  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_MARKOWITZTOL, dval) );
3712  break;
3713  case SCIP_LPPAR_OBJLIM:
3714  /* no restriction on dval */
3715  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_MIPABSCUTOFF, dval) );
3716  break;
3717  default:
3718  return SCIP_PARAMETERUNKNOWN;
3719  } /*lint !e788*/
3720 
3721  return SCIP_OKAY;
3722 }
3723 
3724 /**@} */
3725 
3726 
3727 /**@name Numerical Methods
3728  *
3729  * @{
3730  */
3731 
3732 /** returns value treated as infinity in the LP solver */
3734  SCIP_LPI* lpi /**< LP interface structure */
3735  )
3736 { /*lint --e{715}*/
3737  assert(lpi != NULL);
3738  return XPRS_PLUSINFINITY;
3739 }
3740 
3741 /** checks if given value is treated as infinity in the LP solver */
3743  SCIP_LPI* lpi, /**< LP interface structure */
3744  SCIP_Real val /**< value to be checked for infinity */
3745  )
3746 { /*lint --e{715}*/
3747  assert(lpi != NULL);
3748  return (val >= XPRS_PLUSINFINITY);
3749 }
3750 
3751 /**@} */
3752 
3753 
3754 /**@name File Interface Methods
3755  *
3756  * @{
3757  */
3758 
3759 /** reads LP from a file
3760  *
3761  * The file extension defines the format. That can be lp or mps. Any given file name needs to have one of these two
3762  * extension. If not nothing is read and a SCIP_READERROR is returned.
3763  */
3765  SCIP_LPI* lpi, /**< LP interface structure */
3766  const char* fname /**< file name */
3767  )
3768 {
3769  SCIP_RETCODE retcode = SCIP_OKAY;
3770 
3771  char* basename = NULL;
3772  char* compression = NULL;
3773  char* extension = NULL;
3774  char* filename = NULL;
3775  char* path = NULL;
3776  char* xpressfilename = NULL;
3777 
3778  int size;
3779 
3780  assert(lpi != NULL);
3781  assert(lpi->xprslp != NULL);
3782  assert(fname != NULL);
3783 
3784  SCIPdebugMessage("reading LP from file <%s>\n", fname);
3785 
3786  /* get the length of the file name */
3787  size = (int)strlen(fname)+1;
3788 
3789  /* check that the file name is longer than Xpress can handle */
3790  if (size > XPRS_MAXPROBNAMELENGTH)
3791  return SCIP_WRITEERROR;
3792 
3793  /* get char array for the file name we pass to Xpress */
3794  SCIP_ALLOC( BMSallocMemoryArray(&xpressfilename, size) );
3795 
3796  /* copy filename to be able to split it into its components */
3797  SCIP_ALLOC( BMSduplicateMemoryArray(&filename, fname, size) );
3798 
3799  /* get path, base file name, extension, and compression of the given file name */
3800  SCIPsplitFilename(filename, &path, &basename, &extension, &compression);
3801 
3802  /* construct file name without extension */
3803  if (path != NULL)
3804  (void) SCIPsnprintf(xpressfilename, size, "%s/%s", path, basename);
3805  else
3806  (void) SCIPsnprintf(xpressfilename, size, "%s", basename);
3807 
3808  /* check that the file name did not has a compression extension, has an lp or mps extension, and actually a base name */
3809  if (compression != NULL || extension == NULL || basename == NULL)
3810  retcode = SCIP_READERROR;
3811  if (strcasecmp(extension, "mps") == 0) {
3812  CHECK_ZERO( lpi->messagehdlr, XPRSreadprob(lpi->xprslp, xpressfilename, "") );
3813  }
3814  else if (strcasecmp(extension, "lp") == 0) {
3815  CHECK_ZERO( lpi->messagehdlr, XPRSreadprob(lpi->xprslp, xpressfilename, "l") );
3816  }
3817  else
3818  retcode = SCIP_READERROR;
3819 
3820  /* free array */
3821  BMSfreeMemoryArrayNull(&filename);
3822  BMSfreeMemoryArrayNull(&xpressfilename);
3823 
3824  return retcode;
3825 }
3826 
3827 /** writes LP to a file
3828  *
3829  * The file extension defines the format. That can be lp or mps. Any given file name needs to have one of these two
3830  * extension. If not nothing is written and a SCIP_WRITEERROR is returned.
3831  */
3833  SCIP_LPI* lpi, /**< LP interface structure */
3834  const char* fname /**< file name */
3835  )
3836 {
3837  SCIP_RETCODE retcode = SCIP_OKAY;
3838 
3839  char* basename = NULL;
3840  char* compression = NULL;
3841  char* extension = NULL;
3842  char* filename = NULL;
3843  char* path = NULL;
3844  char* xpressfilename = NULL;
3845 
3846  int size;
3847 
3848  assert(lpi != NULL);
3849  assert(lpi->xprslp != NULL);
3850  assert(fname != NULL);
3851 
3852  SCIPdebugMessage("writing LP to file <%s>\n", fname);
3853 
3854  /* get the length of the file name */
3855  size = (int)strlen(fname)+1;
3856 
3857  /* check that the file name is longer than Xpress can handle */
3858  if (size > XPRS_MAXPROBNAMELENGTH)
3859  return SCIP_WRITEERROR;
3860 
3861  /* get char array for the file name we pass to Xpress */
3862  SCIP_ALLOC( BMSallocMemoryArray(&xpressfilename, size) );
3863 
3864  /* copy filename to be able to split it into its components */
3865  SCIP_ALLOC( BMSduplicateMemoryArray(&filename, fname, size) );
3866 
3867  /* get path, base file name, extension, and compression of the given file name */
3868  SCIPsplitFilename(filename, &path, &basename, &extension, &compression);
3869 
3870  /* construct file name without extension */
3871  if (path != NULL)
3872  (void) SCIPsnprintf(xpressfilename, size, "%s/%s", path, basename);
3873  else
3874  (void) SCIPsnprintf(xpressfilename, size, "%s", basename);
3875 
3876  /* check that the file name did not has a compression extension, has an lp or mps extension, and actually a base name */
3877  if (compression != NULL || extension == NULL || basename == NULL)
3878  retcode = SCIP_WRITEERROR;
3879  if (strcasecmp(extension, "mps") == 0) {
3880  CHECK_ZERO( lpi->messagehdlr, XPRSwriteprob(lpi->xprslp, xpressfilename, "p") );
3881  }
3882  else if (strcasecmp(extension, "lp") == 0) {
3883  CHECK_ZERO( lpi->messagehdlr, XPRSwriteprob(lpi->xprslp, xpressfilename, "lp") );
3884  }
3885  else
3886  retcode = SCIP_WRITEERROR;
3887 
3888  /* free array */
3889  BMSfreeMemoryArrayNull(&filename);
3890  BMSfreeMemoryArrayNull(&xpressfilename);
3891 
3892  return retcode;
3893 }
3894 
3895 /**@} */
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_xprs.c:730
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_xprs.c:3526
SCIP_RETCODE SCIPlpiStrongbranchesFrac(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_xprs.c:2232
static void convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhss, const SCIP_Real *rhss)
Definition: lpi_xprs.c:420
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
Definition: type_lpi.h:95
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_xprs.c:3733
const char * SCIPlpiGetSolverName(void)
Definition: lpi_xprs.c:648
XPRSprob xprslp
Definition: lpi_xprs.c:79
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
Definition: lpi_xprs.c:340
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:140
#define CHECK_ZERO(messagehdlr, x)
Definition: lpi_xprs.c:52
int par_fastlp
Definition: lpi_xprs.c:109
SCIP_Bool solisbasic
Definition: lpi_cpx.c:159
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_xprs.c:3465
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_xprs.c:3427
int nrows
Definition: lpi_none.c:43
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_xprs.c:2770
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_xprs.c:1302
ROWPACKET * packrstat
Definition: lpi_clp.cpp:128
SCIP_PRICING pricing
Definition: lpi_clp.cpp:103
static SCIP_RETCODE ensureSidechgMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:207
#define ROWS_PER_PACKET
Definition: lpi_xprs.c:74
char solmethod
Definition: lpi_xprs.c:85
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_xprs.c:2834
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_xprs.c:1731
int sidechgsize
Definition: lpi_cpx.c:153
enum SCIP_ObjSen SCIP_OBJSEN
Definition: type_lpi.h:36
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_xprs.c:675
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_xprs.c:3355
void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
Definition: bitencode.c:299
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2360
static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
Definition: lpi_xprs.c:324
interface methods for specific LP solvers
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_xprs.c:1970
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_xprs.c:1062
static void reconvertSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs, SCIP_Real *rhs)
Definition: lpi_xprs.c:608
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_xprs.c:3742
static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:276
#define FALSE
Definition: def.h:73
SCIP_Bool SCIPlpiHasPrimalSolve(void)
Definition: lpi_xprs.c:698
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2400
static SCIP_RETCODE ensureValMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:231
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_xprs.c:3138
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_xprs.c:1992
int rstatsize
Definition: lpi_clp.cpp:101
int valsize
Definition: lpi_cpx.c:154
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_xprs.c:3409
SCIP_Real * rhsarray
Definition: lpi_cpx.c:145
#define SCIP_UNUSED(x)
Definition: def.h:424
#define XPRS_LP_OPTIMAL_SCALEDINFEAS
Definition: lpi_xprs.c:50
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:64
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:115
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2605
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_xprs.c:1127
SCIP_DUALPACKET ROWPACKET
Definition: lpi_xprs.c:73
#define SCIPdebugMessage
Definition: pub_message.h:87
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_xprs.c:1808
static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:254
SCIP_DUALPACKET COLPACKET
Definition: lpi_xprs.c:71
#define BMSfreeMemory(ptr)
Definition: memory.h:137
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:77
SCIP_Real par_uobjlim
Definition: lpi_xprs.c:108
static int colpacketNum(int ncols)
Definition: lpi_xprs.c:306
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_xprs.c:3022
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_xprs.c:377
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2617
SCIP_DUALPACKET COLPACKET
Definition: lpi_clp.cpp:117
SCIP_RETCODE SCIPlpiLoadColLP(SCIP_LPI *lpi, SCIP_OBJSEN objsen, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_xprs.c:845
char * larray
Definition: lpi_cpx.c:142
static void reconvertLhs(SCIP_LPI *lpi, int nrows, SCIP_Real *lhss)
Definition: lpi_xprs.c:518
static char xprsname[100]
Definition: lpi_xprs.c:645
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2482
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_xprs.c:1421
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_xprs.c:3365
SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_xprs.c:2211
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_xprs.c:1495
packing single and dual bit values
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:139
static SCIP_RETCODE lpiStrongbranch(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_xprs.c:2017
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_xprs.c:2324
#define SCIPerrorMessage
Definition: pub_message.h:55
int ncols
Definition: lpi_none.c:44
char * senarray
Definition: lpi_cpx.c:144
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2004
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2638
static void invalidateSolution(SCIP_LPI *lpi)
Definition: lpi_xprs.c:628
#define XPRS_LPQUICKPRESOLVE
Definition: lpi_xprs.c:46
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_xprs.c:2874
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_xprs.c:3832
SCIP_Real par_lobjlim
Definition: lpi_xprs.c:107
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_xprs.c:1012
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_xprs.c:1685
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_xprs.c:683
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2452
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsense)
Definition: lpi_xprs.c:1322
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_xprs.c:2686
SCIP_DUALPACKET ROWPACKET
Definition: lpi_clp.cpp:119
SCIP_Bool SCIPlpiHasDualSolve(void)
Definition: lpi_xprs.c:706
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_xprs.c:2670
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:418
static int rowpacketNum(int nrows)
Definition: lpi_xprs.c:315
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_xprs.c:982
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_xprs.c:3323
#define NULL
Definition: lpi_spx1.cpp:155
int * rstat
Definition: lpi_clp.cpp:99
#define REALABS(x)
Definition: def.h:187
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_xprs.c:1779
int cstatsize
Definition: lpi_clp.cpp:100
#define SCIP_CALL(x)
Definition: def.h:370
void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
Definition: misc.c:10823
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_xprs.c:1269
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_xprs.c:2275
static SCIP_RETCODE ensureBoundchgMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:178
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_xprs.c:917
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_xprs.c:3442
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2510
#define COLS_PER_PACKET
Definition: lpi_xprs.c:72
void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: bitencode.c:229
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_xprs.c:1225
#define EPSCEIL(x, eps)
Definition: def.h:197
int * indarray
Definition: lpi_cpx.c:151
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:135
static SCIP_RETCODE lpiStrongbranches(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_xprs.c:2101
COLPACKET * packcstat
Definition: lpi_clp.cpp:127
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:456
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:33
public data structures and miscellaneous methods
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_xprs.c:3064
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_xprs.c:1362
#define SCIP_Bool
Definition: def.h:70
int solstat
Definition: lpi_cpx.c:140
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_xprs.c:1946
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:445
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_xprs.c:664
static void reconvertBothSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_xprs.c:469
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:458
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_xprs.c:3656
#define MAX(x, y)
Definition: tclique_def.h:83
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_xprs.c:1512
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_xprs.c:1751
SCIP_RETCODE SCIPlpiGetCols(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lb, SCIP_Real *ub, int *nnonz, int *beg, int *ind, SCIP_Real *val)
Definition: lpi_xprs.c:1549
SCIP_RETCODE SCIPlpiGetRows(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss, int *nnonz, int *beg, int *ind, SCIP_Real *val)
Definition: lpi_xprs.c:1607
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_xprs.c:1340
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2564
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_xprs.c:2933
int iterations
Definition: lpi_cpx.c:157
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_xprs.c:1662
SCIP_Real * rngarray
Definition: lpi_cpx.c:146
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2659
SCIP_Real * r
Definition: circlepacking.c:50
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2466
int notfromscratch
Definition: lpi_xprs.c:83
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2381
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_xprs.c:2707
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_xprs.c:3192
SCIP_Real * valarray
Definition: lpi_cpx.c:147
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2414
static int xprsObjsen(SCIP_OBJSEN const objsen)
Definition: lpi_xprs.c:401
int boundchgsize
Definition: lpi_cpx.c:152
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2546
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_xprs.c:805
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_xprs.c:3246
int par_presolve
Definition: lpi_xprs.c:110
public methods for message output
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_xprs.c:1529
#define ABORT_ZERO(messagehdlr, retval, x)
Definition: lpi_xprs.c:61
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10604
SCIP_Bool clearstate
Definition: lpi_cpx.c:162
#define SCIP_Real
Definition: def.h:163
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2305
static SCIP_RETCODE lpiSolve(SCIP_LPI *lpi, const char *method)
Definition: lpi_xprs.c:1834
#define BMSallocMemory(ptr)
Definition: memory.h:111
#define SCIP_INVALID
Definition: def.h:183
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:119
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_xprs.c:1205
SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_xprs.c:2254
char * uarray
Definition: lpi_cpx.c:143
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2346
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
Definition: lpi_xprs.c:356
SCIP_MESSAGEHDLR * messagehdlr
Definition: lpi_cpx.c:175
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int row, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_xprs.c:2984
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_xprs.c:1958
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_xprs.c:3336
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_xprs.c:2791
static void debugCheckColrang(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_xprs.c:133
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2496
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:443
static void debugCheckRowrang(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_xprs.c:147
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_xprs.c:3606
#define EPSFLOOR(x, eps)
Definition: def.h:196
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:122
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:429
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_xprs.c:1156
#define SCIP_ALLOC(x)
Definition: def.h:381
#define SCIPABORT()
Definition: def.h:342
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_xprs.c:2749
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_xprs.c:3764
char name[200]
Definition: lpi_xprs.c:80
static void reconvertRhs(SCIP_LPI *lpi, int nrows, SCIP_Real *rhss)
Definition: lpi_xprs.c:563
int * cstat
Definition: lpi_clp.cpp:98
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_xprs.c:2810
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_xprs.c:3382
SCIP_Bool SCIPlpiHasBarrierSolve(void)
Definition: lpi_xprs.c:714
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_xprs.c:1708