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