Scippy

SCIP

Solving Constraint Integer Programs

lpi_msk.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-2022 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_msk.c
17  * @ingroup LPIS
18  * @brief LP interface for MOSEK
19  * @author Bo Jensen
20  * @author Tristan Gally
21  * @author Marc Pfetsch
22  *
23  * @todo Check whether MSK_IPAR_{SIM_DUAL|PRIMAL}_RESTRICT_SELECTION should be used if problem is solved from scratch or
24  * if no basis is available.
25  * @todo Revise handling of the MSK_RES_TRM_MAX_NUM_SETBACKS return value: Remove it form the check of MOSEK_CALL and
26  * include it in filterTRMrescode().
27  * @todo Check whether SCIPlpiGetSolFeasibility() should also return primal/dual feasible if the status is
28  * MSK_SOL_STA_NEAR_PRIM_FEAS, MSK_SOL_STA_NEAR_DUAL_FEAS.
29  * @todo Check why it can happen that the termination code is MSK_RES_OK, but the solution status is MSK_SOL_STA_UNKNOWN.
30  */
31 
32 /*lint -e750*/
33 /*lint -e830*/
34 
35 #include <assert.h>
36 
37 #define MSKCONST const /* this define is needed for older MOSEK versions */
38 #include "mosek.h"
39 
40 #include "lpi/lpi.h"
41 #include "scip/bitencode.h"
42 #include "scip/pub_message.h"
43 #include <string.h>
44 #include "tinycthread/tinycthread.h"
45 
46 /* do defines for windows directly here to make the lpi more independent */
47 #if defined(_WIN32) || defined(_WIN64)
48 #define snprintf _snprintf
49 #endif
50 
51 #if ( MSK_VERSION_MAJOR < 7 )
52 #error "The MOSEK interface only works for MOSEK versions 7.0.0.0 and newer"
53 #endif
54 
55 #define scipmskobjsen MSKobjsensee
56 #define SENSE2MOSEK(objsen) (((objsen)==SCIP_OBJSEN_MINIMIZE)?(MSK_OBJECTIVE_SENSE_MINIMIZE):(MSK_OBJECTIVE_SENSE_MAXIMIZE))
57 
58 typedef enum MSKoptimizertype_enum MSKoptimizertype;
59 
60 #define MOSEK_CALL(x) do \
61  { /*lint --e{641}*/ \
62  MSKrescodee _restat_; \
63  _restat_ = (x); \
64  if( (_restat_) != MSK_RES_OK && (_restat_ ) != MSK_RES_TRM_MAX_NUM_SETBACKS ) \
65  { \
66  SCIPerrorMessage("LP Error: MOSEK returned %d.\n", (int)_restat_); \
67  return SCIP_LPERROR; \
68  } \
69  } \
70  while( FALSE )
71 
72 /* this macro is only called in functions returning SCIP_Bool; thus, we return FALSE if there is an error in optimized mode */
73 #define SCIP_ABORT_FALSE(x) do \
74  { \
75  SCIP_RETCODE _restat_; \
76  if( (_restat_ = (x)) != SCIP_OKAY ) \
77  { \
78  SCIPerrorMessage("LP Error: MOSEK returned %d.\n", (int)_restat_); \
79  SCIPABORT(); \
80  return FALSE; \
81  } \
82  } \
83  while( FALSE )
84 
85 #define IS_POSINF(x) ((x) >= MSK_INFINITY)
86 #define IS_NEGINF(x) ((x) <= -MSK_INFINITY)
87 
88 #ifdef SCIP_THREADSAFE
89  #if defined(_Thread_local)
90  /* Use thread local environment in order to not create a new environment for each new LP. */
91  static _Thread_local MSKenv_t reusemosekenv = NULL;
92  static _Thread_local int numlp = 0;
93  #define SCIP_REUSEENV
94  #endif
95 #else
96  /* Global Mosek environment in order to not create a new environment for each new LP. This is not thread safe. */
97  static MSKenv_t reusemosekenv = NULL;
98  static int numlp = 0;
99  #define SCIP_REUSEENV
100 #endif
101 
102 #if MSK_VERSION_MAJOR >= 9
103 #define NEAR_REL_TOLERANCE 1.0 /* MOSEK will multiply all tolerances with this factor after stalling */
104 #endif
105 #define DEBUG_PRINT_STAT 0
106 #define DEBUG_PARAM_SETTING 0
107 #define DEBUG_CHECK_DATA 0
108 #define DEBUG_EASY_REPRODUCE 0
109 #define DEBUG_DO_INTPNT_FEAS_CHECK 0
110 #define DEBUG_CHECK_STATE_TOL 1e-5
111 #define SHOW_ERRORS 0
112 #define SHOW_RELATIVE_OPTIMAL_GAP 0
113 #define ASSERT_ON_NUMERICAL_TROUBLES 0
114 #define ASSERT_ON_WARNING 0
115 #define FORCE_MOSEK_LOG 0 /* note that changing this AND setting lpinfo will lead to asserts in lpCheckIntpar */
116 #define FORCE_MOSEK_SUMMARY 0
117 #define FORCE_NO_MAXITER 0
118 #define SETBACK_LIMIT 250
119 #define STRONGBRANCH_PRICING MSK_SIM_SELECTION_SE
120 #define SUPRESS_NAME_ERROR 1
121 #define WRITE_DUAL 0
122 #define WRITE_PRIMAL 0
123 #define WRITE_INTPNT 0
124 #if WRITE_DUAL > 0 || WRITE_PRIMAL > 0 || WRITE_INTPNT > 0 || FORCE_MOSEK_LOG > 0 || FORCE_MOSEK_SUMMARY > 0
125 #define WRITE_ABOVE 0
126 #endif
127 #define DEGEN_LEVEL MSK_SIM_DEGEN_FREE
128 #define ALWAYS_SOLVE_PRIMAL_FORM 1
129 #if DEBUG_PRINT_STAT > 0
130 static int numstrongbranchmaxiterup = 0;
131 static int numstrongbranchmaxiterdo = 0;
132 static int numprimalmaxiter = 0;
133 static int numdualmaxiter = 0;
134 static int numstrongbranchobjup = 0;
135 static int numstrongbranchobjdo = 0;
136 static int numprimalobj = 0;
137 static int numdualobj = 0;
138 #endif
139 
140 #if DEBUG_PRINT_STAT > 0
141 static int numstrongbranchmaxiterup = 0;
142 static int numstrongbranchmaxiterdo = 0;
143 static int numprimalmaxiter = 0;
144 static int numdualmaxiter = 0;
145 static int numstrongbranchobjup = 0;
146 static int numstrongbranchobjdo = 0;
147 static int numprimalobj = 0;
148 static int numdualobj = 0;
149 #endif
150 
151 
152 /** internal data for Mosek LPI */
153 struct SCIP_LPi
154 {
155  MSKenv_t mosekenv; /**< Mosek environment */
156  MSKtask_t task; /**< Mosek task */
157  int optimizecount; /**< optimization counter (mainly for debugging) */
158  MSKrescodee termcode; /**< termination code of last optimization run */
159  int itercount; /**< iteration count of last optimization run */
160  SCIP_PRICING pricing; /**< SCIP pricing setting */
161  int lpid; /**< id for LP within same task */
162  MSKoptimizertype lastalgo; /**< algorithm type of last solving call */
163  MSKstakeye* skx; /**< basis status for columns */
164  MSKstakeye* skc; /**< basis status for rows */
165  MSKboundkeye* bkx; /**< bound keys for columns */
166  MSKboundkeye* bkc; /**< bound keys for rows */
167  MSKint32t* aptre; /**< row or column end pointers */
168  int skxsize; /**< size of skx array */
169  int skcsize; /**< size of skc array */
170  int bkxsize; /**< size of bkx */
171  int bkcsize; /**< size of bkx */
172  int aptresize; /**< size of aptre */
173  MSKsoltypee lastsolvetype; /**< Which solver was called last and which solution should be returned? */
174  SCIP_Bool solved; /**< was the current LP solved? */
175  SCIP_Bool fromscratch; /**< Shall solves be performed with MSK_IPAR_SIM_HOTSTART turned off? */
176  SCIP_Bool clearstate; /**< Shall next solve be performed with MSK_IPAR_SIM_HOTSTART turned off? */
177  SCIP_Bool lpinfo; /**< Should LP solver output information to the screen? */
178  int restrictselectdef; /**< default value for MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION */
179  SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
180 };
181 
182 typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
183 #define COLS_PER_PACKET SCIP_DUALPACKETSIZE
184 typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
185 #define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
186 
187 /** basis status */
188 struct SCIP_LPiState
189 {
190  int num;
191  MSKsolstae solsta; /**< solution status */
192  int ncols; /**< number of columns */
193  int nrows; /**< number of rows */
194  COLPACKET* skx; /**< basis status for columns */
195  ROWPACKET* skc; /**< basis status for rows */
196 };
197 
198 
199 /*
200  * Local functions
201  */
202 
203 /** gives problem and solution status for a Mosek Task
204  *
205  * With Mosek 7.0, the routine MSK_getsolutionstatus was replaced by MSK_getprosta and MSK_getsolsta.
206  */
207 static
209  MSKtask_t task, /**< Mosek Task */
210  MSKsoltypee whichsol, /**< for which type of solution a status is requested */
211  MSKprostae* prosta, /**< buffer to store problem status, or NULL if not needed */
212  MSKsolstae* solsta /**< buffer to store solution status, or NULL if not needed */
213  )
214 {
215  MSKrescodee res;
216 
217  if( prosta != NULL )
218  {
219  res = MSK_getprosta(task, whichsol, prosta);
220  if ( res != MSK_RES_OK )
221  return res;
222  }
223  if( solsta != NULL )
224  {
225  res = MSK_getsolsta(task, whichsol, solsta);
226  if ( res != MSK_RES_OK )
227  return res;
228  }
229 
230  return MSK_RES_OK;
231 }
232 
233 /** returns the number of packets needed to store column packet information */
234 static
236  int ncols /**< number of columns to store */
237  )
238 {
239  return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
240 }
241 
242 /** returns the number of packets needed to store row packet information */
243 static
245  int nrows /**< number of rows to store */
246  )
247 {
248  return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
249 }
250 
251 /** print string using message handler of SCIP */
252 static
253 void MSKAPI printstr(
254  MSKuserhandle_t handle, /**< error handle */
255  const char* str /**< string that contains string on output */
256  )
257 { /*lint --e{715}*/
258 #if SUPRESS_NAME_ERROR
259  char errstr[32];
260  (void) snprintf(errstr, 32, "MOSEK Error %d", MSK_RES_ERR_DUP_NAME);
261  if (0 == strncmp(errstr, str, strlen(errstr)))
262  return;
263 #endif
264 
265  SCIPmessagePrintInfo((SCIP_MESSAGEHDLR *) handle, "MOSEK: %s", str);
266 }
267 
268 #if DEBUG_CHECK_DATA > 0
269 /** check data */
270 static
271 SCIP_RETCODE scip_checkdata(
272  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
273  const char* functionname /**< function name */
274  )
275 {
276  int i;
277  int numcon;
278  int numvar;
279  int gotbasicsol;
280  MSKboundkeye* tbkc;
281  MSKboundkeye* tbkx;
282  MSKstakeye *tskc;
283  MSKstakeye* tskx;
284  double* tblc;
285  double* tbuc;
286  double* tblx;
287  double* tbux;
288 
289  assert(lpi != NULL);
290  assert(lpi->mosekenv != NULL);
291  assert(lpi->task != NULL);
292 
293  MOSEK_CALL( MSK_solutiondef(lpi->task, MSK_SOL_BAS, &gotbasicsol) );
294 
295  MOSEK_CALL( MSK_getnumvar(lpi->task, &numvar) );
296  MOSEK_CALL( MSK_getnumcon(lpi->task, &numcon) );
297 
298  /* allocate memory */
299  SCIP_ALLOC( BMSallocMemoryArray(&tbkc, numcon) );
300  SCIP_ALLOC( BMSallocMemoryArray(&tskc, numcon) );
301  SCIP_ALLOC( BMSallocMemoryArray(&tblc, numcon) );
302  SCIP_ALLOC( BMSallocMemoryArray(&tbuc, numcon) );
303 
304  SCIP_ALLOC( BMSallocMemoryArray(&tbkx, numvar) );
305  SCIP_ALLOC( BMSallocMemoryArray(&tskx, numvar) );
306  SCIP_ALLOC( BMSallocMemoryArray(&tblx, numvar) );
307  SCIP_ALLOC( BMSallocMemoryArray(&tbux, numvar) );
308 
309  /* Check bounds */
310  if( gotbasicsol )
311  {
312  MOSEK_CALL( MSK_getsolution(lpi->task, MSK_SOL_BAS, NULL, NULL, tskc, tskx,
313  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
314  }
315 
316  for( i = 0; i < numvar; i++ )
317  {
318  MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_VAR, i, &tbkx[i], &tblx[i], &tbux[i]) );
319  }
320 
321  for( i = 0; i < numcon; i++ )
322  {
323  MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_CON, i, &tbkc[i], &tblc[i], &tbuc[i]) );
324  }
325 
326  for( i = 0; i < numcon; ++i )
327  {
328  if( gotbasicsol )
329  {
330  if( ( tskc[i] == MSK_SK_FIX && tbkc[i] != MSK_BK_FX ) ||
331  ( tskc[i] == MSK_SK_LOW && !(tbkc[i] == MSK_BK_FX || tbkc[i] == MSK_BK_LO || tbkc[i] == MSK_BK_RA ) ) ||
332  ( tskc[i] == MSK_SK_UPR && !(tbkc[i] == MSK_BK_FX || tbkc[i] == MSK_BK_UP || tbkc[i] == MSK_BK_RA ) ) )
333  {
334  SCIPerrorMessage("STATUS KEY ERROR i %d bkc %d skc %d %s\n", i, tbkc[i], tskc[i], functionname);
335  }
336  }
337 
338  if( tbkc[i] == MSK_BK_LO || tbkc[i] == MSK_BK_FX || tbkc[i] == MSK_BK_RA )
339  {
340  if( isnan(tblc[i]) )
341  {
342  SCIPdebugMessage("nan in blc : %s\n", functionname);
343  }
344  }
345 
346  if( tbkc[i] == MSK_BK_UP || tbkc[i] == MSK_BK_FX || tbkc[i] == MSK_BK_RA )
347  {
348  if( isnan(tbuc[i]) )
349  {
350  SCIPdebugMessage("nan in bux : %s\n", functionname);
351  }
352  }
353  }
354 
355  for( i = 0; i < numvar; ++i )
356  {
357  if( tbkx[i] == MSK_BK_LO || tbkx[i] == MSK_BK_FX || tbkx[i] == MSK_BK_RA )
358  {
359  if( isnan(tblx[i]) )
360  {
361  SCIPdebugMessage("nan in blx : %s\n", functionname);
362  }
363  }
364 
365  if( tbkx[i] == MSK_BK_UP || tbkx[i] == MSK_BK_FX || tbkx[i] == MSK_BK_RA )
366  {
367  if( isnan(tbux[i]) )
368  {
369  SCIPdebugMessage("nan in bux : %s\n", functionname);
370  getchar();
371  }
372  }
373  }
374 
375  BMSfreeMemoryArray(&tbkc);
376  BMSfreeMemoryArray(&tskc);
377  BMSfreeMemoryArray(&tblc);
378  BMSfreeMemoryArray(&tbuc);
379  BMSfreeMemoryArray(&tbkx);
380  BMSfreeMemoryArray(&tskx);
381  BMSfreeMemoryArray(&tblx);
382  BMSfreeMemoryArray(&tbux);
383 
384  return SCIP_OKAY;
385 }
386 #endif
387 
388 /** resizes bound keys array bkx to have at least ncols entries */
389 static
391  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
392  int ncols /**< number of columns */
393  )
394 {
395  if ( lpi->bkxsize < ncols )
396  {
397  int newsize;
398  newsize = MAX(2*lpi->bkxsize, ncols);
399 
400  SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->bkx), newsize) );
401  lpi->bkxsize = newsize;
402  }
403 
404  return SCIP_OKAY;
405 }
406 
407 /** resizes bound keys array bkc to have at least nrows entries */
408 static
410  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
411  int nrows /**< number of rows */
412  )
413 {
414  if ( lpi->bkcsize < nrows )
415  {
416  int newsize;
417  newsize = MAX(2*lpi->bkcsize, nrows);
418 
419  SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->bkc), newsize) );
420  lpi->bkcsize = newsize;
421  }
422 
423  return SCIP_OKAY;
424 }
425 
426 /** resizes aptre array to have at least n entries */
427 static
429  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
430  int n /**< number of entries */
431  )
432 {
433  if ( lpi->aptresize < n )
434  {
435  int newsize;
436  newsize = MAX(2*lpi->aptresize, n);
437 
438  SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->aptre), newsize) );
439  lpi->aptresize = newsize;
440  }
441 
442  return SCIP_OKAY;
443 }
444 
445 /** marks the current LP to be unsolved */
446 static
448  SCIP_LPI* lpi /**< pointer to an LP interface structure */
449  )
450 {
451  assert(lpi != NULL);
452 
453  lpi->solved = FALSE;
454 }
455 
456 /** compute boundkeys to inform MOSEK about fixed/free/ranged/lower bounded/upper bounded variables or constraints */
457 static
459  int n, /**< array size */
460  const double* lb, /**< lower bounds of variables or left-hand sides of ranged rows */
461  const double* ub, /**< upper bounds of variables or right-hand sides of ranged rows */
462  MSKboundkeye* bk /**< pointer to store boundkeys to inform MOSEK about status of var/row */
463  )
464 {
465  int i;
466 
467  assert(lb != NULL);
468  assert(ub != NULL);
469  assert(bk != NULL);
470 
471  for( i = 0; i < n; i++ )
472  {
473  if (IS_NEGINF(lb[i]))
474  {
475  if (IS_POSINF(ub[i]))
476  {
477  bk[i] = MSK_BK_FR;
478  }
479  else
480  {
481  assert(!IS_NEGINF(ub[i]));
482  bk[i] = MSK_BK_UP;
483  }
484  }
485  else
486  {
487  assert(!IS_POSINF(lb[i]));
488  if (IS_POSINF(ub[i]))
489  {
490  bk[i] = MSK_BK_LO;
491  }
492  else if (lb[i] == ub[i])/*lint !e777*/ /* No epsilon-test since MOSEK will also test for exact equality */
493  {
494  assert(lb[i] - ub[i] == 0);
495  assert(ub[i] - lb[i] == 0);
496  bk[i] = MSK_BK_FX;
497  }
498  else
499  {
500  assert(lb[i] < ub[i]);
501  bk[i] = MSK_BK_RA;
502  }
503  }
504  }
505 }
506 
507 /** get end pointers of arrays */
508 static
510  int n, /**< array size */
511  const int* beg, /**< array of beginning indices */
512  int nnonz, /**< number of nonzeros */
513  MSKint32t* aptre /**< array to store the result */
514  )
515 {
516  int i;
517 
518  assert(beg != NULL || nnonz == 0);
519 
520  if (nnonz > 0)
521  {
522  assert(beg != NULL);
523  for(i = 0; i < n-1; i++)
524  {
525  aptre[i] = beg[i+1];
526  assert(aptre[i] >= beg[i]);
527  }
528 
529  aptre[n-1] = nnonz;
530  assert(aptre[n-1] >= beg[n-1]);
531  }
532  else
533  {
534  for( i = 0; i < n; i++ )
535  aptre[i] = 0;
536  }
537 
538  return SCIP_OKAY;
539 }
540 
541 /** compute indices from range */
542 static
544  int first, /**< first index */
545  int last, /**< last index */
546  int** sub /**< pointer to store the indices ranges */
547  )
548 {
549  int i;
550 
551  assert(first <= last);
552 
553  SCIP_ALLOC( BMSallocMemoryArray(sub, (last - first + 1)) );
554 
555  for( i = first; i <= last; i++ )
556  {
557  (*sub)[i-first] = i;
558  }
559 
560  return SCIP_OKAY;
561 }
562 
563 /** compute indices from dense array */
564 static
566  int* dstat, /**< array */
567  int n, /**< size of array */
568  int* count, /**< array of counts (sizes) */
569  int** sub /**< pointer to store array of indices */
570  )
571 {
572  int i;
573  int j;
574 
575  assert(dstat != NULL);
576  assert(count != NULL);
577 
578  *count = 0;
579  for( i = 0; i < n; i++ )
580  {
581  if (dstat[i] == 1)
582  {
583  (*count)++;
584  }
585  }
586 
587  if( (*count) > 0 )
588  {
589  SCIP_ALLOC( BMSallocMemoryArray(sub, (*count)) );
590  }
591  else
592  return SCIP_OKAY;
593 
594  j = 0;
595  for( i = 0; i < n; i++ )
596  {
597  if (dstat[i] == 1)
598  {
599  (*sub)[j++] = i;
600  }
601  }
602 
603  return SCIP_OKAY;
604 }
605 
606 /** scale a vector */
607 static
609  int len, /**< length of vector */
610  double* vec, /**< vector to be scaled */
611  double s /**< scaling factor */
612  )
613 {
614  int i;
615  for( i = 0; i < len; i++ )
616  {
617  vec[i] *= s;
618  }
619 }
620 
621 /** scale lower and upper bound */
622 static
624  MSKboundkeye* bk, /**< pointer to store boundkeys to inform MOSEK about status of var/row */
625  double* bl, /**< lower bound */
626  double* bu, /**< upper bound */
627  double s /**< scaling factor */
628  )
629 {
630  switch( *bk )
631  {
632  case MSK_BK_LO:
633  *bl *= s;
634  if ( s < 0.0 )
635  *bk = MSK_BK_UP;
636  break;
637  case MSK_BK_UP:
638  *bu *= s;
639  if ( s < 0.0 )
640  *bk = MSK_BK_LO;
641  break;
642  case MSK_BK_FX:
643  case MSK_BK_RA:
644  *bl *= s;
645  *bu *= s;
646  break;
647  case MSK_BK_FR:
648  break;
649  default:
650  SCIPABORT();
651  break;
652  } /*lint !e788*/
653 
654  /* switch bounds if scaling is negative */
655  if ( s < 0.0 )
656  {
657  double tmp;
658  tmp = *bl;
659  *bl = *bu;
660  *bu = tmp;
661  }
662 }
663 
664 /** resizes state arrays to have at least ncols/nrows entries */
665 static
667  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
668  int ncols, /**< number of columns */
669  int nrows /**< number of rows */
670  )
671 {
672  if ( lpi->skxsize < ncols )
673  {
674  int newsize;
675  newsize = MAX(2*lpi->skxsize, ncols);
676 
677  SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->skx), newsize) );
678  lpi->skxsize = newsize;
679  }
680 
681  if ( lpi->skcsize < nrows )
682  {
683  int newsize;
684  newsize = MAX(2*lpi->skcsize, nrows);
685 
686  SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->skc), newsize) );
687  lpi->skcsize = newsize;
688  }
689 
690  return SCIP_OKAY;
691 }
692 
693 /** get base and store in skc/skx arrays */
694 static
696  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
697  int ncols, /**< number of columns */
698  int nrows /**< number of rows */
699  )
700 {
701  assert(lpi->lastsolvetype == MSK_SOL_BAS);
702 
703  SCIPdebugMessage("Calling getbase (%d)\n", lpi->lpid);
704 
705  SCIP_CALL( ensureStateMem(lpi, ncols, nrows) );
706  MOSEK_CALL( MSK_getsolution(lpi->task, MSK_SOL_BAS, NULL, NULL, lpi->skc, lpi->skx,
707  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
708 
709  return SCIP_OKAY;
710 }
711 
712 /** set base to the values given in skc/skx arrays */
713 static
715  SCIP_LPI* lpi /**< pointer to an LP interface structure */
716  )
717 {
718  SCIPdebugMessage("Calling setbase (%d)\n", lpi->lpid);
719 
720  lpi->lastsolvetype = MSK_SOL_BAS;
721  lpi->solved = FALSE;
722 
723  MOSEK_CALL( MSK_putsolution(lpi->task, MSK_SOL_BAS, lpi->skc, lpi->skx, NULL, NULL,
724  NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
725 
726  return SCIP_OKAY;
727 }
728 
729 
730 
731 /*
732  * Miscellaneous Methods
733  */
734 
735 #define STR_HELPER(x) #x
736 #define STR(x) STR_HELPER(x)
737 
738 #if MSK_VERSION_MAJOR < 9
739  #define mskname "MOSEK " STR(MSK_VERSION_MAJOR) "." STR(MSK_VERSION_MINOR) "." STR(MSK_VERSION_BUILD) "." STR(MSK_VERSION_REVISION)
740 #else
741  #define mskname "MOSEK " STR(MSK_VERSION_MAJOR) "." STR(MSK_VERSION_MINOR) "." STR(MSK_VERSION_REVISION)
742 #endif
743 
744 /**@name Miscellaneous Methods */
745 /**@{ */
746 
747 /** gets name and version of LP solver */
749  void
750  )
751 {
752  return mskname;
753 }
754 
755 /** gets description of LP solver (developer, webpage, ...) */
757  void
758  )
759 {
760  return "Linear Programming Solver developed by MOSEK Optimization Software (www.mosek.com)";
761 }
762 
763 /** gets pointer for LP solver - use only with great care */
765  SCIP_LPI* lpi /**< pointer to an LP interface structure */
766  )
767 {
768  assert(lpi != NULL);
769  assert(lpi->mosekenv != NULL);
770  assert(lpi->task != NULL);
771 
772  return (void*) lpi->task;
773 }
774 
775 /** pass integrality information to LP solver */
777  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
778  int ncols, /**< length of integrality array */
779  int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
780  )
781 { /*lint --e{715}*/
782  assert( lpi != NULL );
783  assert( ncols >= 0 );
784  assert( intInfo != NULL );
785 
786  SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
787  return SCIP_LPERROR;
788 }
789 
790 /** informs about availability of a primal simplex solving method */
792  void
793  )
794 {
795  return TRUE;
796 }
797 
798 /** informs about availability of a dual simplex solving method */
800  void
801  )
802 {
803  return TRUE;
804 }
805 
806 /** informs about availability of a barrier solving method */
808  void
809  )
810 {
811  return TRUE;
812 }
813 
814 /**@} */
815 
816 
817 /*
818  * LPI Creation and Destruction Methods
819  */
820 
821 /**@name LPI Creation and Destruction Methods */
822 /**@{ */
823 
824 /** creates an LP problem object */
826  SCIP_LPI** lpi, /**< pointer to an LP interface structure */
827  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
828  const char* name, /**< problem name */
829  SCIP_OBJSEN objsen /**< objective sense */
830  )
831 {
832  assert(lpi != NULL);
833  assert(name != NULL);
834 
835  SCIPdebugMessage("Calling SCIPlpiCreate\n");
836 
837  SCIP_ALLOC( BMSallocMemory(lpi) );
838 
839 #ifdef SCIP_REUSEENV
840  if ( reusemosekenv == NULL )
841  {
842  assert(numlp == 0);
843  MOSEK_CALL( MSK_makeenv(&reusemosekenv, NULL) );
844  MOSEK_CALL( MSK_linkfunctoenvstream(reusemosekenv, MSK_STREAM_LOG, (MSKuserhandle_t) messagehdlr, printstr) );
845 #if MSK_VERSION_MAJOR < 8
846  MOSEK_CALL( MSK_initenv(reusemosekenv) );
847 #endif
848  }
849  (*lpi)->mosekenv = reusemosekenv;
850  (*lpi)->lpid = numlp++;
851 
852 #else
853 
854  MOSEK_CALL( MSK_makeenv(&(*lpi)->mosekenv, NULL) );
855  MOSEK_CALL( MSK_linkfunctoenvstream((*lpi)->mosekenv, MSK_STREAM_LOG, (MSKuserhandle_t) messagehdlr, printstr) );
856 #if MSK_VERSION_MAJOR < 8
857  MOSEK_CALL( MSK_initenv((*lpi)->mosekenv) );
858 #endif
859 #endif
860 
861  MOSEK_CALL( MSK_makeemptytask((*lpi)->mosekenv, &((*lpi)->task)) );
862 
863  MOSEK_CALL( MSK_linkfunctotaskstream((*lpi)->task, MSK_STREAM_LOG, (MSKuserhandle_t) messagehdlr, printstr) );
864 
865  MOSEK_CALL( MSK_putobjsense((*lpi)->task, SENSE2MOSEK(objsen)) );
866  MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_SIM_MAX_NUM_SETBACKS, SETBACK_LIMIT) );
867  MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_FREE_SIMPLEX) );
868  MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_SIM_DEGEN, DEGEN_LEVEL) );
869  MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_SIM_SWITCH_OPTIMIZER, MSK_ON) );
870  MOSEK_CALL( MSK_puttaskname((*lpi)->task, (char*) name) );
871 
872  /* disable errors for huge values */
873  MOSEK_CALL( MSK_putdouparam((*lpi)->task, MSK_DPAR_DATA_TOL_AIJ_HUGE, MSK_INFINITY * 2)); /* not clear why the *2 is needed */
874  MOSEK_CALL( MSK_putdouparam((*lpi)->task, MSK_DPAR_DATA_TOL_C_HUGE, MSK_INFINITY));
875 
876  /* disable warnings for large values */
877  MOSEK_CALL( MSK_putdouparam((*lpi)->task, MSK_DPAR_DATA_TOL_AIJ_LARGE, MSK_INFINITY * 2));
878  MOSEK_CALL( MSK_putdouparam((*lpi)->task, MSK_DPAR_DATA_TOL_CJ_LARGE, MSK_INFINITY));
879 
880  /* disable warnings for large bounds */
881  MOSEK_CALL( MSK_putdouparam((*lpi)->task, MSK_DPAR_DATA_TOL_BOUND_WRN, MSK_INFINITY));
882 
883  (*lpi)->termcode = MSK_RES_OK;
884  (*lpi)->itercount = 0;
885  (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
886  (*lpi)->lastalgo = MSK_OPTIMIZER_FREE;
887  (*lpi)->skx = NULL;
888  (*lpi)->skc = NULL;
889  (*lpi)->bkx = NULL;
890  (*lpi)->bkc = NULL;
891  (*lpi)->aptre = NULL;
892  (*lpi)->skxsize = 0;
893  (*lpi)->skcsize = 0;
894  (*lpi)->bkxsize = 0;
895  (*lpi)->bkcsize = 0;
896  (*lpi)->aptresize = 0;
897  (*lpi)->lastsolvetype = (MSKsoltypee) -1;
898  (*lpi)->lpinfo = FALSE;
899  (*lpi)->restrictselectdef = 50;
900  (*lpi)->fromscratch = FALSE;
901  (*lpi)->clearstate = FALSE;
902  (*lpi)->messagehdlr = messagehdlr;
903 
904  invalidateSolution(*lpi);
905 
906  MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_LOG, MSK_OFF) );
907  MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_LOG_SIM, MSK_OFF) );
908 
909  return SCIP_OKAY;
910 }
911 
912 /** deletes an LP problem object */
914  SCIP_LPI** lpi /**< pointer to an LP interface structure */
915  )
916 {
917  assert(lpi != NULL);
918  assert(*lpi != NULL);
919 
920  SCIPdebugMessage("Calling SCIPlpiFree (%d)\n", (*lpi)->lpid);
921 
922  MOSEK_CALL( MSK_deletetask(&(*lpi)->task) );
923 
924  BMSfreeMemoryArrayNull(&(*lpi)->aptre);
925  BMSfreeMemoryArrayNull(&(*lpi)->bkx);
926  BMSfreeMemoryArrayNull(&(*lpi)->bkc);
927  BMSfreeMemoryArrayNull(&(*lpi)->skx);
928  BMSfreeMemoryArrayNull(&(*lpi)->skc);
929 
930 #ifdef SCIP_REUSEENV
931  assert(numlp > 0);
932  numlp--;
933  if ( numlp == 0 )
934  {
935  MOSEK_CALL( MSK_deleteenv(&reusemosekenv) );
937  }
938 #else
939  MOSEK_CALL( MSK_deleteenv(&(*lpi)->mosekenv) );
940 #endif
941 
942  BMSfreeMemory(lpi);
943 
944  return SCIP_OKAY;
945 }
946 
947 /*
948  * Modification Methods
949  */
950 
951 
952 /** copies LP data with column matrix into LP solver */
954  SCIP_LPI* lpi, /**< LP interface structure */
955  SCIP_OBJSEN objsen, /**< objective sense */
956  int ncols, /**< number of columns */
957  const SCIP_Real* obj, /**< objective function values of columns */
958  const SCIP_Real* lb, /**< lower bounds of columns */
959  const SCIP_Real* ub, /**< upper bounds of columns */
960  char** colnames, /**< column names, or NULL */
961  int nrows, /**< number of rows */
962  const SCIP_Real* lhs, /**< left hand sides of rows */
963  const SCIP_Real* rhs, /**< right hand sides of rows */
964  char** rownames, /**< row names, or NULL */
965  int nnonz, /**< number of nonzero elements in the constraint matrix */
966  const int* beg, /**< start index of each column in ind- and val-array */
967  const int* ind, /**< row indices of constraint matrix entries */
968  const SCIP_Real* val /**< values of constraint matrix entries */
969  )
970 {
971 #ifndef NDEBUG
972  {
973  int j;
974  for( j = 0; j < nnonz; j++ )
975  assert( val[j] != 0.0 );
976  }
977 #endif
978 
979  assert(lpi != NULL);
980  assert(lpi->mosekenv != NULL);
981  assert(lpi->task != NULL);
982  assert(lhs != NULL);
983  assert(rhs != NULL);
984  assert(obj != NULL);
985  assert(lb != NULL);
986  assert(ub != NULL);
987  assert(beg != NULL);
988  assert(ind != NULL);
989  assert(val != NULL);
990 
991  SCIPdebugMessage("Calling SCIPlpiLoadColLP (%d)\n", lpi->lpid);
992 
993  invalidateSolution(lpi);
994 
995 #if DEBUG_CHECK_DATA > 0
996  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiLoadColLP") );
997 #endif
998 
999  if (nrows > 0)
1000  {
1001  SCIP_CALL( ensureBkcMem(lpi, nrows) );
1002  generateMskBoundkeys(nrows, lhs, rhs, lpi->bkc);
1003  }
1004 
1005  if (ncols > 0)
1006  {
1007  SCIP_CALL( ensureBkxMem(lpi, ncols) );
1008  generateMskBoundkeys(ncols, lb, ub, lpi->bkx);
1009 
1010  SCIP_CALL( ensureAptreMem(lpi, ncols) );
1011  SCIP_CALL( getEndptrs(ncols, beg, nnonz, lpi->aptre) );
1012  }
1013 
1014  MOSEK_CALL( MSK_inputdata(lpi->task, nrows, ncols, nrows, ncols, obj, 0.0, beg, lpi->aptre, ind, val,
1015  lpi->bkc, lhs, rhs, lpi->bkx, lb, ub) );
1016 
1017  MOSEK_CALL( MSK_putobjsense(lpi->task, SENSE2MOSEK(objsen)) );
1018 
1019  if( colnames != NULL )
1020  {
1021  int c;
1022 
1023  for( c = 0; c < ncols; c++ )
1024  {
1025  MOSEK_CALL( MSK_putvarname(lpi->task, c, colnames[c]) );
1026  }
1027  }
1028 
1029  if( rownames != NULL )
1030  {
1031  int r;
1032 
1033  for( r = 0; r < nrows; r++ )
1034  {
1035  MOSEK_CALL( MSK_putconname(lpi->task, r, rownames[r]) );
1036  }
1037  }
1038 
1039 #if DEBUG_CHECK_DATA > 0
1040  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiLoadColLP") );
1041 #endif
1042 
1043  return SCIP_OKAY;
1044 }
1045 
1046 /** adds columns to the LP */
1048  SCIP_LPI* lpi, /**< LP interface structure */
1049  int ncols, /**< number of columns to be added */
1050  const SCIP_Real* obj, /**< objective function values of new columns */
1051  const SCIP_Real* lb, /**< lower bounds of new columns */
1052  const SCIP_Real* ub, /**< upper bounds of new columns */
1053  char** colnames, /**< column names, or NULL */
1054  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1055  const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
1056  const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
1057  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1058  )
1059 {
1060 #if MSK_VERSION_MAJOR < 7
1061  const int* aptrb;
1062 #endif
1063 
1064  int oldcols;
1065 
1066  assert(lpi != NULL);
1067  assert(lpi->mosekenv != NULL);
1068  assert(lpi->task != NULL);
1069  assert(obj != NULL);
1070  assert(lb != NULL);
1071  assert(ub != NULL);
1072  assert(nnonz == 0 || beg != NULL);
1073  assert(nnonz == 0 || ind != NULL);
1074  assert(nnonz == 0 || val != NULL);
1075  assert(nnonz >= 0);
1076  assert(ncols >= 0);
1077 
1078  SCIPdebugMessage("Calling SCIPlpiAddCols (%d)\n", lpi->lpid);
1079 
1080  invalidateSolution(lpi);
1081 
1082 #if DEBUG_CHECK_DATA > 0
1083  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiAddCols") );
1084 #endif
1085 
1086  if (ncols == 0)
1087  return SCIP_OKAY;
1088 
1089  SCIP_CALL( ensureBkxMem(lpi, ncols) );
1090  generateMskBoundkeys(ncols, lb, ub, lpi->bkx);
1091 
1092  MOSEK_CALL( MSK_getnumvar(lpi->task, &oldcols) );
1093 
1094  MOSEK_CALL( MSK_appendvars(lpi->task, ncols) );
1095  MOSEK_CALL( MSK_putcslice(lpi->task, oldcols, oldcols+ncols, obj) );
1096  MOSEK_CALL( MSK_putvarboundslice(lpi->task, oldcols, oldcols+ncols, lpi->bkx, lb, ub) );
1097 
1098  if( nnonz > 0 )
1099  {
1100 #ifndef NDEBUG
1101  /* perform check that no new rows are added - this is forbidden */
1102  int nrows;
1103  int j;
1104 
1105  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
1106  for (j = 0; j < nnonz; ++j)
1107  {
1108  assert( 0 <= ind[j] && ind[j] < nrows );
1109  assert( val[j] != 0.0 );
1110  }
1111 #endif
1112 
1113  SCIP_CALL( ensureAptreMem(lpi, ncols) );
1114  SCIP_CALL( getEndptrs(ncols, beg, nnonz, lpi->aptre) );
1115  MOSEK_CALL( MSK_putacolslice(lpi->task, oldcols, oldcols+ncols, beg, lpi->aptre, ind, val) );
1116  }
1117 
1118  if( colnames != NULL )
1119  {
1120  int c;
1121 
1122  for( c = 0; c < ncols; c++ )
1123  {
1124  MOSEK_CALL( MSK_putvarname(lpi->task, c, colnames[c]) );
1125  }
1126  }
1127 
1128 #if DEBUG_CHECK_DATA > 0
1129  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiAddCols") );
1130 #endif
1131 
1132  return SCIP_OKAY;
1133 }
1134 
1135 /** deletes all columns in the given range from LP */
1137  SCIP_LPI* lpi, /**< LP interface structure */
1138  int firstcol, /**< first column to be deleted */
1139  int lastcol /**< last column to be deleted */
1140  )
1141 {
1142  int* sub;
1143 
1144  assert(lpi != NULL);
1145  assert(lpi->mosekenv != NULL);
1146  assert(lpi->task != NULL);
1147 
1148  SCIPdebugMessage("Calling SCIPlpiDelCols (%d)\n", lpi->lpid);
1149 
1150  invalidateSolution(lpi);
1151 
1152 #if DEBUG_CHECK_DATA > 0
1153  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelCols") );
1154 #endif
1155 
1156  SCIP_CALL( getIndicesRange(firstcol, lastcol, &sub) );
1157 
1158  MOSEK_CALL( MSK_removevars(lpi->task, lastcol-firstcol+1, sub) );
1159 
1160  BMSfreeMemoryArray(&sub);
1161 
1162 #if DEBUG_CHECK_DATA > 0
1163  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelCols") );
1164 #endif
1165 
1166  return SCIP_OKAY;
1167 }
1168 
1169 /** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
1171  SCIP_LPI* lpi, /**< LP interface structure */
1172  int* dstat /**< deletion status of columns
1173  * input: 1 if column should be deleted, 0 if not
1174  * output: new position of column, -1 if column was deleted */
1175  )
1176 {
1177  int* sub = NULL;
1178  int count;
1179  int ncols;
1180  int col;
1181  int i;
1182 
1183  assert(lpi != NULL);
1184  assert(lpi->mosekenv != NULL);
1185  assert(lpi->task != NULL);
1186  assert(dstat != NULL);
1187 
1188  SCIPdebugMessage("Calling SCIPlpiDelColset (%d)\n", lpi->lpid);
1189 
1190  invalidateSolution(lpi);
1191 
1192 #if DEBUG_CHECK_DATA > 0
1193  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelColset") );
1194 #endif
1195 
1196  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
1197 
1198  SCIP_CALL( getIndicesFromDense(dstat, ncols, &count, &sub) );
1199 
1200  col = 0;
1201  for( i = 0; i < ncols; i++)
1202  {
1203  if (dstat[i] == 1)
1204  {
1205  dstat[i] = -1;
1206  }
1207  else
1208  {
1209  dstat[i] = col;
1210  col++;
1211  }
1212  }
1213 
1214  if (count > 0)
1215  {
1216  SCIPdebugMessage("Deleting %d vars %d, ...\n", count, sub[0]);
1217  MOSEK_CALL( MSK_removevars(lpi->task, count, sub) );
1218  BMSfreeMemoryArray(&sub);
1219  }
1220 
1221 #if DEBUG_CHECK_DATA > 0
1222  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelColset") );
1223 #endif
1224 
1225  return SCIP_OKAY;
1226 }
1227 
1228 /** adds rows to the LP */
1230  SCIP_LPI* lpi, /**< LP interface structure */
1231  int nrows, /**< number of rows to be added */
1232  const SCIP_Real* lhs, /**< left hand sides of new rows */
1233  const SCIP_Real* rhs, /**< right hand sides of new rows */
1234  char** rownames, /**< row names, or NULL */
1235  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1236  const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1237  const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1238  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1239  )
1240 {
1241  int oldrows;
1242 
1243  assert(lpi != NULL);
1244  assert(lpi->mosekenv != NULL);
1245  assert(lpi->task != NULL);
1246  assert(nnonz == 0 || beg != NULL);
1247  assert(nnonz == 0 || ind != NULL);
1248  assert(nnonz == 0 || val != NULL);
1249 
1250  SCIPdebugMessage("Calling SCIPlpiAddRows (%d)\n", lpi->lpid);
1251 
1252  invalidateSolution(lpi);
1253 
1254 #if DEBUG_CHECK_DATA > 0
1255  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiAddRows") );
1256 #endif
1257 
1258  if (nrows == 0)
1259  return SCIP_OKAY;
1260 
1261  SCIP_CALL( ensureBkcMem(lpi, nrows) );
1262 
1263  generateMskBoundkeys(nrows, lhs, rhs, lpi->bkc);
1264 
1265  MOSEK_CALL( MSK_getnumcon(lpi->task, &oldrows) );
1266 
1267  MOSEK_CALL( MSK_appendcons(lpi->task, nrows) );
1268  MOSEK_CALL( MSK_putconboundslice(lpi->task, oldrows, oldrows+nrows, lpi->bkc, lhs, rhs) );
1269 
1270  if( nnonz > 0 )
1271  {
1272 #ifndef NDEBUG
1273  /* perform check that no new cols are added - this is forbidden */
1274  int ncols;
1275  int j;
1276 
1277  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
1278  for (j = 0; j < nnonz; ++j)
1279  {
1280  assert( val[j] != 0.0 );
1281  assert( 0 <= ind[j] && ind[j] < ncols );
1282  }
1283 #endif
1284 
1285  SCIP_CALL( ensureAptreMem(lpi, nrows) );
1286  SCIP_CALL( getEndptrs(nrows, beg, nnonz, lpi->aptre) );
1287  MOSEK_CALL( MSK_putarowslice(lpi->task, oldrows, oldrows+nrows, beg, lpi->aptre, ind, val) );
1288  }
1289 
1290  if( rownames != NULL )
1291  {
1292  int r;
1293 
1294  for( r = 0; r < nrows; r++ )
1295  {
1296  MOSEK_CALL( MSK_putconname(lpi->task, r, rownames[r]) );
1297  }
1298  }
1299 
1300 #if DEBUG_CHECK_DATA > 0
1301  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiAddRows") );
1302 #endif
1303 
1304  return SCIP_OKAY;
1305 }
1306 
1307 /** deletes all rows in the given range from LP */
1309  SCIP_LPI* lpi, /**< LP interface structure */
1310  int firstrow, /**< first row to be deleted */
1311  int lastrow /**< last row to be deleted */
1312  )
1313 {
1314  int* sub;
1315 
1316  assert(lpi != NULL);
1317  assert(lpi->mosekenv != NULL);
1318  assert(lpi->task != NULL);
1319 
1320  SCIPdebugMessage("Calling SCIPlpiDelRows (%d)\n", lpi->lpid);
1321 
1322  invalidateSolution(lpi);
1323 
1324 #if DEBUG_CHECK_DATA > 0
1325  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelRows") );
1326 #endif
1327 
1328  SCIP_CALL( getIndicesRange(firstrow, lastrow, &sub) );
1329 
1330  SCIPdebugMessage("Deleting cons %d to %d\n", firstrow, lastrow);
1331 
1332  MOSEK_CALL( MSK_removecons(lpi->task, lastrow-firstrow+1, sub) );
1333 
1334  BMSfreeMemoryArray(&sub);
1335 
1336 #if DEBUG_CHECK_DATA > 0
1337  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelRows") );
1338 #endif
1339 
1340  return SCIP_OKAY;
1341 }
1342 
1343 /** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1345  SCIP_LPI* lpi, /**< LP interface structure */
1346  int* dstat /**< deletion status of rows
1347  * input: 1 if row should be deleted, 0 if not
1348  * output: new position of row, -1 if row was deleted */
1349  )
1350 {
1351  int* sub;
1352  int count;
1353  int nrows;
1354  int row;
1355  int i;
1356 
1357  assert(lpi != NULL);
1358  assert(lpi->mosekenv != NULL);
1359  assert(lpi->task != NULL);
1360 
1361  SCIPdebugMessage("Calling SCIPlpiDelRowset (%d)\n", lpi->lpid);
1362 
1363  invalidateSolution(lpi);
1364 
1365 #if DEBUG_CHECK_DATA > 0
1366  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelRowset") );
1367 #endif
1368 
1369  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
1370 
1371  sub = NULL;
1372  SCIP_CALL( getIndicesFromDense(dstat, nrows, &count, &sub) );
1373 
1374  row = 0;
1375  for( i = 0; i < nrows; i++ )
1376  {
1377  if (dstat[i] == 1)
1378  {
1379  dstat[i] = -1;
1380  }
1381  else
1382  {
1383  dstat[i] = row;
1384  row++;
1385  }
1386  }
1387 
1388  if (count > 0)
1389  {
1390  SCIPdebugMessage("Deleting %d cons %d, ...\n", count, sub[0]);
1391  MOSEK_CALL( MSK_removecons(lpi->task, count, sub) );
1392  BMSfreeMemoryArray(&sub);
1393  }
1394 
1395 #if DEBUG_CHECK_DATA > 0
1396  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelRowset end") );
1397 #endif
1398 
1399  return SCIP_OKAY;
1400 }
1401 
1402 /** clears the whole LP */
1404  SCIP_LPI* lpi /**< LP interface structure */
1405  )
1406 {
1407  int nrows;
1408  int ncols;
1409 
1410  assert(lpi != NULL);
1411  assert(lpi->mosekenv != NULL);
1412  assert(lpi->task != NULL);
1413 
1414  SCIPdebugMessage("Calling SCIPlpiClear (%d)\n", lpi->lpid);
1415 
1416  invalidateSolution(lpi);
1417 
1418  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
1419  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
1420 
1421  SCIP_CALL( SCIPlpiDelRows(lpi, 0, nrows - 1) );
1422  SCIP_CALL( SCIPlpiDelCols(lpi, 0, ncols - 1) );
1423 
1424  return SCIP_OKAY;
1425 }
1426 
1427 /** changes lower and upper bounds of columns */
1429  SCIP_LPI* lpi, /**< LP interface structure */
1430  int ncols, /**< number of columns to change bounds for */
1431  const int* ind, /**< column indices or NULL if ncols is zero */
1432  const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
1433  const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
1434  )
1435 {
1436  int i;
1437 
1438  assert(lpi != NULL);
1439  assert(lpi->mosekenv != NULL);
1440  assert(lpi->task != NULL);
1441  assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
1442 
1443  SCIPdebugMessage("Calling SCIPlpiChgBounds (%d)\n", lpi->lpid);
1444  if( ncols <= 0 )
1445  return SCIP_OKAY;
1446 
1447  invalidateSolution(lpi);
1448 
1449 #if DEBUG_CHECK_DATA > 0
1450  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgBounds") );
1451 #endif
1452 
1453  /* @todo This test could be integrated into generateMskBoundkeys, but then this function needs to be able to return an
1454  * error, which requires some rewriting. */
1455  for (i = 0; i < ncols; ++i)
1456  {
1457  if ( SCIPlpiIsInfinity(lpi, lb[i]) )
1458  {
1459  SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
1460  return SCIP_LPERROR;
1461  }
1462  if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
1463  {
1464  SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
1465  return SCIP_LPERROR;
1466  }
1467  }
1468 
1469  SCIP_CALL( ensureBkxMem(lpi, ncols) );
1470 
1471  generateMskBoundkeys(ncols, lb, ub, lpi->bkx);
1472 #if MSK_VERSION_MAJOR < 9
1473  MOSEK_CALL( MSK_putboundlist(lpi->task, MSK_ACC_VAR, ncols, ind, lpi->bkx, lb, ub) );
1474 #else
1475  MOSEK_CALL( MSK_putvarboundlist(lpi->task, ncols, ind, lpi->bkx, lb, ub) );
1476 #endif
1477 
1478 #if DEBUG_CHECK_DATA > 0
1479  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgBounds") );
1480 #endif
1481 
1482  return SCIP_OKAY;
1483 }
1484 
1485 /** changes left and right hand sides of rows */
1487  SCIP_LPI* lpi, /**< LP interface structure */
1488  int nrows, /**< number of rows to change sides for */
1489  const int* ind, /**< row indices */
1490  const SCIP_Real* lhs, /**< new values for left hand sides */
1491  const SCIP_Real* rhs /**< new values for right hand sides */
1492  )
1493 {
1494  assert(lpi != NULL);
1495  assert(lpi->mosekenv != NULL);
1496  assert(lpi->task != NULL);
1497  assert(ind != NULL);
1498 
1499  if( nrows <= 0 )
1500  return SCIP_OKAY;
1501 
1502  invalidateSolution(lpi);
1503 
1504  SCIPdebugMessage("Calling SCIPlpiChgSides (%d)\n", lpi->lpid);
1505 
1506 #if DEBUG_CHECK_DATA > 0
1507  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgSides") );
1508 #endif
1509 
1510  SCIP_CALL( ensureBkcMem(lpi, nrows) );
1511 
1512  generateMskBoundkeys(nrows, lhs, rhs, lpi->bkc);
1513 #if MSK_VERSION_MAJOR < 9
1514  MOSEK_CALL( MSK_putboundlist(lpi->task, MSK_ACC_CON, nrows, ind, lpi->bkc, lhs, rhs) );
1515 #else
1516  MOSEK_CALL( MSK_putconboundlist(lpi->task, nrows, ind, lpi->bkc, lhs, rhs) );
1517 #endif
1518 
1519 #if DEBUG_CHECK_DATA > 0
1520  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgSides") );
1521 #endif
1522 
1523  return SCIP_OKAY;
1524 }
1525 
1526 /** changes a single coefficient */
1528  SCIP_LPI* lpi, /**< LP interface structure */
1529  int row, /**< row number of coefficient to change */
1530  int col, /**< column number of coefficient to change */
1531  SCIP_Real newval /**< new value of coefficient */
1532  )
1533 {
1534  assert(lpi != NULL);
1535  assert(lpi->mosekenv != NULL);
1536  assert(lpi->task != NULL);
1537 
1538  SCIPdebugMessage("Calling SCIPlpiChgCoef (%d)\n", lpi->lpid);
1539 
1540  invalidateSolution(lpi);
1541 
1542 #if DEBUG_CHECK_DATA > 0
1543  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgCoef") );
1544 #endif
1545 
1546  MOSEK_CALL( MSK_putaij(lpi->task, row, col, newval) );
1547 
1548 #if DEBUG_CHECK_DATA > 0
1549  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgCoef") );
1550 #endif
1551 
1552  return SCIP_OKAY;
1553 }
1554 
1555 /** changes the objective sense */
1557  SCIP_LPI* lpi, /**< LP interface structure */
1558  SCIP_OBJSEN objsen /**< new objective sense */
1559  )
1560 {
1561  assert(lpi != NULL);
1562  assert(lpi->mosekenv != NULL);
1563  assert(lpi->task != NULL);
1564 
1565  SCIPdebugMessage("Calling SCIPlpiChgObjsen (%d)\n", lpi->lpid);
1566 
1567  invalidateSolution(lpi);
1568 
1569  MOSEK_CALL( MSK_putobjsense(lpi->task, SENSE2MOSEK(objsen)) );
1570 
1571  return SCIP_OKAY;
1572 }
1573 
1574 /** changes objective values of columns in the LP */
1576  SCIP_LPI* lpi, /**< LP interface structure */
1577  int ncols, /**< number of columns to change objective value for */
1578  const int* ind, /**< column indices to change objective value for */
1579  const SCIP_Real* obj /**< new objective values for columns */
1580  )
1581 {
1582  assert(lpi != NULL);
1583  assert(lpi->mosekenv != NULL);
1584  assert(lpi->task != NULL);
1585  assert(ind != NULL);
1586  assert(obj != NULL);
1587 
1588  SCIPdebugMessage("Calling SCIPlpiChgObj (%d)\n", lpi->lpid);
1589 
1590  invalidateSolution(lpi);
1591 
1592 #if DEBUG_CHECK_DATA > 0
1593  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgObj") );
1594 #endif
1595 
1596  MOSEK_CALL( MSK_putclist(lpi->task, ncols, ind, obj) );
1597 
1598 #if DEBUG_CHECK_DATA > 0
1599  SCIP_CALL( scip_checkdata(lpi,"SCIPlpiChgObj") );
1600 #endif
1601 
1602  return SCIP_OKAY;
1603 }
1604 
1605 /** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1607  SCIP_LPI* lpi, /**< LP interface structure */
1608  int row, /**< row number to scale */
1609  SCIP_Real scaleval /**< scaling multiplier */
1610  )
1611 {
1612  int nnonz;
1613  int* sub;
1614  double* val;
1615  MSKboundkeye bkc;
1616  double blc;
1617  double buc;
1618 
1619  assert(lpi != NULL);
1620  assert(lpi->mosekenv != NULL);
1621  assert(lpi->task != NULL);
1622 
1623  SCIPdebugMessage("Calling SCIPlpiScaleRow (%d)\n", lpi->lpid);
1624 
1625  invalidateSolution(lpi);
1626 
1627 #if DEBUG_CHECK_DATA > 0
1628  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiScaleRow") );
1629 #endif
1630 
1631  assert(scaleval != 0);
1632 
1633  MOSEK_CALL( MSK_getarownumnz(lpi->task, row, &nnonz) );
1634 
1635  if (nnonz != 0)
1636  {
1637  SCIP_ALLOC( BMSallocMemoryArray(&sub, nnonz) );
1638  SCIP_ALLOC( BMSallocMemoryArray(&val, nnonz) );
1639 
1640  MOSEK_CALL( MSK_getarow(lpi->task, row, &nnonz, sub, val) );
1641  scale_vec(nnonz, val, scaleval);
1642  MOSEK_CALL( MSK_putarow(lpi->task, row, nnonz, sub, val) );
1643 
1644  BMSfreeMemoryArray(&val);
1645  BMSfreeMemoryArray(&sub);
1646  }
1647 
1648 #if MSK_VERSION_MAJOR < 9
1649  MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_CON, row, &bkc, &blc, &buc) );
1650  scale_bound(&bkc, &blc, &buc, scaleval);
1651  MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_CON, row, bkc, blc, buc) );
1652 #else
1653  MOSEK_CALL( MSK_getconbound(lpi->task, row, &bkc, &blc, &buc) );
1654  scale_bound(&bkc, &blc, &buc, scaleval);
1655  MOSEK_CALL( MSK_putconbound(lpi->task, row, bkc, blc, buc) );
1656 #endif
1657 
1658 #if DEBUG_CHECK_DATA > 0
1659  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiScaleRow") );
1660 #endif
1661 
1662  return SCIP_OKAY;
1663 }
1664 
1665 /** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1666  * are divided by the scalar; for negative scalars, the column's bounds are switched
1667  */
1669  SCIP_LPI* lpi, /**< LP interface structure */
1670  int col, /**< column number to scale */
1671  SCIP_Real scaleval /**< scaling multiplier */
1672  )
1673 {
1674  int nnonz;
1675  int *sub = NULL;
1676  double *val = NULL;
1677  MSKboundkeye bkx;
1678  double blx, bux, c;
1679 
1680  assert(lpi != NULL);
1681  assert(lpi->mosekenv != NULL);
1682  assert(lpi->task != NULL);
1683 
1684  SCIPdebugMessage("Calling SCIPlpiScaleCol (%d)\n", lpi->lpid);
1685 
1686  invalidateSolution(lpi);
1687 
1688 #if DEBUG_CHECK_DATA > 0
1689  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiScaleCol") );
1690 #endif
1691 
1692  assert(scaleval != 0);
1693  MOSEK_CALL( MSK_getacolnumnz(lpi->task, col, &nnonz) );
1694 
1695  if (nnonz != 0)
1696  {
1697  SCIP_ALLOC( BMSallocMemoryArray(&sub, nnonz) );
1698  SCIP_ALLOC( BMSallocMemoryArray(&val, nnonz) );
1699 
1700  MOSEK_CALL( MSK_getacol(lpi->task, col, &nnonz, sub, val) );
1701  scale_vec(nnonz, val, scaleval);
1702  MOSEK_CALL( MSK_putacol(lpi->task, col, nnonz, sub, val) );
1703 
1704  BMSfreeMemoryArray(&val);
1705  BMSfreeMemoryArray(&sub);
1706  }
1707 
1708 #if MSK_VERSION_MAJOR < 9
1709  MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_VAR, col, &bkx, &blx, &bux) );
1710  scale_bound(&bkx, &blx, &bux, 1.0/scaleval);
1711  MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, bkx, blx, bux) );
1712 #else
1713  MOSEK_CALL( MSK_getvarbound(lpi->task, col, &bkx, &blx, &bux) );
1714  scale_bound(&bkx, &blx, &bux, 1.0/scaleval);
1715  MOSEK_CALL( MSK_putvarbound(lpi->task, col, bkx, blx, bux) );
1716 #endif
1717 
1718  MOSEK_CALL( MSK_getcslice(lpi->task, col, col+1, &c) );
1719  MOSEK_CALL( MSK_putcj(lpi->task, col, c*scaleval) );
1720 
1721 #if DEBUG_CHECK_DATA > 0
1722  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiScaleCol") );
1723 #endif
1724 
1725  return SCIP_OKAY;
1726 }
1727 
1728 
1729 /*
1730  * Data Accessing Methods
1731  */
1732 
1733 
1734 /** gets the number of rows in the LP */
1736  SCIP_LPI* lpi, /**< LP interface structure */
1737  int* nrows /**< pointer to store the number of rows */
1738  )
1739 {
1740  assert(lpi != NULL);
1741  assert(lpi->mosekenv != NULL);
1742  assert(lpi->task != NULL);
1743  assert(nrows != NULL);
1744 
1745  SCIPdebugMessage("Calling SCIPlpiGetNRows (%d)\n", lpi->lpid);
1746 
1747  MOSEK_CALL( MSK_getnumcon(lpi->task, nrows) );
1748 
1749  return SCIP_OKAY;
1750 }
1751 
1752 /** gets the number of columns in the LP */
1754  SCIP_LPI* lpi, /**< LP interface structure */
1755  int* ncols /**< pointer to store the number of cols */
1756  )
1757 {
1758  assert(lpi != NULL);
1759  assert(lpi->mosekenv != NULL);
1760  assert(lpi->task != NULL);
1761  assert(ncols != NULL);
1762 
1763  SCIPdebugMessage("Calling SCIPlpiGetNCols (%d)\n", lpi->lpid);
1764 
1765  MOSEK_CALL( MSK_getnumvar(lpi->task, ncols) );
1766 
1767  return SCIP_OKAY;
1768 }
1769 
1770 /** gets the number of nonzero elements in the LP constraint matrix */
1772  SCIP_LPI* lpi, /**< LP interface structure */
1773  int* nnonz /**< pointer to store the number of nonzeros */
1774  )
1775 {
1776  assert(lpi != NULL);
1777  assert(lpi->mosekenv != NULL);
1778  assert(lpi->task != NULL);
1779  assert(nnonz != NULL);
1780 
1781  SCIPdebugMessage("Calling SCIPlpiGetNNonz (%d)\n", lpi->lpid);
1782 
1783  MOSEK_CALL( MSK_getnumanz(lpi->task, nnonz) );
1784 
1785  return SCIP_OKAY;
1786 }
1787 
1788 /** get a slice of a row or column */
1789 static
1791  SCIP_LPI* lpi, /**< LP interface structure */
1792  SCIP_Bool iscon, /**< whether we are requesting a slice of a constraint or column */
1793  int first, /**< first index */
1794  int last, /**< last index */
1795  int* nnonz, /**< pointer to store the number of nonzeros */
1796  int* beg, /**< array for begins of indices/values */
1797  int* ind, /**< array of row/column indices */
1798  double* val /**< array of values */
1799  )
1800 {
1801  assert(lpi != NULL);
1802  assert(lpi->mosekenv != NULL);
1803  assert(lpi->task != NULL);
1804  assert(first <= last);
1805 
1806  SCIPdebugMessage("Calling SCIPlpiGetNNonz (%d)\n", lpi->lpid);
1807 
1808 #if DEBUG_CHECK_DATA > 0
1809  SCIP_CALL( scip_checkdata(lpi, "getASlice") );
1810 #endif
1811 
1812  if( nnonz != 0 )
1813  {
1814  int surplus;
1815 
1816  assert(beg != NULL);
1817  assert(ind != NULL);
1818  assert(val != NULL);
1819 
1820  SCIP_CALL( ensureAptreMem(lpi, last - first + 1) );
1821 
1822 #if MSK_VERSION_MAJOR < 9
1823  MOSEK_CALL( MSK_getaslicenumnz(lpi->task, iscon ? MSK_ACC_CON : MSK_ACC_VAR, first, last+1, nnonz) );
1824  surplus = *nnonz;
1825  MOSEK_CALL( MSK_getaslice(lpi->task, iscon ? MSK_ACC_CON : MSK_ACC_VAR, first, last+1, *nnonz, &surplus, beg, lpi->aptre, ind, val) );
1826 #else
1827  if( iscon )
1828  {
1829  MOSEK_CALL( MSK_getarowslicenumnz(lpi->task, first, last+1, nnonz) );
1830  surplus = *nnonz;
1831 #if MSK_VERSION_MAJOR == 9
1832  MOSEK_CALL( MSK_getarowslice(lpi->task, first, last+1, *nnonz, &surplus, beg, lpi->aptre, ind, val) );
1833 #else
1834  MOSEK_CALL( MSK_getarowslice(lpi->task, first, last+1, *nnonz, beg, lpi->aptre, ind, val) );
1835  (void)surplus;
1836 #endif
1837  }
1838  else
1839  {
1840  MOSEK_CALL( MSK_getacolslicenumnz(lpi->task, first, last+1, nnonz) );
1841  surplus = *nnonz;
1842 #if MSK_VERSION_MAJOR == 9
1843  MOSEK_CALL( MSK_getacolslice(lpi->task, first, last+1, *nnonz, &surplus, beg, lpi->aptre, ind, val) );
1844 #else
1845  MOSEK_CALL( MSK_getacolslice(lpi->task, first, last+1, *nnonz, beg, lpi->aptre, ind, val) );
1846  (void)surplus;
1847 #endif
1848  }
1849 #endif
1850 
1851  assert(surplus == 0);
1852  }
1853 
1854 #if DEBUG_CHECK_DATA > 0
1855  SCIP_CALL( scip_checkdata(lpi, "getASlice") );
1856 #endif
1857 
1858  return SCIP_OKAY;
1859 }
1860 
1861 /** gets columns from LP problem object; the arrays have to be large enough to store all values;
1862  * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1863  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1864  */
1866  SCIP_LPI* lpi, /**< LP interface structure */
1867  int firstcol, /**< first column to get from LP */
1868  int lastcol, /**< last column to get from LP */
1869  SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
1870  SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
1871  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1872  int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1873  int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1874  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1875  )
1876 {
1877  assert(lpi != NULL);
1878  assert(lpi->mosekenv != NULL);
1879  assert(lpi->task != NULL);
1880  assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
1881  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1882 
1883 #ifndef NDEBUG
1884  {
1885  int ncols;
1886  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
1887  assert(0 <= firstcol && firstcol <= lastcol && lastcol < ncols);
1888  }
1889 #endif
1890 
1891  SCIPdebugMessage("Calling SCIPlpiGetCols (%d)\n", lpi->lpid);
1892 
1893  SCIP_CALL( SCIPlpiGetBounds(lpi, firstcol, lastcol, lb, ub) );
1894  SCIP_CALL( getASlice(lpi, FALSE, firstcol, lastcol, nnonz, beg, ind, val) );
1895 
1896  return SCIP_OKAY;
1897 }
1898 
1899 /** gets rows from LP problem object; the arrays have to be large enough to store all values.
1900  * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
1901  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1902  */
1904  SCIP_LPI* lpi, /**< LP interface structure */
1905  int firstrow, /**< first row to get from LP */
1906  int lastrow, /**< last row to get from LP */
1907  SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
1908  SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
1909  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1910  int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
1911  int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
1912  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1913  )
1914 {
1915  assert(lpi != NULL);
1916  assert(lpi->mosekenv != NULL);
1917  assert(lpi->task != NULL);
1918  assert((lhs != NULL && rhs != NULL) || (lhs == NULL && rhs == NULL));
1919  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1920 
1921 #ifndef NDEBUG
1922  {
1923  int nrows;
1924  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1925  assert(0 <= firstrow && firstrow <= lastrow && lastrow < nrows);
1926  }
1927 #endif
1928 
1929  SCIPdebugMessage("Calling SCIPlpiGetRows (%d)\n", lpi->lpid);
1930 
1931 #if DEBUG_CHECK_DATA > 0
1932  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetRows") );
1933 #endif
1934 
1935  SCIP_CALL( SCIPlpiGetSides(lpi, firstrow, lastrow, lhs, rhs) );
1936  SCIP_CALL( getASlice(lpi, TRUE, firstrow, lastrow, nnonz, beg, ind, val) );
1937 
1938 #if DEBUG_CHECK_DATA > 0
1939  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetRows") );
1940 #endif
1941 
1942  return SCIP_OKAY;
1943 }
1944 
1945 /** gets column names */
1947  SCIP_LPI* lpi, /**< LP interface structure */
1948  int firstcol, /**< first column to get name from LP */
1949  int lastcol, /**< last column to get name from LP */
1950  char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
1951  char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
1952  int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
1953  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
1954  )
1955 { /*lint --e{715}*/
1956  assert(lpi != NULL);
1957  assert(lpi->mosekenv != NULL);
1958  assert(lpi->task != NULL);
1959  assert(0 <= firstcol && firstcol <= lastcol);
1960  assert(colnames != NULL || namestoragesize == 0);
1961  assert(namestorage != NULL || namestoragesize == 0);
1962  assert(namestoragesize >= 0);
1963  assert(storageleft != NULL);
1964 
1965  SCIPerrorMessage("SCIPlpiGetColNames() has not been implemented yet.\n");
1966 
1967  return SCIP_LPERROR;
1968 }
1969 
1970 /** gets row names */
1972  SCIP_LPI* lpi, /**< LP interface structure */
1973  int firstrow, /**< first row to get name from LP */
1974  int lastrow, /**< last row to get name from LP */
1975  char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
1976  char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
1977  int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
1978  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
1979  )
1980 { /*lint --e{715}*/
1981  assert(lpi != NULL);
1982  assert(lpi->mosekenv != NULL);
1983  assert(lpi->task != NULL);
1984  assert(0 <= firstrow && firstrow <= lastrow);
1985  assert(rownames != NULL || namestoragesize == 0);
1986  assert(namestorage != NULL || namestoragesize == 0);
1987  assert(namestoragesize >= 0);
1988  assert(storageleft != NULL);
1989 
1990  SCIPerrorMessage("SCIPlpiGetRowNames() has not been implemented yet.\n");
1991 
1992  return SCIP_LPERROR;
1993 }
1994 
1995 /** gets the objective sense of the LP */
1997  SCIP_LPI* lpi, /**< LP interface structure */
1998  SCIP_OBJSEN* objsen /**< pointer to store objective sense */
1999  )
2000 {
2001  MSKobjsensee mskobjsen;
2002 
2003  assert(lpi != NULL);
2004  assert(lpi->mosekenv != NULL);
2005  assert(lpi->task != NULL);
2006  assert(objsen != NULL);
2007 
2008  SCIPdebugMessage("Calling SCIPlpiGetObjsen (%d)\n", lpi->lpid);
2009 
2010  MOSEK_CALL( MSK_getobjsense(lpi->task, &mskobjsen) );
2011  *objsen = (mskobjsen == MSK_OBJECTIVE_SENSE_MINIMIZE ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE);
2012 
2013  return SCIP_OKAY;
2014 }
2015 
2016 /** gets objective coefficients from LP problem object */
2018  SCIP_LPI* lpi, /**< LP interface structure */
2019  int firstcol, /**< first column to get objective coefficient for */
2020  int lastcol, /**< last column to get objective coefficient for */
2021  SCIP_Real* vals /**< array to store objective coefficients */
2022  )
2023 {
2024  assert(lpi != NULL);
2025  assert(lpi->mosekenv != NULL);
2026  assert(lpi->task != NULL);
2027  assert(firstcol <= lastcol);
2028  assert(vals != NULL);
2029 
2030  SCIPdebugMessage("Calling SCIPlpiGetObj (%d)\n", lpi->lpid);
2031 
2032  MOSEK_CALL( MSK_getcslice(lpi->task, firstcol, lastcol+1, vals) );
2033 
2034  return SCIP_OKAY;
2035 }
2036 
2037 /** gets current bounds from LP problem object */
2039  SCIP_LPI* lpi, /**< LP interface structure */
2040  int firstcol, /**< first column to get bounds for */
2041  int lastcol, /**< last column to get bounds for */
2042  SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
2043  SCIP_Real* ubs /**< array to store upper bound values, or NULL */
2044  )
2045 {
2046  assert(lpi != NULL);
2047  assert(lpi->mosekenv != NULL);
2048  assert(lpi->task != NULL);
2049  assert(firstcol <= lastcol);
2050 
2051  SCIPdebugMessage("Calling SCIPlpiGetBounds (%d)\n", lpi->lpid);
2052 
2053 #if DEBUG_CHECK_DATA > 0
2054  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetBounds") );
2055 #endif
2056 
2057 #if MSK_VERSION_MAJOR < 9
2058  MOSEK_CALL( MSK_getboundslice(lpi->task, MSK_ACC_VAR, firstcol, lastcol+1, NULL, lbs, ubs) );
2059 #else
2060  MOSEK_CALL( MSK_getvarboundslice(lpi->task, firstcol, lastcol+1, NULL, lbs, ubs) );
2061 #endif
2062 
2063  return SCIP_OKAY;
2064 }
2065 
2066 /** gets current row sides from LP problem object */
2068  SCIP_LPI* lpi, /**< LP interface structure */
2069  int firstrow, /**< first row to get sides for */
2070  int lastrow, /**< last row to get sides for */
2071  SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
2072  SCIP_Real* rhss /**< array to store right hand side values, or NULL */
2073  )
2074 {
2075  assert(lpi != NULL);
2076  assert(lpi->mosekenv != NULL);
2077  assert(lpi->task != NULL);
2078  assert(firstrow <= lastrow);
2079 
2080  SCIPdebugMessage("Calling SCIPlpiGetSides (%d)\n", lpi->lpid);
2081 
2082 #if DEBUG_CHECK_DATA > 0
2083  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetSides") );
2084 #endif
2085 
2086 #if MSK_VERSION_MAJOR < 9
2087  MOSEK_CALL( MSK_getboundslice(lpi->task, MSK_ACC_CON, firstrow, lastrow+1, NULL, lhss, rhss) );
2088 #else
2089  MOSEK_CALL( MSK_getconboundslice(lpi->task, firstrow, lastrow+1, NULL, lhss, rhss) );
2090 #endif
2091 
2092 #if DEBUG_CHECK_DATA > 0
2093  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetSides") );
2094 #endif
2095 
2096  return SCIP_OKAY;
2097 }
2098 
2099 /** gets a single coefficient */
2101  SCIP_LPI* lpi, /**< LP interface structure */
2102  int row, /**< row number of coefficient */
2103  int col, /**< column number of coefficient */
2104  SCIP_Real* val /**< pointer to store the value of the coefficient */
2105  )
2106 {
2107  assert(lpi != NULL);
2108  assert(lpi->mosekenv != NULL);
2109  assert(lpi->task != NULL);
2110  assert(val != NULL);
2111 
2112  SCIPdebugMessage("Calling SCIPlpiGetCoef (%d)\n", lpi->lpid);
2113 
2114 #if DEBUG_CHECK_DATA > 0
2115  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetCoef") );
2116 #endif
2117 
2118  MOSEK_CALL( MSK_getaij(lpi->task, row, col, val) );
2119 
2120 #if DEBUG_CHECK_DATA > 0
2121  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetCoef") );
2122 #endif
2123 
2124  return SCIP_OKAY;
2125 }
2126 
2127 /*
2128  * Solving Methods
2129  */
2130 
2131 
2132 /** gets the internal solution status of the solver */
2133 static
2135  SCIP_LPI* lpi, /**< LP interface structure */
2136  MSKprostae* prosta, /**< pointer to store the problem status */
2137  MSKsolstae* solsta /**< pointer to store the solution status */
2138  )
2139 {
2140  assert(lpi != NULL);
2141  assert(lpi->mosekenv != NULL);
2142  assert(lpi->task != NULL);
2143 
2144  MOSEK_CALL( MSK_getsolutionstatus(lpi->task, lpi->lastsolvetype, prosta, solsta) );
2145 
2146  return SCIP_OKAY;
2147 }
2148 
2149 /** helper method to filter out numerical problems */
2150 static
2151 MSKrescodee filterTRMrescode(
2152  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2153  MSKrescodee* termcode, /**< pointer to store output termination code */
2154  MSKrescodee res /**< input result of call to Mosek function */
2155  )
2156 { /*lint --e{715}*/
2157  assert( termcode != NULL );
2158 
2159 #if ASSERT_ON_NUMERICAL_TROUBLES > 0
2160  if ( res == MSK_RES_TRM_MAX_NUM_SETBACKS || res == MSK_RES_TRM_NUMERICAL_PROBLEM )
2161  {
2162  SCIPmessagePrintWarning(messagehdlr, "Return code %d.\n", res);
2163  assert(0);
2164  *termcode = res;
2165  return MSK_RES_OK;
2166  }
2167 #else
2168  SCIP_UNUSED(messagehdlr);
2169 #endif
2170 
2171  if ( res == MSK_RES_TRM_MAX_ITERATIONS || res == MSK_RES_TRM_MAX_TIME
2172  || res == MSK_RES_TRM_OBJECTIVE_RANGE || res == MSK_RES_TRM_STALL )
2173  {
2174  *termcode = res;
2175  res = MSK_RES_OK;
2176  }
2177  else
2178  *termcode = MSK_RES_OK;
2179 
2180  return res;
2181 }
2182 
2183 /** solve problem with the simplex algorithm */
2184 static
2186  SCIP_LPI* lpi /**< LP interface structure */
2187  )
2188 {
2189  int itercount_primal;
2190  int itercount_dual;
2191  int gotbasicsol;
2192  int presolve;
2193  int maxiter;
2194  MSKprostae prosta;
2195  MSKsolstae solsta;
2196  double pobj, dobj;
2197 
2198  assert(lpi != NULL);
2199  assert(lpi->mosekenv != NULL);
2200  assert(lpi->task != NULL);
2201 
2202  invalidateSolution(lpi);
2203  lpi->lastsolvetype = MSK_SOL_BAS;
2204 
2205  /* store original settings */
2206  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, &presolve) );
2207  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, &maxiter) );
2208 
2209  /* set some paramters */
2210 #if DEBUG_EASY_REPRODUCE
2211  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_AUTO_SORT_A_BEFORE_OPT, MSK_ON) );
2212  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_OFF) );
2213 #else
2214  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
2215 #endif
2216 
2217  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_AUTO_UPDATE_SOL_INFO, MSK_OFF) );
2218 
2219 #if FORCE_MOSEK_LOG
2220  if( lpi->optimizecount > WRITE_ABOVE )
2221  {
2222  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG_SIM, 4) );
2223  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG_SIM_FREQ, 1) );
2224  }
2225  else
2226  {
2227  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG_SIM, 4) );
2228  }
2229 #endif
2230 
2231  MOSEK_CALL( MSK_solutiondef(lpi->task, MSK_SOL_BAS, &gotbasicsol) );
2232 
2233  if( gotbasicsol )
2234  {
2235  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, MSK_PRESOLVE_MODE_OFF) );
2236  }
2237  else
2238  {
2239  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, MSK_PRESOLVE_MODE_ON) );
2240  }
2241 
2242 #if ALWAYS_SOLVE_PRIMAL_FORM > 0
2243  /* always solve the primal formulation */
2244  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SOLVE_FORM, MSK_SOLVE_PRIMAL) );
2245 #endif
2246 
2247 #if DEBUG_CHECK_DATA > 0
2248  SCIP_CALL( scip_checkdata(lpi, "SolveWSimplex") );
2249 #endif
2250 
2251  if( gotbasicsol && maxiter < 20000 )
2252  {
2253  /* Since max iter often is set, we switch off restricted pricing */
2254  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION, 0) );
2255  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION, 0) );
2256  }
2257  else
2258  {
2259  /* otherwise use default value */
2260  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION, lpi->restrictselectdef) );
2261  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION, lpi->restrictselectdef) );
2262  }
2263 
2264 #if FORCE_NO_MAXITER > 0
2265  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, 2000000000) );
2266 #endif
2267 
2268 
2269 #if DEBUG_CHECK_DATA > 0
2270  SCIP_CALL( scip_checkdata(lpi, "Begin optimize with simplex") );
2271 #endif
2272 
2273 #if FORCE_MOSEK_SUMMARY > 1
2274  if( lpi->optimizecount > WRITE_ABOVE )
2275  {
2276  MOSEK_CALL( MSK_solutionsummary(lpi->task, MSK_STREAM_LOG) );
2277  }
2278 #endif
2279 
2280  /* perform actual optimization */
2281  MOSEK_CALL( filterTRMrescode(lpi->messagehdlr, &lpi->termcode, MSK_optimize(lpi->task)) );
2282 
2283 #if MSK_VERSION_MAJOR < 10
2284  /* resolve with aggressive scaling if the maximal number of setbacks has been reached */
2285  if( lpi->termcode == MSK_RES_TRM_MAX_NUM_SETBACKS )
2286  {
2287  int scaling;
2288 
2289  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_SCALING, &scaling) );
2290  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, MSK_SCALING_AGGRESSIVE) );
2291  MOSEK_CALL( filterTRMrescode(lpi->messagehdlr, &lpi->termcode, MSK_optimize(lpi->task)) );
2292  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, scaling) );
2293  }
2294 #endif
2295 
2296 #if FORCE_MOSEK_SUMMARY
2297  if( lpi->optimizecount > WRITE_ABOVE )
2298  {
2299  MOSEK_CALL( MSK_solutionsummary(lpi->task, MSK_STREAM_LOG) );
2300  }
2301 #else
2302  if( lpi->lpinfo )
2303  {
2304  MOSEK_CALL( MSK_solutionsummary(lpi->task, MSK_STREAM_LOG) );
2305  }
2306 #endif
2307 
2308 #if DEBUG_CHECK_DATA > 0
2309  SCIP_CALL( scip_checkdata(lpi, "End optimize with simplex") );
2310 #endif
2311 
2312  /* set parameters to their original values */
2313  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, presolve) );
2314  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, maxiter) );
2315 
2316  /* obtain iteration count */
2317  MOSEK_CALL( MSK_getintinf(lpi->task, MSK_IINF_SIM_PRIMAL_ITER, &itercount_primal) );
2318  MOSEK_CALL( MSK_getintinf(lpi->task, MSK_IINF_SIM_DUAL_ITER, &itercount_dual) );
2319 
2320  lpi->itercount = itercount_primal + itercount_dual;
2321 
2322  /* get solution information */
2323  MOSEK_CALL( MSK_getprimalobj(lpi->task, MSK_SOL_BAS, &pobj) );
2324  MOSEK_CALL( MSK_getdualobj(lpi->task, MSK_SOL_BAS, &dobj) );
2325 
2326  MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, &prosta, &solsta) );
2327 
2328  SCIPdebugMessage("maxiter = %d, termcode = %d, prosta = %d, solsta = %d, objval = %g : %g, iter = %d+%d\n",
2329  maxiter, lpi->termcode, prosta, solsta, pobj, dobj, itercount_primal, itercount_dual);
2330 
2331  switch (solsta)
2332  {
2333  case MSK_SOL_STA_OPTIMAL:
2334  case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
2335  case MSK_SOL_STA_PRIM_FEAS:
2336  case MSK_SOL_STA_DUAL_FEAS:
2337  case MSK_SOL_STA_PRIM_INFEAS_CER:
2338  case MSK_SOL_STA_DUAL_INFEAS_CER:
2339  if (lpi->termcode == MSK_RES_OK)
2340  lpi->solved = TRUE;
2341  break;
2342 
2343  case MSK_SOL_STA_UNKNOWN:
2344  /* Mosek seems to have status unknown on the following termination codes */
2345  assert( lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS || lpi->termcode == MSK_RES_TRM_MAX_TIME ||
2346  lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE || lpi->termcode == MSK_RES_TRM_STALL ||
2347  lpi->termcode == MSK_RES_OK );
2348 
2349  if ( lpi->termcode != MSK_RES_TRM_MAX_ITERATIONS && lpi->termcode != MSK_RES_TRM_MAX_TIME &&
2350  lpi->termcode != MSK_RES_TRM_OBJECTIVE_RANGE )
2351  {
2352  SCIPmessagePrintWarning(lpi->messagehdlr, "Numerical problem: simplex[%d] returned solsta = %d.\n", lpi->optimizecount, solsta);
2353  lpi->termcode = MSK_RES_TRM_NUMERICAL_PROBLEM;
2354 #if ASSERT_ON_WARNING
2355  assert(0);
2356 #endif
2357  }
2358  break;
2359 
2360 #if MSK_VERSION_MAJOR < 9
2361  case MSK_SOL_STA_NEAR_OPTIMAL:
2362  case MSK_SOL_STA_NEAR_PRIM_FEAS:
2363  case MSK_SOL_STA_NEAR_DUAL_FEAS:
2364  case MSK_SOL_STA_NEAR_PRIM_AND_DUAL_FEAS:
2365  case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
2366  case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
2367 
2368  assert(lpi->termcode == MSK_RES_OK);
2369 
2370  SCIPmessagePrintWarning(lpi->messagehdlr, "Simplex[%d] returned solsta = %d (numerical problem).\n", lpi->optimizecount, solsta);
2371  lpi->termcode = MSK_RES_TRM_NUMERICAL_PROBLEM;
2372 #if ASSERT_ON_WARNING
2373  assert(0);
2374 #endif
2375  break;
2376 #endif
2377 
2378  case MSK_SOL_STA_INTEGER_OPTIMAL:
2379 #if MSK_VERSION_MAJOR < 9
2380  case MSK_SOL_STA_NEAR_INTEGER_OPTIMAL:
2381 #endif
2382  default:
2383 #if SHOW_ERRORS
2384  SCIPerrorMessage("Simplex[%d] returned solsta = %d\n", lpi->optimizecount, solsta);
2385 #endif
2386 
2387 #if ASSERT_ON_WARNING
2388  assert(0);
2389 #endif
2390 
2391  return SCIP_LPERROR;
2392  } /*lint !e788*/
2393 
2394  switch (prosta)
2395  {
2396  /* already handled above */
2397  case MSK_PRO_STA_PRIM_AND_DUAL_FEAS:
2398  case MSK_PRO_STA_PRIM_FEAS:
2399  case MSK_PRO_STA_DUAL_FEAS:
2400  case MSK_PRO_STA_PRIM_AND_DUAL_INFEAS:
2401  case MSK_PRO_STA_PRIM_INFEAS:
2402  case MSK_PRO_STA_DUAL_INFEAS:
2403  case MSK_PRO_STA_UNKNOWN:
2404  break;
2405 
2406 #if MSK_VERSION_MAJOR < 9
2407  case MSK_PRO_STA_NEAR_PRIM_AND_DUAL_FEAS:
2408  case MSK_PRO_STA_NEAR_PRIM_FEAS:
2409  case MSK_PRO_STA_NEAR_DUAL_FEAS:
2410 #endif
2411  case MSK_PRO_STA_ILL_POSED:
2412  case MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED:
2413  assert(lpi->termcode == MSK_RES_OK);
2414 
2415  SCIPmessagePrintWarning(lpi->messagehdlr, "Simplex[%d] returned prosta = %d\n", lpi->optimizecount, prosta);
2416  lpi->termcode = MSK_RES_TRM_NUMERICAL_PROBLEM;
2417  invalidateSolution(lpi);
2418 #if ASSERT_ON_WARNING
2419  assert(0);
2420 #endif
2421  break;
2422 
2423  default:
2424 #if SHOW_ERRORS
2425  SCIPerrorMessage("Simplex[%d] returned prosta = %d\n", lpi->optimizecount, prosta);
2426 #endif
2427 
2428 #if ASSERT_ON_WARNING
2429  assert(0);
2430 #endif
2431 
2432  return SCIP_LPERROR;
2433  } /*lint !e788*/
2434 
2435  /* todo: replace numbers by constants, e.g., tolerances */
2436 #if SHOW_RELATIVE_OPTIMAL_GAP
2437  if ( solsta == MSK_SOL_STA_OPTIMAL && fabs(pobj) + fabs(dobj) > 1.0e-6 && fabs(pobj-dobj) > 0.0001*(fabs(pobj) + fabs(dobj)))
2438  {
2439  SCIPerrorMessage("Simplex[%d] returned optimal solution with different objvals %g != %g reldiff %.2g%%\n",
2440  lpi->optimizecount, pobj, dobj, 100.0 * fabs(pobj-dobj)/ MAX(fabs(pobj), fabs(dobj))); /*lint !e666*/
2441  }
2442 #endif
2443 
2444  /* The optimizer terminated with an objective value outside the objective range. */
2445  if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
2446  {
2447  if (solsta != MSK_SOL_STA_DUAL_FEAS && solsta != MSK_SOL_STA_OPTIMAL && solsta != MSK_SOL_STA_PRIM_AND_DUAL_FEAS)
2448  {
2449  SCIPerrorMessage("[%d] Terminated on objective range without dual feasible solsta.\n", lpi->optimizecount);
2450 
2451  /* solve again with barrier */
2453  }
2454  }
2455 
2456  /* if the simplex took too many iterations, solve again with barrier */
2457  if (maxiter >= 2000000000)
2458  {
2459  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, maxiter) );
2460 
2461  if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
2462  {
2463  SCIPmessagePrintWarning(lpi->messagehdlr, "Simplex[%d] failed to terminate in 10000 iterations, switching to interior point\n",
2464  lpi->optimizecount);
2465 
2467  }
2468  }
2469 
2470 #if DEBUG_DO_INTPNT_FEAS_CHECK
2471  if (solsta == MSK_SOL_STA_PRIM_INFEAS_CER || solsta == MSK_SOL_STA_DUAL_INFEAS_CER)
2472  {
2473  SCIPdebugMessage("Checking infeasibility[%d]... ", lpi->optimizecount);
2474 
2475  SCIP_CALL( SCIPlpiSolveBarrier(lpi, true) );
2476 
2477  MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, &prosta, &solsta) );
2478 
2479  if (solsta == MSK_SOL_STA_PRIM_INFEAS_CER || solsta == MSK_SOL_STA_DUAL_INFEAS_CER)
2480  {
2481  SCIPdebugPrintf("ok\n");
2482  }
2483  else
2484  {
2485  SCIPdebugPrintf("wrong [%d] prosta = %d, solsta = %d\n", lpi->optimizecount, prosta, solsta);
2486  }
2487  }
2488 #endif
2489 
2490 
2491 #if DEBUG_PRINT_STAT > 0
2492  SCIPdebugMessage("Max iter stat : Count %d branchup = %d branchlo = %d primal %d dual %d\n",
2493  lpi->optimizecount, numstrongbranchmaxiterup, numstrongbranchmaxiterdo, numprimalmaxiter, numdualmaxiter);
2494  SCIPdebugMessage("Objcut iter stat : Count %d branchup = %d branchlo = %d primal %d dual %d\n",
2495  lpi->optimizecount, numstrongbranchobjup, numstrongbranchobjdo, numprimalobj, numdualobj);
2496 #endif
2497 
2498 #if DEBUG_CHECK_DATA > 0
2499  SCIP_CALL( scip_checkdata(lpi, "SolveWSimplex") );
2500 #endif
2501 
2502  return SCIP_OKAY;
2503 }
2504 
2505 /** calls primal simplex to solve the LP */
2507  SCIP_LPI* lpi /**< LP interface structure */
2508  )
2509 {
2510  assert(lpi != NULL);
2511  assert(lpi->mosekenv != NULL);
2512  assert(lpi->task != NULL);
2513 
2514  lpi->optimizecount++;
2515 
2516  SCIPdebugMessage("Calling SCIPlpiSolvePrimal[%d] (%d) ", lpi->optimizecount, lpi->lpid);
2517 
2518  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
2519 
2520  /* Set warmstarting information in MOSEK. We only have status keys (recalculate dual solution without dual superbasics) */
2521  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, lpi->fromscratch || lpi->clearstate ?
2522  MSK_SIM_HOTSTART_NONE : MSK_SIM_HOTSTART_STATUS_KEYS) );
2523  lpi->clearstate = FALSE;
2524 
2525 #if DEBUG_CHECK_DATA > 0
2526  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiSolvePrimal") );
2527 #endif
2528 
2529  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_PRIMAL_SIMPLEX) );
2530  lpi->lastalgo = MSK_OPTIMIZER_PRIMAL_SIMPLEX;
2531 
2532 #if WRITE_PRIMAL > 0
2533  if( lpi->optimizecount > WRITE_ABOVE )
2534  {
2535  char fname[40];
2536  snprintf(fname, 40, "primal_%d.lp", lpi->optimizecount);
2537  SCIPdebugMessage("\nWriting lp %s\n", fname);
2538  /*MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_GENERIC_NAMES, MSK_ON) );*/
2539  MSK_writedata(lpi->task, fname);
2540  }
2541 #endif
2542 
2543  SCIP_CALL( SolveWSimplex(lpi) );
2544 
2545 #ifdef SCIP_DISABLED_CODE
2546  /* the following code is unclear: Why should the resolve change anything ?????? */
2547  if ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE )
2548  {
2549  MSKsolstae solsta;
2550 
2551  MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, NULL, &solsta) );
2552 
2553  if( solsta != MSK_SOL_STA_PRIM_FEAS )
2554  {
2555  SCIP_CALL( SolveWSimplex(lpi) );
2556  }
2557  }
2558 #endif
2559 
2560 #if DEBUG_PRINT_STAT > 0
2561  if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
2562  ++numprimalobj;
2563 #endif
2564 
2565 #if DEBUG_PRINT_STAT > 0
2566  if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
2567  ++numprimalmaxiter;
2568 #endif
2569 
2570 #if DEBUG_CHECK_DATA > 0
2571  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiSolvePrimal") );
2572 #endif
2573 
2574  return SCIP_OKAY;
2575 }
2576 
2577 /** calls dual simplex to solve the LP */
2579  SCIP_LPI* lpi /**< LP interface structure */
2580  )
2581 {
2582  assert(lpi != NULL);
2583  assert(lpi->mosekenv != NULL);
2584  assert(lpi->task != NULL);
2585 
2586  lpi->optimizecount++;
2587 
2588  SCIPdebugMessage("Calling SCIPlpiSolveDual[%d] (%d)\n", lpi->optimizecount, lpi->lpid);
2589 
2590 /* MSK_IPAR_SIM_INTEGER is removed in Mosek 8.1 */
2591 #if (MSK_VERSION_MAJOR < 8) || (MSK_VERSION_MAJOR == 8 && MSK_VERSION_MINOR == 0)
2592  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_INTEGER, MSK_ON) );
2593 #endif
2594  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
2595 
2596  /* Set warmstarting information in MOSEK. We only have status keys (recalculate dual solution without dual superbasics) */
2597  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, (lpi->fromscratch || lpi->clearstate) ?
2598  MSK_SIM_HOTSTART_NONE : MSK_SIM_HOTSTART_STATUS_KEYS) );
2599  lpi->clearstate = FALSE;
2600 
2601  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_DUAL_SIMPLEX) );
2602  lpi->lastalgo = MSK_OPTIMIZER_DUAL_SIMPLEX;
2603 
2604 #if WRITE_DUAL > 0
2605  if( lpi->optimizecount > WRITE_ABOVE )
2606  {
2607  char fname[40];
2608  snprintf(fname,40,"dual_%d.lp", lpi->optimizecount);
2609  SCIPdebugMessage("\nWriting lp %s\n", fname);
2610  MSK_writedata(lpi->task, fname);
2611  }
2612 #endif
2613 
2614  SCIP_CALL( SolveWSimplex(lpi) );
2615 
2616 #ifdef SCIP_DISABLED_CODE
2617  /* the following code is unclear: Why should the resolve change anything ?????? */
2618  if ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE )
2619  {
2620  MSKsolstae solsta;
2621 
2622  MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, NULL, &solsta) );
2623 
2624  if( solsta != MSK_SOL_STA_DUAL_FEAS )
2625  {
2626  SCIP_CALL( SolveWSimplex(lpi) );
2627  }
2628  }
2629 #endif
2630 
2631 #if DEBUG_PRINT_STAT > 0
2632  if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
2633  ++numdualobj;
2634 #endif
2635 
2636 #if DEBUG_PRINT_STAT > 0
2637  if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
2638  ++numdualmaxiter;
2639 #endif
2640 
2641  return SCIP_OKAY;
2642 }
2643 
2644 /** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
2646  SCIP_LPI* lpi, /**< LP interface structure */
2647  SCIP_Bool crossover /**< perform crossover */
2648  )
2649 {
2650  MSKprostae prosta;
2651  MSKsolstae solsta;
2652 
2653  assert(lpi != NULL);
2654  assert(lpi->mosekenv != NULL);
2655  assert(lpi->task != NULL);
2656 
2657  lpi->optimizecount++;
2658 
2659  invalidateSolution(lpi);
2660  lpi->lastsolvetype = crossover ? MSK_SOL_BAS : MSK_SOL_ITR;
2661 
2662 #if FORCE_MOSEK_LOG
2663  if( lpi->optimizecount > WRITE_ABOVE )
2664  {
2665  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, 4) );
2666  }
2667  else
2668  {
2669  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, 0) );
2670  }
2671 #endif
2672 
2673  SCIPdebugMessage("Calling SCIPlpiSolveBarrier[%d] (%d) ", lpi->optimizecount, lpi->lpid);
2674 
2675 #if DEBUG_CHECK_DATA > 0
2676  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiSolveBarrier") );
2677 #endif
2678 
2679 #ifdef SCIP_DISABLED_CODE
2680  /* The parameter exists in MOSEK, but as of version 8, it is not in use and the interior-point solver is never warmstarted */
2681  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_HOTSTART, (lpi->fromscratch || lpi->clearstate) ?
2682  MSK_SIM_HOTSTART_NONE : MSK_INTPNT_HOTSTART_PRIMAL_DUAL) );
2683 #endif
2684  lpi->clearstate = FALSE;
2685 
2686  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_BASIS, crossover ? MSK_BI_ALWAYS : MSK_BI_NEVER) );
2687  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_INTPNT) );
2688  lpi->lastalgo = MSK_OPTIMIZER_INTPNT;
2689 
2690 #if MSK_VERSION_MAJOR >= 9
2691  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_INTPNT_CO_TOL_NEAR_REL, NEAR_REL_TOLERANCE) );
2692 #endif
2693 
2694 #if WRITE_INTPNT > 0
2695  if( lpi->optimizecount > WRITE_ABOVE )
2696  {
2697  char fname[40];
2698  snprintf(fname,40,"intpnt_%d.lp", lpi->optimizecount);
2699  SCIPdebugMessage("\nWriting lp %s\n", fname);
2700  /*MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_GENERIC_NAMES, MSK_ON) );*/
2701  MSK_writedata(lpi->task, fname);
2702  }
2703 #endif
2704 
2705  MOSEK_CALL( filterTRMrescode(lpi->messagehdlr, &lpi->termcode, MSK_optimize(lpi->task)) );
2706 
2707 #if DEBUG_PRINT_STAT > 0
2708  if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
2709  ++numdualmaxiter;
2710 #endif
2711 
2712  MOSEK_CALL( MSK_getintinf(lpi->task, MSK_IINF_INTPNT_ITER, &lpi->itercount) );
2713 
2714  MOSEK_CALL( MSK_getsolutionstatus(lpi->task, lpi->lastsolvetype, &prosta, &solsta) );
2715  SCIPdebugMessage("termcode = %d, prosta = %d, solsta = %d, iter = %d\n",
2716  lpi->termcode, prosta, solsta, lpi->itercount);
2717 
2718  switch (solsta)
2719  {
2720  case MSK_SOL_STA_OPTIMAL:
2721  case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
2722  case MSK_SOL_STA_PRIM_FEAS:
2723  case MSK_SOL_STA_DUAL_FEAS:
2724  case MSK_SOL_STA_PRIM_INFEAS_CER:
2725  case MSK_SOL_STA_DUAL_INFEAS_CER:
2726  if (lpi->termcode == MSK_RES_OK)
2727  lpi->solved = TRUE;
2728  break;
2729  case MSK_SOL_STA_UNKNOWN:
2730 #if MSK_VERSION_MAJOR < 9
2731  case MSK_SOL_STA_NEAR_OPTIMAL:
2732  case MSK_SOL_STA_NEAR_PRIM_FEAS:
2733  case MSK_SOL_STA_NEAR_DUAL_FEAS:
2734  case MSK_SOL_STA_NEAR_PRIM_AND_DUAL_FEAS:
2735  case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
2736  case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
2737 #endif
2738  SCIPmessagePrintWarning(lpi->messagehdlr, "Barrier[%d] returned solsta = %d\n", lpi->optimizecount, solsta);
2739 
2740  if (lpi->termcode == MSK_RES_OK)
2741  lpi->termcode = MSK_RES_TRM_NUMERICAL_PROBLEM;
2742 
2743 #if ASSERT_ON_WARNING
2744  assert(0);
2745 #endif
2746  break;
2747  case MSK_SOL_STA_INTEGER_OPTIMAL:
2748 #if MSK_VERSION_MAJOR < 9
2749  case MSK_SOL_STA_NEAR_INTEGER_OPTIMAL:
2750 #endif
2751  default:
2752 #if SHOW_ERRORS
2753  SCIPerrorMessage("Barrier[%d] returned solsta = %d\n", lpi->optimizecount, solsta);
2754 #endif
2755 
2756 #if ASSERT_ON_WARNING
2757  assert(0);
2758 #endif
2759 
2760  return SCIP_LPERROR;
2761  } /*lint !e788*/
2762 
2763  switch (prosta)
2764  {
2765  case MSK_PRO_STA_PRIM_AND_DUAL_FEAS:
2766  case MSK_PRO_STA_PRIM_FEAS:
2767  case MSK_PRO_STA_DUAL_FEAS:
2768  case MSK_PRO_STA_PRIM_AND_DUAL_INFEAS:
2769  case MSK_PRO_STA_PRIM_INFEAS:
2770  case MSK_PRO_STA_DUAL_INFEAS:
2771  break;
2772  case MSK_PRO_STA_UNKNOWN:
2773 #if MSK_VERSION_MAJOR < 9
2774  case MSK_PRO_STA_NEAR_PRIM_AND_DUAL_FEAS:
2775  case MSK_PRO_STA_NEAR_PRIM_FEAS:
2776  case MSK_PRO_STA_NEAR_DUAL_FEAS:
2777 #endif
2778  case MSK_PRO_STA_ILL_POSED:
2779  case MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED:
2780  SCIPmessagePrintWarning(lpi->messagehdlr, "Barrier[%d] returned prosta = %d\n", lpi->optimizecount, prosta);
2781 
2782  if (lpi->termcode == MSK_RES_OK)
2783  lpi->termcode = MSK_RES_TRM_NUMERICAL_PROBLEM;
2784 
2785  invalidateSolution(lpi);
2786 
2787 #if ASSERT_ON_WARNING
2788  assert(0);
2789 #endif
2790  break;
2791  default:
2792 #if SHOW_ERRORS
2793  SCIPerrorMessage("Barrier[%d] returned prosta = %d\n", lpi->optimizecount, prosta);
2794 #endif
2795 
2796 #if ASSERT_ON_WARNING
2797  assert(0);
2798 #endif
2799 
2800  return SCIP_LPERROR;
2801  } /*lint !e788*/
2802 
2803 #if DEBUG_CHECK_DATA > 0
2804  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiSolveBarrier") );
2805 #endif
2806 
2807  return SCIP_OKAY;
2808 }
2809 
2810 /** start strong branching - call before any strong branching */
2812  SCIP_LPI* lpi /**< LP interface structure */
2813  )
2814 { /*lint --e{715}*/
2815  assert(lpi != NULL);
2816  assert(lpi->mosekenv != NULL);
2817  assert(lpi->task != NULL);
2818 
2819  /* currently do nothing */
2820  return SCIP_OKAY;
2821 }
2822 
2823 /** end strong branching - call after any strong branching */
2825  SCIP_LPI* lpi /**< LP interface structure */
2826  )
2827 { /* lint --e{715}*/
2828  assert(lpi != NULL);
2829  /* assert(MosekEnv != NULL);
2830  assert(lpi->task != NULL); */
2831 
2832  /* currently do nothing */
2833  return SCIP_OKAY;
2834 }
2835 
2836 /** performs strong branching iterations on all candidates
2837  *
2838  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
2839  */
2840 static
2842  SCIP_LPI* lpi, /**< LP interface structure */
2843  int col, /**< column to apply strong branching on */
2844  SCIP_Real psol, /**< current primal solution value of column */
2845  int itlim, /**< iteration limit for strong branchings */
2846  SCIP_Real* down, /**< stores dual bound after branching column down */
2847  SCIP_Real* up, /**< stores dual bound after branching column up */
2848  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2849  * otherwise, it can only be used as an estimate value */
2850  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2851  * otherwise, it can only be used as an estimate value */
2852  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2853  )
2854 {
2855  MSKobjsensee objsen;
2856  int olditerlim;
2857  int oldselection;
2858  int oldhotstart;
2859 
2860  double bound;
2861  int ncols;
2862  int nrows;
2863  MSKboundkeye bkx;
2864  double blx;
2865  double bux;
2866  double newub;
2867  double newlb;
2868 
2869  assert(lpi != NULL);
2870  assert(lpi->mosekenv != NULL);
2871  assert(lpi->task != NULL);
2872 
2873  SCIPdebugMessage("Calling SCIPlpiStrongbranch (%d)\n", lpi->lpid);
2874 
2875 #if DEBUG_CHECK_DATA > 0
2876  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiStrongbranch") );
2877 #endif
2878 
2879  if (lpi->termcode != MSK_RES_OK)
2880  {
2881  SCIPmessagePrintWarning(lpi->messagehdlr, "SB Warning: Previous termcode is %d\n", lpi->termcode);
2882  }
2883 
2884  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
2885  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
2886 
2887  SCIP_CALL( getbase(lpi, ncols, nrows) );
2888 
2889  MOSEK_CALL( MSK_getobjsense(lpi->task, &objsen) );
2890  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, &olditerlim) );
2891  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, &oldselection) );
2892  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, &oldhotstart) );
2893 
2894  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, itlim) );
2895  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, STRONGBRANCH_PRICING) );
2896 
2897  if (objsen == MSK_OBJECTIVE_SENSE_MINIMIZE)
2898  {
2899  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, &bound) );
2900  }
2901  else /* objsen == MSK_OBJECTIVE_SENSE_MAX */
2902  {
2903  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, &bound) );
2904  }
2905 
2906 #if MSK_VERSION_MAJOR < 9
2907  MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_VAR, col, &bkx, &blx, &bux) );
2908 #else
2909  MOSEK_CALL( MSK_getvarbound(lpi->task, col, &bkx, &blx, &bux) );
2910 #endif
2911 
2912  *iter = 0;
2913 
2914  newub = EPSCEIL(psol-1.0, 1e-06);
2915 
2916  if (newub < blx - 0.5) /* infeasible */
2917  {
2918  *down = bound;
2919  *downvalid = TRUE;
2920  }
2921  else
2922  {
2923  MSKboundkeye newbk;
2924 
2925  if (IS_NEGINF(blx))
2926  newbk = MSK_BK_UP;
2927  else if (EPSEQ(blx, newub,1.0e-6))
2928  {
2929  newbk = MSK_BK_FX;
2930  newub = blx;
2931  }
2932  else
2933  newbk = MSK_BK_RA;
2934 
2935 #if MSK_VERSION_MAJOR < 9
2936  MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, newbk, blx, newub) );
2937 #else
2938  MOSEK_CALL( MSK_putvarbound(lpi->task, col, newbk, blx, newub) );
2939 #endif
2940 
2941  SCIP_CALL( SCIPlpiSolveDual(lpi) );
2942 
2943  *iter += lpi->itercount;
2944 
2945  if (SCIPlpiIsStable(lpi))
2946  *downvalid = TRUE;
2947  else
2948  *downvalid = FALSE;
2949 
2950  if (SCIPlpiExistsPrimalRay(lpi))
2951  {
2952  SCIPmessagePrintWarning(lpi->messagehdlr, "SB ERROR: Lp [%d] is dual infeasible\n", lpi->optimizecount);
2953 
2954  *down = -1e20;
2955  *downvalid = FALSE;
2956  }
2957  else if (SCIPlpiExistsDualRay(lpi))
2958  {
2959  *down = bound;
2960  }
2961  else
2962  {
2963  SCIP_Bool pfeas;
2964  SCIP_Bool dfeas;
2965 
2966  SCIP_CALL( SCIPlpiGetSolFeasibility(lpi, &pfeas, &dfeas) );
2967 
2968  if (!dfeas)
2969  {
2970  SCIPmessagePrintWarning(lpi->messagehdlr, "SB ERROR: Lp [%d] is not dual feasible\n", lpi->optimizecount);
2971 
2972  *down = -1e20;
2973  *downvalid = FALSE;
2974  }
2975  else
2976  {
2977  MOSEK_CALL( MSK_getdualobj(lpi->task, lpi->lastsolvetype, down) );
2978  }
2979  }
2980 
2981 #if DEBUG_PRINT_STAT > 0
2982  if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
2983  ++numstrongbranchobjup;
2984 
2985  if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
2986  ++numstrongbranchmaxiterup;
2987 #endif
2988  }
2989 
2990  /* Reset basis solution before doing the up branch */
2991 #if MSK_VERSION_MAJOR < 9
2992  MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, bkx, blx, bux) );
2993 #else
2994  MOSEK_CALL( MSK_putvarbound(lpi->task, col, bkx, blx, bux) );
2995 #endif
2996  SCIP_CALL( setbase(lpi) );
2997 
2998  newlb = EPSFLOOR(psol+1.0, 1e-06);
2999  if (newlb > bux + 0.5) /* infeasible */
3000  {
3001  *up = bound;
3002  *upvalid = TRUE;
3003  }
3004  else
3005  {
3006  MSKboundkeye newbk;
3007 
3008  if (IS_POSINF(bux))
3009  newbk = MSK_BK_LO;
3010  else if (EPSEQ(bux, newlb,1.0e-6))
3011  {
3012  newbk = MSK_BK_FX;
3013  newlb = bux;
3014  }
3015  else
3016  newbk = MSK_BK_RA;
3017 
3018 #if MSK_VERSION_MAJOR < 9
3019  MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, newbk, newlb, bux) );
3020 #else
3021  MOSEK_CALL( MSK_putvarbound(lpi->task, col, newbk, newlb, bux) );
3022 #endif
3023  SCIP_CALL( SCIPlpiSolveDual(lpi) );
3024 
3025  *iter += lpi->itercount;
3026 
3027  if (SCIPlpiIsStable(lpi))
3028  *upvalid = TRUE;
3029  else
3030  *upvalid = FALSE;
3031 
3032  if (SCIPlpiExistsPrimalRay(lpi))
3033  {
3034  *up = -1e20;
3035  *upvalid = FALSE;
3036  }
3037  else if (SCIPlpiExistsDualRay(lpi))
3038  {
3039  *up = bound;
3040  }
3041  else
3042  {
3043  SCIP_Bool pfeas;
3044  SCIP_Bool dfeas;
3045 
3046  SCIP_CALL( SCIPlpiGetSolFeasibility(lpi, &pfeas, &dfeas) );
3047 
3048  if (!dfeas)
3049  {
3050  SCIPmessagePrintWarning(lpi->messagehdlr, "SB ERROR: Lp [%d] is not dual feasible\n", lpi->optimizecount);
3051 
3052  *up = -1e20;
3053  *upvalid = FALSE;
3054  }
3055  else
3056  {
3057  MOSEK_CALL( MSK_getdualobj(lpi->task, lpi->lastsolvetype, up) );
3058  }
3059  }
3060 
3061 #if DEBUG_PRINT_STAT > 0
3062  if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
3063  ++numstrongbranchobjdo;
3064 
3065  if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
3066  ++numstrongbranchmaxiterdo;
3067 #endif
3068  }
3069 
3070 #if MSK_VERSION_MAJOR < 9
3071  MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, bkx, blx, bux) );
3072 #else
3073  MOSEK_CALL( MSK_putvarbound(lpi->task, col, bkx, blx, bux) );
3074 #endif
3075  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, olditerlim) );
3076  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, oldselection) );
3077  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, oldhotstart) );
3078 
3079  SCIP_CALL( setbase(lpi) );
3080 
3081  invalidateSolution(lpi);
3082 
3083  lpi->termcode = MSK_RES_OK;
3084  lpi->itercount = 0;
3085 
3086 #if DEBUG_CHECK_DATA > 0
3087  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiStrongbranch") );
3088 #endif
3089 
3090  SCIPdebugMessage("End SCIPlpiStrongbranch (%d)\n", lpi->lpid);
3091 
3092  return SCIP_OKAY;
3093 }
3094 
3095 /** performs strong branching iterations on one @b fractional candidate
3096  *
3097  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
3098  */
3100  SCIP_LPI* lpi, /**< LP interface structure */
3101  int col, /**< column to apply strong branching on */
3102  SCIP_Real psol, /**< fractional current primal solution value of column */
3103  int itlim, /**< iteration limit for strong branchings */
3104  SCIP_Real* down, /**< stores dual bound after branching column down */
3105  SCIP_Real* up, /**< stores dual bound after branching column up */
3106  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3107  * otherwise, it can only be used as an estimate value */
3108  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3109  * otherwise, it can only be used as an estimate value */
3110  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3111  )
3112 {
3113  /* pass call on to lpiStrongbranch() */
3114  SCIP_CALL( SCIPlpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
3115 
3116  return SCIP_OKAY;
3117 }
3118 
3119 /** performs strong branching iterations on given @b fractional candidates
3120  *
3121  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
3122  */
3124  SCIP_LPI* lpi, /**< LP interface structure */
3125  int* cols, /**< columns to apply strong branching on */
3126  int ncols, /**< number of columns */
3127  SCIP_Real* psols, /**< fractional current primal solution values of columns */
3128  int itlim, /**< iteration limit for strong branchings */
3129  SCIP_Real* down, /**< stores dual bounds after branching columns down */
3130  SCIP_Real* up, /**< stores dual bounds after branching columns up */
3131  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
3132  * otherwise, they can only be used as an estimate values */
3133  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
3134  * otherwise, they can only be used as an estimate values */
3135  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3136  )
3137 {
3138  int j;
3139 
3140  assert( cols != NULL );
3141  assert( psols != NULL );
3142  assert( down != NULL );
3143  assert( up != NULL );
3144  assert( downvalid != NULL );
3145  assert( upvalid != NULL );
3146  assert( down != NULL );
3147 
3148  if ( iter != NULL )
3149  *iter = 0;
3150 
3151  for (j = 0; j < ncols; ++j)
3152  {
3153  /* pass call on to lpiStrongbranch() */
3154  SCIP_CALL( SCIPlpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
3155  }
3156  return SCIP_OKAY;
3157 }
3158 
3159 /** performs strong branching iterations on one candidate with @b integral value
3160  *
3161  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
3162  */
3164  SCIP_LPI* lpi, /**< LP interface structure */
3165  int col, /**< column to apply strong branching on */
3166  SCIP_Real psol, /**< current integral primal solution value of column */
3167  int itlim, /**< iteration limit for strong branchings */
3168  SCIP_Real* down, /**< stores dual bound after branching column down */
3169  SCIP_Real* up, /**< stores dual bound after branching column up */
3170  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3171  * otherwise, it can only be used as an estimate value */
3172  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3173  * otherwise, it can only be used as an estimate value */
3174  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3175  )
3176 {
3177  /* pass call on to lpiStrongbranch() */
3178  SCIP_CALL( SCIPlpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
3179 
3180  return SCIP_OKAY;
3181 }
3182 
3183 /** performs strong branching iterations on given candidates with @b integral values
3184  *
3185  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
3186  */
3188  SCIP_LPI* lpi, /**< LP interface structure */
3189  int* cols, /**< columns to apply strong branching on */
3190  int ncols, /**< number of columns */
3191  SCIP_Real* psols, /**< current integral primal solution values of columns */
3192  int itlim, /**< iteration limit for strong branchings */
3193  SCIP_Real* down, /**< stores dual bounds after branching columns down */
3194  SCIP_Real* up, /**< stores dual bounds after branching columns up */
3195  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
3196  * otherwise, they can only be used as an estimate values */
3197  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
3198  * otherwise, they can only be used as an estimate values */
3199  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3200  )
3201 {
3202  int j;
3203 
3204  assert( cols != NULL );
3205  assert( psols != NULL );
3206  assert( down != NULL );
3207  assert( up != NULL );
3208  assert( downvalid != NULL );
3209  assert( upvalid != NULL );
3210  assert( down != NULL );
3211 
3212  if ( iter != NULL )
3213  *iter = 0;
3214 
3215  for (j = 0; j < ncols; ++j)
3216  {
3217  /* pass call on to lpiStrongbranch() */
3218  SCIP_CALL( SCIPlpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
3219  }
3220  return SCIP_OKAY;
3221 }
3222 
3223 
3224 /*
3225  * Solution Information Methods
3226  */
3227 
3228 
3229 /** returns whether a solve method was called after the last modification of the LP */
3231  SCIP_LPI* lpi /**< LP interface structure */
3232  )
3233 {
3234  assert(lpi != NULL);
3235 
3236  return lpi->solved;
3237 }
3238 
3239 /** gets information about primal and dual feasibility of the current LP solution
3240  *
3241  * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
3242  * returns true. If the LP is changed, this information might be invalidated.
3243  *
3244  * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
3245  * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
3246  * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
3247  * the problem might actually be feasible).
3248  */
3250  SCIP_LPI* lpi, /**< LP interface structure */
3251  SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
3252  SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
3253  )
3254 {
3255  MSKprostae prosta;
3256 
3257  assert( lpi != NULL );
3258  assert( lpi->mosekenv != NULL );
3259  assert( lpi->task != NULL );
3260  assert( primalfeasible != NULL );
3261  assert( dualfeasible != NULL );
3262 
3263  SCIPdebugMessage("Calling SCIPlpiGetSolFeasibility (%d)\n", lpi->lpid);
3264 
3265  MOSEK_CALL( MSK_getsolutionstatus(lpi->task, lpi->lastsolvetype, &prosta, NULL) );
3266 
3267  switch (prosta)
3268  {
3269  case MSK_PRO_STA_PRIM_AND_DUAL_FEAS:
3270  *primalfeasible = TRUE;
3271  *dualfeasible = TRUE;
3272  break;
3273  case MSK_PRO_STA_PRIM_FEAS:
3274  *primalfeasible = TRUE;
3275  *dualfeasible = FALSE;
3276  break;
3277  case MSK_PRO_STA_DUAL_FEAS:
3278  *primalfeasible = FALSE;
3279  *dualfeasible = TRUE;
3280  break;
3281  case MSK_PRO_STA_DUAL_INFEAS:
3282  /* assume that we have a primal solution if we used the primal simplex */
3283  *primalfeasible = (lpi->lastalgo == MSK_OPTIMIZER_PRIMAL_SIMPLEX);
3284  *dualfeasible = FALSE;
3285  break;
3286  case MSK_PRO_STA_UNKNOWN:
3287  case MSK_PRO_STA_PRIM_INFEAS:
3288  case MSK_PRO_STA_PRIM_AND_DUAL_INFEAS:
3289  case MSK_PRO_STA_ILL_POSED:
3290 #if MSK_VERSION_MAJOR < 9
3291  case MSK_PRO_STA_NEAR_PRIM_AND_DUAL_FEAS:
3292  case MSK_PRO_STA_NEAR_PRIM_FEAS:
3293  case MSK_PRO_STA_NEAR_DUAL_FEAS:
3294 #endif
3295  case MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED:
3296  *primalfeasible = FALSE;
3297  *dualfeasible = FALSE;
3298  break;
3299  default:
3300  return SCIP_LPERROR;
3301  } /*lint !e788*/
3302 
3303  return SCIP_OKAY;
3304 }
3305 
3306 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
3307  * this does not necessarily mean, that the solver knows and can return the primal ray
3308  */
3310  SCIP_LPI* lpi /**< LP interface structure */
3311  )
3312 {
3313  MSKprostae prosta;
3314  MSKsolstae solsta;
3315 
3316  assert(lpi != NULL);
3317  assert(lpi->mosekenv != NULL);
3318  assert(lpi->task != NULL);
3319 
3320  SCIPdebugMessage("Calling SCIPlpiExistsPrimalRay (%d)\n", lpi->lpid);
3321 
3322  SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, &solsta) );
3323 
3324  return ( solsta == MSK_SOL_STA_DUAL_INFEAS_CER
3325  || prosta == MSK_PRO_STA_DUAL_INFEAS
3326  || prosta == MSK_PRO_STA_PRIM_AND_DUAL_INFEAS );
3327 }
3328 
3329 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
3330  * and the solver knows and can return the primal ray
3331  */
3333  SCIP_LPI* lpi /**< LP interface structure */
3334  )
3335 {
3336  MSKsolstae solsta;
3337 
3338  assert(lpi != NULL);
3339  assert(lpi->mosekenv != NULL);
3340  assert(lpi->task != NULL);
3341 
3342  SCIPdebugMessage("Calling SCIPlpiHasPrimalRay (%d)\n", lpi->lpid);
3343 
3344  SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
3345 
3346  return (solsta == MSK_SOL_STA_DUAL_INFEAS_CER);
3347 }
3348 
3349 /** returns TRUE iff LP is proven to be primal unbounded */
3351  SCIP_LPI* lpi /**< LP interface structure */
3352  )
3353 { /*lint --e{715}*/
3354  MSKsolstae solsta;
3355 
3356  assert(lpi != NULL);
3357  assert(lpi->mosekenv != NULL);
3358  assert(lpi->task != NULL);
3359 
3360  SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
3361 
3362  /* assume primal solution and ray is available if we used the primal simplex and the dual is proven to be infeasible */
3363  return (solsta == MSK_SOL_STA_DUAL_INFEAS_CER && lpi->lastalgo == MSK_OPTIMIZER_PRIMAL_SIMPLEX);
3364 }
3365 
3366 /** returns TRUE iff LP is proven to be primal infeasible */
3368  SCIP_LPI* lpi /**< LP interface structure */
3369  )
3370 {
3371  assert(lpi != NULL);
3372  assert(lpi->mosekenv != NULL);
3373  assert(lpi->task != NULL);
3374 
3375  return SCIPlpiExistsDualRay(lpi);
3376 }
3377 
3378 /** returns TRUE iff LP is proven to be primal feasible */
3380  SCIP_LPI* lpi /**< LP interface structure */
3381  )
3382 {
3383  MSKprostae prosta;
3384 
3385  assert(lpi != NULL);
3386  assert(lpi->mosekenv != NULL);
3387  assert(lpi->task != NULL);
3388 
3389  SCIPdebugMessage("Calling SCIPlpiIsPrimalFeasible (%d)\n", lpi->lpid);
3390 
3391  SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, NULL) );
3392 
3393  return (prosta == MSK_PRO_STA_PRIM_FEAS || prosta == MSK_PRO_STA_PRIM_AND_DUAL_FEAS || (prosta == MSK_PRO_STA_DUAL_INFEAS && lpi->lastalgo == MSK_OPTIMIZER_PRIMAL_SIMPLEX));
3394 }
3395 
3396 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
3397  * this does not necessarily mean, that the solver knows and can return the dual ray
3398  */
3400  SCIP_LPI* lpi /**< LP interface structure */
3401  )
3402 {
3403  MSKprostae prosta;
3404  MSKsolstae solsta;
3405 
3406  assert(lpi != NULL);
3407  assert(lpi->mosekenv != NULL);
3408  assert(lpi->task != NULL);
3409 
3410  SCIPdebugMessage("Calling SCIPlpiExistsDualRay (%d)\n", lpi->lpid);
3411 
3412  SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, &solsta) );
3413 
3414  return ( solsta == MSK_SOL_STA_PRIM_INFEAS_CER
3415  || prosta == MSK_PRO_STA_PRIM_INFEAS
3416  || prosta == MSK_PRO_STA_PRIM_AND_DUAL_INFEAS );
3417 }
3418 
3419 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
3420  * and the solver knows and can return the dual ray
3421  */
3423  SCIP_LPI* lpi /**< LP interface structure */
3424  )
3425 {
3426  MSKsolstae solsta;
3427 
3428  assert(lpi != NULL);
3429  assert(lpi->mosekenv != NULL);
3430  assert(lpi->task != NULL);
3431 
3432  SCIPdebugMessage("Calling SCIPlpiHasDualRay (%d)\n", lpi->lpid);
3433 
3434  SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
3435 
3436  return (solsta == MSK_SOL_STA_PRIM_INFEAS_CER);
3437 }
3438 
3439 /** returns TRUE iff LP is proven to be dual unbounded */
3441  SCIP_LPI* lpi /**< LP interface structure */
3442  )
3443 { /*lint --e{715}*/
3444  assert(lpi != NULL);
3445  assert(lpi->mosekenv != NULL);
3446  assert(lpi->task != NULL);
3447 
3448  return FALSE;
3449 }
3450 
3451 /** returns TRUE iff LP is proven to be dual infeasible */
3453  SCIP_LPI* lpi /**< LP interface structure */
3454  )
3455 {
3456  assert(lpi != NULL);
3457  assert(lpi->mosekenv != NULL);
3458  assert(lpi->task != NULL);
3459 
3460  return SCIPlpiExistsPrimalRay(lpi);
3461 }
3462 
3463 /** returns TRUE iff LP is proven to be dual feasible */
3465  SCIP_LPI* lpi /**< LP interface structure */
3466  )
3467 {
3468  MSKprostae prosta;
3469 
3470  assert(lpi != NULL);
3471  assert(lpi->mosekenv != NULL);
3472  assert(lpi->task != NULL);
3473 
3474  SCIPdebugMessage("Calling SCIPlpiIsDualFeasible (%d)\n", lpi->lpid);
3475 
3476  SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, NULL) );
3477 
3478  return (prosta == MSK_PRO_STA_DUAL_FEAS || prosta == MSK_PRO_STA_PRIM_AND_DUAL_FEAS);
3479 }
3480 
3481 /** returns TRUE iff LP was solved to optimality */
3483  SCIP_LPI* lpi /**< LP interface structure */
3484  )
3485 {
3486  MSKsolstae solsta;
3487 
3488  assert(lpi != NULL);
3489  assert(lpi->mosekenv != NULL);
3490  assert(lpi->task != NULL);
3491 
3492  SCIPdebugMessage("Calling SCIPlpiIsOptimal (%d)\n", lpi->lpid);
3493 
3494  SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
3495 
3496  return (solsta == MSK_SOL_STA_OPTIMAL);
3497 }
3498 
3499 /** returns TRUE iff current LP solution is stable
3500  *
3501  * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
3502  * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
3503  * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
3504  * SCIPlpiIsStable() should return false.
3505  */
3507  SCIP_LPI* lpi /**< LP interface structure */
3508  )
3509 {
3510  assert(lpi != NULL);
3511  assert(lpi->mosekenv != NULL);
3512  assert(lpi->task != NULL);
3513 
3514  return ( lpi->termcode == MSK_RES_OK
3515  || lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS
3516  || lpi->termcode == MSK_RES_TRM_MAX_TIME
3517  || lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE );
3518 }
3519 
3520 /** returns TRUE iff the objective limit was reached */
3522  SCIP_LPI* lpi /**< LP interface structure */
3523  )
3524 {
3525  assert(lpi != NULL);
3526  assert(lpi->mosekenv != NULL);
3527  assert(lpi->task != NULL);
3528 
3529  return ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE );
3530 }
3531 
3532 /** returns TRUE iff the iteration limit was reached */
3534  SCIP_LPI* lpi /**< LP interface structure */
3535  )
3536 {
3537  assert(lpi != NULL);
3538  assert(lpi->mosekenv != NULL);
3539  assert(lpi->task != NULL);
3540 
3541  return ( lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS );
3542 }
3543 
3544 /** returns TRUE iff the time limit was reached */
3546  SCIP_LPI* lpi /**< LP interface structure */
3547  )
3548 {
3549  assert(lpi != NULL);
3550  assert(lpi->mosekenv != NULL);
3551  assert(lpi->task != NULL);
3552 
3553  return ( lpi->termcode == MSK_RES_TRM_MAX_TIME );
3554 }
3555 
3556 /** returns the internal solution status of the solver */
3558  SCIP_LPI* lpi /**< LP interface structure */
3559  )
3560 {
3561  MSKsolstae solsta;
3562  SCIP_RETCODE retcode;
3563 
3564  assert(lpi != NULL);
3565  assert(lpi->mosekenv != NULL);
3566  assert(lpi->task != NULL);
3567 
3568  SCIPdebugMessage("Calling SCIPlpiGetInternalStatus (%d)\n", lpi->lpid);
3569 
3570  retcode = getSolutionStatus(lpi, NULL, &solsta);
3571  if ( retcode != SCIP_OKAY )
3572  return 0;
3573 
3574  return (int) solsta;
3575 }
3576 
3577 /** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
3579  SCIP_LPI* lpi, /**< LP interface structure */
3580  SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
3581  )
3582 {
3583  assert(lpi != NULL);
3584  assert(lpi->mosekenv != NULL);
3585  assert(lpi->task != NULL);
3586  assert(success != NULL);
3587 
3588  SCIPdebugMessage("Calling SCIPlpiIgnoreInstability (%d)\n", lpi->lpid);
3589 
3590  *success = FALSE;
3591 
3592  return SCIP_OKAY;
3593 }
3594 
3595 /** gets objective value of solution */
3597  SCIP_LPI* lpi, /**< LP interface structure */
3598  SCIP_Real* objval /**< stores the objective value */
3599  )
3600 {
3601  assert(lpi != NULL);
3602  assert(lpi->mosekenv != NULL);
3603  assert(lpi->task != NULL);
3604  assert(objval != NULL);
3605 
3606  SCIPdebugMessage("Calling SCIPlpiGetObjval (%d)\n", lpi->lpid);
3607 
3608  /* TODO: tjek lighed med dual objektiv i de fleste tilfaelde. */
3609 
3610  if ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE )
3611  {
3612  /* if we reached the objective limit, return this value */
3613  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, objval) );
3614  }
3615  else
3616  {
3617  /* otherwise get the value from Mosek */
3618  MOSEK_CALL( MSK_getprimalobj(lpi->task, lpi->lastsolvetype, objval) );
3619  }
3620 
3621  return SCIP_OKAY;
3622 }
3623 
3624 /** gets primal and dual solution vectors for feasible LPs
3625  *
3626  * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
3627  * SCIPlpiIsOptimal() returns true.
3628  */
3630  SCIP_LPI* lpi, /**< LP interface structure */
3631  SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
3632  SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
3633  SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
3634  SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
3635  SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
3636  )
3637 {
3638  MSKsolstae solsta;
3639  double* sux = NULL;
3640  int ncols = 0;
3641  int i;
3642 
3643  assert(lpi != NULL);
3644  assert(lpi->mosekenv != NULL);
3645  assert(lpi->task != NULL);
3646 
3647  SCIPdebugMessage("Calling SCIPlpiGetSol (%d)\n", lpi->lpid);
3648 
3649  if ( objval != NULL )
3650  {
3651  if ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE )
3652  {
3653  /* if we reached the objective limit, return this value */
3654  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, objval) );
3655  }
3656  else
3657  {
3658  /* otherwise get the value from Mosek */
3659  MOSEK_CALL( MSK_getprimalobj(lpi->task, lpi->lastsolvetype, objval) );
3660  }
3661  }
3662 
3663  if( redcost )
3664  {
3665  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
3666  SCIP_ALLOC( BMSallocMemoryArray(&sux, ncols) );
3667  }
3668 
3669  if ( primsol != NULL && lpi->lastalgo == MSK_OPTIMIZER_PRIMAL_SIMPLEX )
3670  {
3671  /* If the status shows that the dual is infeasible this is due to the primal being unbounded. In this case, we need
3672  * to compute a feasible solution by setting the objective to 0.
3673  */
3674  MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, NULL, &solsta) );
3675  if ( solsta == MSK_SOL_STA_DUAL_INFEAS_CER )
3676  {
3677  SCIP_Real* objcoefs;
3678  int j;
3679 
3680  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
3681  SCIP_ALLOC( BMSallocMemoryArray(&objcoefs, ncols) );
3682 
3683  /* store old objective coefficients and set them to 0 */
3684  for (j = 0; j < ncols; ++j)
3685  {
3686  MOSEK_CALL( MSK_getcj(lpi->task, j, &objcoefs[j]) );
3687  MOSEK_CALL( MSK_putcj(lpi->task, j, 0.0) );
3688  }
3689 
3690  /* solve problem again */
3691  SCIP_CALL( SolveWSimplex(lpi) );
3692 
3693  /* At this point we assume that the problem is feasible, since we previously ran the primal simplex and it
3694  * produced a ray.
3695  */
3696 
3697  /* get primal solution */
3698  MOSEK_CALL( MSK_getsolution(lpi->task, lpi->lastsolvetype, NULL, NULL, NULL, NULL, NULL, activity,
3699  primsol, NULL, NULL, NULL, NULL, NULL, NULL) );
3700 
3701  /* restore objective */
3702  MOSEK_CALL( MSK_putcslice(lpi->task, 0, ncols, objcoefs) );
3703 
3704  /* resolve to restore original status */
3705  SCIP_CALL( SolveWSimplex(lpi) );
3706 
3707  BMSfreeMemoryArray(&objcoefs);
3708  }
3709  else
3710  {
3711  MOSEK_CALL( MSK_getsolution(lpi->task, lpi->lastsolvetype, NULL, NULL, NULL, NULL, NULL, activity,
3712  primsol, dualsol, NULL, NULL, redcost, sux, NULL) );
3713  }
3714  }
3715  else
3716  {
3717  MOSEK_CALL( MSK_getsolution(lpi->task, lpi->lastsolvetype, NULL, NULL, NULL, NULL, NULL, activity,
3718  primsol, dualsol, NULL, NULL, redcost, sux, NULL) );
3719  }
3720 
3721  /* the reduced costs are given by the difference of the slx and sux variables (third and second to last parameters) */
3722  if( redcost )
3723  {
3724  for( i = 0; i < ncols; i++ )
3725  {
3726  assert(sux != NULL);
3727  redcost[i] -= sux[i];
3728  }
3729  BMSfreeMemoryArray(&sux);
3730  }
3731 
3732  return SCIP_OKAY;
3733 }
3734 
3735 /** gets primal ray for unbounded LPs */
3737  SCIP_LPI* lpi, /**< LP interface structure */
3738  SCIP_Real* ray /**< primal ray */
3739  )
3740 {
3741  assert(lpi != NULL);
3742  assert(lpi->mosekenv != NULL);
3743  assert(lpi->task != NULL);
3744  assert(ray != NULL);
3745 
3746  SCIPdebugMessage("Calling SCIPlpiGetPrimalRay (%d)\n", lpi->lpid);
3747 
3748  MOSEK_CALL( MSK_getsolution(lpi->task, lpi->lastsolvetype, NULL, NULL, NULL, NULL, NULL, NULL, ray,
3749  NULL, NULL, NULL, NULL, NULL, NULL) );
3750 
3751  return SCIP_OKAY;
3752 }
3753 
3754 /** gets dual Farkas proof for infeasibility */
3756  SCIP_LPI* lpi, /**< LP interface structure */
3757  SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
3758  )
3759 {
3760  assert(lpi != NULL);
3761  assert(lpi->mosekenv != NULL);
3762  assert(lpi->task != NULL);
3763  assert(dualfarkas != NULL);
3764 
3765  SCIPdebugMessage("Calling SCIPlpiGetDualfarkas (%d)\n", lpi->lpid);
3766 
3767  MOSEK_CALL( MSK_getsolution(lpi->task, lpi->lastsolvetype, NULL, NULL, NULL, NULL, NULL, NULL, NULL, dualfarkas,
3768  NULL, NULL, NULL, NULL, NULL) );
3769 
3770  return SCIP_OKAY;
3771 }
3772 
3773 /** gets the number of LP iterations of the last solve call */
3775  SCIP_LPI* lpi, /**< LP interface structure */
3776  int* iterations /**< pointer to store the number of iterations of the last solve call */
3777  )
3778 {
3779  assert(lpi != NULL);
3780  assert(lpi->mosekenv != NULL);
3781  assert(lpi->task != NULL);
3782  assert(iterations != NULL);
3783 
3784  SCIPdebugMessage("Calling SCIPlpiGetIterations (%d)\n", lpi->lpid);
3785 
3786  *iterations = lpi->itercount;
3787 
3788  return SCIP_OKAY;
3789 }
3790 
3791 /** gets information about the quality of an LP solution
3792  *
3793  * Such information is usually only available, if also a (maybe not optimal) solution is available.
3794  * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
3795  */
3797  SCIP_LPI* lpi, /**< LP interface structure */
3798  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
3799  SCIP_Real* quality /**< pointer to store quality number */
3800  )
3801 { /*lint --e{715}*/
3802  assert(lpi != NULL);
3803  assert(lpi->mosekenv != NULL);
3804  assert(lpi->task != NULL);
3805  assert(quality != NULL);
3806  SCIP_UNUSED(qualityindicator);
3807 
3808  *quality = SCIP_INVALID;
3809 
3810  return SCIP_OKAY;
3811 }
3812 
3813 /** handle singular basis */
3814 static
3816  SCIP_LPI* lpi, /**< LP interface structure */
3817  int* basis, /**< array of basis indices */
3818  MSKrescodee res /**< result */
3819  )
3820 {
3821  if (res == MSK_RES_ERR_BASIS_SINGULAR)
3822  {
3823  SCIP_CALL( SCIPlpiSolvePrimal(lpi) );
3824 
3825  MOSEK_CALL( MSK_initbasissolve(lpi->task, basis) );
3826  }
3827  else
3828  {
3829  MOSEK_CALL( res );
3830  }
3831 
3832  return SCIP_OKAY;
3833 }
3834 
3835 
3836 /*
3837  * LP Basis Methods
3838  */
3839 
3840 /** convert Mosek basis status to SCIP basis status
3841  *
3842  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
3843  */
3844 static
3846  SCIP_LPI* lpi, /**< LP interface structure */
3847  SCIP_Bool iscon, /**< whether constraints/variables are considered */
3848  MSKstakeye* sk, /**< status array of Mosek */
3849  int n, /**< size */
3850  int* stat /**< status array of SCIP */
3851  )
3852 {
3853  int i;
3854 
3855  assert(lpi->lastsolvetype == MSK_SOL_BAS);
3856 
3857  for( i = 0; i < n; i++ )
3858  {
3859  double sl;
3860  double su;
3861 
3862  switch (sk[i])
3863  {
3864  case MSK_SK_BAS:
3865  stat[i] = (int)SCIP_BASESTAT_BASIC;
3866  break;
3867  case MSK_SK_SUPBAS:
3868  stat[i] = (int)SCIP_BASESTAT_ZERO;
3869  break;
3870  case MSK_SK_FIX:
3871 #if MSK_VERSION_MAJOR < 9
3872  MOSEK_CALL( MSK_getsolutioni(lpi->task, iscon ? MSK_ACC_CON : MSK_ACC_VAR, i, MSK_SOL_BAS, NULL, NULL, &sl, &su, NULL) );
3873 #else
3874  if( iscon )
3875  {
3876  MOSEK_CALL( MSK_getslcslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
3877  MOSEK_CALL( MSK_getsucslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
3878  }
3879  else
3880  {
3881  MOSEK_CALL( MSK_getslxslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
3882  MOSEK_CALL( MSK_getsuxslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
3883  }
3884 #endif
3885 
3886  if (sl < su) /* Negative reduced cost */
3887  stat[i] = (int)SCIP_BASESTAT_UPPER;
3888  else
3889  stat[i] = (int)SCIP_BASESTAT_LOWER;
3890  break;
3891  case MSK_SK_UNK:
3892  stat[i] = (int)SCIP_BASESTAT_LOWER;
3893  break;
3894  case MSK_SK_INF:
3895  stat[i] = (int)SCIP_BASESTAT_LOWER;
3896  break;
3897  case MSK_SK_LOW:
3898  stat[i] = (int)SCIP_BASESTAT_LOWER;
3899  break;
3900  case MSK_SK_UPR:
3901  stat[i] = (int)SCIP_BASESTAT_UPPER;
3902  break;
3903 #if MSK_VERSION_MAJOR < 10
3904  case MSK_SK_END:
3905  break;
3906 #endif
3907  default:
3908  SCIPABORT();
3909  return SCIP_INVALIDDATA; /*lint !e527*/
3910  } /*lint !e788*/
3911  }
3912 
3913  return SCIP_OKAY;
3914 }
3915 
3916 /** convert Mosek to SCIP basis status - slack variables
3917  *
3918  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
3919  */
3920 static
3922  SCIP_LPI* lpi, /**< LP interface structure */
3923  SCIP_Bool iscon, /**< whether constraints or variables are accessed */
3924  MSKstakeye* sk, /**< Mosek basis status */
3925  int m, /**< size */
3926  int* stat /**< status array */
3927  )
3928 {
3929  int i;
3930 
3931  assert(lpi->lastsolvetype == MSK_SOL_BAS);
3932 
3933  for( i = 0; i < m; i++ )
3934  {
3935  double sl;
3936  double su;
3937  switch (sk[i])
3938  {
3939  case MSK_SK_BAS:
3940  stat[i] = (int)SCIP_BASESTAT_BASIC;
3941  break;
3942  case MSK_SK_SUPBAS:
3943  stat[i] = (int)SCIP_BASESTAT_ZERO;
3944  break;
3945  case MSK_SK_FIX:
3946 #if MSK_VERSION_MAJOR < 9
3947  MOSEK_CALL( MSK_getsolutioni(lpi->task, iscon ? MSK_ACC_CON : MSK_ACC_VAR, i, MSK_SOL_BAS, NULL, NULL, &sl, &su, NULL) );
3948 #else
3949  if( iscon )
3950  {
3951  MOSEK_CALL( MSK_getslcslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
3952  MOSEK_CALL( MSK_getsucslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
3953  }
3954  else
3955  {
3956  MOSEK_CALL( MSK_getslxslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
3957  MOSEK_CALL( MSK_getsuxslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
3958  }
3959 #endif
3960 
3961  if (sl < su) /* Negative reduced cost */
3962  stat[i] = (int)SCIP_BASESTAT_UPPER;
3963  else
3964  stat[i] = (int)SCIP_BASESTAT_LOWER;
3965  break;
3966  case MSK_SK_UNK:
3967  case MSK_SK_INF:
3968  case MSK_SK_UPR:
3969  stat[i] = (int)SCIP_BASESTAT_UPPER;
3970  break;
3971  case MSK_SK_LOW:
3972  stat[i] = (int)SCIP_BASESTAT_LOWER;
3973  break;
3974 #if MSK_VERSION_MAJOR < 10
3975  case MSK_SK_END:
3976 #endif
3977  default:
3978  SCIPABORT();
3979  return SCIP_INVALIDDATA; /*lint !e527*/
3980  } /*lint !e788*/
3981  }
3982 
3983  return SCIP_OKAY;
3984 }
3985 
3986 /** convert SCIP to Mosek basis status */
3987 static
3989  const int* stat, /**< SCIP status array */
3990  int n, /**< size of array */
3991  MSKstakeye* resstat /**< resulting Mosek status array */
3992  )
3993 {
3994  int i;
3995  for( i = 0; i < n; i++ )
3996  {
3997  switch (stat[i])
3998  {
3999  case SCIP_BASESTAT_LOWER:
4000  resstat[i] = MSK_SK_LOW;
4001  break;
4002  case SCIP_BASESTAT_BASIC:
4003  resstat[i] = MSK_SK_BAS;
4004  break;
4005  case SCIP_BASESTAT_UPPER:
4006  resstat[i] = MSK_SK_UPR;
4007  break;
4008  case SCIP_BASESTAT_ZERO:
4009  resstat[i] = MSK_SK_SUPBAS;
4010  break;
4011  default:
4012  SCIPABORT();
4013  }
4014  }
4015 }
4016 
4017 /** convert SCIP to Mosek basis status - slack variables */
4018 static
4020  const int* stat, /**< SCIP status array */
4021  int n, /**< size of array */
4022  MSKstakeye* resstat /**< resulting Mosek status array */
4023  )
4024 {
4025  /* slacks are stored as -1 in Mosek, i.e., bounds are reversed compared to SCIP */
4026  int i;
4027 
4028  for( i = 0; i < n; i++ )
4029  {
4030  switch (stat[i])
4031  {
4032  case SCIP_BASESTAT_LOWER:
4033  resstat[i] = MSK_SK_UPR; /* Reversed */
4034  break;
4035  case SCIP_BASESTAT_BASIC:
4036  resstat[i] = MSK_SK_BAS;
4037  break;
4038  case SCIP_BASESTAT_UPPER:
4039  resstat[i] = MSK_SK_LOW; /* Reversed */
4040  break;
4041  case SCIP_BASESTAT_ZERO:
4042  resstat[i] = MSK_SK_SUPBAS;
4043  break;
4044  default:
4045  SCIPABORT();
4046  }
4047  }
4048 }
4049 
4050 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status
4051  *
4052  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
4053  */
4055  SCIP_LPI* lpi, /**< LP interface structure */
4056  int* cstat, /**< array to store column basis status, or NULL */
4057  int* rstat /**< array to store row basis status, or NULL */
4058  )
4059 {
4060  int nrows;
4061  int ncols;
4062 
4063  assert(lpi != NULL);
4064  assert(lpi->mosekenv != NULL);
4065  assert(lpi->task != NULL);
4066  assert(lpi->lastsolvetype == MSK_SOL_BAS);
4067 
4068  SCIPdebugMessage("Calling SCIPlpiGetBase (%d)\n", lpi->lpid);
4069 
4070  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
4071  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
4072 
4073  SCIP_CALL( getbase(lpi, ncols, nrows) );
4074 
4075  if (cstat)
4076  {
4077  SCIP_CALL( convertstat_mosek2scip(lpi, FALSE, lpi->skx, ncols, cstat) );
4078  }
4079 
4080  if (rstat)
4081  {
4082  SCIP_CALL( convertstat_mosek2scip_slack(lpi, TRUE, lpi->skc, nrows, rstat) );
4083  }
4084 
4085  return SCIP_OKAY;
4086 }
4087 
4088 /** sets current basis status for columns and rows */
4090  SCIP_LPI* lpi, /**< LP interface structure */
4091  const int* cstat, /**< array with column basis status */
4092  const int* rstat /**< array with row basis status */
4093  )
4094 {
4095  int nrows;
4096  int ncols;
4097 
4098  assert(lpi != NULL);
4099  assert(lpi->mosekenv != NULL);
4100  assert(lpi->task != NULL);
4101 
4102  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4103  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4104 
4105  assert(cstat != NULL || ncols == 0);
4106  assert(rstat != NULL || nrows == 0);
4107 
4108  SCIPdebugMessage("Calling SCIPlpiSetBase (%d)\n", lpi->lpid);
4109 
4110  SCIP_CALL( ensureStateMem(lpi, ncols, nrows) );
4111 
4112  convertstat_scip2mosek(cstat, ncols, lpi->skx);
4113  convertstat_scip2mosek_slack(rstat, nrows, lpi->skc);
4114 
4115  SCIP_CALL( setbase(lpi) );
4116 
4117  invalidateSolution(lpi);
4118 
4119  return SCIP_OKAY;
4120 }
4121 
4122 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
4124  SCIP_LPI* lpi, /**< LP interface structure */
4125  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
4126  )
4127 {
4128  int nrows;
4129  int i;
4130 
4131  assert(lpi != NULL);
4132  assert(lpi->mosekenv != NULL);
4133  assert(lpi->task != NULL);
4134  assert(bind != NULL);
4135 
4136  SCIPdebugMessage("Calling SCIPlpiGetBasisInd (%d)\n", lpi->lpid);
4137 
4138  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
4139 
4140  SCIP_CALL( handle_singular(lpi, bind, MSK_initbasissolve(lpi->task, bind)) );
4141 
4142  for (i = 0; i < nrows; i++ )
4143  {
4144  if (bind[i] < nrows) /* row bind[i] is basic */
4145  bind[i] = -1 - bind[i];
4146  else /* column bind[i]-nrows is basic */
4147  bind[i] = bind[i] - nrows;
4148  }
4149 
4150  return SCIP_OKAY;
4151 }
4152 
4153 /** get row of inverse basis matrix B^-1
4154  *
4155  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4156  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4157  * see also the explanation in lpi.h.
4158  *
4159  * @todo check that the result is in terms of the LP interface definition
4160  *
4161  * @todo check if this should invalidate the solution
4162  */
4164  SCIP_LPI* lpi, /**< LP interface structure */
4165  int r, /**< row number */
4166  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
4167  int* inds, /**< array to store the non-zero indices, or NULL */
4168  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4169  * (-1: if we do not store sparsity information) */
4170  )
4171 {
4172  int nrows;
4173  int i;
4174 
4175  assert(lpi != NULL);
4176  assert(lpi->mosekenv != NULL);
4177  assert(lpi->task != NULL);
4178  assert(coef != NULL);
4179 
4180  SCIPdebugMessage("Calling SCIPlpiGetBInvRow (%d)\n", lpi->lpid);
4181 
4182  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
4183 
4184  /* set coefficient for slack variables to be 1 instead of -1 */
4185  MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_ON) );
4186 
4187  /* prepare basis in Mosek, since we do not need the basis ourselves, we set the return parameter to NULL */
4188  SCIP_CALL( handle_singular(lpi, NULL, MSK_initbasissolve(lpi->task, NULL)) );
4189 
4190  /* initialize rhs of system to be a dense +/- unit vector (needed for MSK_solvewithbasis()) */
4191  for (i = 0; i < nrows; ++i)
4192  coef[i] = 0.0;
4193  coef[r] = 1.0; /* unit vector e_r */
4194 
4195  /* check whether we require a dense or sparse result vector */
4196  if ( ninds != NULL && inds != NULL )
4197  {
4198  *ninds = 1;
4199  inds[0]= r;
4200 
4201  /* solve transposed system */
4202 #if MSK_VERSION_MAJOR < 10
4203  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, ninds, inds, coef) );
4204 #else
4205  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, *ninds, inds, coef, ninds) );
4206 #endif
4207  assert( *ninds <= nrows );
4208  }
4209  else
4210  {
4211  int* sub;
4212  int numnz;
4213 
4214  SCIP_ALLOC( BMSallocMemoryArray(&sub, nrows) );
4215 
4216  numnz = 1;
4217  sub[0] = r;
4218 
4219  /* solve transposed system */
4220 #if MSK_VERSION_MAJOR < 10
4221  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, &numnz, sub, coef) );
4222 #else
4223  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, numnz, sub, coef, &numnz) );
4224 #endif
4225  assert( numnz <= nrows );
4226 
4227  BMSfreeMemoryArray(&sub);
4228  }
4229  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
4230 
4231  SCIPdebugMessage("End SCIPlpiGetBInvRow (%d)\n", lpi->lpid);
4232 
4233  return SCIP_OKAY;
4234 }
4235 
4236 /** get column of inverse basis matrix B^-1
4237  *
4238  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4239  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4240  * see also the explanation in lpi.h.
4241  *
4242  * @todo check that the result is in terms of the LP interface definition
4243  *
4244  * @todo check if this should invalidate the solution
4245  */
4247  SCIP_LPI* lpi, /**< LP interface structure */
4248  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
4249  * you have to call SCIPlpiGetBasisInd() to get the array which links the
4250  * B^-1 column numbers to the row and column numbers of the LP!
4251  * c must be between 0 and nrows-1, since the basis has the size
4252  * nrows * nrows */
4253  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
4254  int* inds, /**< array to store the non-zero indices, or NULL */
4255  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4256  * (-1: if we do not store sparsity information) */
4257  )
4258 {
4259  int nrows;
4260  int i;
4261 
4262  assert(lpi != NULL);
4263  assert(lpi->mosekenv != NULL);
4264  assert(lpi->task != NULL);
4265  assert(coef != NULL);
4266 
4267  SCIPdebugMessage("Calling SCIPlpiGetBInvCol (%d)\n", lpi->lpid);
4268 
4269  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
4270 
4271  /* set coefficient for slack variables to be 1 instead of -1 */
4272  MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_ON) );
4273 
4274  /* prepare basis in Mosek, since we do not need the basis ourselves, we set the return parameter to NULL */
4275  SCIP_CALL( handle_singular(lpi, NULL, MSK_initbasissolve(lpi->task, NULL)) );
4276 
4277  /* initialize rhs of system to be a dense +/- unit vector (needed for MSK_solvewithbasis()) */
4278  for (i = 0; i < nrows; ++i)
4279  coef[i] = 0.0;
4280  coef[c] = 1.0; /* unit vector e_c */
4281 
4282  /* check whether we require a dense or sparse result vector */
4283  if ( ninds != NULL && inds != NULL )
4284  {
4285  *ninds = 1;
4286  inds[0]= c;
4287 
4288 #if MSK_VERSION_MAJOR < 10
4289  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, ninds, inds, coef) );
4290 #else
4291  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, *ninds, inds, coef, ninds) );
4292 #endif
4293  assert( *ninds <= nrows );
4294  }
4295  else
4296  {
4297  int* sub;
4298  int numnz;
4299 
4300  SCIP_ALLOC( BMSallocMemoryArray(&sub, nrows) );
4301 
4302  numnz = 1;
4303  sub[0]= c;
4304 
4305 #if MSK_VERSION_MAJOR < 10
4306  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, &numnz, sub, coef) );
4307 #else
4308  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, numnz, sub, coef, &numnz) );
4309 #endif
4310  assert( numnz <= nrows );
4311 
4312  BMSfreeMemoryArray(&sub);
4313  }
4314  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
4315 
4316  return SCIP_OKAY;
4317 }
4318 
4319 /** get row of inverse basis matrix times constraint matrix B^-1 * A
4320  *
4321  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4322  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4323  * see also the explanation in lpi.h.
4324  *
4325  * @todo check that the result is in terms of the LP interface definition
4326  *
4327  * @todo check if this should invalidate the solution
4328  */
4330  SCIP_LPI* lpi, /**< LP interface structure */
4331  int row, /**< row number */
4332  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
4333  SCIP_Real* coef, /**< vector to return coefficients of the row */
4334  int* inds, /**< array to store the non-zero indices, or NULL */
4335  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4336  * (-1: if we do not store sparsity information) */
4337  )
4338 { /*lint --e{715}*/
4339  int nrows;
4340  int ncols;
4341  int numnz;
4342  int* csub;
4343  int didalloc = 0;
4344  double* cval;
4345  double* binv;
4346  int i;
4347  int k;
4348 
4349  assert(lpi != NULL);
4350  assert(lpi->mosekenv != NULL);
4351  assert(lpi->task != NULL);
4352  assert(coef != NULL);
4353  SCIP_UNUSED(inds);
4354 
4355  SCIPdebugMessage("Calling SCIPlpiGetBInvARow (%d)\n", lpi->lpid);
4356 
4357  /* currently only return dense result */
4358  if ( ninds != NULL )
4359  *ninds = -1;
4360 
4361  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
4362  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
4363 
4364  SCIP_ALLOC( BMSallocMemoryArray(&csub, nrows) );
4365  SCIP_ALLOC( BMSallocMemoryArray(&cval, nrows) );
4366 
4367  if( binvrow == NULL )
4368  {
4369  didalloc = 1;
4370 
4371  /* get dense vector */
4372  SCIP_ALLOC( BMSallocMemoryArray(&binv, nrows) );
4373  SCIP_CALL( SCIPlpiGetBInvRow(lpi, row, binv, NULL, NULL) );
4374  }
4375  else
4376  binv = (SCIP_Real*)binvrow;
4377 
4378  /* binvrow*A */
4379  for (i = 0; i < ncols; ++i)
4380  {
4381  MOSEK_CALL( MSK_getacol(lpi->task, i, &numnz, csub, cval) );
4382 
4383  /* compute dense vector */
4384  coef[i] = 0.0;
4385  for (k = 0; k < numnz; ++k)
4386  {
4387  assert( 0 <= csub[k] && csub[k] < nrows );
4388  coef[i] += binv[csub[k]] * cval[k];
4389  }
4390  }
4391 
4392  /* free memory arrays */
4393  BMSfreeMemoryArray(&cval);
4394  BMSfreeMemoryArray(&csub);
4395 
4396  if ( didalloc > 0 )
4397  {
4398  BMSfreeMemoryArray(&binv);
4399  }
4400 
4401  return SCIP_OKAY;
4402 }
4403 
4404 /** get column of inverse basis matrix times constraint matrix B^-1 * A
4405  *
4406  * @todo check if this should invalidate the solution
4407  */
4409  SCIP_LPI* lpi, /**< LP interface structure */
4410  int c, /**< column number */
4411  SCIP_Real* coef, /**< vector to return coefficients of the columnn */
4412  int* inds, /**< array to store the non-zero indices, or NULL */
4413  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4414  * (-1: if we do not store sparsity information) */
4415  )
4416 { /*lint --e{715}*/
4417  SCIP_Real* val;
4418  int nrows;
4419  int numnz;
4420  int i;
4421 
4422  assert(lpi != NULL);
4423  assert(lpi->mosekenv != NULL);
4424  assert(lpi->task != NULL);
4425  assert(coef != NULL);
4426 
4427  SCIPdebugMessage("Calling SCIPlpiGetBInvACol (%d)\n", lpi->lpid);
4428 
4429  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
4430  MOSEK_CALL( MSK_getacolnumnz(lpi->task, c, &numnz) );
4431  SCIP_ALLOC( BMSallocMemoryArray(&val, numnz+1) );
4432 
4433  /* set coefficient for slack variables to be 1 instead of -1 */
4434  MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_ON) );
4435 
4436  /* prepare basis in Mosek, since we do not need the basis ourselves, we set the return parameter to NULL */
4437  SCIP_CALL( handle_singular(lpi, NULL, MSK_initbasissolve(lpi->task, NULL)) );
4438 
4439  /* init coefficients */
4440  for (i = 0; i < nrows; ++i)
4441  coef[i] = 0.0;
4442 
4443  /* check whether we require a dense or sparse result vector */
4444  if ( ninds != NULL && inds != NULL )
4445  {
4446  /* fill column into dense vector */
4447  MOSEK_CALL( MSK_getacol(lpi->task, c, &numnz, inds, val) );
4448  for (i = 0; i < numnz; ++i)
4449  {
4450  assert( 0 <= inds[i] && inds[i] < nrows );
4451  coef[inds[i]] = val[i];
4452  }
4453 
4454  *ninds = numnz;
4455 
4456 #if MSK_VERSION_MAJOR < 10
4457  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, ninds, inds, coef) );
4458 #else
4459  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, *ninds, inds, coef, ninds) );
4460 #endif
4461  assert( *ninds <= nrows );
4462  }
4463  else
4464  {
4465  int* sub;
4466  SCIP_ALLOC( BMSallocMemoryArray(&sub, nrows) );
4467 
4468  /* fill column into dense vector */
4469  MOSEK_CALL( MSK_getacol(lpi->task, c, &numnz, sub, val) );
4470  for (i = 0; i < numnz; ++i)
4471  {
4472  assert( 0 <= sub[i] && sub[i] < nrows );
4473  coef[sub[i]] = val[i];
4474  }
4475 
4476 #if MSK_VERSION_MAJOR < 10
4477  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, &numnz, sub, coef) );
4478 #else
4479  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, numnz, sub, coef, &numnz) );
4480 #endif
4481 
4482  if ( ninds != NULL )
4483  *ninds = numnz;
4484 
4485  BMSfreeMemoryArray(&sub);
4486  }
4487 
4488  BMSfreeMemoryArray(&val);
4489  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
4490 
4491  return SCIP_OKAY;
4492 }
4493 
4494 
4495 /*
4496  * LP State Methods
4497  */
4498 
4499 /** creates LPi state information object */
4500 static
4502  SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
4503  BMS_BLKMEM* blkmem, /**< block memory */
4504  int ncols, /**< number of columns to store */
4505  int nrows /**< number of rows to store */
4506  )
4507 {
4508  assert(lpistate != NULL);
4509  assert(blkmem != NULL);
4510  assert(ncols >= 0);
4511  assert(nrows >= 0);
4512 
4513  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
4514  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->skx, colpacketNum(ncols)) );
4515  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->skc, rowpacketNum(nrows)) );
4516 
4517  (*lpistate)->solsta = MSK_SOL_STA_UNKNOWN;
4518  (*lpistate)->num = -1;
4519  (*lpistate)->ncols = ncols;
4520  (*lpistate)->nrows = nrows;
4521 
4522  return SCIP_OKAY;
4523 }
4524 
4525 /** frees LPi state information */
4526 static
4528  SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
4529  BMS_BLKMEM* blkmem /**< block memory */
4530  )
4531 {
4532  assert(blkmem != NULL);
4533  assert(lpistate != NULL);
4534  assert(*lpistate != NULL);
4535 
4536  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->skx, colpacketNum((*lpistate)->ncols));
4537  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->skc, rowpacketNum((*lpistate)->nrows));
4538  BMSfreeBlockMemory(blkmem, lpistate);
4539 }
4540 
4541 #ifndef NDEBUG
4542 /** check state
4543  *
4544  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
4545  */
4546 static
4548  SCIP_LPI* lpi, /**< LP interface structure */
4549  int n, /**< number of rows or columns */
4550  MSKstakeye* sk, /**< basis status */
4551  SCIP_Bool isrow /**< whether rows/columns are considered */
4552  )
4553 {
4554  char xc;
4555  int i;
4556 
4557  assert(lpi != NULL);
4558  assert(lpi->lastsolvetype == MSK_SOL_BAS);
4559 
4560 #ifdef SCIP_DEBUG
4561  if( !isrow )
4562  xc = 'x';
4563  else
4564  xc = 'c';
4565 #endif
4566 
4567  /* printout for all except LOW, UPR, FIX and BAS with sl[xc]==su[xc] */
4568  for( i = 0; i < n; i++ )
4569  {
4570  double sl;
4571  double su;
4572  switch (sk[i])
4573  {
4574  case MSK_SK_UNK:
4575  SCIPdebugMessage("STATE[%d]: %c[%d] = unk\n", lpi->optimizecount, xc, i);
4576  break;
4577  case MSK_SK_BAS:
4578  /* the following function is deprecated */
4579 #if MSK_VERSION_MAJOR < 9
4580  MOSEK_CALL( MSK_getsolutioni(lpi->task, isrow ? MSK_ACC_CON : MSK_ACC_VAR, i, MSK_SOL_BAS, NULL, NULL, &sl, &su, NULL) );
4581 #else
4582  if( isrow )
4583  {
4584  MOSEK_CALL( MSK_getslcslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
4585  MOSEK_CALL( MSK_getsucslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
4586  }
4587  else
4588  {
4589  MOSEK_CALL( MSK_getslxslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
4590  MOSEK_CALL( MSK_getsuxslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
4591  }
4592 #endif
4593  if (fabs(sl-su) > DEBUG_CHECK_STATE_TOL)
4594  {
4595  SCIPdebugMessage("STATE[%d]: %c[%d] = bas, sl%c = %g, su%c = %g\n", lpi->optimizecount, xc, i, xc, sl, xc, su);
4596  }
4597  break;
4598  case MSK_SK_SUPBAS:
4599  SCIPdebugMessage("STATE[%d]: %c[%d] = supbas\n", lpi->optimizecount, xc, i);
4600  break;
4601  case MSK_SK_LOW:
4602  case MSK_SK_UPR:
4603  case MSK_SK_FIX:
4604  break;
4605  case MSK_SK_INF:
4606  SCIPdebugMessage("STATE[%d]: %c[%d] = inf\n", lpi->optimizecount, xc, i);
4607  break;
4608  default:
4609  SCIPdebugMessage("STATE[%d]: %c[%d] = unknown status <%d>\n", lpi->optimizecount, xc, i, sk[i]);
4610  break;
4611  } /*lint !e788*/
4612  }
4613 
4614  return SCIP_OKAY;
4615 }
4616 
4617 /** check state
4618  *
4619  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
4620  */
4621 static
4623  SCIP_LPI* lpi, /**< LP interface structure */
4624  int ncols, /**< number of columns */
4625  int nrows /**< number of rows */
4626  )
4627 {
4628  assert(lpi != NULL);
4629  assert(lpi->lastsolvetype == MSK_SOL_BAS);
4630 
4631  SCIP_CALL( checkState1(lpi, ncols, lpi->skx, FALSE) );
4632  SCIP_CALL( checkState1(lpi, nrows, lpi->skc, TRUE) );
4633 
4634  return SCIP_OKAY;
4635  }
4636 #endif
4637 
4638 /** store row and column basis status in a packed LPi state object
4639  *
4640  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
4641  */
4642 static
4644  SCIP_LPI* lpi, /**< LP interface structure */
4645  SCIP_LPISTATE* lpistate /**< pointer to LPi state data */
4646  )
4647 {
4648  int *skxi = (int *) lpi->skx; /* Used as temp. buffer */
4649  int *skci = (int *) lpi->skc; /* Used as temp. buffer */
4650 
4651  assert(sizeof(int) == sizeof(MSKstakeye)); /*lint !e506*/
4652  assert(lpi != NULL);
4653  assert(lpistate != NULL);
4654  assert(lpi->lastsolvetype == MSK_SOL_BAS);
4655 
4656  SCIP_CALL( convertstat_mosek2scip(lpi, FALSE, lpi->skx, lpistate->ncols, skxi) );
4657  SCIP_CALL( convertstat_mosek2scip_slack(lpi, TRUE, lpi->skc, lpistate->nrows, skci) );
4658 
4659  SCIPencodeDualBit(skxi, lpistate->skx, lpistate->ncols);
4660  SCIPencodeDualBit(skci, lpistate->skc, lpistate->nrows);
4661 
4662  return SCIP_OKAY;
4663 }
4664 
4665 /** unpacks row and column basis status from a packed LPi state object */
4666 static
4668  const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
4669  MSKstakeye* skx, /**< basis status for columns */
4670  MSKstakeye* skc /**< basis status for rows */
4671  )
4672 {
4673  assert(sizeof(int) == sizeof(MSKstakeye)); /*lint !e506*/
4674 
4675  SCIPdecodeDualBit(lpistate->skx, (int*) skx, lpistate->ncols);
4676  SCIPdecodeDualBit(lpistate->skc, (int*) skc, lpistate->nrows);
4677 
4678  convertstat_scip2mosek((int*) skx, lpistate->ncols, skx);
4679  convertstat_scip2mosek_slack((int*) skc, lpistate->nrows, skc);
4680 }
4681 
4682 /** stores LP state (like basis information) into lpistate object
4683  *
4684  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
4685  */
4687  SCIP_LPI* lpi, /**< LP interface structure */
4688  BMS_BLKMEM* blkmem, /**< block memory */
4689  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
4690  )
4691 {
4692  int gotbasicsol;
4693  int nrows;
4694  int ncols;
4695 
4696  assert(lpi != NULL);
4697  assert(lpi->mosekenv != NULL);
4698  assert(lpi->task != NULL);
4699  assert(lpistate != NULL);
4700  assert(blkmem != NULL);
4701  assert(lpi->lastsolvetype == MSK_SOL_BAS);
4702 
4703  SCIPdebugMessage("Calling SCIPlpiGetState (%d)\n", lpi->lpid);
4704 
4705  *lpistate = NULL;
4706 
4707  MOSEK_CALL( MSK_solutiondef(lpi->task, MSK_SOL_BAS, &gotbasicsol) );
4708 
4709  if ( gotbasicsol == 0 || SCIPlpiExistsDualRay(lpi) || lpi->clearstate )
4710  return SCIP_OKAY;
4711 
4712  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
4713  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
4714 
4715  /* allocate lpistate data */
4716  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
4717 
4718  lpistate[0]->num = lpi->optimizecount;
4719 
4720  MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, NULL, &lpistate[0]->solsta) );
4721 
4722  SCIP_CALL( getbase(lpi, ncols, nrows) );
4723 
4724 #ifndef NDEBUG
4725  SCIP_CALL( checkState(lpi, ncols, nrows) );
4726 #endif
4727 
4728  SCIP_CALL( lpistatePack(lpi, lpistate[0]) );
4729 
4730  SCIPdebugMessage("Store into state from iter : %d\n", lpi->optimizecount);
4731 
4732  /* if (r != SCIP_OKAY)
4733  * lpistateFree(lpistate, blkmem );
4734  */
4735 
4736  return SCIP_OKAY;
4737 }
4738 
4739 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
4740  * columns and rows since the state was stored with SCIPlpiGetState()
4741  */
4743  SCIP_LPI* lpi, /**< LP interface structure */
4744  BMS_BLKMEM* blkmem, /**< block memory */
4745  const SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
4746  )
4747 { /*lint --e{715}*/
4748  int nrows;
4749  int ncols;
4750  int i;
4751 
4752  assert(lpi != NULL);
4753  assert(lpi->mosekenv != NULL);
4754  assert(lpi->task != NULL);
4755  assert(blkmem != NULL);
4756 #ifdef SCIP_DISABLED_CODE
4757  assert(lpi->lastsolvetype == MSK_SOL_BAS);
4758 #endif
4759 
4760  if (lpistate == NULL)
4761  {
4762  SCIPdebugMessage("Setting NULL state\n");
4763  return SCIP_OKAY;
4764  }
4765 
4766  if (lpistate->nrows == 0 || lpistate->ncols == 0)
4767  return SCIP_OKAY;
4768 
4769  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
4770  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
4771  assert(lpistate->nrows <= nrows);
4772  assert(lpistate->ncols <= ncols);
4773 
4774  SCIP_CALL( ensureStateMem(lpi, ncols, nrows) );
4775 
4776 #ifdef SCIP_DISABLED_CODE
4777  SCIP_CALL( getbase(lpi, ncols, nrows) ); /* Why do we need to get the basis ????? */
4778 #endif
4779 
4780  lpistateUnpack(lpistate, lpi->skx, lpi->skc);
4781 
4782  /* extend the basis to the current LP beyond the previously existing columns */
4783  for (i = lpistate->ncols; i < ncols; ++i)
4784  {
4785  SCIP_Real lb;
4786  SCIP_Real ub;
4787 #if MSK_VERSION_MAJOR < 9
4788  MOSEK_CALL( MSK_getboundslice(lpi->task, MSK_ACC_VAR, i, i, NULL, &lb, &ub) );
4789 #else
4790  MOSEK_CALL( MSK_getvarboundslice(lpi->task, i, i, NULL, &lb, &ub) );
4791 #endif
4792  if ( SCIPlpiIsInfinity(lpi, REALABS(lb)) )
4793  {
4794  /* if lower bound is +/- infinity -> try upper bound */
4795  if ( SCIPlpiIsInfinity(lpi, REALABS(ub)) )
4796  lpi->skx[i] = MSK_SK_SUPBAS; /* variable is free (super basic) */
4797  else
4798  lpi->skx[i] = MSK_SK_UPR; /* use finite upper bound */
4799  }
4800  else
4801  lpi->skx[i] = MSK_SK_LOW; /* use finite lower bound */
4802  }
4803  for (i = lpistate->nrows; i < nrows; ++i)
4804  lpi->skc[i] = MSK_SK_BAS;
4805 
4806  /* load basis information into MOSEK */
4807  SCIP_CALL( setbase(lpi) );
4808 
4809  invalidateSolution(lpi);
4810 
4811  SCIPdebugMessage("Store from state into task iter : %d with solsta : %d\n", lpistate->num, lpistate->solsta);
4812 
4813  return SCIP_OKAY;
4814 }
4815 
4816 /** clears current LPi state (like basis information) of the solver */
4818  SCIP_LPI* lpi /**< LP interface structure */
4819  )
4820 {
4821  assert(lpi != NULL);
4822  assert(lpi->mosekenv != NULL);
4823  assert(lpi->task != NULL);
4824 
4825  lpi->clearstate = TRUE;
4826 
4827  return SCIP_OKAY;
4828 }
4829 
4830 /** frees LP state information */
4832  SCIP_LPI* lpi, /**< LP interface structure */
4833  BMS_BLKMEM* blkmem, /**< block memory */
4834  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
4835  )
4836 { /*lint --e{715}*/
4837  assert(lpi != NULL);
4838  assert(lpi->mosekenv != NULL);
4839  assert(lpi->task != NULL);
4840  assert(lpistate != NULL);
4841  assert(blkmem != NULL);
4842 
4843  SCIPdebugMessage("Calling SCIPlpiFreeState (%d)\n", lpi->lpid);
4844 
4845  if( *lpistate != NULL )
4846  {
4847  lpistateFree(lpistate, blkmem);
4848  }
4849 
4850  return SCIP_OKAY;
4851 }
4852 
4853 /** checks, whether the given LP state contains simplex basis information */
4855  SCIP_LPI* lpi, /**< LP interface structure */
4856  SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
4857  )
4858 { /*lint --e{715}*/
4859  assert(lpi != NULL);
4860  assert(lpi->mosekenv != NULL);
4861  assert(lpi->task != NULL);
4862 
4863  SCIPdebugMessage("Calling SCIPlpiHasStateBasis (%d)\n", lpi->lpid);
4864 
4865  return ( lpistate != NULL && lpistate->num >= 0);
4866 }
4867 
4868 /** reads LP state (like basis information) from a file
4869  *
4870  * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
4871  */
4873  SCIP_LPI* lpi, /**< LP interface structure */
4874  const char* fname /**< file name */
4875  )
4876 {
4877  assert(lpi != NULL);
4878  assert(lpi->mosekenv != NULL);
4879  assert(lpi->task != NULL);
4880  assert(fname != NULL);
4881 
4882  SCIPdebugMessage("reading LP state from file <%s>\n", fname);
4883 
4884  lpi->clearstate = FALSE;
4885 
4886  MOSEK_CALL( MSK_readsolution(lpi->task, MSK_SOL_BAS, fname) );
4887 
4888  return SCIP_OKAY;
4889 }
4890 
4891 /** writes LPi state (i.e. basis information) to a file */
4893  SCIP_LPI* lpi, /**< LP interface structure */
4894  const char* fname /**< file name */
4895  )
4896 {
4897  int v;
4898  int nvars;
4899  int c = 0;
4900  int nconss;
4901  SCIP_Bool emptyname = FALSE;
4902  char name[SCIP_MAXSTRLEN];
4903 
4904  assert(lpi != NULL);
4905  assert(lpi->mosekenv != NULL);
4906  assert(lpi->task != NULL);
4907  assert(fname != NULL);
4908  assert(lpi->lastsolvetype == MSK_SOL_BAS);
4909 
4910  SCIPdebugMessage("writing LP state to file <%s>\n", fname);
4911 
4912  if( lpi->clearstate )
4913  {
4914  SCIPdebugMessage("No LP state written, since it was cleared after the last solve \n");
4915  return SCIP_OKAY;
4916  }
4917 
4918  /* If any rows or columns have empty names, MOSEK will make up names like C1 and X1, but will no
4919  * longer recognize them when reading the same state file back in, therefore we return an error in
4920  * this case
4921  */
4922  MOSEK_CALL( MSK_getnumvar(lpi->task, &nvars) );
4923  for( v = 0; v < nvars; v++ )
4924  {
4925  MOSEK_CALL( MSK_getvarname(lpi->task, v, SCIP_MAXSTRLEN, name) );
4926  if( strcmp(name, "") == 0 )
4927  {
4928  emptyname = TRUE;
4929  break;
4930  }
4931  }
4932  if( !emptyname )
4933  {
4934  MOSEK_CALL( MSK_getnumcon(lpi->task, &nconss) );
4935  for( c = 0; c < nconss; c++ )
4936  {
4937  MOSEK_CALL( MSK_getconname(lpi->task, c, SCIP_MAXSTRLEN, name) );
4938  if( strcmp(name, "") == 0 )
4939  {
4940  emptyname = TRUE;
4941  break;
4942  }
4943  }
4944  }
4945 
4946  if( emptyname )
4947  {
4948  SCIPmessagePrintWarning(lpi->messagehdlr, "Writing LP state with unnamed %s %d, using default"
4949  " names instead. Note that this state cannot be read back in later!\n",
4950  v < nvars ? "variable" : "constraint", v < nvars ? v : c);
4951  }
4952 
4953  /* set parameter to be able to write */
4954  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_HEAD, MSK_ON) );
4955  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_VARIABLES, MSK_ON) );
4956  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_CONSTRAINTS, MSK_ON) );
4957 
4958  MOSEK_CALL( MSK_writesolution(lpi->task, MSK_SOL_BAS, fname) );
4959 
4960  return SCIP_OKAY;
4961 }
4962 
4963 /**@} */
4964 
4965 /*
4966  * LP Pricing Norms Methods
4967  */
4968 
4969 /**@name LP Pricing Norms Methods */
4970 /**@{ */
4971 
4972 /** stores LPi pricing norms information
4973  * @todo should we store norm information?
4974  */
4976  SCIP_LPI* lpi, /**< LP interface structure */
4977  BMS_BLKMEM* blkmem, /**< block memory */
4978  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4979  )
4980 { /*lint --e{715}*/
4981  assert(lpi != NULL);
4982  assert(lpi->mosekenv != NULL);
4983  assert(lpi->task != NULL);
4984  assert(lpinorms != NULL);
4985  assert(blkmem != NULL);
4986 
4987  (*lpinorms) = NULL;
4988 
4989  return SCIP_OKAY;
4990 }
4991 
4992 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
4993  * columns and rows since the state was stored with SCIPlpiGetNorms()
4994  */
4996  SCIP_LPI* lpi, /**< LP interface structure */
4997  BMS_BLKMEM* blkmem, /**< block memory */
4998  const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
4999  )
5000 { /*lint --e{715}*/
5001  assert(lpi != NULL);
5002  SCIP_UNUSED(blkmem);
5003  assert(lpinorms == NULL);
5004 
5005  /* no work necessary */
5006  return SCIP_OKAY;
5007 }
5008 
5009 /** frees pricing norms information */
5011  SCIP_LPI* lpi, /**< LP interface structure */
5012  BMS_BLKMEM* blkmem, /**< block memory */
5013  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
5014  )
5015 { /*lint --e{715}*/
5016  assert(lpi != NULL);
5017  SCIP_UNUSED(blkmem);
5018  assert(lpinorms == NULL);
5019 
5020  /* no work necessary */
5021  return SCIP_OKAY;
5022 }
5023 
5024 /**@} */
5025 
5026 /*
5027  * Parameter Methods
5028  */
5029 
5030 /** constant array containing the parameter names */
5031 static const char* paramname[] = {
5032  "SCIP_LPPAR_FROMSCRATCH", /* solver should start from scratch at next call? */
5033  "SCIP_LPPAR_FASTMIP", /* fast mip setting of LP solver */
5034  "SCIP_LPPAR_SCALING", /* which scaling should LP solver use? */
5035  "SCIP_LPPAR_PRESOLVING", /* should LP solver use presolving? */
5036  "SCIP_LPPAR_PRICING", /* pricing strategy */
5037  "SCIP_LPPAR_LPINFO", /* should LP solver output information to the screen? */
5038  "SCIP_LPPAR_FEASTOL", /* feasibility tolerance for primal variables and slacks */
5039  "SCIP_LPPAR_DUALFEASTOL", /* feasibility tolerance for dual variables and reduced costs */
5040  "SCIP_LPPAR_BARRIERCONVTOL", /* convergence tolerance used in barrier algorithm */
5041  "SCIP_LPPAR_OBJLIM", /* objective limit (stop if objective is known be larger/smaller than limit for min/max-imization) */
5042  "SCIP_LPPAR_LPITLIM", /* LP iteration limit, greater than or equal 0 */
5043  "SCIP_LPPAR_LPTILIM", /* LP time limit, positive */
5044  "SCIP_LPPAR_MARKOWITZ", /* Markowitz tolerance */
5045  "SCIP_LPPAR_ROWREPSWITCH", /* simplex algorithm shall use row representation of the basis
5046  * if number of rows divided by number of columns exceeds this value */
5047  "SCIP_LPPAR_THREADS", /* number of threads used to solve the LP */
5048  "SCIP_LPPAR_CONDITIONLIMIT", /* maximum condition number of LP basis counted as stable */
5049  "SCIP_LPPAR_TIMING", /* type of timer (1 - cpu, 2 - wallclock, 0 - off) */
5050  "SCIP_LPPAR_RANDOMSEED", /* inital random seed, e.g. for perturbations in the simplex (0: LP default) */
5051  "SCIP_LPPAR_POLISHING", /* set solution polishing (0 - disable, 1 - enable) */
5052  "SCIP_LPPAR_REFACTOR" /* set refactorization interval (0 - automatic) */
5053 };
5054 
5055 /** method mapping parameter index to parameter name */
5056 static
5057 const char* paramty2str(
5058  SCIP_LPPARAM type
5059  )
5060 { /*lint --e{641}*/
5061  /* check whether the parameters are in the right order */
5062  /*lint --e{506}*/
5063  assert(SCIP_LPPAR_FROMSCRATCH == 0); /* solver should start from scratch at next call? */
5064  assert(SCIP_LPPAR_FASTMIP == 1); /* fast mip setting of LP solver */
5065  assert(SCIP_LPPAR_SCALING == 2); /* which scaling should LP solver use? */
5066  assert(SCIP_LPPAR_PRESOLVING == 3); /* should LP solver use presolving? */
5067  assert(SCIP_LPPAR_PRICING == 4); /* pricing strategy */
5068  assert(SCIP_LPPAR_LPINFO == 5); /* should LP solver output information to the screen? */
5069  assert(SCIP_LPPAR_FEASTOL == 6); /* feasibility tolerance for primal variables and slacks */
5070  assert(SCIP_LPPAR_DUALFEASTOL == 7); /* feasibility tolerance for dual variables and reduced costs */
5071  assert(SCIP_LPPAR_BARRIERCONVTOL == 8); /* convergence tolerance used in barrier algorithm */
5072  assert(SCIP_LPPAR_OBJLIM == 9); /* objective limit (stop if objective is known be larger/smaller than limit for min/max-imization) */
5073  assert(SCIP_LPPAR_LPITLIM == 10); /* LP iteration limit, greater than or equal 0 */
5074  assert(SCIP_LPPAR_LPTILIM == 11); /* LP time limit, positive */
5075  assert(SCIP_LPPAR_MARKOWITZ == 12); /* Markowitz tolerance */
5076  assert(SCIP_LPPAR_ROWREPSWITCH == 13); /* row representation switch */
5077  assert(SCIP_LPPAR_THREADS == 14); /* number of threads used to solve the LP */
5078  assert(SCIP_LPPAR_CONDITIONLIMIT == 15); /* maximum condition number of LP basis counted as stable */
5079  assert(SCIP_LPPAR_TIMING == 16); /* type of timer (1 - cpu, 2 - wallclock, 0 - off) */
5080  assert(SCIP_LPPAR_RANDOMSEED == 17); /* inital random seed, e.g. for perturbations in the simplex (0: LP default) */
5081  assert(SCIP_LPPAR_POLISHING == 18); /* set solution polishing (0 - disable, 1 - enable) */
5082  assert(SCIP_LPPAR_REFACTOR == 19); /* set refactorization interval (0 - automatic) */
5083 
5084  return paramname[type];
5085 }
5086 
5087 /** gets integer parameter of LP */
5089  SCIP_LPI* lpi, /**< LP interface structure */
5090  SCIP_LPPARAM type, /**< parameter number */
5091  int* ival /**< buffer to store the parameter value */
5092  )
5093 { /*lint --e{641}*/
5094  assert(lpi != NULL);
5095  assert(lpi->mosekenv != NULL);
5096  assert(lpi->task != NULL);
5097  assert(ival != NULL);
5098 
5099  SCIPdebugMessage("getting int parameter %s\n", paramty2str(type));
5100 
5101  switch (type)
5102  {
5103  case SCIP_LPPAR_FROMSCRATCH: /* solver should start from scratch at next call? */
5104  *ival = (int) lpi->fromscratch;
5105  break;
5106  case SCIP_LPPAR_FASTMIP: /* fast mip setting of LP solver */
5107  return SCIP_PARAMETERUNKNOWN;
5108  case SCIP_LPPAR_SCALING: /* should LP solver use scaling? */
5109  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_SCALING, ival) );
5110  if( *ival == MSK_SCALING_NONE )
5111  *ival = 0;
5112  else if( *ival == MSK_SCALING_FREE )
5113  *ival = 1;
5114 #if MSK_VERSION_MAJOR < 10
5115  else if( *ival == MSK_SCALING_AGGRESSIVE )
5116  *ival = 2;
5117 #endif
5118  else /* MSK_SCALING_MODERATE should not be used by the interface */
5119  return SCIP_PARAMETERWRONGVAL;
5120  break;
5121  case SCIP_LPPAR_PRESOLVING: /* should LP solver use presolving? */
5122  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, ival) );
5123  *ival = (*ival != MSK_PRESOLVE_MODE_OFF);
5124  break;
5125  case SCIP_LPPAR_PRICING: /* pricing strategy */
5126  *ival = lpi->pricing;
5127  break;
5128  case SCIP_LPPAR_LPINFO: /* should LP solver output information to the screen? */
5129  *ival = (int) lpi->lpinfo;
5130  break;
5131  case SCIP_LPPAR_LPITLIM: /* LP iteration limit */
5132  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, ival) );
5133  break;
5134  case SCIP_LPPAR_THREADS: /* number of threads */
5135  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_NUM_THREADS, ival) );
5136  break;
5137  case SCIP_LPPAR_REFACTOR: /* refactorization interval */
5138  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_REFACTOR_FREQ, ival) );
5139  break;
5140  default:
5141  return SCIP_PARAMETERUNKNOWN;
5142  } /*lint !e788*/
5143 
5144  return SCIP_OKAY;
5145 }
5146 
5147 /** sets integer parameter of LP */
5149  SCIP_LPI* lpi, /**< LP interface structure */
5150  SCIP_LPPARAM type, /**< parameter number */
5151  int ival /**< parameter value */
5152  )
5153 {
5154  static int pricing[7] =
5155  {
5156  (int)MSK_SIM_SELECTION_SE, /**< mosek pricing for SCIP_PRICING_LPIDEFAULT */
5157  (int)MSK_SIM_SELECTION_FREE, /**< mosek pricing for SCIP_PRICING_AUTO */
5158  (int)MSK_SIM_SELECTION_FULL, /**< mosek pricing for SCIP_PRICING_FULL */
5159  (int)MSK_SIM_SELECTION_PARTIAL, /**< mosek pricing for SCIP_PRICING_PARTIAL */
5160  (int)MSK_SIM_SELECTION_SE, /**< mosek pricing for SCIP_PRICING_STEEP */
5161  (int)MSK_SIM_SELECTION_ASE, /**< mosek pricing for SCIP_PRICING_STEEPQSTART */
5162  (int)MSK_SIM_SELECTION_DEVEX, /**< mosek pricing for SCIP_PRICING_DEVEX */
5163  };
5164 
5165  /*lint --e{506}*/
5166  assert((int)SCIP_PRICING_LPIDEFAULT == 0);
5167  assert((int)SCIP_PRICING_AUTO == 1);
5168  assert((int)SCIP_PRICING_FULL == 2);
5169  assert((int)SCIP_PRICING_PARTIAL == 3);
5170  assert((int)SCIP_PRICING_STEEP == 4);
5171  assert((int)SCIP_PRICING_STEEPQSTART == 5);
5172  assert((int)SCIP_PRICING_DEVEX == 6);
5173 
5174  assert(lpi != NULL);
5175  assert(lpi->mosekenv != NULL);
5176  assert(lpi->task != NULL);
5177 
5178  SCIPdebugMessage("Calling SCIPlpiSetIntpar (%d) Parameter=<%s> Value=<%d>\n", lpi->lpid, paramty2str(type), ival);
5179 
5180  switch (type)
5181  {
5182  case SCIP_LPPAR_FROMSCRATCH: /* solver should start from scratch at next call? */
5183  lpi->fromscratch = (SCIP_Bool) ival;
5184  break;
5185  case SCIP_LPPAR_FASTMIP: /* fast mip setting of LP solver */
5186  return SCIP_PARAMETERUNKNOWN;
5187  case SCIP_LPPAR_SCALING: /* should LP solver use scaling? */
5188 #if MSK_VERSION_MAJOR < 10
5189  assert( ival >= 0 && ival <= 2 );
5190 #else
5191  assert( ival >= 0 && ival <= 1 );
5192 #endif
5193  if( ival == 0 )
5194  {
5195  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, MSK_SCALING_NONE) );
5196  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_SCALING, MSK_SCALING_NONE) );
5197  }
5198 #if MSK_VERSION_MAJOR < 10
5199  else if( ival == 1 )
5200  {
5201  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, MSK_SCALING_FREE) );
5202  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_SCALING, MSK_SCALING_FREE) );
5203  }
5204  else
5205  {
5206  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, MSK_SCALING_AGGRESSIVE) );
5207  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_SCALING, MSK_SCALING_AGGRESSIVE) );
5208  }
5209 #else
5210  else
5211  {
5212  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, MSK_SCALING_FREE) );
5213  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_SCALING, MSK_SCALING_FREE) );
5214  }
5215 #endif
5216 
5217  break;
5218  case SCIP_LPPAR_PRESOLVING: /* should LP solver use presolving? */
5219  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_PRESOLVE_USE,
5220  ival ? MSK_PRESOLVE_MODE_FREE : MSK_PRESOLVE_MODE_OFF) );
5221  break;
5222  case SCIP_LPPAR_PRICING: /* pricing strategy */
5223  assert(ival >= 0 && ival <= (int)SCIP_PRICING_DEVEX);
5224  lpi->pricing = (SCIP_PRICING)ival;
5225 
5226  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_SELECTION, pricing[ival]) );
5227  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, pricing[ival]) );
5228 
5229  /* for certain pricing values, do not use restricted pricing */
5230  if( lpi->pricing == SCIP_PRICING_PARTIAL || lpi->pricing == SCIP_PRICING_AUTO )
5231  lpi->restrictselectdef = 50;
5232  else
5233  lpi->restrictselectdef = 0;
5234 
5235  break;
5236  case SCIP_LPPAR_LPINFO:
5237  /* should LP solver output information to the screen? */
5238 #if FORCE_MOSEK_LOG
5239  SCIPdebugMessage("Ignoring log setting!\n");
5240 #else
5241  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, ival ? 4 : MSK_OFF) );
5242  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG_SIM, ival ? 4 : MSK_OFF) );
5243 #endif
5244  lpi->lpinfo = (SCIP_Bool) ival;
5245  break;
5246  case SCIP_LPPAR_LPITLIM: /* LP iteration limit */
5247 #if DEBUG_PARAM_SETTING
5248  if( ival )
5249  {
5250  SCIPdebugMessage("Setting max iter to : %d\n", ival);
5251  }
5252 #endif
5253  /* 0 <= ival, 0 stopping immediately */
5254  assert( ival >= 0 );
5255  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, ival) );
5256  break;
5257  case SCIP_LPPAR_THREADS: /* number of threads (0 => MOSEK chooses) */
5258  assert(ival >= 0);
5259  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_NUM_THREADS, ival) );
5260  break;
5261  case SCIP_LPPAR_REFACTOR: /* refactorization interval */
5262  assert(ival >= 0);
5263  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_REFACTOR_FREQ, ival) );
5264  break;
5265  default:
5266  return SCIP_PARAMETERUNKNOWN;
5267  } /*lint !e788*/
5268 
5269  return SCIP_OKAY;
5270 }
5271 
5272 /** gets floating point parameter of LP */
5274  SCIP_LPI* lpi, /**< LP interface structure */
5275  SCIP_LPPARAM type, /**< parameter number */
5276  SCIP_Real* dval /**< buffer to store the parameter value */
5277  )
5278 {
5279  assert(lpi != NULL);
5280  assert(lpi->mosekenv != NULL);
5281  assert(lpi->task != NULL);
5282  assert(dval != NULL);
5283 
5284  SCIPdebugMessage("getting real parameter %s\n", paramty2str(type));
5285 
5286  switch (type)
5287  {
5288  case SCIP_LPPAR_FEASTOL: /* feasibility tolerance for primal variables and slacks */
5289  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_BASIS_TOL_X, dval) );
5290  break;
5291  case SCIP_LPPAR_DUALFEASTOL: /* feasibility tolerance for dual variables and reduced costs */
5292  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_BASIS_TOL_S, dval) );
5293  break;
5294  case SCIP_LPPAR_BARRIERCONVTOL: /* convergence tolerance used in barrier algorithm */
5295  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_INTPNT_TOL_REL_GAP, dval) );
5296  break;
5297  case SCIP_LPPAR_OBJLIM: /* objective limit */
5298  {
5299  MSKobjsensee objsen;
5300  MOSEK_CALL( MSK_getobjsense(lpi->task, &objsen) );
5301  if (objsen == MSK_OBJECTIVE_SENSE_MINIMIZE)
5302  {
5303  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, dval) );
5304  }
5305  else /* objsen == MSK_OBJECTIVE_SENSE_MAX */
5306  {
5307  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, dval) );
5308  }
5309  break;
5310  }
5311  case SCIP_LPPAR_LPTILIM: /* LP time limit */
5312  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_OPTIMIZER_MAX_TIME, dval) );
5313  break;
5314  case SCIP_LPPAR_MARKOWITZ: /* Markowitz tolerance */
5315  default:
5316  return SCIP_PARAMETERUNKNOWN;
5317  } /*lint !e788*/
5318 
5319  return SCIP_OKAY;
5320 }
5321 
5322 /** sets floating point parameter of LP */
5324  SCIP_LPI* lpi, /**< LP interface structure */
5325  SCIP_LPPARAM type, /**< parameter number */
5326  SCIP_Real dval /**< parameter value */
5327  )
5328 {
5329  assert(lpi != NULL);
5330  assert(lpi->mosekenv != NULL);
5331  assert(lpi->task != NULL);
5332 
5333  SCIPdebugMessage("setting real parameter %s to %g\n", paramty2str(type), dval);
5334 
5335  /**@todo Limits shouldn't be hardcoded */
5336 
5337  switch (type)
5338  {
5339  case SCIP_LPPAR_FEASTOL: /* feasibility tolerance for primal variables and slacks */
5340  assert( dval > 0.0 );
5341  /* 1e-9 <= dval <= inf */
5342  if( dval < 1e-9 )
5343  dval = 1e-9;
5344 
5345  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_BASIS_TOL_X, dval) );
5346  break;
5347  case SCIP_LPPAR_DUALFEASTOL: /* feasibility tolerance for dual variables and reduced costs */
5348  assert( dval > 0.0 );
5349  /* 1e-9 <= dval <= inf */
5350  if( dval < 1e-9 )
5351  dval = 1e-9;
5352 
5353  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_BASIS_TOL_S, dval) );
5354  break;
5355  case SCIP_LPPAR_BARRIERCONVTOL: /* convergence tolerance used in barrier algorithm */
5356  /* 1e-14 <= dval <= inf */
5357  assert( dval >= 0.0 );
5358  if( dval < 1e-14 )
5359  dval = 1e-14;
5360 
5361  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_INTPNT_TOL_REL_GAP, dval) );
5362  break;
5363  case SCIP_LPPAR_OBJLIM: /* objective limit */
5364  {
5365  /* no restriction on dval */
5366  MSKobjsensee objsen;
5367  MOSEK_CALL( MSK_getobjsense(lpi->task, &objsen) );
5368  if (objsen == MSK_OBJECTIVE_SENSE_MINIMIZE)
5369  {
5370  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, dval) );
5371  }
5372  else /* objsen == MSK_OBJECTIVE_SENSE_MAX */
5373  {
5374  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, dval) );
5375  }
5376  break;
5377  }
5378  case SCIP_LPPAR_LPTILIM: /* LP time limit */
5379  assert( dval > 0.0 );
5380  /* mosek requires 0 <= dval
5381  *
5382  * However for consistency we assert the timelimit to be strictly positive.
5383  */
5384  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_OPTIMIZER_MAX_TIME, dval) );
5385  break;
5386  case SCIP_LPPAR_MARKOWITZ: /* Markowitz tolerance */
5387  default:
5388  return SCIP_PARAMETERUNKNOWN;
5389  } /*lint !e788*/
5390 
5391  return SCIP_OKAY;
5392 }
5393 
5394 /** interrupts the currently ongoing lp solve or disables the interrupt */
5396  SCIP_LPI* lpi, /**< LP interface structure */
5397  SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
5398  )
5399 {
5400  /*lint --e{715}*/
5401  assert(lpi != NULL);
5402 
5403  return SCIP_OKAY;
5404 }
5405 
5406 
5407 /*
5408  * Numerical Methods
5409  */
5410 
5411 
5412 /** returns value treated as infinity in the LP solver */
5414  SCIP_LPI* lpi /**< LP interface structure */
5415  )
5416 { /*lint --e{715}*/
5417  assert(lpi != NULL);
5418  assert(lpi->mosekenv != NULL);
5419  assert(lpi->task != NULL);
5420 
5421  return MSK_INFINITY;
5422 }
5423 
5424 /** checks if given value is treated as infinity in the LP solver */
5426  SCIP_LPI* lpi, /**< LP interface structure */
5427  SCIP_Real val /**< value to be checked for infinity */
5428  )
5429 { /*lint --e{715}*/
5430  assert(lpi != NULL);
5431  assert(lpi->mosekenv != NULL);
5432  assert(lpi->task != NULL);
5433 
5434  return IS_POSINF(val);
5435 }
5436 
5437 
5438 /*
5439  * File Interface Methods
5440  */
5441 
5442 
5443 /** reads LP from a file */
5445  SCIP_LPI* lpi, /**< LP interface structure */
5446  const char* fname /**< file name */
5447  )
5448 {
5449 #if MSK_VERSION_MAJOR < 9
5450  int olddataformat;
5451 #endif
5452 
5453  assert(lpi != NULL);
5454  assert(lpi->mosekenv != NULL);
5455  assert(lpi->task != NULL);
5456  assert(fname != NULL);
5457 
5458  SCIPdebugMessage("Calling SCIPlpiReadLP (%d), filename <%s>\n", lpi->lpid, fname);
5459 
5460 #if MSK_VERSION_MAJOR < 9
5461  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, &olddataformat) );
5462  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, MSK_DATA_FORMAT_LP) );
5463  MOSEK_CALL( MSK_readdata(lpi->task, fname) );
5464  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, olddataformat) );
5465 #else
5466  MOSEK_CALL( MSK_readdataformat(lpi->task, fname, MSK_DATA_FORMAT_LP, MSK_COMPRESS_FREE) );
5467 #endif
5468 
5469  return SCIP_OKAY;
5470 }
5471 
5472 /** writes LP to a file */
5474  SCIP_LPI* lpi, /**< LP interface structure */
5475  const char* fname /**< file name */
5476  )
5477 {
5478 #if MSK_VERSION_MAJOR < 9
5479  int olddataformat;
5480 #endif
5481 
5482  assert(lpi != NULL);
5483  assert(lpi->mosekenv != NULL);
5484  assert(lpi->task != NULL);
5485  assert(fname != NULL);
5486 #if MSK_VERSION_MAJOR >= 9
5487  /* Mosek 9 derives file format from given filename */
5488  assert(strstr(fname, ".lp") != NULL);
5489 #endif
5490 
5491  SCIPdebugMessage("Calling SCIPlpiWriteLP (%d), filename <%s>\n", lpi->lpid, fname);
5492 
5493 #if MSK_VERSION_MAJOR < 9
5494  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, &olddataformat) );
5495  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, MSK_DATA_FORMAT_LP) );
5496  MOSEK_CALL( MSK_writedata(lpi->task, fname) );
5497  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, olddataformat) );
5498 #else
5499  MOSEK_CALL( MSK_writedata(lpi->task, fname) );
5500 #endif
5501 
5502  return SCIP_OKAY;
5503 }
static SCIP_RETCODE ensureBkxMem(SCIP_LPI *lpi, int ncols)
Definition: lpi_msk.c:390
ROWPACKET * skc
Definition: lpi_msk.c:195
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_msk.c:4246
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_msk.c:1735
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
Definition: type_lpi.h:95
COLPACKET * skx
Definition: lpi_msk.c:194
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_msk.c:913
static void scale_bound(MSKboundkeye *bk, double *bl, double *bu, double s)
Definition: lpi_msk.c:623
int restrictselectdef
Definition: lpi_msk.c:178
static void invalidateSolution(SCIP_LPI *lpi)
Definition: lpi_msk.c:447
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_msk.c:4742
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_msk.c:5425
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:141
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_msk.c:3440
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_msk.c:4995
int nrows
Definition: lpi_none.c:43
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_msk.c:3755
static SCIP_RETCODE checkState1(SCIP_LPI *lpi, int n, MSKstakeye *sk, SCIP_Bool isrow)
Definition: lpi_msk.c:4547
SCIP_PRICING pricing
Definition: lpi_clp.cpp:103
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_msk.c:2811
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_msk.c:3629
static SCIP_RETCODE ensureBkcMem(SCIP_LPI *lpi, int nrows)
Definition: lpi_msk.c:409
static SCIP_RETCODE ensureAptreMem(SCIP_LPI *lpi, int n)
Definition: lpi_msk.c:428
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_msk.c:5148
#define SCIP_MAXSTRLEN
Definition: def.h:293
enum SCIP_ObjSen SCIP_OBJSEN
Definition: type_lpi.h:36
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_msk.c:2506
MSKenv_t mosekenv
Definition: lpi_msk.c:155
static long bound
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_msk.c:764
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_msk.c:4054
SCIP_Bool solved
Definition: lpi_clp.cpp:105
void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
Definition: bitencode.c:299
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_msk.c:1486
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_msk.c:5088
interface methods for specific LP solvers
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_msk.c:3774
static void convertstat_scip2mosek_slack(const int *stat, int n, MSKstakeye *resstat)
Definition: lpi_msk.c:4019
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_msk.c:1771
#define FALSE
Definition: def.h:87
int bkxsize
Definition: lpi_msk.c:170
#define EPSEQ(x, y, eps)
Definition: def.h:202
static SCIP_RETCODE convertstat_mosek2scip_slack(SCIP_LPI *lpi, SCIP_Bool iscon, MSKstakeye *sk, int m, int *stat)
Definition: lpi_msk.c:3921
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
static SCIP_RETCODE getASlice(SCIP_LPI *lpi, SCIP_Bool iscon, int first, int last, int *nnonz, int *beg, int *ind, double *val)
Definition: lpi_msk.c:1790
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_msk.c:5323
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_msk.c:3332
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_msk.c:4975
#define IS_NEGINF(x)
Definition: lpi_msk.c:86
#define SCIP_UNUSED(x)
Definition: def.h:438
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:64
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_msk.c:1753
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:116
static void MSKAPI printstr(MSKuserhandle_t handle, const char *str)
Definition: lpi_msk.c:253
MSKoptimizertype lastalgo
Definition: lpi_msk.c:162
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_msk.c:4872
#define SCIPdebugMessage
Definition: pub_message.h:87
SCIP_Bool SCIPlpiHasDualSolve(void)
Definition: lpi_msk.c:799
MSKsolstae solsta
Definition: lpi_msk.c:191
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_msk.c:2038
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_msk.c:1403
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_msk.c:3796
#define SETBACK_LIMIT
Definition: lpi_msk.c:118
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_msk.c:1668
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_msk.c:1996
#define BMSfreeMemory(ptr)
Definition: memory.h:138
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_msk.c:776
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:77
int lpid
Definition: lpi_msk.c:161
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_msk.c:4817
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_msk.c:1865
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_msk.c:825
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int row, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_msk.c:4329
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_msk.c:1047
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_msk.c:3350
#define mskname
Definition: lpi_msk.c:739
SCIP_DUALPACKET COLPACKET
Definition: lpi_clp.cpp:117
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_msk.c:3557
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_msk.c:2578
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_msk.c:3506
int skcsize
Definition: lpi_msk.c:169
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_msk.c:1229
SCIP_DUALPACKET COLPACKET
Definition: lpi_msk.c:182
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_msk.c:5473
packing single and dual bit values
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:140
static SCIP_RETCODE checkState(SCIP_LPI *lpi, int ncols, int nrows)
Definition: lpi_msk.c:4622
enum MSKoptimizertype_enum MSKoptimizertype
Definition: lpi_msk.c:58
#define SCIPerrorMessage
Definition: pub_message.h:55
int ncols
Definition: lpi_none.c:44
#define SCIPdebugPrintf
Definition: pub_message.h:90
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_msk.c:4123
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_msk.c:3123
static void convertstat_scip2mosek(const int *stat, int n, MSKstakeye *resstat)
Definition: lpi_msk.c:3988
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_msk.c:4831
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_msk.c:3367
SCIP_DUALPACKET ROWPACKET
Definition: lpi_clp.cpp:119
static SCIP_RETCODE handle_singular(SCIP_LPI *lpi, int *basis, MSKrescodee res)
Definition: lpi_msk.c:3815
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_msk.c:1946
static SCIP_RETCODE presolve(SCIP *scip, SCIP_Bool *unbounded, SCIP_Bool *infeasible, SCIP_Bool *vanished)
Definition: scip_solve.c:1242
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_msk.c:3099
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:418
#define NULL
Definition: lpi_spx1.cpp:155
int skxsize
Definition: lpi_msk.c:168
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_msk.c:3187
int * rstat
Definition: lpi_clp.cpp:99
#define REALABS(x)
Definition: def.h:201
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_msk.c:756
static SCIP_RETCODE setbase(SCIP_LPI *lpi)
Definition: lpi_msk.c:714
int bkcsize
Definition: lpi_msk.c:171
#define DEBUG_CHECK_STATE_TOL
Definition: lpi_msk.c:110
int optimizecount
Definition: lpi_msk.c:157
MSKtask_t task
Definition: lpi_msk.c:156
#define SCIP_CALL(x)
Definition: def.h:384
SCIP_Bool SCIPlpiHasBarrierSolve(void)
Definition: lpi_msk.c:807
SCIP_Bool fromscratch
Definition: lpi_cpx.c:161
static SCIP_RETCODE getbase(SCIP_LPI *lpi, int ncols, int nrows)
Definition: lpi_msk.c:695
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_msk.c:3249
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:585
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_msk.c:4527
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_msk.c:5010
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_msk.c:1308
static SCIP_RETCODE getEndptrs(int n, const int *beg, int nnonz, MSKint32t *aptre)
Definition: lpi_msk.c:509
void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: bitencode.c:229
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_msk.c:5444
MSKstakeye * skx
Definition: lpi_msk.c:163
#define EPSCEIL(x, eps)
Definition: def.h:211
SCIP_Bool lpinfo
Definition: lpi_msk.c:177
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_msk.c:3230
MSKsoltypee lastsolvetype
Definition: lpi_msk.c:173
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:458
static SCIP_RETCODE convertstat_mosek2scip(SCIP_LPI *lpi, SCIP_Bool iscon, MSKstakeye *sk, int n, int *stat)
Definition: lpi_msk.c:3845
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_msk.c:3309
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:33
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_msk.c:3596
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_msk.c:1344
static void scale_vec(int len, double *vec, double s)
Definition: lpi_msk.c:608
#define SCIP_ABORT_FALSE(x)
Definition: lpi_msk.c:73
static SCIP_RETCODE ensureStateMem(SCIP_LPI *lpi, int ncols, int nrows)
Definition: lpi_msk.c:666
#define MOSEK_CALL(x)
Definition: lpi_msk.c:60
#define SCIP_Bool
Definition: def.h:84
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_msk.c:4854
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_msk.c:1136
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:447
static const char * paramty2str(SCIP_LPPARAM type)
Definition: lpi_msk.c:5057
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_msk.c:4892
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_msk.c:5413
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_msk.c:1527
static const char * paramname[]
Definition: lpi_msk.c:5031
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_msk.c:3464
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_msk.c:4686
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_msk.c:3452
MSKint32t * aptre
Definition: lpi_msk.c:167
static void generateMskBoundkeys(int n, const double *lb, const double *ub, MSKboundkeye *bk)
Definition: lpi_msk.c:458
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:460
#define MAX(x, y)
Definition: tclique_def.h:83
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, MSKstakeye *skx, MSKstakeye *skc)
Definition: lpi_msk.c:4667
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_msk.c:1971
static SCIP_RETCODE getIndicesFromDense(int *dstat, int n, int *count, int **sub)
Definition: lpi_msk.c:565
MSKrescodee termcode
Definition: lpi_msk.c:158
static SCIP_RETCODE SolveWSimplex(SCIP_LPI *lpi)
Definition: lpi_msk.c:2185
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_msk.c:4089
#define IS_POSINF(x)
Definition: lpi_msk.c:85
int iterations
Definition: lpi_cpx.c:157
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_msk.c:3482
static MSKrescodee filterTRMrescode(SCIP_MESSAGEHDLR *messagehdlr, MSKrescodee *termcode, MSKrescodee res)
Definition: lpi_msk.c:2151
SCIP_Bool SCIPlpiHasPrimalSolve(void)
Definition: lpi_msk.c:791
static int rowpacketNum(int nrows)
Definition: lpi_msk.c:244
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_msk.c:1428
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_msk.c:3545
SCIP_Real * r
Definition: circlepacking.c:50
SCIP_RETCODE SCIPlpiGetRows(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhs, SCIP_Real *rhs, int *nnonz, int *beg, int *ind, SCIP_Real *val)
Definition: lpi_msk.c:1903
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_msk.c:3163
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_msk.c:2645
MSKstakeye * skc
Definition: lpi_msk.c:164
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_msk.c:3736
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_msk.c:2824
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_msk.c:953
static SCIP_RETCODE SCIPlpiStrongbranch(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_msk.c:2841
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_msk.c:1606
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_msk.c:2067
static SCIP_RETCODE getSolutionStatus(SCIP_LPI *lpi, MSKprostae *prosta, MSKsolstae *solsta)
Definition: lpi_msk.c:2134
#define STRONGBRANCH_PRICING
Definition: lpi_msk.c:119
#define ROWS_PER_PACKET
Definition: lpi_msk.c:185
static MSKrescodee MSK_getsolutionstatus(MSKtask_t task, MSKsoltypee whichsol, MSKprostae *prosta, MSKsolstae *solsta)
Definition: lpi_msk.c:208
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_msk.c:3422
static MSKenv_t reusemosekenv
Definition: lpi_msk.c:97
public methods for message output
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_msk.c:4408
SCIP_DUALPACKET ROWPACKET
Definition: lpi_msk.c:184
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_msk.c:2017
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_msk.c:3521
static int colpacketNum(int ncols)
Definition: lpi_msk.c:235
SCIP_Bool clearstate
Definition: lpi_cpx.c:162
#define SCIP_Real
Definition: def.h:177
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_msk.c:3379
#define BMSallocMemory(ptr)
Definition: memory.h:111
#define SCIP_INVALID
Definition: def.h:197
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:120
static SCIP_RETCODE getIndicesRange(int first, int last, int **sub)
Definition: lpi_msk.c:543
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_msk.c:1575
int aptresize
Definition: lpi_msk.c:172
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_msk.c:3399
SCIP_MESSAGEHDLR * messagehdlr
Definition: lpi_cpx.c:175
#define COLS_PER_PACKET
Definition: lpi_msk.c:183
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:444
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition: lpi_msk.c:5395
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_msk.c:3533
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_msk.c:2100
#define SENSE2MOSEK(objsen)
Definition: lpi_msk.c:56
#define EPSFLOOR(x, eps)
Definition: def.h:210
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
Definition: lpi_msk.c:4501
MSKboundkeye * bkx
Definition: lpi_msk.c:165
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:430
static SCIP_RETCODE lpistatePack(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_msk.c:4643
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
Definition: lpi_msk.c:1556
int itercount
Definition: lpi_msk.c:159
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_msk.c:4163
#define SCIP_ALLOC(x)
Definition: def.h:395
#define SCIPABORT()
Definition: def.h:356
MSKboundkeye * bkc
Definition: lpi_msk.c:166
const char * SCIPlpiGetSolverName(void)
Definition: lpi_msk.c:748
char name[200]
Definition: lpi_xprs.c:81
int * cstat
Definition: lpi_clp.cpp:98
#define DEGEN_LEVEL
Definition: lpi_msk.c:127
static int numlp
Definition: lpi_msk.c:98
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_msk.c:3578
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_msk.c:5273
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_msk.c:1170