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