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