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  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_INTEGER, MSK_ON) );
2281  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
2282  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_DUAL_SIMPLEX) );
2283 
2284 #if WRITE_DUAL > 0
2285  if( optimizecount > WRITE_ABOVE )
2286  {
2287  char fname[40];
2288  snprintf(fname,40,"dual_%d.lp",optimizecount);
2289  SCIPdebugMessage("\nWriting lp %s\n",fname);
2290  MSK_writedata(lpi->task,fname);
2291  }
2292 #endif
2293 
2294 #if !FORCE_SILENCE
2295  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, MSK_ON) );
2296  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG_SIM_FREQ, 1) );
2297 #endif
2298 
2299  SCIP_CALL( SolveWSimplex(lpi) );
2300 
2301  if ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE )
2302  {
2303  MSKsolstae solsta;
2304 
2305  MOSEK_CALL( MSK_getsolutionstatus ( lpi->task, MSK_SOL_BAS, NULL, &solsta) );
2306 
2307  if( solsta != MSK_SOL_STA_DUAL_FEAS )
2308  {
2309  SCIP_CALL( SolveWSimplex(lpi) );
2310  }
2311  }
2312 
2313  if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
2314  ++numdualobj;
2315 
2316  if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
2317  ++numdualmaxiter;
2318 
2319  return SCIP_OKAY;
2320 }
2321 
2322 /** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
2324  SCIP_LPI* lpi, /**< LP interface structure */
2325  SCIP_Bool crossover /**< perform crossover */
2326  )
2327 {
2328  assert(MosekEnv != NULL);
2329  assert(lpi != NULL);
2330  assert(lpi->task != NULL);
2331 
2332  optimizecount++;
2333 
2334 #if FORCE_MOSEK_LOG
2335  if( optimizecount > WRITE_ABOVE )
2336  {
2337  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, MSK_ON) );
2338  }
2339  else
2340  {
2341  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, MSK_OFF) );
2342  }
2343 #else
2344  {
2345  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, MSK_OFF) );
2346  }
2347 #endif
2348 
2349 
2350  SCIPdebugMessage("Calling SCIPlpiSolveBarrier[%d] (%d) ",optimizecount,lpi->lpid);
2351 
2352 #if DEBUG_CHECK_DATA > 0
2353  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiSolveBarrier") );
2354 #endif
2355 
2356  MOSEK_CALL( MSK_putintparam(lpi->task,MSK_IPAR_INTPNT_BASIS, crossover ? MSK_BI_ALWAYS : MSK_BI_NEVER) );
2357  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_INTPNT) );
2358 
2359 
2360 #if WRITE_INTPNT > 0
2361  if( optimizecount > WRITE_ABOVE )
2362  {
2363  char fname[40];
2364  snprintf(fname,40,"intpnt_%d.lp",optimizecount);
2365  SCIPdebugMessage("\nWriting lp %s\n",fname);
2366  /*MOSEK_CALL( MSK_putintparam(lpi->task,MSK_IPAR_WRITE_GENERIC_NAMES,MSK_ON) );*/
2367  MSK_writedata(lpi->task,fname);
2368  }
2369 #endif
2370 
2371  MOSEK_CALL( filterTRMrescode(lpi->messagehdlr, &lpi->termcode, MSK_optimize(lpi->task)) );
2372 
2373  if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
2374  ++numdualmaxiter;
2375 
2376  MOSEK_CALL( MSK_getintinf(lpi->task, MSK_IINF_INTPNT_ITER, &lpi->itercount) );
2377 
2378 #ifdef SCIP_DEBUG
2379  {
2380  MSKprostae prosta;
2381  MSKsolstae solsta;
2382 
2383  MOSEK_CALL( MSK_getsolutionstatus ( lpi->task, MSK_SOL_BAS, &prosta, &solsta) );
2384  SCIPdebugMessage("termcode = %d, prosta = %d, solsta = %d, iter = %d\n",
2385  lpi->termcode, prosta, solsta, lpi->itercount);
2386  }
2387 #endif
2388 
2389 #if DEBUG_CHECK_DATA > 0
2390  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiSolveBarrier") );
2391 #endif
2392 
2393  return SCIP_OKAY;
2394 }
2395 
2396 /** start strong branching - call before any strong branching */
2398  SCIP_LPI* lpi /**< LP interface structure */
2399  )
2400 {
2401  /* currently do nothing */
2402  return SCIP_OKAY;
2403 }
2404 
2405 /** end strong branching - call after any strong branching */
2407  SCIP_LPI* lpi /**< LP interface structure */
2408  )
2409 {
2410  /* currently do nothing */
2411  return SCIP_OKAY;
2412 }
2413 
2414 /** performs strong branching iterations on all candidates */
2415 static
2417  SCIP_LPI* lpi, /**< LP interface structure */
2418  int col, /**< column to apply strong branching on */
2419  SCIP_Real psol, /**< current primal solution value of column */
2420  int itlim, /**< iteration limit for strong branchings */
2421  SCIP_Real* down, /**< stores dual bound after branching column down */
2422  SCIP_Real* up, /**< stores dual bound after branching column up */
2423  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2424  * otherwise, it can only be used as an estimate value */
2425  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2426  * otherwise, it can only be used as an estimate value */
2427  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2428  )
2429 {
2430  MSKobjsensee objsen;
2431  int olditerlim;
2432  int oldselection;
2433  int oldhotstart;
2434 
2435  double bound;
2436  int ncols;
2437  int nrows;
2438  MSKboundkeye bkx;
2439  double blx;
2440  double bux;
2441  double newub;
2442  double newlb;
2443 
2444  assert(MosekEnv != NULL);
2445  assert(lpi != NULL);
2446  assert(lpi->task != NULL);
2447 
2448  SCIPdebugMessage("Calling SCIPlpiStrongbranch (%d)\n", lpi->lpid);
2449 
2450 #if DEBUG_CHECK_DATA > 0
2451  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiStrongbranch") );
2452 #endif
2453 
2454  if (lpi->termcode != MSK_RES_OK)
2455  {
2456  SCIPmessagePrintWarning(lpi->messagehdlr, "SB Warning: Previous termcode is %d\n",lpi->termcode);
2457  }
2458 
2459  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
2460  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
2461 
2462  SCIP_CALL( getbase(lpi, ncols, nrows) );
2463 
2464  MOSEK_CALL( MSK_getobjsense(lpi->task, &objsen) );
2465  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, &olditerlim) );
2466  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, &oldselection) );
2467  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, &oldhotstart) );
2468 
2469  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, itlim) );
2470  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, STRONGBRANCH_PRICING) );
2471 
2472  if (objsen == MSK_OBJECTIVE_SENSE_MINIMIZE)
2473  {
2474  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, &bound) );
2475  }
2476  else /* objsen == MSK_OBJECTIVE_SENSE_MAX */
2477  {
2478  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, &bound) );
2479  }
2480 
2481  MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_VAR, col, &bkx, &blx, &bux) );
2482 
2483  *iter = 0;
2484 
2485  newub = EPSCEIL(psol-1.0, 1e-06);
2486 
2487  if (newub < blx - 0.5) /* infeasible */
2488  {
2489  *down = bound;
2490  *downvalid = TRUE;
2491  }
2492  else
2493  {
2494  MSKboundkeye newbk;
2495 
2496  if (IS_NEGINF(blx))
2497  newbk = MSK_BK_UP;
2498  else if (EPSEQ(blx,newub,1.0e-6))
2499  {
2500  newbk = MSK_BK_FX;
2501  newub = blx;
2502  }
2503  else
2504  newbk = MSK_BK_RA;
2505 
2506  MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, newbk, blx, newub) );
2507 
2508  SCIP_CALL( SCIPlpiSolveDual(lpi) );
2509 
2510  *iter += lpi->itercount;
2511 
2512  if (SCIPlpiIsStable(lpi))
2513  *downvalid = TRUE;
2514  else
2515  *downvalid = FALSE;
2516 
2517  if (SCIPlpiExistsPrimalRay(lpi))
2518  {
2519  SCIPmessagePrintWarning(lpi->messagehdlr, "SB ERROR: Lp [%d] is dual infeasible\n",optimizecount);
2520 
2521  *down = -1e20;
2522  *downvalid = FALSE;
2523  }
2524  else if (SCIPlpiExistsDualRay(lpi))
2525  {
2526  *down = bound;
2527  }
2528  else
2529  {
2530  SCIP_Bool dfeas;
2531 
2532  SCIP_CALL( SCIPlpiGetSolFeasibility(lpi, NULL, &dfeas) );
2533 
2534  if (!dfeas)
2535  {
2536  SCIPmessagePrintWarning(lpi->messagehdlr, "SB ERROR: Lp [%d] is not dual feasible\n", optimizecount);
2537 
2538  *down = -1e20;
2539  *downvalid = FALSE;
2540  }
2541  else
2542  {
2543  MOSEK_CALL( MSK_getdualobj(lpi->task, MSK_SOL_BAS, down) );
2544  }
2545  }
2546 
2547  if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
2549 
2550  if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
2552  }
2553 
2554  /* Reset basis solution before doing the up branch */
2555  MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, bkx, blx, bux) );
2556  SCIP_CALL( setbase(lpi) );
2557 
2558  newlb = EPSFLOOR(psol+1.0, 1e-06);
2559  if (newlb > bux + 0.5) /* infeasible */
2560  {
2561  *up = bound;
2562  *upvalid = TRUE;
2563  }
2564  else
2565  {
2566  MSKboundkeye newbk;
2567 
2568  if (IS_POSINF(bux))
2569  newbk = MSK_BK_LO;
2570  else if (EPSEQ(bux,newlb,1.0e-6))
2571  {
2572  newbk = MSK_BK_FX;
2573  newlb = bux;
2574  }
2575  else
2576  newbk = MSK_BK_RA;
2577 
2578  MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, newbk, newlb, bux) );
2579  SCIP_CALL( SCIPlpiSolveDual(lpi) );
2580 
2581  *iter += lpi->itercount;
2582 
2583  if (SCIPlpiIsStable(lpi))
2584  *upvalid = TRUE;
2585  else
2586  *upvalid = FALSE;
2587 
2588  if (SCIPlpiExistsPrimalRay(lpi))
2589  {
2590  *up = -1e20;
2591  *upvalid = FALSE;
2592  }
2593  else if (SCIPlpiExistsDualRay(lpi))
2594  {
2595  *up = bound;
2596  }
2597  else
2598  {
2599  SCIP_Bool dfeas;
2600 
2601  SCIP_CALL( SCIPlpiGetSolFeasibility(lpi, NULL, &dfeas) );
2602 
2603  if (!dfeas)
2604  {
2605  SCIPmessagePrintWarning(lpi->messagehdlr, "SB ERROR: Lp [%d] is not dual feasible\n",optimizecount);
2606 
2607  *up = -1e20;
2608  *upvalid = FALSE;
2609  }
2610  else
2611  {
2612  MOSEK_CALL( MSK_getdualobj(lpi->task, MSK_SOL_BAS, up) );
2613  }
2614  }
2615 
2616  if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
2618 
2619  if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
2621  }
2622 
2623  MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, bkx, blx, bux) );
2624  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, olditerlim) );
2625  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, oldselection) );
2626  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, oldhotstart) );
2627 
2628  SCIP_CALL( setbase(lpi) );
2629 
2630  lpi->termcode = MSK_RES_OK;
2631  lpi->itercount = 0;
2632 
2633 #if DEBUG_CHECK_DATA > 0
2634  SCIP_CALL( scip_checkdata(lpi, "SCIPlpiStrongbranch") );
2635 #endif
2636 
2637  SCIPdebugMessage("End SCIPlpiStrongbranch (%d)\n", lpi->lpid);
2638 
2639  return SCIP_OKAY;
2640 }
2641 
2642 /** performs strong branching iterations on one @b fractional candidate */
2644  SCIP_LPI* lpi, /**< LP interface structure */
2645  int col, /**< column to apply strong branching on */
2646  SCIP_Real psol, /**< fractional current primal solution value of column */
2647  int itlim, /**< iteration limit for strong branchings */
2648  SCIP_Real* down, /**< stores dual bound after branching column down */
2649  SCIP_Real* up, /**< stores dual bound after branching column up */
2650  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2651  * otherwise, it can only be used as an estimate value */
2652  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2653  * otherwise, it can only be used as an estimate value */
2654  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2655  )
2656 {
2657  /* pass call on to lpiStrongbranch() */
2658  SCIP_CALL( SCIPlpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
2659 
2660  return SCIP_OKAY;
2661 }
2662 
2663 /** performs strong branching iterations on given @b fractional candidates */
2665  SCIP_LPI* lpi, /**< LP interface structure */
2666  int* cols, /**< columns to apply strong branching on */
2667  int ncols, /**< number of columns */
2668  SCIP_Real* psols, /**< fractional current primal solution values of columns */
2669  int itlim, /**< iteration limit for strong branchings */
2670  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2671  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2672  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2673  * otherwise, they can only be used as an estimate values */
2674  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2675  * otherwise, they can only be used as an estimate values */
2676  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2677  )
2678 {
2679  int j;
2680 
2681  assert( iter != NULL );
2682  assert( cols != NULL );
2683  assert( psols != NULL );
2684  assert( down != NULL );
2685  assert( up != NULL );
2686  assert( downvalid != NULL );
2687  assert( upvalid != NULL );
2688  assert( down != NULL );
2689 
2690  if ( iter != NULL )
2691  *iter = 0;
2692 
2693  for (j = 0; j < ncols; ++j)
2694  {
2695  /* pass call on to lpiStrongbranch() */
2696  SCIP_CALL( SCIPlpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
2697  }
2698  return SCIP_OKAY;
2699 }
2700 
2701 /** performs strong branching iterations on one candidate with @b integral value */
2703  SCIP_LPI* lpi, /**< LP interface structure */
2704  int col, /**< column to apply strong branching on */
2705  SCIP_Real psol, /**< current integral primal solution value of column */
2706  int itlim, /**< iteration limit for strong branchings */
2707  SCIP_Real* down, /**< stores dual bound after branching column down */
2708  SCIP_Real* up, /**< stores dual bound after branching column up */
2709  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2710  * otherwise, it can only be used as an estimate value */
2711  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2712  * otherwise, it can only be used as an estimate value */
2713  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2714  )
2715 {
2716  /* pass call on to lpiStrongbranch() */
2717  SCIP_CALL( SCIPlpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
2718 
2719  return SCIP_OKAY;
2720 }
2721 
2722 /** performs strong branching iterations on given candidates with @b integral values */
2724  SCIP_LPI* lpi, /**< LP interface structure */
2725  int* cols, /**< columns to apply strong branching on */
2726  int ncols, /**< number of columns */
2727  SCIP_Real* psols, /**< current integral primal solution values of columns */
2728  int itlim, /**< iteration limit for strong branchings */
2729  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2730  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2731  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2732  * otherwise, they can only be used as an estimate values */
2733  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2734  * otherwise, they can only be used as an estimate values */
2735  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2736  )
2737 {
2738  int j;
2739 
2740  assert( iter != NULL );
2741  assert( cols != NULL );
2742  assert( psols != NULL );
2743  assert( down != NULL );
2744  assert( up != NULL );
2745  assert( downvalid != NULL );
2746  assert( upvalid != NULL );
2747  assert( down != NULL );
2748 
2749  if ( iter != NULL )
2750  *iter = 0;
2751 
2752  for (j = 0; j < ncols; ++j)
2753  {
2754  /* pass call on to lpiStrongbranch() */
2755  SCIP_CALL( SCIPlpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
2756  }
2757  return SCIP_OKAY;
2758 }
2759 
2760 
2761 /*
2762  * Solution Information Methods
2763  */
2764 
2765 
2766 /** returns whether a solve method was called after the last modification of the LP */
2768  SCIP_LPI* lpi /**< LP interface structure */
2769  )
2770 {
2771  MSKsolstae solsta;
2772  MSKrescodee restat;
2773 #if MSK_VERSION_MAJOR < 7
2774  MSKprostae prosta;
2775 #endif
2776 
2777  assert(MosekEnv != NULL);
2778  assert(lpi != NULL);
2779  assert(lpi->task != NULL);
2780 
2781  SCIPdebugMessage("Calling SCIPlpiWasSolved (%d)\n",lpi->lpid);
2782 
2783 #if MSK_VERSION_MAJOR >= 7
2784  restat = MSK_getsolsta(lpi->task, MSK_SOL_BAS, &solsta);
2785 #else
2786  restat = MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, &prosta, &solsta);
2787 #endif
2788 
2789  if ( restat != MSK_RES_OK )
2790  return FALSE;
2791  return (solsta != MSK_SOL_STA_UNKNOWN);
2792 }
2793 
2794 /** gets information about primal and dual feasibility of the current LP solution */
2796  SCIP_LPI* lpi, /**< LP interface structure */
2797  SCIP_Bool* primalfeasible, /**< stores primal feasibility status */
2798  SCIP_Bool* dualfeasible /**< stores dual feasibility status */
2799  )
2800 {
2801  MSKsolstae solsta;
2802  SCIP_Bool pfeas;
2803  SCIP_Bool dfeas;
2804 
2805  assert(MosekEnv != NULL);
2806  assert(lpi != NULL);
2807  assert(lpi->task != NULL);
2808 
2809  SCIPdebugMessage("Calling SCIPlpiGetSolFeasibility (%d)\n",lpi->lpid);
2810 
2811  pfeas = FALSE;
2812  dfeas = FALSE;
2813 
2814  MOSEK_CALL( MSK_getsolutionstatus ( lpi->task, MSK_SOL_BAS, NULL, &solsta) );
2815 
2816  switch (solsta)
2817  {
2818  case MSK_SOL_STA_OPTIMAL:
2819  case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
2820  pfeas = TRUE;
2821  dfeas = TRUE;
2822  break;
2823  case MSK_SOL_STA_PRIM_FEAS:
2824  pfeas = TRUE;
2825  break;
2826  case MSK_SOL_STA_DUAL_FEAS:
2827  dfeas = TRUE;
2828  break;
2829  case MSK_SOL_STA_UNKNOWN:
2830  case MSK_SOL_STA_NEAR_OPTIMAL:
2831  case MSK_SOL_STA_NEAR_PRIM_FEAS:
2832  case MSK_SOL_STA_NEAR_DUAL_FEAS:
2833  case MSK_SOL_STA_NEAR_PRIM_AND_DUAL_FEAS:
2834  case MSK_SOL_STA_PRIM_INFEAS_CER:
2835  case MSK_SOL_STA_DUAL_INFEAS_CER:
2836  case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
2837  case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
2838  case MSK_SOL_STA_INTEGER_OPTIMAL:
2839  case MSK_SOL_STA_NEAR_INTEGER_OPTIMAL:
2840  break;
2841  default:
2842  return SCIP_LPERROR;
2843  } /*lint !e788*/
2844 
2845  if( primalfeasible != NULL )
2846  *primalfeasible = pfeas;
2847 
2848  if( dualfeasible != NULL )
2849  *dualfeasible = dfeas;
2850 
2851  return SCIP_OKAY;
2852 }
2853 
2854 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
2855  * this does not necessarily mean, that the solver knows and can return the primal ray
2856  */
2858  SCIP_LPI* lpi /**< LP interface structure */
2859  )
2860 {
2861  MSKprostae prosta;
2862  MSKsolstae solsta;
2863 
2864  assert(MosekEnv != NULL);
2865  assert(lpi != NULL);
2866  assert(lpi->task != NULL);
2867 
2868  SCIPdebugMessage("Calling SCIPlpiExistsPrimalRay (%d)\n",lpi->lpid);
2869 
2870  SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, &solsta) );
2871 
2872  return ( solsta == MSK_SOL_STA_DUAL_INFEAS_CER
2873  || prosta == MSK_PRO_STA_DUAL_INFEAS
2874  || prosta == MSK_PRO_STA_PRIM_AND_DUAL_INFEAS);
2875 }
2876 
2877 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
2878  * and the solver knows and can return the primal ray
2879  */
2881  SCIP_LPI* lpi /**< LP interface structure */
2882  )
2883 {
2884  MSKsolstae solsta;
2885 
2886  assert(MosekEnv != NULL);
2887  assert(lpi != NULL);
2888  assert(lpi->task != NULL);
2889 
2890  SCIPdebugMessage("Calling SCIPlpiHasPrimalRay (%d)\n",lpi->lpid);
2891 
2892  SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
2893 
2894  return (solsta == MSK_SOL_STA_DUAL_INFEAS_CER);
2895 }
2896 
2897 /** returns TRUE iff LP is proven to be primal unbounded */
2899  SCIP_LPI* lpi /**< LP interface structure */
2900  )
2901 { /*lint --e{715}*/
2902  return FALSE;
2903 }
2904 
2905 /** returns TRUE iff LP is proven to be primal infeasible */
2907  SCIP_LPI* lpi /**< LP interface structure */
2908  )
2909 {
2910  return SCIPlpiExistsDualRay(lpi);
2911 }
2912 
2913 /** returns TRUE iff LP is proven to be primal feasible */
2915  SCIP_LPI* lpi /**< LP interface structure */
2916  )
2917 {
2918  MSKprostae prosta;
2919 
2920  assert(MosekEnv != NULL);
2921  assert(lpi != NULL);
2922  assert(lpi->task != NULL);
2923 
2924  SCIPdebugMessage("Calling SCIPlpiIsPrimalFeasible (%d)\n",lpi->lpid);
2925 
2926  SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, NULL) );
2927 
2928  return (prosta == MSK_PRO_STA_PRIM_FEAS || prosta == MSK_PRO_STA_PRIM_AND_DUAL_FEAS);
2929 }
2930 
2931 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
2932  * this does not necessarily mean, that the solver knows and can return the dual ray
2933  */
2935  SCIP_LPI* lpi /**< LP interface structure */
2936  )
2937 {
2938  MSKprostae prosta;
2939  MSKsolstae solsta;
2940 
2941  assert(MosekEnv != NULL);
2942  assert(lpi != NULL);
2943  assert(lpi->task != NULL);
2944 
2945  SCIPdebugMessage("Calling SCIPlpiExistsDualRay (%d)\n",lpi->lpid);
2946 
2947  SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, &solsta) );
2948 
2949  return ( solsta == MSK_SOL_STA_PRIM_INFEAS_CER
2950  || prosta == MSK_PRO_STA_PRIM_INFEAS
2951  || prosta == MSK_PRO_STA_PRIM_AND_DUAL_INFEAS);
2952 }
2953 
2954 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
2955  * and the solver knows and can return the dual ray
2956  */
2958  SCIP_LPI* lpi /**< LP interface structure */
2959  )
2960 {
2961  MSKsolstae solsta;
2962 
2963  assert(MosekEnv != NULL);
2964  assert(lpi != NULL);
2965  assert(lpi->task != NULL);
2966 
2967  SCIPdebugMessage("Calling SCIPlpiHasDualRay (%d)\n",lpi->lpid);
2968 
2969  SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
2970 
2971  return (solsta == MSK_SOL_STA_PRIM_INFEAS_CER);
2972 }
2973 
2974 /** returns TRUE iff LP is proven to be dual unbounded */
2976  SCIP_LPI* lpi /**< LP interface structure */
2977  )
2978 { /*lint --e{715}*/
2979  return FALSE;
2980 }
2981 
2982 /** returns TRUE iff LP is proven to be dual infeasible */
2984  SCIP_LPI* lpi /**< LP interface structure */
2985  )
2986 {
2987  return SCIPlpiExistsPrimalRay(lpi);
2988 }
2989 
2990 /** returns TRUE iff LP is proven to be dual feasible */
2992  SCIP_LPI* lpi /**< LP interface structure */
2993  )
2994 {
2995  MSKprostae prosta;
2996 
2997  assert(MosekEnv != NULL);
2998  assert(lpi != NULL);
2999  assert(lpi->task != NULL);
3000 
3001  SCIPdebugMessage("Calling SCIPlpiIsDualFeasible (%d)\n",lpi->lpid);
3002 
3003  SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, NULL) );
3004 
3005  return (prosta == MSK_PRO_STA_DUAL_FEAS || prosta == MSK_PRO_STA_PRIM_AND_DUAL_FEAS);
3006 }
3007 
3008 
3009 /** returns TRUE iff LP was solved to optimality */
3011  SCIP_LPI* lpi /**< LP interface structure */
3012  )
3013 {
3014  MSKsolstae solsta;
3015 
3016  assert(MosekEnv != NULL);
3017  assert(lpi != NULL);
3018  assert(lpi->task != NULL);
3019 
3020  SCIPdebugMessage("Calling SCIPlpiIsOptimal (%d)\n",lpi->lpid);
3021 
3022  SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
3023 
3024  return (solsta == MSK_SOL_STA_OPTIMAL);
3025 }
3026 
3027 /** returns TRUE iff current LP basis is stable */
3029  SCIP_LPI* lpi /**< LP interface structure */
3030  )
3031 {
3032  assert(MosekEnv != NULL);
3033  assert(lpi != NULL);
3034  assert(lpi->task != NULL);
3035 
3036  return ( lpi->termcode == MSK_RES_OK
3037  || lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS
3038  || lpi->termcode == MSK_RES_TRM_MAX_TIME
3039  || lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE);
3040 }
3041 
3042 /** returns TRUE iff the objective limit was reached */
3044  SCIP_LPI* lpi /**< LP interface structure */
3045  )
3046 {
3047  assert(MosekEnv != NULL);
3048  assert(lpi != NULL);
3049  assert(lpi->task != NULL);
3050 
3051  return lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE;
3052 }
3053 
3054 /** returns TRUE iff the iteration limit was reached */
3056  SCIP_LPI* lpi /**< LP interface structure */
3057  )
3058 {
3059  assert(MosekEnv != NULL);
3060  assert(lpi != NULL);
3061  assert(lpi->task != NULL);
3062 
3063  return lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS;
3064 }
3065 
3066 /** returns TRUE iff the time limit was reached */
3068  SCIP_LPI* lpi /**< LP interface structure */
3069  )
3070 {
3071  assert(MosekEnv != NULL);
3072  assert(lpi != NULL);
3073  assert(lpi->task != NULL);
3074 
3075  return lpi->termcode == MSK_RES_TRM_MAX_TIME;
3076 }
3077 
3078 /** returns the internal solution status of the solver */
3080  SCIP_LPI* lpi /**< LP interface structure */
3081  )
3082 {
3083  MSKsolstae solsta;
3084  SCIP_RETCODE retcode;
3085 
3086  assert(MosekEnv != NULL);
3087  assert(lpi != NULL);
3088  assert(lpi->task != NULL);
3089 
3090  SCIPdebugMessage("Calling SCIPlpiGetInternalStatus (%d)\n", lpi->lpid);
3091 
3092  retcode = getSolutionStatus(lpi, NULL, &solsta);
3093  if ( retcode != SCIP_OKAY )
3094  return 0;
3095 
3096  return solsta; /*lint !e641*/
3097 }
3098 
3099 /** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
3101  SCIP_LPI* lpi, /**< LP interface structure */
3102  SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
3103  )
3104 {
3105  assert(MosekEnv != NULL);
3106  assert(lpi != NULL);
3107  assert(lpi->task != NULL);
3108 
3109  SCIPdebugMessage("Calling SCIPlpiIgnoreInstability (%d)\n",lpi->lpid);
3110 
3111  *success = FALSE;
3112 
3113  return SCIP_OKAY;
3114 }
3115 
3116 /** gets objective value of solution */
3118  SCIP_LPI* lpi, /**< LP interface structure */
3119  SCIP_Real* objval /**< stores the objective value */
3120  )
3121 {
3122  assert(MosekEnv != NULL);
3123  assert(lpi != NULL);
3124  assert(lpi->task != NULL);
3125 
3126  SCIPdebugMessage("Calling SCIPlpiGetObjval (%d)\n",lpi->lpid);
3127 
3128  MOSEK_CALL( MSK_getprimalobj(lpi->task, MSK_SOL_BAS, objval) );
3129 
3130  /* TODO: tjek lighed med dual objektiv i de fleste tilfaelde. */
3131 
3132  return SCIP_OKAY;
3133 }
3134 
3135 /** gets primal and dual solution vectors */
3137  SCIP_LPI* lpi, /**< LP interface structure */
3138  SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
3139  SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
3140  SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
3141  SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
3142  SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
3143  )
3144 { /*lint --e{715}*/
3145  double* sux;
3146  int ncols;
3147  int i;
3148 
3149  assert(MosekEnv != NULL);
3150  assert(lpi != NULL);
3151  assert(lpi->task != NULL);
3152 
3153  SCIPdebugMessage("Calling SCIPlpiGetSol (%d)\n",lpi->lpid);
3154 
3155  sux = NULL;
3156  ncols = 0;
3157 
3158  if( redcost )
3159  {
3160  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
3161  SCIP_ALLOC( BMSallocMemoryArray( &sux, ncols) );
3162  }
3163 
3164  MOSEK_CALL( MSK_getsolution(lpi->task, MSK_SOL_BAS, NULL, NULL, NULL, NULL, NULL, activity,
3165  primsol, dualsol, NULL, NULL, redcost, sux, NULL) );
3166 
3167  if( redcost )
3168  {
3169  for( i = 0; i < ncols; i++ )
3170  {
3171  assert(sux != NULL);
3172  redcost[i] -= sux[i];
3173  }
3174  }
3175 
3176  BMSfreeMemoryArray(&sux);
3177 
3178  return SCIP_OKAY;
3179 }
3180 
3181 /** gets primal ray for unbounded LPs */
3183  SCIP_LPI* lpi, /**< LP interface structure */
3184  SCIP_Real* ray /**< primal ray */
3185  )
3186 {
3187  assert(MosekEnv != NULL);
3188  assert(lpi != NULL);
3189  assert(lpi->task != NULL);
3190 
3191  SCIPdebugMessage("Calling SCIPlpiGetPrimalRay (%d)\n",lpi->lpid);
3192 
3193  MOSEK_CALL( MSK_getsolution(lpi->task, MSK_SOL_BAS, NULL, NULL, NULL, NULL, NULL, NULL, ray,
3194  NULL, NULL, NULL, NULL, NULL, NULL) );
3195 
3196  return SCIP_OKAY;
3197 }
3198 
3199 /** gets dual Farkas proof for infeasibility */
3201  SCIP_LPI* lpi, /**< LP interface structure */
3202  SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
3203  )
3204 {
3205  assert(MosekEnv != NULL);
3206  assert(lpi != NULL);
3207  assert(lpi->task != NULL);
3208 
3209  SCIPdebugMessage("Calling SCIPlpiGetDualfarkas (%d)\n",lpi->lpid);
3210 
3211  MOSEK_CALL( MSK_getsolution(lpi->task, MSK_SOL_BAS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, dualfarkas,
3212  NULL, NULL, NULL, NULL, NULL) );
3213 
3214  return SCIP_OKAY;
3215 }
3216 
3217 /** gets the number of LP iterations of the last solve call */
3219  SCIP_LPI* lpi, /**< LP interface structure */
3220  int* iterations /**< pointer to store the number of iterations of the last solve call */
3221  )
3222 {
3223  assert(MosekEnv != NULL);
3224  assert(lpi != NULL);
3225  assert(lpi->task != NULL);
3226 
3227  SCIPdebugMessage("Calling SCIPlpiGetIterations (%d)\n",lpi->lpid);
3228 
3229  *iterations = lpi->itercount;
3230 
3231  return SCIP_OKAY;
3232 }
3233 
3234 /** gets information about the quality of an LP solution
3235  *
3236  * Such information is usually only available, if also a (maybe not optimal) solution is available.
3237  * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
3238  */
3240  SCIP_LPI* lpi, /**< LP interface structure */
3241  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
3242  SCIP_Real* quality /**< pointer to store quality number */
3243  )
3244 {
3245  assert(lpi != NULL);
3246  assert(quality != NULL);
3247 
3248  *quality = SCIP_INVALID;
3249 
3250  return SCIP_OKAY;
3251 }
3252 
3253 /** handle singular basis */
3254 static
3256  SCIP_LPI* lpi, /**< LP interface structure */
3257  int* basis, /**< array of basis indices */
3258  MSKrescodee res /**< result */
3259  )
3260 {
3261  if (res == MSK_RES_ERR_BASIS_SINGULAR)
3262  {
3263  SCIP_CALL( SCIPlpiSolvePrimal(lpi) );
3264 
3265  MOSEK_CALL( MSK_initbasissolve(lpi->task, basis) );
3266  }
3267  else
3268  {
3269  MOSEK_CALL( res );
3270  }
3271 
3272  return SCIP_OKAY;
3273 }
3274 
3275 
3276 /*
3277  * LP Basis Methods
3278  */
3279 
3280 /** convert Mosek status to SCIP status */
3281 static
3283  SCIP_LPI* lpi, /**< LP interface structure */
3284  MSKaccmodee acc, /**< ??? */
3285  MSKstakeye* sk, /**< ??? */
3286  int n, /**< size */
3287  int* stat /**< status array */
3288  )
3289 {
3290  int i;
3291 
3292  for( i = 0; i < n; i++ )
3293  {
3294  double sl;
3295  double su;
3296 
3297  switch (sk[i])
3298  {
3299  case MSK_SK_BAS:
3300  stat[i] = (int)SCIP_BASESTAT_BASIC;
3301  break;
3302  case MSK_SK_SUPBAS:
3303  stat[i] = (int)SCIP_BASESTAT_ZERO;
3304  break;
3305  case MSK_SK_FIX:
3306  MOSEK_CALL( MSK_getsolutioni(lpi->task, acc, i, MSK_SOL_BAS, NULL, NULL, &sl, &su, NULL) );
3307 
3308  if (sl < su) /* Negative reduced cost */
3309  stat[i] = (int)SCIP_BASESTAT_UPPER;
3310  else
3311  stat[i] = (int)SCIP_BASESTAT_LOWER;
3312  break;
3313  case MSK_SK_UNK:
3314  stat[i] = (int)SCIP_BASESTAT_LOWER;
3315  break;
3316  case MSK_SK_INF:
3317  stat[i] = (int)SCIP_BASESTAT_LOWER;
3318  break;
3319  case MSK_SK_LOW:
3320  stat[i] = (int)SCIP_BASESTAT_LOWER;
3321  break;
3322  case MSK_SK_UPR:
3323  stat[i] = (int)SCIP_BASESTAT_UPPER;
3324  break;
3325  case MSK_SK_END:
3326  break;
3327  default:
3328  SCIPABORT();
3329  return SCIP_INVALIDDATA; /*lint !e527*/
3330  } /*lint !e788*/
3331  }
3332 
3333  return SCIP_OKAY;
3334 }
3335 
3336 /** convert Mosek to SCIP status - slack variables */
3337 static
3339  SCIP_LPI* lpi, /**< LP interface structure */
3340  MSKaccmodee acc, /**< whether constraints or variables are accessed */
3341  MSKstakeye* sk, /**< Mosek basis status */
3342  int m, /**< size */
3343  int* stat /**< status array */
3344  )
3345 {
3346  int i;
3347 
3348  for( i = 0; i < m; i++ )
3349  {
3350  double sl;
3351  double su;
3352  switch (sk[i])
3353  {
3354  case MSK_SK_BAS:
3355  stat[i] = (int)SCIP_BASESTAT_BASIC;
3356  break;
3357  case MSK_SK_SUPBAS:
3358  stat[i] = (int)SCIP_BASESTAT_ZERO;
3359  break;
3360  case MSK_SK_FIX:
3361  MOSEK_CALL( MSK_getsolutioni(lpi->task, acc, i, MSK_SOL_BAS, NULL, NULL, &sl, &su, NULL) );
3362 
3363  if (sl < su) /* Negative reduced cost */
3364  stat[i] = (int)SCIP_BASESTAT_UPPER;
3365  else
3366  stat[i] = (int)SCIP_BASESTAT_LOWER;
3367  break;
3368  case MSK_SK_UNK:
3369  case MSK_SK_INF:
3370  case MSK_SK_UPR:
3371  stat[i] = (int)SCIP_BASESTAT_UPPER;
3372  break;
3373  case MSK_SK_LOW:
3374  stat[i] = (int)SCIP_BASESTAT_LOWER;
3375  break;
3376  case MSK_SK_END:
3377  default:
3378  SCIPABORT();
3379  return SCIP_INVALIDDATA; /*lint !e527*/
3380  } /*lint !e788*/
3381  }
3382 
3383  return SCIP_OKAY;
3384 }
3385 
3386 /** convert SCIP to Mosek status */
3387 static
3389  const int* stat, /**< SCIP status array */
3390  int n, /**< size of array */
3391  MSKstakeye* resstat /**< resulting Mosek status array */
3392  )
3393 {
3394  int i;
3395  for( i = 0; i < n; i++ )
3396  {
3397  switch (stat[i])
3398  {
3399  case SCIP_BASESTAT_LOWER:
3400  resstat[i] = MSK_SK_LOW;
3401  break;
3402  case SCIP_BASESTAT_BASIC:
3403  resstat[i] = MSK_SK_BAS;
3404  break;
3405  case SCIP_BASESTAT_UPPER:
3406  resstat[i] = MSK_SK_UPR;
3407  break;
3408  case SCIP_BASESTAT_ZERO:
3409  resstat[i] = MSK_SK_SUPBAS;
3410  break;
3411  default:
3412  SCIPABORT();
3413  }
3414  }
3415 }
3416 
3417 /** convert SCIP to Mosek status - slack variables */
3418 static
3420  const int* stat, /**< SCIP status array */
3421  int n, /**< size of array */
3422  MSKstakeye* resstat /**< resulting Mosek status array */
3423  )
3424 {
3425  /* slacks are stored as -1 in Mosek, i.e., bounds are reversed compared to SCIP */
3426  int i;
3427 
3428  for( i = 0; i < n; i++ )
3429  {
3430  switch (stat[i])
3431  {
3432  case SCIP_BASESTAT_LOWER:
3433  resstat[i] = MSK_SK_UPR;/* Reversed */
3434  break;
3435  case SCIP_BASESTAT_BASIC:
3436  resstat[i] = MSK_SK_BAS;
3437  break;
3438  case SCIP_BASESTAT_UPPER:
3439  resstat[i] = MSK_SK_LOW; /* Reversed */
3440  break;
3441  case SCIP_BASESTAT_ZERO:
3442  resstat[i] = MSK_SK_SUPBAS;
3443  break;
3444  default:
3445  SCIPABORT();
3446  }
3447  }
3448 }
3449 
3450 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
3452  SCIP_LPI* lpi, /**< LP interface structure */
3453  int* cstat, /**< array to store column basis status, or NULL */
3454  int* rstat /**< array to store row basis status, or NULL */
3455  )
3456 {
3457  int nrows;
3458  int ncols;
3459 
3460  assert(MosekEnv != NULL);
3461  assert(lpi != NULL);
3462  assert(lpi->task != NULL);
3463 
3464  SCIPdebugMessage("Calling SCIPlpiGetBase (%d)\n",lpi->lpid);
3465 
3466  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
3467  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
3468 
3469  SCIP_CALL( getbase(lpi, ncols, nrows) );
3470 
3471  if (cstat)
3472  {
3473  SCIP_CALL( convertstat_mosek2scip(lpi, MSK_ACC_VAR, lpi->skx, ncols, cstat) );
3474  }
3475 
3476  if (rstat)
3477  {
3478  SCIP_CALL( convertstat_mosek2scip_slack(lpi, MSK_ACC_CON, lpi->skc, nrows, rstat) );
3479  }
3480 
3481  return SCIP_OKAY;
3482 }
3483 
3484 /** sets current basis status for columns and rows */
3486  SCIP_LPI* lpi, /**< LP interface structure */
3487  const int* cstat, /**< array with column basis status */
3488  const int* rstat /**< array with row basis status */
3489  )
3490 {
3491  int nrows;
3492  int ncols;
3493 
3494  assert(MosekEnv != NULL);
3495  assert(lpi != NULL);
3496  assert(lpi->task != NULL);
3497 
3498  SCIPdebugMessage("Calling SCIPlpiSetBase (%d)\n",lpi->lpid);
3499 
3500  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
3501  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
3502 
3503  SCIP_CALL( ensureStateMem(lpi, ncols, nrows) );
3504 
3505  convertstat_scip2mosek(cstat, ncols, lpi->skx);
3506  convertstat_scip2mosek_slack(rstat, nrows, lpi->skc);
3507 
3508  SCIP_CALL( setbase(lpi) );
3509 
3510  return SCIP_OKAY;
3511 }
3512 
3513 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
3514 extern
3516  SCIP_LPI* lpi, /**< LP interface structure */
3517  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
3518  )
3519 {
3520  int nrows;
3521  int i;
3522 
3523  assert(MosekEnv != NULL);
3524  assert(lpi != NULL);
3525  assert(lpi->task != NULL);
3526 
3527  SCIPdebugMessage("Calling SCIPlpiGetBasisInd (%d)\n",lpi->lpid);
3528 
3529  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
3530 
3531 #if 0
3532  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_OFF) );
3533 #endif
3534 
3535  SCIP_CALL( handle_singular(lpi,bind,MSK_initbasissolve(lpi->task, bind)) );
3536 
3537 #if 0
3538  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
3539 #endif
3540 
3541  for (i = 0; i < nrows; i++ )
3542  {
3543  if (bind[i] < nrows) /* row bind[i] is basic */
3544  bind[i] = -1 - bind[i];
3545  else /* column bind[i]-nrows is basic */
3546  bind[i] = bind[i] - nrows;
3547  }
3548 
3549  return SCIP_OKAY;
3550 }
3551 
3552 /** get column of inverse basis matrix B^-1
3553  *
3554  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3555  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3556  * see also the explanation in lpi.h.
3557  *
3558  * @todo check that the result is in terms of the LP interface definition
3559  */
3561  SCIP_LPI* lpi, /**< LP interface structure */
3562  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3563  * you have to call SCIPlpiGetBasisInd() to get the array which links the
3564  * B^-1 column numbers to the row and column numbers of the LP!
3565  * c must be between 0 and nrows-1, since the basis has the size
3566  * nrows * nrows */
3567  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
3568  int* inds, /**< array to store the non-zero indices */
3569  int* ninds /**< pointer to store the number of non-zero indices
3570  * (-1: if we do not store sparsity informations) */
3571  )
3572 {
3573  int nrows;
3574  int i;
3575 
3576  assert(MosekEnv != NULL);
3577  assert(lpi != NULL);
3578  assert(lpi->task != NULL);
3579 
3580  SCIPdebugMessage("Calling SCIPlpiGetBInvCol (%d)\n",lpi->lpid);
3581 
3582  MOSEK_CALL( MSK_getnumcon(lpi->task,&nrows) );
3583  MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_OFF) );
3584 
3585  /* check whether we require a dense or sparse result vector */
3586  if ( ninds != NULL && inds != NULL )
3587  {
3588  for (i = 0; i < nrows; ++i)
3589  coef[i] = 0;
3590 
3591  *ninds = 1;
3592  inds[0]= c;
3593  coef[c] = 1; /* Unit vector e_col */
3594 
3595  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, ninds, inds, coef) );
3596  assert( *ninds <= nrows );
3597  }
3598  else
3599  {
3600  int* sub;
3601  int numnz;
3602 
3603  SCIP_ALLOC( BMSallocMemoryArray(&sub, nrows) );
3604 
3605  for (i = 0; i < nrows; ++i)
3606  coef[i] = 0;
3607 
3608  numnz = 1;
3609  sub[0]= c;
3610  coef[c] = 1; /* Unit vector e_col */
3611 
3612  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, &numnz, sub, coef) );
3613  assert( numnz <= nrows );
3614 
3615  BMSfreeMemoryArray(&sub);
3616  }
3617  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
3618 
3619  return SCIP_OKAY;
3620 }
3621 
3622 
3623 /** get row of inverse basis matrix B^-1
3624  *
3625  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3626  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3627  * see also the explanation in lpi.h.
3628  *
3629  * @todo check that the result is in terms of the LP interface definition
3630  */
3632  SCIP_LPI* lpi, /**< LP interface structure */
3633  int row, /**< row number */
3634  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
3635  int* inds, /**< array to store the non-zero indices */
3636  int* ninds /**< pointer to store the number of non-zero indices
3637  * (-1: if we do not store sparsity informations) */
3638  )
3639 {
3640  int nrows;
3641  int i;
3642 
3643  assert(MosekEnv != NULL);
3644  assert(lpi != NULL);
3645  assert(lpi->task != NULL);
3646 
3647  SCIPdebugMessage("Calling SCIPlpiGetBInvRow (%d)\n", lpi->lpid);
3648 
3649  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
3650  MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_ON) );
3651 
3652  /* check whether we require a dense or sparse result vector */
3653  if ( ninds != NULL && inds != NULL )
3654  {
3655  for (i = 0; i < nrows; ++i)
3656  coef[i] = 0;
3657 
3658  *ninds = 1;
3659  inds[0]= row;
3660  coef[row] = 1; /* Unit vector e_row */
3661 
3662  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, ninds, inds, coef) );
3663  assert( *ninds <= nrows );
3664  }
3665  else
3666  {
3667  int* sub;
3668  int numnz;
3669 
3670  SCIP_ALLOC( BMSallocMemoryArray( &sub, nrows) );
3671 
3672  for (i = 0; i < nrows; ++i)
3673  coef[i] = 0;
3674 
3675  numnz = 1;
3676  sub[0] = row;
3677  coef[row] = 1; /* Unit vector e_row */
3678 
3679  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, &numnz, sub, coef) );
3680 
3681  BMSfreeMemoryArray(&sub);
3682  }
3683  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
3684 
3685  SCIPdebugMessage("End SCIPlpiGetBInvRow (%d)\n", lpi->lpid);
3686 
3687  return SCIP_OKAY;
3688 }
3689 
3690 /** get row of inverse basis matrix times constraint matrix B^-1 * A
3691  *
3692  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3693  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3694  * see also the explanation in lpi.h.
3695  *
3696  * @todo check that the result is in terms of the LP interface definition
3697  */
3699  SCIP_LPI* lpi, /**< LP interface structure */
3700  int row, /**< row number */
3701  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3702  SCIP_Real* coef, /**< vector to return coefficients */
3703  int* inds, /**< array to store the non-zero indices */
3704  int* ninds /**< pointer to store the number of non-zero indices
3705  * (-1: if we do not store sparsity informations) */
3706  )
3707 {
3708  int nrows;
3709  int ncols;
3710  int numnz;
3711  int* csub;
3712  int didalloc;
3713  double* cval;
3714  double* binv;
3715  int i;
3716  int k;
3717 
3718  assert(MosekEnv != NULL);
3719  assert(lpi != NULL);
3720  assert(lpi->task != NULL);
3721 
3722  SCIPdebugMessage("Calling SCIPlpiGetBInvARow (%d)\n",lpi->lpid);
3723 
3724  didalloc = 0;
3725 
3726  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
3727  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
3728 
3729  SCIP_ALLOC( BMSallocMemoryArray(&csub, nrows) );
3730  SCIP_ALLOC( BMSallocMemoryArray(&cval, nrows) );
3731 
3732  if( binvrow == NULL )
3733  {
3734  didalloc = 1;
3735 
3736  /* get dense vector */
3737  SCIP_ALLOC( BMSallocMemoryArray(&binv, nrows) );
3738  SCIP_CALL( SCIPlpiGetBInvRow(lpi, row, binv, NULL, NULL) );
3739  }
3740  else
3741  binv = (SCIP_Real*)binvrow;
3742 
3743  /* binvrow*A */
3744  for (i = 0; i < ncols; ++i)
3745  {
3746  coef[i] = 0;
3747 
3748 #if MSK_VERSION_MAJOR < 7
3749  MOSEK_CALL( MSK_getavec(lpi->task, MSK_ACC_VAR, i, &numnz, csub, cval) );
3750 #else
3751  MOSEK_CALL( MSK_getacol(lpi->task, i, &numnz, csub, cval) );
3752 #endif
3753 
3754  /* construct dense vector */
3755  for (k = 0; k < numnz; ++k)
3756  coef[i] += binv[csub[k]] * cval[k];
3757  }
3758 
3759  if ( ninds != NULL )
3760  *ninds = -1;
3761 
3762  /* free memory arrays */
3763  BMSfreeMemoryArray(&cval);
3764  BMSfreeMemoryArray(&csub);
3765 
3766  if ( didalloc > 0 )
3767  {
3768  BMSfreeMemoryArray(&binv);
3769  }
3770 
3771  return SCIP_OKAY;
3772 }
3773 
3774 
3775 /** get column of inverse basis matrix times constraint matrix B^-1 * A */
3777  SCIP_LPI* lpi, /**< LP interface structure */
3778  int c, /**< column number */
3779  SCIP_Real* coef, /**< vector to return coefficients */
3780  int* inds, /**< array to store the non-zero indices, or NULL */
3781  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3782  * (-1: if we do not store sparsity informations) */
3783  )
3784 { /*lint --e{715}*/
3785  SCIP_Real* val;
3786  int nrows;
3787  int numnz;
3788  int i;
3789 
3790  assert(MosekEnv != NULL);
3791  assert(lpi != NULL);
3792  assert(lpi->task != NULL);
3793 
3794  SCIPdebugMessage("Calling SCIPlpiGetBInvACol (%d)\n",lpi->lpid);
3795 
3796  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
3797 #if MSK_VERSION_MAJOR < 7
3798  MOSEK_CALL( MSK_getavecnumnz(lpi->task, MSK_ACC_VAR, c, &numnz) );
3799 #else
3800  MOSEK_CALL( MSK_getacolnumnz(lpi->task, c, &numnz) );
3801 #endif
3802  SCIP_ALLOC( BMSallocMemoryArray( &val, numnz+1) );
3803 
3804  /* init coefficients */
3805  for (i = 0; i < nrows; ++i)
3806  coef[i] = 0;
3807 
3808  /* check whether we require a dense or sparse result vector */
3809  if ( ninds != NULL && inds != NULL )
3810  {
3811 #if MSK_VERSION_MAJOR < 7
3812  MOSEK_CALL( MSK_getavec(lpi->task, MSK_ACC_VAR, c, &numnz, inds, val) );
3813 #else
3814  MOSEK_CALL( MSK_getacol(lpi->task, c, &numnz, inds, val) );
3815 #endif
3816 
3817  for (i = 0; i < numnz; ++i)
3818  coef[inds[i]] = val[i];
3819 
3820  *ninds = numnz;
3821  MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_OFF) );
3822  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, ninds, inds, coef) );
3823  assert( *ninds <= nrows );
3824  }
3825  else
3826  {
3827  int* sub;
3828  SCIP_ALLOC( BMSallocMemoryArray( &sub, nrows) );
3829 
3830 #if MSK_VERSION_MAJOR < 7
3831  MOSEK_CALL( MSK_getavec(lpi->task, MSK_ACC_VAR, c, &numnz, sub, val) );
3832 #else
3833  MOSEK_CALL( MSK_getacol(lpi->task, c, &numnz, sub, val) );
3834 #endif
3835 
3836  for (i = 0; i < numnz; ++i)
3837  coef[sub[i]] = val[i];
3838 
3839  if ( ninds != NULL )
3840  *ninds = numnz;
3841  MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_OFF) );
3842  MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, &numnz, sub, coef) );
3843 
3844  BMSfreeMemoryArray(&sub);
3845  }
3846 
3847  BMSfreeMemoryArray(&val);
3848  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
3849 
3850  return SCIP_OKAY;
3851 }
3852 
3853 
3854 /*
3855  * LP State Methods
3856  */
3857 
3858 /** creates LPi state information object */
3859 static
3861  SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
3862  BMS_BLKMEM* blkmem, /**< block memory */
3863  int ncols, /**< number of columns to store */
3864  int nrows /**< number of rows to store */
3865  )
3866 {
3867  assert(lpistate != NULL);
3868  assert(blkmem != NULL);
3869  assert(ncols >= 0);
3870  assert(nrows >= 0);
3871 
3872  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
3873  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->skx, colpacketNum(ncols)) );
3874  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->skc, rowpacketNum(nrows)) );
3875 
3876  if( lpistate[0] )
3877  {
3878  lpistate[0]->solsta = MSK_SOL_STA_UNKNOWN;
3879  lpistate[0]->num = -1;
3880  lpistate[0]->ncols = ncols;
3881  lpistate[0]->nrows = nrows;
3882  }
3883 
3884  return SCIP_OKAY;
3885 }
3886 
3887 /** frees LPi state information */
3888 static
3890  SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
3891  BMS_BLKMEM* blkmem /**< block memory */
3892  )
3893 {
3894  assert(blkmem != NULL);
3895  assert(lpistate != NULL);
3896  assert(*lpistate != NULL);
3897 
3898  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->skx, colpacketNum((*lpistate)->ncols));
3899  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->skc, rowpacketNum((*lpistate)->nrows));
3900  BMSfreeBlockMemory(blkmem, lpistate);
3901 }
3902 
3903 #ifndef NDEBUG
3904 /** check state */
3905 static
3907  SCIP_LPI* lpi, /**< LP interface structure */
3908  int n, /**< number of rows or columns */
3909  MSKstakeye* sk, /**< ??? */
3910  MSKaccmodee accmode, /**< ??? */
3911  char xc /**< ??? */
3912  )
3913 {
3914  int i;
3915 
3916  /* printout for all except LOW, UPR, FIX and BAS with sl[xc]==su[xc] */
3917  for( i = 0; i < n; i++ )
3918  {
3919  double sl;
3920  double su;
3921  switch (sk[i])
3922  {
3923  case MSK_SK_UNK:
3924  SCIPdebugMessage("STATE[%d]: %c[%d] = unk\n", optimizecount, xc, i);
3925  break;
3926  case MSK_SK_BAS:
3927  MOSEK_CALL( MSK_getsolutioni(lpi->task, accmode, i, MSK_SOL_BAS, NULL, NULL, &sl, &su, NULL) );
3928  if (fabs(sl-su) > DEBUG_CHECK_STATE_TOL)
3929  SCIPdebugMessage("STATE[%d]: %c[%d] = bas, sl%c = %g, su%c = %g\n", optimizecount, xc, i, xc, sl, xc, su);
3930  break;
3931  case MSK_SK_SUPBAS:
3932  SCIPdebugMessage("STATE[%d]: %c[%d] = supbas\n", optimizecount, xc, i);
3933  break;
3934  case MSK_SK_LOW:
3935  case MSK_SK_UPR:
3936  case MSK_SK_FIX:
3937  break;
3938  case MSK_SK_INF:
3939  SCIPdebugMessage("STATE[%d]: %c[%d] = inf\n", optimizecount, xc, i);
3940  break;
3941  default:
3942  SCIPdebugMessage("STATE[%d]: %c[%d] = unknown status <%d>\n", optimizecount, xc, i, sk[i]);
3943  break;
3944  } /*lint !e788*/
3945  }
3946 
3947  return SCIP_OKAY;
3948 }
3949 
3950 /** check state */
3951 static
3953  SCIP_LPI* lpi, /**< LP interface structure */
3954  int ncols, /**< number of columns */
3955  int nrows /**< number of rows */
3956  )
3957 {
3958  SCIP_CALL( checkState1(lpi, ncols, lpi->skx, MSK_ACC_VAR, 'x') );
3959  SCIP_CALL( checkState1(lpi, nrows, lpi->skc, MSK_ACC_CON, 'c') );
3960 
3961  return SCIP_OKAY;
3962  }
3963 #endif
3964 
3965 /** store row and column basis status in a packed LPi state object */
3966 static
3968  SCIP_LPI* lpi, /**< LP interface structure */
3969  SCIP_LPISTATE* lpistate /**< pointer to LPi state data */
3970  )
3971 {
3972  int *skxi = (int *) lpi->skx; /* Used as temp. buffer */
3973  int *skci = (int *) lpi->skc; /* Used as temp. buffer */
3974 
3975  assert(sizeof(int) == sizeof(MSKstakeye));
3976 
3977  SCIP_CALL( convertstat_mosek2scip(lpi, MSK_ACC_VAR, lpi->skx, lpistate->ncols, skxi) );
3978  SCIP_CALL( convertstat_mosek2scip_slack(lpi, MSK_ACC_CON, lpi->skc, lpistate->nrows, skci) );
3979 
3980  SCIPencodeDualBit(skxi, lpistate->skx, lpistate->ncols);
3981  SCIPencodeDualBit(skci, lpistate->skc, lpistate->nrows);
3982 
3983  return SCIP_OKAY;
3984 }
3985 
3986 /** unpacks row and column basis status from a packed LPi state object */
3987 static
3989  const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
3990  MSKstakeye* skx, /**< ??? */
3991  MSKstakeye* skc /**< ??? */
3992  )
3993 {
3994  assert(sizeof(int) == sizeof(MSKstakeye));
3995 
3996  SCIPdecodeDualBit(lpistate->skx, (int*) skx, lpistate->ncols);
3997  SCIPdecodeDualBit(lpistate->skc, (int*) skc, lpistate->nrows);
3998 
3999  convertstat_scip2mosek((int*) skx, lpistate->ncols, skx);
4000  convertstat_scip2mosek_slack((int*) skc, lpistate->nrows, skc);
4001 }
4002 
4003 /** stores LP state (like basis information) into lpistate object */
4005  SCIP_LPI* lpi, /**< LP interface structure */
4006  BMS_BLKMEM* blkmem, /**< block memory */
4007  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
4008  )
4009 {
4010  int gotbasicsol;
4011  int nrows;
4012  int ncols;
4013 
4014  assert(MosekEnv != NULL);
4015  assert(lpi != NULL);
4016  assert(lpi->task != NULL);
4017  assert(lpistate != NULL);
4018 
4019  SCIPdebugMessage("Calling SCIPlpiGetState (%d)\n",lpi->lpid);
4020 
4021  *lpistate = NULL;
4022 
4023  MOSEK_CALL( MSK_solutiondef(lpi->task, MSK_SOL_BAS, &gotbasicsol) );
4024 
4025  if ( gotbasicsol == 0 || SCIPlpiExistsDualRay(lpi) )
4026  return SCIP_OKAY;
4027 
4028  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
4029  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
4030 
4031  /* allocate lpistate data */
4032  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
4033 
4034  lpistate[0]->num = optimizecount;
4035 
4036  MOSEK_CALL(MSK_getsolutionstatus ( lpi->task, MSK_SOL_BAS, NULL, &lpistate[0]->solsta));
4037 
4038  SCIP_CALL( getbase(lpi, ncols, nrows) );
4039 
4040 #ifndef NDEBUG
4041  SCIP_CALL( checkState(lpi, ncols, nrows) );
4042 #endif
4043 
4044  SCIP_CALL( lpistatePack(lpi, lpistate[0]) );
4045 
4046  SCIPdebugMessage("Store into state from iter : %d\n",optimizecount);
4047 
4048  /* if (r != SCIP_OKAY)
4049  * lpistateFree(lpistate, blkmem );
4050  */
4051 
4052  return SCIP_OKAY;
4053 }
4054 
4055 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
4056  * columns and rows since the state was stored with SCIPlpiGetState()
4057  */
4059  SCIP_LPI* lpi, /**< LP interface structure */
4060  BMS_BLKMEM* blkmem, /**< block memory */
4061  const SCIP_LPISTATE* lpistate /**< LP state information (like basis information) */
4062  )
4063 { /*lint --e{715}*/
4064  int nrows;
4065  int ncols;
4066  int i;
4067 
4068  assert(MosekEnv != NULL);
4069  assert(lpi != NULL);
4070  assert(lpi->task != NULL);
4071 
4072  if (lpistate == NULL)
4073  {
4074  SCIPdebugMessage("Setting NULL state\n");
4075  return SCIP_OKAY;
4076  }
4077 
4078  if (lpistate->nrows == 0 || lpistate->ncols == 0)
4079  return SCIP_OKAY;
4080 
4081  MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
4082  MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
4083  assert(lpistate->nrows <= nrows);
4084  assert(lpistate->ncols <= ncols);
4085 
4086  SCIP_CALL( ensureStateMem(lpi, ncols, nrows) );
4087  SCIP_CALL( getbase(lpi, ncols, nrows) );
4088 
4089  lpistateUnpack(lpistate, lpi->skx, lpi->skc);
4090 
4091  /* extend the basis to the current LP beyond the previously existing columns */
4092  for (i = lpistate->ncols; i < ncols; ++i)
4093  {
4094  SCIP_Real lb;
4095  SCIP_Real ub;
4096  MOSEK_CALL( MSK_getboundslice(lpi->task, MSK_ACC_VAR, i, i, NULL, &lb, &ub) );
4097  if ( SCIPlpiIsInfinity(lpi, REALABS(lb)) )
4098  {
4099  /* if lower bound is +/- infinity -> try upper bound */
4100  if ( SCIPlpiIsInfinity(lpi, REALABS(ub)) )
4101  lpi->skx[i] = MSK_SK_SUPBAS; /* variable is free (super basic) */
4102  else
4103  lpi->skx[i] = MSK_SK_UPR; /* use finite upper bound */
4104  }
4105  else
4106  lpi->skx[i] = MSK_SK_LOW; /* use finite lower bound */
4107  }
4108  for (i = lpistate->nrows; i < nrows; ++i)
4109  lpi->skc[i] = MSK_SK_BAS;
4110 
4111  /* load basis information into MOSEK */
4112  SCIP_CALL( setbase(lpi) );
4113 
4114  SCIPdebugMessage("Store from state into task iter : %d with solsta : %d\n", lpistate->num, lpistate->solsta);
4115 
4116  return SCIP_OKAY;
4117 }
4118 
4119 /** clears current LPi state (like basis information) of the solver */
4121  SCIP_LPI* lpi /**< LP interface structure */
4122  )
4123 {
4124  assert(lpi != NULL);
4125 
4126  /**@todo implement SCIPlpiClearState() for MOSEK */
4127  SCIPmessagePrintWarning(lpi->messagehdlr, "MOSEK interface does not implement SCIPlpiClearState()\n");
4128 
4129  return SCIP_OKAY;
4130 }
4131 
4132 /** frees LP state information */
4134  SCIP_LPI* lpi, /**< LP interface structure */
4135  BMS_BLKMEM* blkmem, /**< block memory */
4136  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
4137  )
4138 { /*lint --e{715}*/
4139  assert(MosekEnv != NULL);
4140  assert(lpi != NULL);
4141  assert(lpi->task != NULL);
4142 
4143  SCIPdebugMessage("Calling SCIPlpiFreeState (%d)\n",lpi->lpid);
4144 
4145  if( *lpistate != NULL )
4146  {
4147  lpistateFree(lpistate, blkmem);
4148  }
4149 
4150  return SCIP_OKAY;
4151 }
4152 
4153 /** checks, whether the given LP state contains simplex basis information */
4155  SCIP_LPI* lpi, /**< LP interface structure */
4156  SCIP_LPISTATE* lpistate /**< LP state information (like basis information) */
4157  )
4158 { /*lint --e{715}*/
4159  assert(MosekEnv != NULL);
4160  assert(lpi != NULL);
4161  assert(lpi->task != NULL);
4162 
4163  SCIPdebugMessage("Calling SCIPlpiHasStateBasis (%d)\n",lpi->lpid);
4164 
4165  return ( lpistate != NULL && lpistate->num >= 0);
4166 }
4167 
4168 /** reads LP state (like basis information from a file */
4170  SCIP_LPI* lpi, /**< LP interface structure */
4171  const char* fname /**< file name */
4172  )
4173 {
4174  assert(MosekEnv != NULL);
4175  assert(lpi != NULL);
4176  assert(lpi->task != NULL);
4177 
4178  SCIPdebugMessage("reading LP state from file <%s>\n", fname);
4179 
4180  MOSEK_CALL( MSK_readsolution(lpi->task, MSK_SOL_BAS, fname) );
4181 
4182  return SCIP_OKAY;
4183 }
4184 
4185 /** writes LP state (like basis information) to a file */
4187  SCIP_LPI* lpi, /**< LP interface structure */
4188  const char* fname /**< file name */
4189  )
4190 {
4191  assert(MosekEnv != NULL);
4192  assert(lpi != NULL);
4193  assert(lpi->task != NULL);
4194 
4195  SCIPdebugMessage("writing LP state to file <%s>\n", fname);
4196 
4197  /* set parameter to be able to write */
4198  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_HEAD, MSK_ON) );
4199  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_VARIABLES, MSK_ON) );
4200  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_CONSTRAINTS, MSK_ON) );
4201 
4202  MOSEK_CALL( MSK_writesolution(lpi->task, MSK_SOL_BAS, fname) );
4203 
4204  return SCIP_OKAY;
4205 }
4206 
4207 
4208 
4209 
4210 /*
4211  * LP Pricing Norms Methods
4212  */
4213 
4214 /**@name LP Pricing Norms Methods */
4215 /**@{ */
4216 
4217 /** stores LPi pricing norms information
4218  * @todo should we store norm information?
4219  */
4221  SCIP_LPI* lpi, /**< LP interface structure */
4222  BMS_BLKMEM* blkmem, /**< block memory */
4223  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4224  )
4225 {
4226  assert(lpinorms != NULL);
4227 
4228  (*lpinorms) = NULL;
4229 
4230  return SCIP_OKAY;
4231 }
4232 
4233 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
4234  * columns and rows since the state was stored with SCIPlpiGetNorms()
4235  */
4237  SCIP_LPI* lpi, /**< LP interface structure */
4238  BMS_BLKMEM* blkmem, /**< block memory */
4239  const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information */
4240  )
4241 {
4242  assert(lpinorms == NULL);
4243 
4244  /* no work necessary */
4245  return SCIP_OKAY;
4246 }
4247 
4248 /** frees pricing norms information */
4250  SCIP_LPI* lpi, /**< LP interface structure */
4251  BMS_BLKMEM* blkmem, /**< block memory */
4252  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4253  )
4254 {
4255  assert(lpinorms == NULL);
4256 
4257  /* no work necessary */
4258  return SCIP_OKAY;
4259 }
4260 
4261 /**@} */
4262 
4263 /*
4264  * Parameter Methods
4265  */
4266 
4267 /** constant array containing the parameter names */
4268 static const char* paramname[] = {
4269  "SCIP_LPPAR_FROMSCRATCH", /* solver should start from scratch at next call? */
4270  "SCIP_LPPAR_FASTMIP", /* fast mip setting of LP solver */
4271  "SCIP_LPPAR_SCALING", /* which scaling should LP solver use? */
4272  "SCIP_LPPAR_PRESOLVING", /* should LP solver use presolving? */
4273  "SCIP_LPPAR_PRICING", /* pricing strategy */
4274  "SCIP_LPPAR_LPINFO", /* should LP solver output information to the screen? */
4275  "SCIP_LPPAR_FEASTOL", /* feasibility tolerance for primal variables and slacks */
4276  "SCIP_LPPAR_DUALFEASTOL", /* feasibility tolerance for dual variables and reduced costs */
4277  "SCIP_LPPAR_BARRIERCONVTOL", /* convergence tolerance used in barrier algorithm */
4278  "SCIP_LPPAR_LOBJLIM", /* lower objective limit */
4279  "SCIP_LPPAR_UOBJLIM", /* upper objective limit */
4280  "SCIP_LPPAR_LPITLIM", /* LP iteration limit */
4281  "SCIP_LPPAR_LPTILIM", /* LP time limit */
4282  "SCIP_LPPAR_MARKOWITZ", /* Markowitz tolerance */
4283  "SCIP_LPPAR_ROWREPSWITCH", /* simplex algorithm shall use row representation of the basis
4284  * if number of rows divided by number of columns exceeds this value */
4285  "SCIP_LPPAR_THREADS" /* number of threads used to solve the LP */
4286 };
4287 
4288 /** method mapping parameter index to parameter name */
4289 static
4290 const char* paramty2str(
4291  SCIP_LPPARAM type
4292  )
4293 { /*lint --e{641}*/
4294  /* check if the parameters in this order */
4295  assert(SCIP_LPPAR_FROMSCRATCH == 0); /* solver should start from scratch at next call? */
4296  assert(SCIP_LPPAR_FASTMIP == 1); /* fast mip setting of LP solver */
4297  assert(SCIP_LPPAR_SCALING == 2); /* which scaling should LP solver use? */
4298  assert(SCIP_LPPAR_PRESOLVING == 3); /* should LP solver use presolving? */
4299  assert(SCIP_LPPAR_PRICING == 4); /* pricing strategy */
4300  assert(SCIP_LPPAR_LPINFO == 5); /* should LP solver output information to the screen? */
4301  assert(SCIP_LPPAR_FEASTOL == 6); /* feasibility tolerance for primal variables and slacks */
4302  assert(SCIP_LPPAR_DUALFEASTOL == 7); /* feasibility tolerance for dual variables and reduced costs */
4303  assert(SCIP_LPPAR_BARRIERCONVTOL == 8); /* convergence tolerance used in barrier algorithm */
4304  assert(SCIP_LPPAR_LOBJLIM == 9); /* lower objective limit */
4305  assert(SCIP_LPPAR_UOBJLIM == 10); /* upper objective limit */
4306  assert(SCIP_LPPAR_LPITLIM == 11); /* LP iteration limit */
4307  assert(SCIP_LPPAR_LPTILIM == 12); /* LP time limit */
4308  assert(SCIP_LPPAR_MARKOWITZ == 13); /* Markowitz tolerance */
4309  assert(SCIP_LPPAR_ROWREPSWITCH == 14); /* row representation switch */
4310  assert(SCIP_LPPAR_THREADS == 15); /* number of threads used to solve the LP */
4311 
4312  return paramname[type];
4313 }
4314 
4315 /** gets integer parameter of LP */
4317  SCIP_LPI* lpi, /**< LP interface structure */
4318  SCIP_LPPARAM type, /**< parameter number */
4319  int* ival /**< buffer to store the parameter value */
4320  )
4321 { /*lint --e{641}*/
4322  assert(MosekEnv != NULL);
4323  assert(lpi != NULL);
4324  assert(lpi->task != NULL);
4325 
4326  SCIPdebugMessage("getting int parameter %s\n", paramty2str(type));
4327 
4328  switch (type)
4329  {
4330  case SCIP_LPPAR_FROMSCRATCH: /* solver should start from scratch at next call? */
4331  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, ival) );
4332  *ival = (*ival == MSK_SIM_HOTSTART_NONE);
4333  break;
4334  case SCIP_LPPAR_FASTMIP: /* fast mip setting of LP solver */
4335  return SCIP_PARAMETERUNKNOWN;
4336  case SCIP_LPPAR_SCALING: /* should LP solver use scaling? */
4337  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_SCALING, ival) );
4338  if( *ival == MSK_SCALING_NONE )
4339  *ival = 0;
4340  else if( *ival == MSK_SCALING_AGGRESSIVE )
4341  *ival = 2;
4342  else
4343  *ival = 1;
4344  break;
4345  case SCIP_LPPAR_PRESOLVING: /* should LP solver use presolving? */
4346  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, ival) );
4347  *ival = (*ival != MSK_PRESOLVE_MODE_OFF);
4348  break;
4349  case SCIP_LPPAR_PRICING: /* pricing strategy */
4350  *ival = lpi->pricing;
4351  break;
4352  case SCIP_LPPAR_LPINFO: /* should LP solver output information to the screen? */
4353  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_LOG, ival) );
4354  *ival = (*ival == MSK_ON);
4355  break;
4356  case SCIP_LPPAR_LPITLIM: /* LP iteration limit */
4357  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, ival) );
4358  break;
4359  default:
4360  return SCIP_PARAMETERUNKNOWN;
4361  } /*lint !e788*/
4362 
4363  return SCIP_OKAY;
4364 }
4365 
4366 /** sets integer parameter of LP */
4368  SCIP_LPI* lpi, /**< LP interface structure */
4369  SCIP_LPPARAM type, /**< parameter number */
4370  int ival /**< parameter value */
4371  )
4372 {
4373  int scaling;
4374 
4375 #if SCIP_CONTROLS_PRICING
4376  /*lint --e{641}*/
4377  static int pricing[7] =
4378  {
4379  MSK_SIM_SELECTION_SE,
4380  MSK_SIM_SELECTION_SE,
4381  MSK_SIM_SELECTION_FULL,
4382  MSK_SIM_SELECTION_PARTIAL,
4383  MSK_SIM_SELECTION_SE,
4384  MSK_SIM_SELECTION_ASE,
4385  MSK_SIM_SELECTION_DEVEX,
4386  };
4387 #endif
4388 
4389  assert(SCIP_PRICING_LPIDEFAULT == 0);
4390  assert(SCIP_PRICING_AUTO == 1);
4391  assert(SCIP_PRICING_FULL == 2);
4392  assert(SCIP_PRICING_PARTIAL == 3);
4393  assert(SCIP_PRICING_STEEP == 4);
4394  assert(SCIP_PRICING_STEEPQSTART == 5);
4395  assert(SCIP_PRICING_DEVEX == 6);
4396 
4397  assert(MosekEnv != NULL);
4398  assert(lpi != NULL);
4399  assert(lpi->task != NULL);
4400 
4401  SCIPdebugMessage("Calling SCIPlpiSetIntpar (%d) Parameter=<%s> Value=<%d>\n", lpi->lpid, paramty2str(type), ival);
4402 
4403  switch (type)
4404  {
4405  case SCIP_LPPAR_FROMSCRATCH: /* solver should start from scratch at next call? */
4406  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART,
4407  ival ? MSK_SIM_HOTSTART_NONE : MSK_SIM_HOTSTART_STATUS_KEYS ) );
4408  break;
4409  case SCIP_LPPAR_FASTMIP: /* fast mip setting of LP solver */
4410  return SCIP_PARAMETERUNKNOWN;
4411  case SCIP_LPPAR_SCALING: /* should LP solver use scaling? */
4412  if( ival == 0 )
4413  scaling = MSK_SCALING_NONE;
4414  else if( ival == 1 )
4415  scaling = MSK_SCALING_FREE;
4416  else
4417  scaling = MSK_SCALING_AGGRESSIVE;
4418 
4419  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, scaling) );
4420  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_SCALING, scaling) );
4421  break;
4422  case SCIP_LPPAR_PRESOLVING: /* should LP solver use presolving? */
4423  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_PRESOLVE_USE,
4424  ival ? MSK_PRESOLVE_MODE_FREE : MSK_PRESOLVE_MODE_OFF) );
4425 
4426 #ifdef SCIP_DEBUG
4427  if( ival )
4428  {
4429  SCIPdebugMessage("Setting presolve to on\n");
4430  }
4431 #endif
4432  break;
4433  case SCIP_LPPAR_PRICING: /* pricing strategy */
4434  assert(ival >= 0 && ival <= SCIP_PRICING_DEVEX);
4435  lpi->pricing = (SCIP_PRICING)ival;
4436 
4437 #ifdef SCIP_DEBUG
4438  switch( (SCIP_PRICING)ival )
4439  {
4440  case SCIP_PRICING_AUTO:
4441  SCIPdebugMessage("Setting pricing to auto\n");
4442  break;
4443  case SCIP_PRICING_FULL:
4444  SCIPdebugMessage("Setting pricing to full\n");
4445  break;
4446  case SCIP_PRICING_PARTIAL:
4447  SCIPdebugMessage("Setting pricing to partial\n");
4448  break;
4450  SCIPdebugMessage("Setting pricing to lpi default\n");
4451  break;
4452  case SCIP_PRICING_STEEP:
4453  SCIPdebugMessage("Setting pricing to steep\n");
4454  break;
4456  SCIPdebugMessage("Setting pricing to steep quick start\n");
4457  break;
4458  case SCIP_PRICING_DEVEX:
4459  SCIPdebugMessage("Setting pricing to devex\n");
4460  break;
4461  }
4462 #endif
4463 
4464 #if SCIP_CONTROLS_PRICING
4465  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_SELECTION, pricing[ival]) );
4466 
4467  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, pricing[ival]) );
4468 
4469  if( !(lpi->pricing == SCIP_PRICING_PARTIAL || lpi->pricing == SCIP_PRICING_AUTO ) )
4470  {
4471  /* No restrict */
4472  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION, 0) );
4473 
4474  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION, 0) );
4475  }
4476 #else
4477  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_SELECTION, MSK_SIM_SELECTION_FREE) );
4478 
4479  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, MSK_SIM_SELECTION_FREE) );
4480 #endif
4481  break;
4482  case SCIP_LPPAR_LPINFO:
4483  /* should LP solver output information to the screen? */
4484 #if FORCE_MOSEK_LOG
4485  SCIPdebugMessage("Ignoring log setting!\n");
4486 #else
4487  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, ival ? MSK_ON : MSK_OFF) );
4488 #endif
4489  break;
4490  case SCIP_LPPAR_LPITLIM: /* LP iteration limit */
4491 #if DEBUG_PARAM_SETTING
4492  if( ival )
4493  {
4494  SCIPdebugMessage("Setting max iter to : %d\n",ival);
4495  }
4496 #endif
4497 
4498  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, ival) );
4499  break;
4500  default:
4501  return SCIP_PARAMETERUNKNOWN;
4502  } /*lint !e788*/
4503 
4504  return SCIP_OKAY;
4505 }
4506 
4507 /** gets floating point parameter of LP */
4509  SCIP_LPI* lpi, /**< LP interface structure */
4510  SCIP_LPPARAM type, /**< parameter number */
4511  SCIP_Real* dval /**< buffer to store the parameter value */
4512  )
4513 {
4514  assert(MosekEnv != NULL);
4515  assert(lpi != NULL);
4516  assert(lpi->task != NULL);
4517 
4518  SCIPdebugMessage("getting real parameter %s\n", paramty2str(type));
4519 
4520  switch (type)
4521  {
4522 #if SCIP_CONTROLS_TOLERANCES
4523  case SCIP_LPPAR_FEASTOL: /* feasibility tolerance for primal variables and slacks */
4524  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_BASIS_TOL_X, dval) );
4525  break;
4526  case SCIP_LPPAR_DUALFEASTOL: /* feasibility tolerance for dual variables and reduced costs */
4527  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_BASIS_TOL_S, dval) );
4528  break;
4529  case SCIP_LPPAR_BARRIERCONVTOL: /* convergence tolerance used in barrier algorithm */
4530  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_INTPNT_TOL_REL_GAP, dval) );
4531  break;
4532 #endif
4533  case SCIP_LPPAR_LOBJLIM: /* lower objective limit */
4534  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, dval) );
4535  break;
4536  case SCIP_LPPAR_UOBJLIM: /* upper objective limit */
4537  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, dval) );
4538  break;
4539  case SCIP_LPPAR_LPTILIM: /* LP time limit */
4540  MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_OPTIMIZER_MAX_TIME, dval) );
4541  break;
4542  case SCIP_LPPAR_MARKOWITZ: /* Markowitz tolerance */
4543  default:
4544  return SCIP_PARAMETERUNKNOWN;
4545  } /*lint !e788*/
4546 
4547  return SCIP_OKAY;
4548 }
4549 
4550 /** sets floating point parameter of LP */
4552  SCIP_LPI* lpi, /**< LP interface structure */
4553  SCIP_LPPARAM type, /**< parameter number */
4554  SCIP_Real dval /**< parameter value */
4555  )
4556 {
4557  assert(MosekEnv != NULL);
4558  assert(lpi != NULL);
4559  assert(lpi->task != NULL);
4560 
4561  SCIPdebugMessage("setting real parameter %s to %g\n", paramty2str(type), dval);
4562 
4563  /**@todo Limits shouldn't be hardcoded */
4564 
4565  switch (type)
4566  {
4567 #if SCIP_CONTROLS_TOLERANCES
4568  case SCIP_LPPAR_FEASTOL: /* feasibility tolerance for primal variables and slacks */
4569  if (dval < 1e-9)
4570  dval = 1e-9;
4571 
4572  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_BASIS_TOL_X, dval) );
4573  break;
4574  case SCIP_LPPAR_DUALFEASTOL: /* feasibility tolerance for dual variables and reduced costs */
4575  if (dval < 1e-9)
4576  return SCIP_PARAMETERUNKNOWN;
4577  /* dval = 1e-9; */
4578 
4579  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_BASIS_TOL_S, dval) );
4580  break;
4581  case SCIP_LPPAR_BARRIERCONVTOL: /* convergence tolerance used in barrier algorithm */
4582  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_INTPNT_TOL_REL_GAP, dval) );
4583  break;
4584 #endif
4585  case SCIP_LPPAR_LOBJLIM: /* lower objective limit */
4586  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, dval) );
4587  break;
4588  case SCIP_LPPAR_UOBJLIM: /* upper objective limit */
4589  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, dval) );
4590  break;
4591  case SCIP_LPPAR_LPTILIM: /* LP time limit */
4592  MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_OPTIMIZER_MAX_TIME, dval) );
4593  break;
4594  case SCIP_LPPAR_MARKOWITZ: /* Markowitz tolerance */
4595  default:
4596  return SCIP_PARAMETERUNKNOWN;
4597  } /*lint !e788*/
4598 
4599  return SCIP_OKAY;
4600 }
4601 
4602 
4603 /*
4604  * Numerical Methods
4605  */
4606 
4607 
4608 /** returns value treated as infinity in the LP solver */
4610  SCIP_LPI* lpi /**< LP interface structure */
4611  )
4612 { /*lint --e{715}*/
4613  assert(MosekEnv != NULL);
4614  assert(lpi != NULL);
4615  assert(lpi->task != NULL);
4616 
4617  return MSK_INFINITY;
4618 }
4619 
4620 /** checks if given value is treated as infinity in the LP solver */
4622  SCIP_LPI* lpi, /**< LP interface structure */
4623  SCIP_Real val /**< value to be checked for infinity */
4624  )
4625 { /*lint --e{715}*/
4626  assert(MosekEnv != NULL);
4627  assert(lpi != NULL);
4628  assert(lpi->task != NULL);
4629 
4630  return IS_POSINF(val);
4631 }
4632 
4633 
4634 /*
4635  * File Interface Methods
4636  */
4637 
4638 
4639 /** reads LP from a file */
4641  SCIP_LPI* lpi, /**< LP interface structure */
4642  const char* fname /**< file name */
4643  )
4644 {
4645  int olddataformat;
4646 
4647  assert(MosekEnv != NULL);
4648  assert(lpi != NULL);
4649  assert(lpi->task != NULL);
4650 
4651  SCIPdebugMessage("Calling SCIPlpiReadLP (%d), filename <%s>\n",lpi->lpid, fname);
4652 
4653  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, &olddataformat) );
4654  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, MSK_DATA_FORMAT_LP) );
4655  MOSEK_CALL( MSK_readdata(lpi->task, fname) );
4656  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, olddataformat) );
4657 
4658  return SCIP_OKAY;
4659 }
4660 
4661 /** writes LP to a file */
4663  SCIP_LPI* lpi, /**< LP interface structure */
4664  const char* fname /**< file name */
4665  )
4666 {
4667  int olddataformat;
4668 
4669  assert(MosekEnv != NULL);
4670  assert(lpi != NULL);
4671  assert(lpi->task != NULL);
4672 
4673  SCIPdebugMessage("Calling SCIPlpiReadLP (%d), filename <%s>\n",lpi->lpid, fname);
4674 
4675  MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, &olddataformat) );
4676  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, MSK_DATA_FORMAT_LP) );
4677  MOSEK_CALL( MSK_writedata(lpi->task, fname) );
4678  MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, olddataformat) );
4679 
4680  return SCIP_OKAY;
4681 }
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:4662
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_msk.c:3776
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:3043
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_msk.c:3055
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:103
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_msk.c:4640
int nrows
Definition: lpi_none.c:39
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_msk.c:3889
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_msk.c:3200
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:3988
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:3136
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int row, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_msk.c:3631
interface methods for specific LP solvers
static void convertstat_scip2mosek(const int *stat, int n, MSKstakeye *resstat)
Definition: lpi_msk.c:3388
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_msk.c:3218
#define FALSE
Definition: def.h:64
#define EPSEQ(x, y, eps)
Definition: def.h:160
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_msk.c:2934
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:3451
#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:4367
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:2702
#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:3860
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_msk.c:4249
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:78
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:3419
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int row, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_msk.c:3698
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_msk.c:1213
#define BMSfreeMemory(ptr)
Definition: memory.h:100
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_msk.c:3485
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_msk.c:4220
#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:3010
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:3182
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:3967
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:2983
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_msk.c:2991
int skcsize
Definition: lpi_msk.c:143
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_msk.c:4186
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:3515
packing single and dual bit values
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_msk.c:2397
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:102
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_msk.c:3239
#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:3282
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:4236
static SCIP_RETCODE presolve(SCIP *scip, SCIP_Bool *unbounded, SCIP_Bool *infeasible)
Definition: scip.c:14530
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:4058
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:4551
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:2416
#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:159
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:3255
MSKtask_t task
Definition: lpi_msk.c:137
#define SCIP_CALL(x)
Definition: def.h:306
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:3117
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:4004
static SCIP_RETCODE checkState1(SCIP_LPI *lpi, int n, MSKstakeye *sk, MSKaccmodee accmode, char xc)
Definition: lpi_msk.c:3906
void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: bitencode.c:228
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_msk.c:2767
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:169
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_msk.c:3028
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:419
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:2880
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:4120
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:408
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:4290
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:2643
static const char * paramname[]
Definition: lpi_msk.c:4268
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_msk.c:2898
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_msk.c:3100
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_msk.c:4169
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_msk.c:705
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:421
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:2723
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_msk.c:2975
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:4621
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:4154
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:2664
static SCIP_RETCODE checkState(SCIP_LPI *lpi, int ncols, int nrows)
Definition: lpi_msk.c:3952
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:4133
static int numstrongbranchobjdo
Definition: lpi_msk.c:77
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_msk.c:2957
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_msk.c:2906
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:2795
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:3560
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:135
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_msk.c:4609
#define BMSallocMemory(ptr)
Definition: memory.h:74
#define SCIP_INVALID
Definition: def.h:155
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:82
static SCIP_RETCODE convertstat_mosek2scip_slack(SCIP_LPI *lpi, MSKaccmodee acc, MSKstakeye *sk, int m, int *stat)
Definition: lpi_msk.c:3338
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:4508
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_msk.c:4316
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_msk.c:2406
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:2914
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:406
#define SENSE2MOSEK(objsen)
Definition: lpi_msk.c:37
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_msk.c:2857
#define EPSFLOOR(x, eps)
Definition: def.h:168
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_msk.c:2323
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:392
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:3067
#define SCIP_ALLOC(x)
Definition: def.h:317
#define SCIPABORT()
Definition: def.h:278
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:3079
#define DEGEN_LEVEL
Definition: lpi_msk.c:103
static int numlp
Definition: lpi_msk.c:68