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 */
3487  SCIP_LPI* lpi, /**< LP interface structure */
3488  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3489  * you have to call SCIPlpiGetBasisInd() to get the array which links the
3490  * B^-1 column numbers to the row and column numbers of the LP!
3491  * c must be between 0 and nrows-1, since the basis has the size
3492  * nrows * nrows */
3493  SCIP_Real* coef /**< pointer to store the coefficients of the column */
3494  )
3495 {
3496  int* sub;
3497  int nrows;
3498  int numnz;
3499  int i;
3500 
3501  SCIPdebugMessage("Calling SCIPlpiGetBInvCol (%d)\n",lpi->lpid);
3502 
3503  assert(MosekEnv != NULL);
3504  assert(lpi != NULL);
3505  assert(lpi->task != NULL);
3506 
3507  MOSEK_CALL( MSK_getnumcon(lpi->task,&nrows) );
3508  SCIP_ALLOC( BMSallocMemoryArray( &sub, nrows) );
3509 
3510  for (i=0; i<nrows; i++)
3511  coef[i] = 0;
3512 
3513  numnz = 1;
3514  sub[0]= c;
3515  coef[c] = 1; /* Unit vector e_col */
3516 
3517  MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_OFF) );
3518  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, &numnz, sub, coef) );
3519 
3520  BMSfreeMemoryArray(&sub);
3521  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
3522 
3523  return SCIP_OKAY;
3524 }
3525 
3526 /** get dense column of inverse basis matrix times constraint matrix B^-1 * A */
3528  SCIP_LPI* lpi, /**< LP interface structure */
3529  int c, /**< column number */
3530  SCIP_Real* coef /**< vector to return coefficients */
3531  )
3532 { /*lint --e{715}*/
3533  SCIP_Real* val;
3534  int* sub;
3535  int nrows;
3536  int numnz;
3537  int i;
3538 
3539  SCIPdebugMessage("Calling SCIPlpiGetBInvACol (%d)\n",lpi->lpid);
3540 
3541  assert(MosekEnv != NULL);
3542  assert(lpi != NULL);
3543  assert(lpi->task != NULL);
3544 
3545  MOSEK_CALL( MSK_getnumcon(lpi->task,&nrows) );
3546 #if MSK_VERSION_MAJOR < 7
3547  MOSEK_CALL( MSK_getavecnumnz(lpi->task,MSK_ACC_VAR,c,&numnz) );
3548 #else
3549  MOSEK_CALL( MSK_getacolnumnz(lpi->task,c,&numnz) );
3550 #endif
3551  SCIP_ALLOC( BMSallocMemoryArray( &sub, nrows) );
3552  SCIP_ALLOC( BMSallocMemoryArray( &val, numnz+1) );
3553 
3554  for (i=0; i<nrows; i++)
3555  coef[i] = 0;
3556 
3557 #if MSK_VERSION_MAJOR < 7
3558  MOSEK_CALL( MSK_getavec(lpi->task, MSK_ACC_VAR, c, &numnz, sub, val) );
3559 #else
3560  MOSEK_CALL( MSK_getacol(lpi->task, c, &numnz, sub, val) );
3561 #endif
3562 
3563  for (i=0; i<numnz; i++)
3564  coef[sub[i]] = val[i];
3565 
3566  MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_OFF) );
3567  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, &numnz, sub, coef) );
3568 
3569  BMSfreeMemoryArray(&sub);
3570  BMSfreeMemoryArray(&val);
3571  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
3572 
3573  return SCIP_OKAY;
3574 }
3575 
3576 
3577 /** get dense row of inverse basis matrix B^-1 */
3579  SCIP_LPI* lpi, /**< LP interface structure */
3580  int row, /**< row number */
3581  SCIP_Real* coef /**< pointer to store the coefficients of the row */
3582  )
3583 {
3584  int* sub;
3585  int nrows;
3586  int numnz;
3587  int i;
3588 
3589  assert(MosekEnv != NULL);
3590  assert(lpi != NULL);
3591  assert(lpi->task != NULL);
3592 
3593  SCIPdebugMessage("Calling SCIPlpiGetBInvRow (%d)\n",lpi->lpid);
3594 
3595  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
3596  SCIP_ALLOC( BMSallocMemoryArray( &sub, nrows) );
3597 
3598  for (i=0; i<nrows; i++)
3599  coef[i] = 0;
3600 
3601  numnz = 1;
3602  sub[0] = row;
3603  coef[row] = 1; /* Unit vector e_row */
3604 
3605  MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_ON) );
3606  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, &numnz, sub, coef) );
3607 
3608  BMSfreeMemoryArray(&sub);
3609 
3610  SCIPdebugMessage("End SCIPlpiGetBInvRow (%d)\n",lpi->lpid);
3611 
3612  return SCIP_OKAY;
3613 }
3614 
3615 /** get dense row of inverse basis matrix times constraint matrix B^-1 * A */
3617  SCIP_LPI* lpi, /**< LP interface structure */
3618  int row, /**< row number */
3619  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3620  SCIP_Real* val /**< vector to return coefficients */
3621  )
3622 {
3623  int nrows;
3624  int ncols;
3625  int numnz;
3626  int* csub;
3627  int didalloc;
3628  double* cval;
3629  double* binv;
3630  int i;
3631  int k;
3632 
3633  assert(MosekEnv != NULL);
3634  assert(lpi != NULL);
3635  assert(lpi->task != NULL);
3636 
3637  SCIPdebugMessage("Calling SCIPlpiGetBInvARow (%d)\n",lpi->lpid);
3638 
3639  didalloc = 0;
3640 
3641  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
3642  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
3643 
3644  SCIP_ALLOC( BMSallocMemoryArray(&csub, nrows) );
3645  SCIP_ALLOC( BMSallocMemoryArray(&cval, nrows) );
3646 
3647  for( i = 0; i < ncols; i++ )
3648  val[i] = 0;
3649 
3650  if( binvrow == NULL )
3651  {
3652  didalloc = 1;
3653 
3654  SCIP_ALLOC( BMSallocMemoryArray( &binv, nrows) );
3655  SCIP_CALL( SCIPlpiGetBInvRow(lpi, row, binv) );
3656  }
3657  else
3658  binv = (SCIP_Real*)binvrow;
3659 
3660  /* binvrow*A */
3661  for( i = 0; i < ncols; i++)
3662  {
3663  val[i] = 0;
3664 
3665 #if MSK_VERSION_MAJOR < 7
3666  MOSEK_CALL( MSK_getavec(lpi->task, MSK_ACC_VAR, i, &numnz, csub, cval) );
3667 #else
3668  MOSEK_CALL( MSK_getacol(lpi->task, i, &numnz, csub, cval) );
3669 #endif
3670 
3671  for( k = 0; k < numnz; ++k )
3672  val[i] += binv[csub[k]] * cval[k];
3673  }
3674 
3675  /* free memory arrays */
3676  BMSfreeMemoryArray(&cval);
3677  BMSfreeMemoryArray(&csub);
3678 
3679  if( didalloc > 0 )
3680  {
3681  BMSfreeMemoryArray(&binv);
3682  }
3683 
3684  return SCIP_OKAY;
3685 }
3686 
3687 /*
3688  * LP State Methods
3689  */
3690 
3691 /** creates LPi state information object */
3692 static
3693 SCIP_RETCODE lpistateCreate(
3694  SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
3695  BMS_BLKMEM* blkmem, /**< block memory */
3696  int ncols, /**< number of columns to store */
3697  int nrows /**< number of rows to store */
3698  )
3699 {
3700  assert(lpistate != NULL);
3701  assert(blkmem != NULL);
3702  assert(ncols >= 0);
3703  assert(nrows >= 0);
3704 
3705  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
3706  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->skx, colpacketNum(ncols)) );
3707  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->skc, rowpacketNum(nrows)) );
3708 
3709  if( lpistate[0] )
3710  {
3711  lpistate[0]->solsta = MSK_SOL_STA_UNKNOWN;
3712  lpistate[0]->num = -1;
3713  lpistate[0]->ncols = ncols;
3714  lpistate[0]->nrows = nrows;
3715  }
3716 
3717  return SCIP_OKAY;
3718 }
3719 
3720 /** frees LPi state information */
3721 static
3722 void lpistateFree(
3723  SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
3724  BMS_BLKMEM* blkmem /**< block memory */
3725  )
3726 {
3727  assert(blkmem != NULL);
3728  assert(lpistate != NULL);
3729  assert(*lpistate != NULL);
3730 
3731  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->skx, colpacketNum((*lpistate)->ncols));
3732  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->skc, rowpacketNum((*lpistate)->nrows));
3733  BMSfreeBlockMemory(blkmem, lpistate);
3734 }
3735 
3736 #ifndef NDEBUG
3737 /** check state */
3738 static
3739 SCIP_RETCODE checkState1(
3740  SCIP_LPI* lpi, /**< LP interface structure */
3741  int n, /**< number of rows or columns */
3742  MSKstakeye* sk, /**< ??? */
3743  MSKaccmodee accmode, /**< ??? */
3744  char xc /**< ??? */
3745  )
3746 {
3747  int i;
3748 
3749  /* printout for all except LOW, UPR, FIX and BAS with sl[xc]==su[xc] */
3750  for( i = 0; i < n; i++ )
3751  {
3752  double sl;
3753  double su;
3754  switch (sk[i])
3755  {
3756  case MSK_SK_UNK:
3757  SCIPdebugMessage("STATE[%d]: %c[%d] = unk\n", optimizecount, xc, i);
3758  break;
3759  case MSK_SK_BAS:
3760  MOSEK_CALL( MSK_getsolutioni(lpi->task, accmode, i, MSK_SOL_BAS, NULL, NULL, &sl, &su, NULL) );
3761  if (fabs(sl-su) > DEBUG_CHECK_STATE_TOL)
3762  SCIPdebugMessage("STATE[%d]: %c[%d] = bas, sl%c = %g, su%c = %g\n", optimizecount, xc, i, xc, sl, xc, su);
3763  break;
3764  case MSK_SK_SUPBAS:
3765  SCIPdebugMessage("STATE[%d]: %c[%d] = supbas\n", optimizecount, xc, i);
3766  break;
3767  case MSK_SK_LOW:
3768  case MSK_SK_UPR:
3769  case MSK_SK_FIX:
3770  break;
3771  case MSK_SK_INF:
3772  SCIPdebugMessage("STATE[%d]: %c[%d] = inf\n", optimizecount, xc, i);
3773  break;
3774  default:
3775  SCIPdebugMessage("STATE[%d]: %c[%d] = unknown status <%d>\n", optimizecount, xc, i, sk[i]);
3776  break;
3777  } /*lint !e788*/
3778  }
3779 
3780  return SCIP_OKAY;
3781 }
3782 
3783 /** check state */
3784 static
3785 SCIP_RETCODE checkState(
3786  SCIP_LPI* lpi, /**< LP interface structure */
3787  int ncols, /**< number of columns */
3788  int nrows /**< number of rows */
3789  )
3790 {
3791  SCIP_CALL( checkState1(lpi, ncols, lpi->skx, MSK_ACC_VAR, 'x') );
3792  SCIP_CALL( checkState1(lpi, nrows, lpi->skc, MSK_ACC_CON, 'c') );
3793 
3794  return SCIP_OKAY;
3795  }
3796 #endif
3797 
3798 /** store row and column basis status in a packed LPi state object */
3799 static
3800 SCIP_RETCODE lpistatePack(
3801  SCIP_LPI* lpi, /**< LP interface structure */
3802  SCIP_LPISTATE* lpistate /**< pointer to LPi state data */
3803  )
3804 {
3805  int *skxi = (int *) lpi->skx; /* Used as temp. buffer */
3806  int *skci = (int *) lpi->skc; /* Used as temp. buffer */
3807 
3808  assert(sizeof(int) == sizeof(MSKstakeye));
3809 
3810  SCIP_CALL( convertstat_mosek2scip(lpi, MSK_ACC_VAR, lpi->skx, lpistate->ncols, skxi) );
3811  SCIP_CALL( convertstat_mosek2scip_slack(lpi, MSK_ACC_CON, lpi->skc, lpistate->nrows, skci) );
3812 
3813  SCIPencodeDualBit(skxi, lpistate->skx, lpistate->ncols);
3814  SCIPencodeDualBit(skci, lpistate->skc, lpistate->nrows);
3815 
3816  return SCIP_OKAY;
3817 }
3818 
3819 /** unpacks row and column basis status from a packed LPi state object */
3820 static
3821 void lpistateUnpack(
3822  SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
3823  MSKstakeye* skx, /**< ??? */
3824  MSKstakeye* skc /**< ??? */
3825  )
3826 {
3827  assert(sizeof(int) == sizeof(MSKstakeye));
3828 
3829  SCIPdecodeDualBit(lpistate->skx, (int*) skx, lpistate->ncols);
3830  SCIPdecodeDualBit(lpistate->skc, (int*) skc, lpistate->nrows);
3831 
3832  convertstat_scip2mosek((int*) skx, lpistate->ncols, skx);
3833  convertstat_scip2mosek_slack((int*) skc, lpistate->nrows, skc);
3834 }
3835 
3836 /** stores LP state (like basis information) into lpistate object */
3838  SCIP_LPI* lpi, /**< LP interface structure */
3839  BMS_BLKMEM* blkmem, /**< block memory */
3840  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
3841  )
3842 {
3843  int gotbasicsol;
3844  int nrows;
3845  int ncols;
3846 
3847  SCIPdebugMessage("Calling SCIPlpiGetState (%d)\n",lpi->lpid);
3848 
3849  assert(MosekEnv != NULL);
3850  assert(lpi != NULL);
3851  assert(lpi->task != NULL);
3852  assert(lpistate != NULL);
3853 
3854  *lpistate = NULL;
3855 
3856  MOSEK_CALL( MSK_solutiondef(lpi->task, MSK_SOL_BAS, &gotbasicsol) );
3857 
3858  if ( gotbasicsol == 0 || SCIPlpiExistsDualRay(lpi) )
3859  return SCIP_OKAY;
3860 
3861  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
3862  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
3863 
3864  /* allocate lpistate data */
3865  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
3866 
3867  lpistate[0]->num = optimizecount;
3868 
3869  MOSEK_CALL(MSK_getsolutionstatus ( lpi->task, MSK_SOL_BAS, NULL, &lpistate[0]->solsta));
3870 
3871  SCIP_CALL( getbase(lpi, ncols, nrows) );
3872 
3873 #ifndef NDEBUG
3874  SCIP_CALL( checkState(lpi, ncols, nrows) );
3875 #endif
3876 
3877  SCIP_CALL( lpistatePack(lpi, lpistate[0]) );
3878 
3879  SCIPdebugMessage("Store into state from iter : %d\n",optimizecount);
3880 
3881  /* if (r != SCIP_OKAY)
3882  * lpistateFree(lpistate, blkmem );
3883  */
3884 
3885  return SCIP_OKAY;
3886 }
3887 
3888 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
3889  * columns and rows since the state was stored with SCIPlpiGetState()
3890  */
3892  SCIP_LPI* lpi, /**< LP interface structure */
3893  BMS_BLKMEM* blkmem, /**< block memory */
3894  SCIP_LPISTATE* lpistate /**< LP state information (like basis information) */
3895  )
3896 { /*lint --e{715}*/
3897  int nrows;
3898  int ncols;
3899  int i;
3900 
3901  assert(MosekEnv != NULL);
3902  assert(lpi != NULL);
3903  assert(lpi->task != NULL);
3904 
3905  if (lpistate == NULL)
3906  {
3907  SCIPdebugMessage("Setting NULL state\n");
3908  return SCIP_OKAY;
3909  }
3910 
3911  if (lpistate->nrows == 0 || lpistate->ncols == 0)
3912  return SCIP_OKAY;
3913 
3914  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
3915  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
3916  assert(lpistate->nrows <= nrows);
3917  assert(lpistate->ncols <= ncols);
3918 
3919  SCIP_CALL( ensureStateMem(lpi, ncols, nrows) );
3920  SCIP_CALL( getbase(lpi, ncols, nrows) );
3921 
3922  lpistateUnpack(lpistate, lpi->skx, lpi->skc);
3923 
3924  /* extend the basis to the current LP beyond the previously existing columns */
3925  for (i = lpistate->ncols; i < ncols; ++i)
3926  {
3927  SCIP_Real lb;
3928  SCIP_Real ub;
3929  MOSEK_CALL( MSK_getboundslice(lpi->task, MSK_ACC_VAR, i, i, NULL, &lb, &ub) );
3930  if ( SCIPlpiIsInfinity(lpi, REALABS(lb)) )
3931  {
3932  /* if lower bound is +/- infinity -> try upper bound */
3933  if ( SCIPlpiIsInfinity(lpi, REALABS(ub)) )
3934  lpi->skx[i] = MSK_SK_SUPBAS; /* variable is free (super basic) */
3935  else
3936  lpi->skx[i] = MSK_SK_UPR; /* use finite upper bound */
3937  }
3938  else
3939  lpi->skx[i] = MSK_SK_LOW; /* use finite lower bound */
3940  }
3941  for (i = lpistate->nrows; i < nrows; ++i)
3942  lpi->skc[i] = MSK_SK_BAS;
3943 
3944  /* load basis information into MOSEK */
3945  SCIP_CALL( setbase(lpi) );
3946 
3947  SCIPdebugMessage("Store from state into task iter : %d with solsta : %d\n", lpistate->num, lpistate->solsta);
3948 
3949  return SCIP_OKAY;
3950 }
3951 
3952 /** clears current LPi state (like basis information) of the solver */
3954  SCIP_LPI* lpi /**< LP interface structure */
3955  )
3956 {
3957  assert(lpi != NULL);
3958 
3959  /**@todo implement SCIPlpiClearState() for MOSEK */
3960  SCIPmessagePrintWarning(lpi->messagehdlr, "MOSEK interface does not implement SCIPlpiClearState()\n");
3961 
3962  return SCIP_OKAY;
3963 }
3964 
3965 /** frees LP state information */
3967  SCIP_LPI* lpi, /**< LP interface structure */
3968  BMS_BLKMEM* blkmem, /**< block memory */
3969  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
3970  )
3971 { /*lint --e{715}*/
3972  assert(MosekEnv != NULL);
3973  assert(lpi != NULL);
3974  assert(lpi->task != NULL);
3975 
3976  SCIPdebugMessage("Calling SCIPlpiFreeState (%d)\n",lpi->lpid);
3977 
3978  if( *lpistate != NULL )
3979  {
3980  lpistateFree(lpistate, blkmem);
3981  }
3982 
3983  return SCIP_OKAY;
3984 }
3985 
3986 /** checks, whether the given LP state contains simplex basis information */
3988  SCIP_LPI* lpi, /**< LP interface structure */
3989  SCIP_LPISTATE* lpistate /**< LP state information (like basis information) */
3990  )
3991 { /*lint --e{715}*/
3992  assert(MosekEnv != NULL);
3993  assert(lpi != NULL);
3994  assert(lpi->task != NULL);
3995 
3996  SCIPdebugMessage("Calling SCIPlpiHasStateBasis (%d)\n",lpi->lpid);
3997 
3998  return ( lpistate != NULL && lpistate->num >= 0);
3999 }
4000 
4001 /** reads LP state (like basis information from a file */
4003  SCIP_LPI* lpi, /**< LP interface structure */
4004  const char* fname /**< file name */
4005  )
4006 {
4007  assert(MosekEnv != NULL);
4008  assert(lpi != NULL);
4009  assert(lpi->task != NULL);
4010 
4011  SCIPdebugMessage("reading LP state from file <%s>\n", fname);
4012 
4013  MOSEK_CALL( MSK_readsolution(lpi->task, MSK_SOL_BAS, fname) );
4014 
4015  return SCIP_OKAY;
4016 }
4017 
4018 /** writes LP state (like basis information) to a file */
4020  SCIP_LPI* lpi, /**< LP interface structure */
4021  const char* fname /**< file name */
4022  )
4023 {
4024  SCIPdebugMessage("writing LP state to file <%s>\n", fname);
4025 
4026  assert(MosekEnv != NULL);
4027  assert(lpi != NULL);
4028  assert(lpi->task != NULL);
4029 
4030  /* set parameter to be able to write */
4031  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_HEAD, MSK_ON) );
4032  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_VARIABLES, MSK_ON) );
4033  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_CONSTRAINTS, MSK_ON) );
4034 
4035  MOSEK_CALL( MSK_writesolution(lpi->task, MSK_SOL_BAS, fname) );
4036 
4037  return SCIP_OKAY;
4038 }
4039 
4040 
4041 
4042 
4043 /*
4044  * LP Pricing Norms Methods
4045  */
4046 
4047 /**@name LP Pricing Norms Methods */
4048 /**@{ */
4049 
4050 /** stores LPi pricing norms information
4051  * @todo should we store norm information?
4052  */
4054  SCIP_LPI* lpi, /**< LP interface structure */
4055  BMS_BLKMEM* blkmem, /**< block memory */
4056  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4057  )
4058 {
4059  assert(lpinorms != NULL);
4060 
4061  (*lpinorms) = NULL;
4062 
4063  return SCIP_OKAY;
4064 }
4065 
4066 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
4067  * columns and rows since the state was stored with SCIPlpiGetNorms()
4068  */
4070  SCIP_LPI* lpi, /**< LP interface structure */
4071  BMS_BLKMEM* blkmem, /**< block memory */
4072  SCIP_LPINORMS* lpinorms /**< LPi pricing norms information */
4073  )
4074 {
4075  assert(lpinorms == NULL);
4076 
4077  /* no work necessary */
4078  return SCIP_OKAY;
4079 }
4080 
4081 /** frees pricing norms information */
4083  SCIP_LPI* lpi, /**< LP interface structure */
4084  BMS_BLKMEM* blkmem, /**< block memory */
4085  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4086  )
4087 {
4088  assert(lpinorms == NULL);
4089 
4090  /* no work necessary */
4091  return SCIP_OKAY;
4092 }
4093 
4094 /**@} */
4095 
4096 /*
4097  * Parameter Methods
4098  */
4099 
4100 /** constant array containing the parameter names */
4101 static const char* paramname[] = {
4102  "SCIP_LPPAR_FROMSCRATCH", /**< solver should start from scratch at next call? */
4103  "SCIP_LPPAR_FASTMIP", /**< fast mip setting of LP solver */
4104  "SCIP_LPPAR_SCALING", /**< should LP solver use scaling? */
4105  "SCIP_LPPAR_PRESOLVING", /**< should LP solver use presolving? */
4106  "SCIP_LPPAR_PRICING", /**< pricing strategy */
4107  "SCIP_LPPAR_LPINFO", /**< should LP solver output information to the screen? */
4108  "SCIP_LPPAR_FEASTOL", /**< feasibility tolerance for primal variables and slacks */
4109  "SCIP_LPPAR_DUALFEASTOL", /**< feasibility tolerance for dual variables and reduced costs */
4110  "SCIP_LPPAR_BARRIERCONVTOL", /**< convergence tolerance used in barrier algorithm */
4111  "SCIP_LPPAR_LOBJLIM", /**< lower objective limit */
4112  "SCIP_LPPAR_UOBJLIM", /**< upper objective limit */
4113  "SCIP_LPPAR_LPITLIM", /**< LP iteration limit */
4114  "SCIP_LPPAR_LPTILIM", /**< LP time limit */
4115  "SCIP_LPPAR_MARKOWITZ", /**< Markowitz tolerance */
4116  "SCIP_LPPAR_ROWREPSWITCH", /**< simplex algorithm shall use row representation of the basis
4117  * if number of rows divided by number of columns exceeds this value */
4118  "SCIP_LPPAR_THREADS" /**< number of threads used to solve the LP */
4119 };
4120 
4121 /** method mapping parameter index to parameter name */
4122 static
4123 const char* paramty2str(
4124  SCIP_LPPARAM type
4125  )
4126 { /*lint --e{641}*/
4127  /* check if the parameters in this order */
4128  assert(SCIP_LPPAR_FROMSCRATCH == 0); /**< solver should start from scratch at next call? */
4129  assert(SCIP_LPPAR_FASTMIP == 1); /**< fast mip setting of LP solver */
4130  assert(SCIP_LPPAR_SCALING == 2); /**< should LP solver use scaling? */
4131  assert(SCIP_LPPAR_PRESOLVING == 3); /**< should LP solver use presolving? */
4132  assert(SCIP_LPPAR_PRICING == 4); /**< pricing strategy */
4133  assert(SCIP_LPPAR_LPINFO == 5); /**< should LP solver output information to the screen? */
4134  assert(SCIP_LPPAR_FEASTOL == 6); /**< feasibility tolerance for primal variables and slacks */
4135  assert(SCIP_LPPAR_DUALFEASTOL == 7); /**< feasibility tolerance for dual variables and reduced costs */
4136  assert(SCIP_LPPAR_BARRIERCONVTOL == 8); /**< convergence tolerance used in barrier algorithm */
4137  assert(SCIP_LPPAR_LOBJLIM == 9); /**< lower objective limit */
4138  assert(SCIP_LPPAR_UOBJLIM == 10); /**< upper objective limit */
4139  assert(SCIP_LPPAR_LPITLIM == 11); /**< LP iteration limit */
4140  assert(SCIP_LPPAR_LPTILIM == 12); /**< LP time limit */
4141  assert(SCIP_LPPAR_MARKOWITZ == 13); /**< Markowitz tolerance */
4142  assert(SCIP_LPPAR_ROWREPSWITCH == 14); /**< row representation switch */
4143  assert(SCIP_LPPAR_THREADS == 15); /**< number of threads used to solve the LP */
4144 
4145  return paramname[type];
4146 }
4147 
4148 /** gets integer parameter of LP */
4150  SCIP_LPI* lpi, /**< LP interface structure */
4151  SCIP_LPPARAM type, /**< parameter number */
4152  int* ival /**< buffer to store the parameter value */
4153  )
4154 { /*lint --e{641}*/
4155  SCIPdebugMessage("getting int parameter %s\n", paramty2str(type));
4156 
4157  assert(MosekEnv != NULL);
4158  assert(lpi != NULL);
4159  assert(lpi->task != NULL);
4160 
4161  switch (type)
4162  {
4163  case SCIP_LPPAR_FROMSCRATCH: /* solver should start from scratch at next call? */
4164  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, ival) );
4165  *ival = (*ival == MSK_SIM_HOTSTART_NONE);
4166  break;
4167  case SCIP_LPPAR_FASTMIP: /* fast mip setting of LP solver */
4168  return SCIP_PARAMETERUNKNOWN;
4169  case SCIP_LPPAR_SCALING: /* should LP solver use scaling? */
4170  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_SCALING, ival) );
4171  *ival = (*ival != MSK_SCALING_NONE);
4172  break;
4173  case SCIP_LPPAR_PRESOLVING: /* should LP solver use presolving? */
4174  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, ival) );
4175  *ival = (*ival != MSK_PRESOLVE_MODE_OFF);
4176  break;
4177  case SCIP_LPPAR_PRICING: /* pricing strategy */
4178  *ival = lpi->pricing;
4179  break;
4180  case SCIP_LPPAR_LPINFO: /* should LP solver output information to the screen? */
4181  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_LOG, ival) );
4182  *ival = (*ival == MSK_ON);
4183  break;
4184  case SCIP_LPPAR_LPITLIM: /* LP iteration limit */
4185  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, ival) );
4186  break;
4187  default:
4188  return SCIP_PARAMETERUNKNOWN;
4189  } /*lint !e788*/
4190 
4191  return SCIP_OKAY;
4192 }
4193 
4194 /** sets integer parameter of LP */
4196  SCIP_LPI* lpi, /**< LP interface structure */
4197  SCIP_LPPARAM type, /**< parameter number */
4198  int ival /**< parameter value */
4199  )
4200 {
4201  int scaling;
4202 
4203 #if SCIP_CONTROLS_PRICING
4204  /*lint --e{641}*/
4205  static int pricing[7] = {
4206  MSK_SIM_SELECTION_SE,
4207  MSK_SIM_SELECTION_SE,
4208  MSK_SIM_SELECTION_FULL,
4209  MSK_SIM_SELECTION_PARTIAL,
4210  MSK_SIM_SELECTION_SE,
4211  MSK_SIM_SELECTION_ASE,
4212  MSK_SIM_SELECTION_DEVEX,
4213  };
4214 #endif
4215 
4216  SCIPdebugMessage("Calling SCIPlpiSetIntpar (%d) Parameter=<%s> Value=<%d>\n", lpi->lpid, paramty2str(type), ival);
4217 
4218  assert(SCIP_PRICING_LPIDEFAULT == 0);
4219  assert(SCIP_PRICING_AUTO == 1);
4220  assert(SCIP_PRICING_FULL == 2);
4221  assert(SCIP_PRICING_PARTIAL == 3);
4222  assert(SCIP_PRICING_STEEP == 4);
4223  assert(SCIP_PRICING_STEEPQSTART == 5);
4224  assert(SCIP_PRICING_DEVEX == 6);
4225 
4226  SCIPdebugMessage("Calling SCIPlpiSetIntpar (%d) %s = %d\n",lpi->lpid,paramty2str(type),ival);
4227 
4228  assert(MosekEnv != NULL);
4229  assert(lpi != NULL);
4230  assert(lpi->task != NULL);
4231 
4232  switch (type)
4233  {
4234  case SCIP_LPPAR_FROMSCRATCH: /* solver should start from scratch at next call? */
4235  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART,
4236  ival ? MSK_SIM_HOTSTART_NONE : MSK_SIM_HOTSTART_STATUS_KEYS ) );
4237  break;
4238  case SCIP_LPPAR_FASTMIP: /* fast mip setting of LP solver */
4239  return SCIP_PARAMETERUNKNOWN;
4240  case SCIP_LPPAR_SCALING: /* should LP solver use scaling? */
4241  scaling = (ival ? MSK_SCALING_FREE : MSK_SCALING_NONE);
4242  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, scaling) );
4243  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_SCALING, scaling) );
4244  break;
4245  case SCIP_LPPAR_PRESOLVING: /* should LP solver use presolving? */
4246  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_PRESOLVE_USE,
4247  ival ? MSK_PRESOLVE_MODE_FREE : MSK_PRESOLVE_MODE_OFF) );
4248 
4249 #ifdef SCIP_DEBUG
4250  if( ival )
4251  {
4252  SCIPdebugMessage("Setting presolve to on\n");
4253  }
4254 #endif
4255  break;
4256  case SCIP_LPPAR_PRICING: /* pricing strategy */
4257  assert(ival >= 0 && ival <= SCIP_PRICING_DEVEX);
4258  lpi->pricing = (SCIP_PRICING)ival;
4259 
4260 #ifdef SCIP_DEBUG
4261  switch( (SCIP_PRICING)ival )
4262  {
4263  case SCIP_PRICING_AUTO:
4264  SCIPdebugMessage("Setting pricing to auto\n");
4265  break;
4266  case SCIP_PRICING_FULL:
4267  SCIPdebugMessage("Setting pricing to full\n");
4268  break;
4269  case SCIP_PRICING_PARTIAL:
4270  SCIPdebugMessage("Setting pricing to partial\n");
4271  break;
4273  SCIPdebugMessage("Setting pricing to lpi default\n");
4274  break;
4275  case SCIP_PRICING_STEEP:
4276  SCIPdebugMessage("Setting pricing to steep\n");
4277  break;
4279  SCIPdebugMessage("Setting pricing to steep quick start\n");
4280  break;
4281  case SCIP_PRICING_DEVEX:
4282  SCIPdebugMessage("Setting pricing to devex\n");
4283  break;
4284  }
4285 #endif
4286 
4287 #if SCIP_CONTROLS_PRICING
4288  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_SELECTION, pricing[ival]) );
4289 
4290  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, pricing[ival]) );
4291 
4292  if( !(lpi->pricing == SCIP_PRICING_PARTIAL || lpi->pricing == SCIP_PRICING_AUTO ) )
4293  {
4294  /* No restrict */
4295  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION, 0) );
4296 
4297  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION, 0) );
4298  }
4299 #else
4300  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_SELECTION, MSK_SIM_SELECTION_FREE) );
4301 
4302  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, MSK_SIM_SELECTION_FREE) );
4303 #endif
4304  break;
4305  case SCIP_LPPAR_LPINFO:
4306  /* should LP solver output information to the screen? */
4307 #if FORCE_MOSEK_LOG
4308  SCIPdebugMessage("Ignoring log setting!\n");
4309 #else
4310  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, ival ? MSK_ON : MSK_OFF) );
4311 #endif
4312  break;
4313  case SCIP_LPPAR_LPITLIM: /* LP iteration limit */
4314 #if DEBUG_PARAM_SETTING
4315  if( ival )
4316  {
4317  SCIPdebugMessage("Setting max iter to : %d\n",ival);
4318  }
4319 #endif
4320 
4321  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, ival) );
4322  break;
4323  default:
4324  return SCIP_PARAMETERUNKNOWN;
4325  } /*lint !e788*/
4326 
4327  return SCIP_OKAY;
4328 }
4329 
4330 /** gets floating point parameter of LP */
4332  SCIP_LPI* lpi, /**< LP interface structure */
4333  SCIP_LPPARAM type, /**< parameter number */
4334  SCIP_Real* dval /**< buffer to store the parameter value */
4335  )
4336 {
4337  SCIPdebugMessage("getting real parameter %s\n", paramty2str(type));
4338 
4339  assert(MosekEnv != NULL);
4340  assert(lpi != NULL);
4341  assert(lpi->task != NULL);
4342 
4343  switch (type)
4344  {
4345 #if SCIP_CONTROLS_TOLERANCES
4346  case SCIP_LPPAR_FEASTOL: /* feasibility tolerance for primal variables and slacks */
4347  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_BASIS_TOL_X, dval) );
4348  break;
4349  case SCIP_LPPAR_DUALFEASTOL: /* feasibility tolerance for dual variables and reduced costs */
4350  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_BASIS_TOL_S, dval) );
4351  break;
4352  case SCIP_LPPAR_BARRIERCONVTOL: /* convergence tolerance used in barrier algorithm */
4353  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_INTPNT_TOL_REL_GAP, dval) );
4354  break;
4355 #endif
4356  case SCIP_LPPAR_LOBJLIM: /* lower objective limit */
4357  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, dval) );
4358  break;
4359  case SCIP_LPPAR_UOBJLIM: /* upper objective limit */
4360  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, dval) );
4361  break;
4362  case SCIP_LPPAR_LPTILIM: /* LP time limit */
4363  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_OPTIMIZER_MAX_TIME, dval) );
4364  break;
4365  case SCIP_LPPAR_MARKOWITZ: /* Markowitz tolerance */
4366  default:
4367  return SCIP_PARAMETERUNKNOWN;
4368  } /*lint !e788*/
4369 
4370  return SCIP_OKAY;
4371 }
4372 
4373 /** sets floating point parameter of LP */
4375  SCIP_LPI* lpi, /**< LP interface structure */
4376  SCIP_LPPARAM type, /**< parameter number */
4377  SCIP_Real dval /**< parameter value */
4378  )
4379 {
4380  SCIPdebugMessage("setting real parameter %s to %g\n", paramty2str(type), dval);
4381 
4382  assert(MosekEnv != NULL);
4383  assert(lpi != NULL);
4384  assert(lpi->task != NULL);
4385 
4386  /**@todo Limits shouldn't be hardcoded */
4387 
4388  switch (type)
4389  {
4390 #if SCIP_CONTROLS_TOLERANCES
4391  case SCIP_LPPAR_FEASTOL: /* feasibility tolerance for primal variables and slacks */
4392  if (dval < 1e-9)
4393  dval = 1e-9;
4394 
4395  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_BASIS_TOL_X, dval) );
4396  break;
4397  case SCIP_LPPAR_DUALFEASTOL: /* feasibility tolerance for dual variables and reduced costs */
4398  if (dval < 1e-9)
4399  return SCIP_PARAMETERUNKNOWN;
4400  /* dval = 1e-9; */
4401 
4402  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_BASIS_TOL_S, dval) );
4403  break;
4404  case SCIP_LPPAR_BARRIERCONVTOL: /* convergence tolerance used in barrier algorithm */
4405  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_INTPNT_TOL_REL_GAP, dval) );
4406  break;
4407 #endif
4408  case SCIP_LPPAR_LOBJLIM: /* lower objective limit */
4409  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, dval) );
4410  break;
4411  case SCIP_LPPAR_UOBJLIM: /* upper objective limit */
4412  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, dval) );
4413  break;
4414  case SCIP_LPPAR_LPTILIM: /* LP time limit */
4415  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_OPTIMIZER_MAX_TIME, dval) );
4416  break;
4417  case SCIP_LPPAR_MARKOWITZ: /* Markowitz tolerance */
4418  default:
4419  return SCIP_PARAMETERUNKNOWN;
4420  } /*lint !e788*/
4421 
4422  return SCIP_OKAY;
4423 }
4424 
4425 
4426 /*
4427  * Numerical Methods
4428  */
4429 
4430 
4431 /** returns value treated as infinity in the LP solver */
4433  SCIP_LPI* lpi /**< LP interface structure */
4434  )
4435 { /*lint --e{715}*/
4436  assert(MosekEnv != NULL);
4437  assert(lpi != NULL);
4438  assert(lpi->task != NULL);
4439 
4440  return MSK_INFINITY;
4441 }
4442 
4443 /** checks if given value is treated as infinity in the LP solver */
4445  SCIP_LPI* lpi, /**< LP interface structure */
4446  SCIP_Real val /**< value to be checked for infinity */
4447  )
4448 { /*lint --e{715}*/
4449  assert(MosekEnv != NULL);
4450  assert(lpi != NULL);
4451  assert(lpi->task != NULL);
4452 
4453  return IS_POSINF(val);
4454 }
4455 
4456 
4457 /*
4458  * File Interface Methods
4459  */
4460 
4461 
4462 /** reads LP from a file */
4464  SCIP_LPI* lpi, /**< LP interface structure */
4465  const char* fname /**< file name */
4466  )
4467 {
4468  int olddataformat;
4469 
4470  SCIPdebugMessage("Calling SCIPlpiReadLP (%d), filename <%s>\n",lpi->lpid, fname);
4471 
4472  assert(MosekEnv != NULL);
4473  assert(lpi != NULL);
4474  assert(lpi->task != NULL);
4475 
4476  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, &olddataformat) );
4477  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, MSK_DATA_FORMAT_LP) );
4478  MOSEK_CALL( MSK_readdata(lpi->task, fname) );
4479  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, olddataformat) );
4480 
4481  return SCIP_OKAY;
4482 }
4483 
4484 /** writes LP to a file */
4486  SCIP_LPI* lpi, /**< LP interface structure */
4487  const char* fname /**< file name */
4488  )
4489 {
4490  int olddataformat;
4491 
4492  SCIPdebugMessage("Calling SCIPlpiReadLP (%d), filename <%s>\n",lpi->lpid, fname);
4493 
4494  assert(MosekEnv != NULL);
4495  assert(lpi != NULL);
4496  assert(lpi->task != NULL);
4497 
4498  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, &olddataformat) );
4499  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, MSK_DATA_FORMAT_LP) );
4500  MOSEK_CALL( MSK_writedata(lpi->task, fname) );
4501  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, olddataformat) );
4502 
4503  return SCIP_OKAY;
4504 }
4505