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-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file lpi_msk.c
    26 * @ingroup LPIS
    27 * @brief LP interface for MOSEK
    28 * @author Bo Jensen
    29 * @author Tristan Gally
    30 * @author Marc Pfetsch
    31 *
    32 * @todo Check whether MSK_IPAR_{SIM_DUAL|PRIMAL}_RESTRICT_SELECTION should be used if problem is solved from scratch or
    33 * if no basis is available.
    34 * @todo Revise handling of the MSK_RES_TRM_MAX_NUM_SETBACKS return value: Remove it form the check of MOSEK_CALL and
    35 * include it in filterTRMrescode().
    36 * @todo Check whether SCIPlpiGetSolFeasibility() should also return primal/dual feasible if the status is
    37 * MSK_SOL_STA_NEAR_PRIM_FEAS, MSK_SOL_STA_NEAR_DUAL_FEAS.
    38 * @todo Check why it can happen that the termination code is MSK_RES_OK, but the solution status is MSK_SOL_STA_UNKNOWN.
    39 */
    40
    41/*lint -e750*/
    42/*lint -e830*/
    43
    44#include <assert.h>
    45
    46#define MSKCONST const /* this define is needed for older MOSEK versions */
    47#include "mosek.h"
    48
    49#include "lpi/lpi.h"
    50#include "scip/bitencode.h"
    51#include "scip/pub_message.h"
    52#include <string.h>
    53#include "tinycthread/tinycthread.h"
    54
    55/* do defines for windows directly here to make the lpi more independent */
    56#ifdef _WIN32
    57#define snprintf _snprintf
    58#endif
    59
    60#if ( MSK_VERSION_MAJOR < 7 )
    61#error "The MOSEK interface only works for MOSEK versions 7.0.0.0 and newer"
    62#endif
    63
    64#define scipmskobjsen MSKobjsensee
    65#define SENSE2MOSEK(objsen) (((objsen)==SCIP_OBJSEN_MINIMIZE)?(MSK_OBJECTIVE_SENSE_MINIMIZE):(MSK_OBJECTIVE_SENSE_MAXIMIZE))
    66
    67typedef enum MSKoptimizertype_enum MSKoptimizertype;
    68
    69#define MOSEK_CALL(x) do \
    70 { /*lint --e{641}*/ \
    71 MSKrescodee _restat_; \
    72 _restat_ = (x); \
    73 if( (_restat_) != MSK_RES_OK && (_restat_ ) != MSK_RES_TRM_MAX_NUM_SETBACKS ) \
    74 { \
    75 SCIPerrorMessage("LP Error: MOSEK returned %d.\n", (int)_restat_); \
    76 return SCIP_LPERROR; \
    77 } \
    78 } \
    79 while( FALSE )
    80
    81/* this macro is only called in functions returning SCIP_Bool; thus, we return FALSE if there is an error in optimized mode */
    82#define SCIP_ABORT_FALSE(x) do \
    83 { \
    84 SCIP_RETCODE _restat_; \
    85 if( (_restat_ = (x)) != SCIP_OKAY ) \
    86 { \
    87 SCIPerrorMessage("LP Error: MOSEK returned %d.\n", (int)_restat_); \
    88 SCIPABORT(); \
    89 return FALSE; \
    90 } \
    91 } \
    92 while( FALSE )
    93
    94#define IS_POSINF(x) ((x) >= MSK_INFINITY)
    95#define IS_NEGINF(x) ((x) <= -MSK_INFINITY)
    96#define MOSEK_relDiff(val1, val2) ( ((val1)-(val2))/(MAX3(1.0,REALABS(val1),REALABS(val2))) )
    97
    98#ifdef SCIP_THREADSAFE
    99 #if defined(_Thread_local)
    100 /* Use thread local environment in order to not create a new environment for each new LP. */
    101 static _Thread_local MSKenv_t reusemosekenv = NULL;
    102 static _Thread_local int numlp = 0;
    103 #define SCIP_REUSEENV
    104 #endif
    105#else
    106 /* Global Mosek environment in order to not create a new environment for each new LP. This is not thread safe. */
    107 static MSKenv_t reusemosekenv = NULL;
    108 static int numlp = 0;
    109 #define SCIP_REUSEENV
    110#endif
    111
    112#if MSK_VERSION_MAJOR >= 9
    113#define NEAR_REL_TOLERANCE 1.0 /* MOSEK will multiply all tolerances with this factor after stalling */
    114#endif
    115#define DEBUG_PRINT_STAT 0
    116#define DEBUG_PARAM_SETTING 0
    117#define DEBUG_CHECK_DATA 0
    118#define DEBUG_EASY_REPRODUCE 0
    119#define DEBUG_DO_INTPNT_FEAS_CHECK 0
    120#define DEBUG_CHECK_STATE_TOL 1e-5
    121#define SHOW_ERRORS 0
    122#define SHOW_RELATIVE_OPTIMAL_GAP 0
    123#define ASSERT_ON_NUMERICAL_TROUBLES 0
    124#define ASSERT_ON_WARNING 0
    125#define FORCE_MOSEK_LOG 0 /* note that changing this AND setting lpinfo will lead to asserts in lpCheckIntpar */
    126#define FORCE_MOSEK_SUMMARY 0
    127#define FORCE_NO_MAXITER 0
    128#define SETBACK_LIMIT 250
    129#define STRONGBRANCH_PRICING MSK_SIM_SELECTION_SE
    130#define SUPRESS_NAME_ERROR 1
    131#define WRITE_DUAL 0
    132#define WRITE_PRIMAL 0
    133#define WRITE_INTPNT 0
    134#if WRITE_DUAL > 0 || WRITE_PRIMAL > 0 || WRITE_INTPNT > 0 || FORCE_MOSEK_LOG > 0 || FORCE_MOSEK_SUMMARY > 0
    135#define WRITE_ABOVE 0
    136#endif
    137#define DEGEN_LEVEL MSK_SIM_DEGEN_FREE
    138#define ALWAYS_SOLVE_PRIMAL_FORM 1
    139#if DEBUG_PRINT_STAT > 0
    140static int numstrongbranchmaxiterup = 0;
    141static int numstrongbranchmaxiterdo = 0;
    142static int numprimalmaxiter = 0;
    143static int numdualmaxiter = 0;
    144static int numstrongbranchobjup = 0;
    145static int numstrongbranchobjdo = 0;
    146static int numprimalobj = 0;
    147static int numdualobj = 0;
    148#endif
    149
    150#if DEBUG_PRINT_STAT > 0
    151static int numstrongbranchmaxiterup = 0;
    152static int numstrongbranchmaxiterdo = 0;
    153static int numprimalmaxiter = 0;
    154static int numdualmaxiter = 0;
    155static int numstrongbranchobjup = 0;
    156static int numstrongbranchobjdo = 0;
    157static int numprimalobj = 0;
    158static int numdualobj = 0;
    159#endif
    160
    161
    162/** internal data for Mosek LPI */
    163struct SCIP_LPi
    164{
    165 MSKenv_t mosekenv; /**< Mosek environment */
    166#ifdef SCIP_REUSEENV
    167 int* numlp; /**< pointer to count on number of tasks in environment */
    168 MSKenv_t* reusemosekenv; /**< pointer to reused Mosek environment */
    169#endif
    170 MSKtask_t task; /**< Mosek task */
    171 int optimizecount; /**< optimization counter (mainly for debugging) */
    172 MSKrescodee termcode; /**< termination code of last optimization run */
    173 int itercount; /**< iteration count of last optimization run */
    174 SCIP_PRICING pricing; /**< SCIP pricing setting */
    175 int scaling; /**< SCIP scaling setting */
    176 int lpid; /**< id for LP within same task */
    177 MSKoptimizertype lastalgo; /**< algorithm type of last solving call */
    178 MSKstakeye* skx; /**< basis status for columns */
    179 MSKstakeye* skc; /**< basis status for rows */
    180 MSKboundkeye* bkx; /**< bound keys for columns */
    181 MSKboundkeye* bkc; /**< bound keys for rows */
    182 MSKint32t* aptre; /**< row or column end pointers */
    183 int skxsize; /**< size of skx array */
    184 int skcsize; /**< size of skc array */
    185 int bkxsize; /**< size of bkx */
    186 int bkcsize; /**< size of bkx */
    187 int aptresize; /**< size of aptre */
    188 MSKsoltypee lastsolvetype; /**< Which solver was called last and which solution should be returned? */
    189 SCIP_Bool solved; /**< was the current LP solved? */
    190 SCIP_Bool fromscratch; /**< Shall solves be performed with MSK_IPAR_SIM_HOTSTART turned off? */
    191 SCIP_Bool clearstate; /**< Shall next solve be performed with MSK_IPAR_SIM_HOTSTART turned off? */
    192 SCIP_Bool lpinfo; /**< Should LP solver output information to the screen? */
    193 int restrictselectdef; /**< default value for MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION */
    194 SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
    195};
    196
    197typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
    198#define COLS_PER_PACKET SCIP_DUALPACKETSIZE
    199typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
    200#define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
    201
    202/** basis status */
    203struct SCIP_LPiState
    204{
    205 int num;
    206 MSKsolstae solsta; /**< solution status */
    207 int ncols; /**< number of columns */
    208 int nrows; /**< number of rows */
    209 COLPACKET* skx; /**< basis status for columns */
    210 ROWPACKET* skc; /**< basis status for rows */
    211};
    212
    213
    214/*
    215 * Local functions
    216 */
    217
    218/** gives problem and solution status for a Mosek Task
    219 *
    220 * With Mosek 7.0, the routine MSK_getsolutionstatus was replaced by MSK_getprosta and MSK_getsolsta.
    221 */
    222static
    224 MSKtask_t task, /**< Mosek Task */
    225 MSKsoltypee whichsol, /**< for which type of solution a status is requested */
    226 MSKprostae* prosta, /**< buffer to store problem status, or NULL if not needed */
    227 MSKsolstae* solsta /**< buffer to store solution status, or NULL if not needed */
    228 )
    229{
    230 MSKrescodee res;
    231
    232 if( prosta != NULL )
    233 {
    234 res = MSK_getprosta(task, whichsol, prosta);
    235 if ( res != MSK_RES_OK )
    236 return res;
    237 }
    238 if( solsta != NULL )
    239 {
    240 res = MSK_getsolsta(task, whichsol, solsta);
    241 if ( res != MSK_RES_OK )
    242 return res;
    243 }
    244
    245 return MSK_RES_OK;
    246}
    247
    248/** returns the number of packets needed to store column packet information */
    249static
    251 int ncols /**< number of columns to store */
    252 )
    253{
    254 return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
    255}
    256
    257/** returns the number of packets needed to store row packet information */
    258static
    260 int nrows /**< number of rows to store */
    261 )
    262{
    263 return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
    264}
    265
    266/** print string using message handler of SCIP */
    267static
    268void MSKAPI printstr(
    269 MSKuserhandle_t handle, /**< error handle */
    270 const char* str /**< string that contains string on output */
    271 )
    272{ /*lint --e{715}*/
    273#if SUPRESS_NAME_ERROR
    274 char errstr[32];
    275 (void) snprintf(errstr, 32, "MOSEK Error %d", MSK_RES_ERR_DUP_NAME);
    276 if (0 == strncmp(errstr, str, strlen(errstr)))
    277 return;
    278#endif
    279
    280 if ( handle == NULL )
    281 printf("MOSEK: %s", str);
    282 else
    283 SCIPmessagePrintInfo((SCIP_MESSAGEHDLR *) handle, "MOSEK: %s", str);
    284}
    285
    286#if DEBUG_CHECK_DATA > 0
    287/** check data */
    288static
    289SCIP_RETCODE scip_checkdata(
    290 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
    291 const char* functionname /**< function name */
    292 )
    293{
    294 int i;
    295 int numcon;
    296 int numvar;
    297 int gotbasicsol;
    298 MSKboundkeye* tbkc;
    299 MSKboundkeye* tbkx;
    300 MSKstakeye *tskc;
    301 MSKstakeye* tskx;
    302 double* tblc;
    303 double* tbuc;
    304 double* tblx;
    305 double* tbux;
    306
    307 assert(lpi != NULL);
    308 assert(lpi->mosekenv != NULL);
    309 assert(lpi->task != NULL);
    310
    311 MOSEK_CALL( MSK_solutiondef(lpi->task, MSK_SOL_BAS, &gotbasicsol) );
    312
    313 MOSEK_CALL( MSK_getnumvar(lpi->task, &numvar) );
    314 MOSEK_CALL( MSK_getnumcon(lpi->task, &numcon) );
    315
    316 /* allocate memory */
    317 SCIP_ALLOC( BMSallocMemoryArray(&tbkc, numcon) );
    318 SCIP_ALLOC( BMSallocMemoryArray(&tskc, numcon) );
    319 SCIP_ALLOC( BMSallocMemoryArray(&tblc, numcon) );
    320 SCIP_ALLOC( BMSallocMemoryArray(&tbuc, numcon) );
    321
    322 SCIP_ALLOC( BMSallocMemoryArray(&tbkx, numvar) );
    323 SCIP_ALLOC( BMSallocMemoryArray(&tskx, numvar) );
    324 SCIP_ALLOC( BMSallocMemoryArray(&tblx, numvar) );
    325 SCIP_ALLOC( BMSallocMemoryArray(&tbux, numvar) );
    326
    327 /* Check bounds */
    328 if( gotbasicsol )
    329 {
    330 MOSEK_CALL( MSK_getsolution(lpi->task, MSK_SOL_BAS, NULL, NULL, tskc, tskx,
    331 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
    332 }
    333
    334 for( i = 0; i < numvar; i++ )
    335 {
    336 MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_VAR, i, &tbkx[i], &tblx[i], &tbux[i]) );
    337 }
    338
    339 for( i = 0; i < numcon; i++ )
    340 {
    341 MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_CON, i, &tbkc[i], &tblc[i], &tbuc[i]) );
    342 }
    343
    344 for( i = 0; i < numcon; ++i )
    345 {
    346 if( gotbasicsol )
    347 {
    348 if( ( tskc[i] == MSK_SK_FIX && tbkc[i] != MSK_BK_FX ) ||
    349 ( tskc[i] == MSK_SK_LOW && !(tbkc[i] == MSK_BK_FX || tbkc[i] == MSK_BK_LO || tbkc[i] == MSK_BK_RA ) ) ||
    350 ( tskc[i] == MSK_SK_UPR && !(tbkc[i] == MSK_BK_FX || tbkc[i] == MSK_BK_UP || tbkc[i] == MSK_BK_RA ) ) )
    351 {
    352 SCIPerrorMessage("STATUS KEY ERROR i %d bkc %d skc %d %s\n", i, tbkc[i], tskc[i], functionname);
    353 }
    354 }
    355
    356 if( tbkc[i] == MSK_BK_LO || tbkc[i] == MSK_BK_FX || tbkc[i] == MSK_BK_RA )
    357 {
    358 if( isnan(tblc[i]) )
    359 {
    360 SCIPdebugMessage("nan in blc : %s\n", functionname);
    361 }
    362 }
    363
    364 if( tbkc[i] == MSK_BK_UP || tbkc[i] == MSK_BK_FX || tbkc[i] == MSK_BK_RA )
    365 {
    366 if( isnan(tbuc[i]) )
    367 {
    368 SCIPdebugMessage("nan in bux : %s\n", functionname);
    369 }
    370 }
    371 }
    372
    373 for( i = 0; i < numvar; ++i )
    374 {
    375 if( tbkx[i] == MSK_BK_LO || tbkx[i] == MSK_BK_FX || tbkx[i] == MSK_BK_RA )
    376 {
    377 if( isnan(tblx[i]) )
    378 {
    379 SCIPdebugMessage("nan in blx : %s\n", functionname);
    380 }
    381 }
    382
    383 if( tbkx[i] == MSK_BK_UP || tbkx[i] == MSK_BK_FX || tbkx[i] == MSK_BK_RA )
    384 {
    385 if( isnan(tbux[i]) )
    386 {
    387 SCIPdebugMessage("nan in bux : %s\n", functionname);
    388 getchar();
    389 }
    390 }
    391 }
    392
    393 BMSfreeMemoryArray(&tbkc);
    394 BMSfreeMemoryArray(&tskc);
    395 BMSfreeMemoryArray(&tblc);
    396 BMSfreeMemoryArray(&tbuc);
    397 BMSfreeMemoryArray(&tbkx);
    398 BMSfreeMemoryArray(&tskx);
    399 BMSfreeMemoryArray(&tblx);
    400 BMSfreeMemoryArray(&tbux);
    401
    402 return SCIP_OKAY;
    403}
    404#endif
    405
    406/** resizes bound keys array bkx to have at least ncols entries */
    407static
    409 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
    410 int ncols /**< number of columns */
    411 )
    412{
    413 if ( lpi->bkxsize < ncols )
    414 {
    415 int newsize;
    416 newsize = MAX(2*lpi->bkxsize, ncols);
    417
    418 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->bkx), newsize) );
    419 lpi->bkxsize = newsize;
    420 }
    421
    422 return SCIP_OKAY;
    423}
    424
    425/** resizes bound keys array bkc to have at least nrows entries */
    426static
    428 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
    429 int nrows /**< number of rows */
    430 )
    431{
    432 if ( lpi->bkcsize < nrows )
    433 {
    434 int newsize;
    435 newsize = MAX(2*lpi->bkcsize, nrows);
    436
    437 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->bkc), newsize) );
    438 lpi->bkcsize = newsize;
    439 }
    440
    441 return SCIP_OKAY;
    442}
    443
    444/** resizes aptre array to have at least n entries */
    445static
    447 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
    448 int n /**< number of entries */
    449 )
    450{
    451 if ( lpi->aptresize < n )
    452 {
    453 int newsize;
    454 newsize = MAX(2*lpi->aptresize, n);
    455
    456 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->aptre), newsize) );
    457 lpi->aptresize = newsize;
    458 }
    459
    460 return SCIP_OKAY;
    461}
    462
    463/** marks the current LP to be unsolved */
    464static
    466 SCIP_LPI* lpi /**< pointer to an LP interface structure */
    467 )
    468{
    469 assert(lpi != NULL);
    470
    471 lpi->solved = FALSE;
    472}
    473
    474/** compute boundkeys to inform MOSEK about fixed/free/ranged/lower bounded/upper bounded variables or constraints */
    475static
    477 int n, /**< array size */
    478 const double* lb, /**< lower bounds of variables or left-hand sides of ranged rows */
    479 const double* ub, /**< upper bounds of variables or right-hand sides of ranged rows */
    480 MSKboundkeye* bk /**< pointer to store boundkeys to inform MOSEK about status of var/row */
    481 )
    482{
    483 int i;
    484
    485 assert(lb != NULL);
    486 assert(ub != NULL);
    487 assert(bk != NULL);
    488
    489 for( i = 0; i < n; i++ )
    490 {
    491 if (IS_NEGINF(lb[i]))
    492 {
    493 if (IS_POSINF(ub[i]))
    494 {
    495 bk[i] = MSK_BK_FR;
    496 }
    497 else
    498 {
    499 assert(!IS_NEGINF(ub[i]));
    500 bk[i] = MSK_BK_UP;
    501 }
    502 }
    503 else
    504 {
    505 assert(!IS_POSINF(lb[i]));
    506 if (IS_POSINF(ub[i]))
    507 {
    508 bk[i] = MSK_BK_LO;
    509 }
    510 else if (lb[i] == ub[i])/*lint !e777*/ /* No epsilon-test since MOSEK will also test for exact equality */
    511 {
    512 assert(lb[i] - ub[i] == 0);
    513 assert(ub[i] - lb[i] == 0);
    514 bk[i] = MSK_BK_FX;
    515 }
    516 else
    517 {
    518 assert(lb[i] < ub[i]);
    519 bk[i] = MSK_BK_RA;
    520 }
    521 }
    522 }
    523}
    524
    525/** get end pointers of arrays */
    526static
    528 int n, /**< array size */
    529 const int* beg, /**< array of beginning indices */
    530 int nnonz, /**< number of nonzeros */
    531 MSKint32t* aptre /**< array to store the result */
    532 )
    533{
    534 int i;
    535
    536 assert(beg != NULL || nnonz == 0);
    537
    538 if (nnonz > 0)
    539 {
    540 assert(beg != NULL);
    541 for(i = 0; i < n-1; i++)
    542 {
    543 aptre[i] = beg[i+1];
    544 assert(aptre[i] >= beg[i]);
    545 }
    546
    547 aptre[n-1] = nnonz;
    548 assert(aptre[n-1] >= beg[n-1]);
    549 }
    550 else
    551 {
    552 for( i = 0; i < n; i++ )
    553 aptre[i] = 0;
    554 }
    555
    556 return SCIP_OKAY;
    557}
    558
    559/** compute indices from range */
    560static
    562 int first, /**< first index */
    563 int last, /**< last index */
    564 int** sub /**< pointer to store the indices ranges */
    565 )
    566{
    567 int i;
    568
    569 assert(first <= last);
    570
    571 SCIP_ALLOC( BMSallocMemoryArray(sub, (last - first + 1)) );
    572
    573 for( i = first; i <= last; i++ )
    574 {
    575 (*sub)[i-first] = i;
    576 }
    577
    578 return SCIP_OKAY;
    579}
    580
    581/** compute indices from dense array */
    582static
    584 int* dstat, /**< array */
    585 int n, /**< size of array */
    586 int* count, /**< array of counts (sizes) */
    587 int** sub /**< pointer to store array of indices */
    588 )
    589{
    590 int i;
    591 int j;
    592
    593 assert(dstat != NULL);
    594 assert(count != NULL);
    595
    596 *count = 0;
    597 for( i = 0; i < n; i++ )
    598 {
    599 if (dstat[i] == 1)
    600 {
    601 (*count)++;
    602 }
    603 }
    604
    605 if( (*count) > 0 )
    606 {
    607 SCIP_ALLOC( BMSallocMemoryArray(sub, (*count)) );
    608 }
    609 else
    610 return SCIP_OKAY;
    611
    612 j = 0;
    613 for( i = 0; i < n; i++ )
    614 {
    615 if (dstat[i] == 1)
    616 {
    617 (*sub)[j++] = i;
    618 }
    619 }
    620
    621 return SCIP_OKAY;
    622}
    623
    624/** scale a vector */
    625static
    627 int len, /**< length of vector */
    628 double* vec, /**< vector to be scaled */
    629 double s /**< scaling factor */
    630 )
    631{
    632 int i;
    633 for( i = 0; i < len; i++ )
    634 {
    635 vec[i] *= s;
    636 }
    637}
    638
    639/** scale lower and upper bound */
    640static
    642 MSKboundkeye* bk, /**< pointer to store boundkeys to inform MOSEK about status of var/row */
    643 double* bl, /**< lower bound */
    644 double* bu, /**< upper bound */
    645 double s /**< scaling factor */
    646 )
    647{
    648 switch( *bk )
    649 {
    650 case MSK_BK_LO:
    651 *bl *= s;
    652 if ( s < 0.0 )
    653 *bk = MSK_BK_UP;
    654 break;
    655 case MSK_BK_UP:
    656 *bu *= s;
    657 if ( s < 0.0 )
    658 *bk = MSK_BK_LO;
    659 break;
    660 case MSK_BK_FX:
    661 case MSK_BK_RA:
    662 *bl *= s;
    663 *bu *= s;
    664 break;
    665 case MSK_BK_FR:
    666 break;
    667 default:
    668 SCIPABORT();
    669 break;
    670 } /*lint !e788*/
    671
    672 /* switch bounds if scaling is negative */
    673 if ( s < 0.0 )
    674 {
    675 double tmp;
    676 tmp = *bl;
    677 *bl = *bu;
    678 *bu = tmp;
    679 }
    680}
    681
    682/** resizes state arrays to have at least ncols/nrows entries */
    683static
    685 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
    686 int ncols, /**< number of columns */
    687 int nrows /**< number of rows */
    688 )
    689{
    690 if ( lpi->skxsize < ncols )
    691 {
    692 int newsize;
    693 newsize = MAX(2*lpi->skxsize, ncols);
    694
    695 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->skx), newsize) );
    696 lpi->skxsize = newsize;
    697 }
    698
    699 if ( lpi->skcsize < nrows )
    700 {
    701 int newsize;
    702 newsize = MAX(2*lpi->skcsize, nrows);
    703
    704 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->skc), newsize) );
    705 lpi->skcsize = newsize;
    706 }
    707
    708 return SCIP_OKAY;
    709}
    710
    711/** get base and store in skc/skx arrays */
    712static
    714 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
    715 int ncols, /**< number of columns */
    716 int nrows /**< number of rows */
    717 )
    718{
    719 assert(lpi->lastsolvetype == MSK_SOL_BAS);
    720
    721 SCIPdebugMessage("Calling getbase (%d)\n", lpi->lpid);
    722
    723 SCIP_CALL( ensureStateMem(lpi, ncols, nrows) );
    724 MOSEK_CALL( MSK_getsolution(lpi->task, MSK_SOL_BAS, NULL, NULL, lpi->skc, lpi->skx,
    725 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
    726
    727 return SCIP_OKAY;
    728}
    729
    730/** set base to the values given in skc/skx arrays */
    731static
    733 SCIP_LPI* lpi /**< pointer to an LP interface structure */
    734 )
    735{
    736 SCIPdebugMessage("Calling setbase (%d)\n", lpi->lpid);
    737
    738 lpi->lastsolvetype = MSK_SOL_BAS;
    739 lpi->solved = FALSE;
    740
    741 MOSEK_CALL( MSK_putsolution(lpi->task, MSK_SOL_BAS, lpi->skc, lpi->skx, NULL, NULL,
    742 NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
    743
    744 return SCIP_OKAY;
    745}
    746
    747
    748
    749/*
    750 * Miscellaneous Methods
    751 */
    752
    753#define STR_HELPER(x) #x
    754#define STR(x) STR_HELPER(x)
    755
    756#if MSK_VERSION_MAJOR < 9
    757 #define mskname "MOSEK " STR(MSK_VERSION_MAJOR) "." STR(MSK_VERSION_MINOR) "." STR(MSK_VERSION_BUILD) "." STR(MSK_VERSION_REVISION)
    758#else
    759 #define mskname "MOSEK " STR(MSK_VERSION_MAJOR) "." STR(MSK_VERSION_MINOR) "." STR(MSK_VERSION_REVISION)
    760#endif
    761
    762/**@name Miscellaneous Methods */
    763/**@{ */
    764
    765/** gets name and version of LP solver */
    767 void
    768 )
    769{
    770 return mskname;
    771}
    772
    773/** gets description of LP solver (developer, webpage, ...) */
    775 void
    776 )
    777{
    778 return "Linear Programming Solver developed by MOSEK Optimization Software (www.mosek.com)";
    779}
    780
    781/** gets pointer for LP solver - use only with great care */
    783 SCIP_LPI* lpi /**< pointer to an LP interface structure */
    784 )
    785{
    786 assert(lpi != NULL);
    787 assert(lpi->mosekenv != NULL);
    788 assert(lpi->task != NULL);
    789
    790 return (void*) lpi->task;
    791}
    792
    793/** pass integrality information to LP solver */
    795 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
    796 int ncols, /**< length of integrality array */
    797 int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
    798 )
    799{ /*lint --e{715}*/
    800 assert( lpi != NULL );
    801 assert( ncols >= 0 );
    802 assert( intInfo != NULL );
    803
    804 SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
    805 return SCIP_LPERROR;
    806}
    807
    808/** informs about availability of a primal simplex solving method */
    810 void
    811 )
    812{
    813 return TRUE;
    814}
    815
    816/** informs about availability of a dual simplex solving method */
    818 void
    819 )
    820{
    821 return TRUE;
    822}
    823
    824/** informs about availability of a barrier solving method */
    826 void
    827 )
    828{
    829 return TRUE;
    830}
    831
    832/**@} */
    833
    834
    835/*
    836 * LPI Creation and Destruction Methods
    837 */
    838
    839/**@name LPI Creation and Destruction Methods */
    840/**@{ */
    841
    842/** creates an LP problem object */
    844 SCIP_LPI** lpi, /**< pointer to an LP interface structure */
    845 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
    846 const char* name, /**< problem name */
    847 SCIP_OBJSEN objsen /**< objective sense */
    848 )
    849{
    850 assert(lpi != NULL);
    851 assert(name != NULL);
    852
    853 SCIPdebugMessage("Calling SCIPlpiCreate\n");
    854
    856
    857#ifdef SCIP_REUSEENV
    858 if ( reusemosekenv == NULL )
    859 {
    860 assert(numlp == 0);
    861 MOSEK_CALL( MSK_makeenv(&reusemosekenv, NULL) );
    862 MOSEK_CALL( MSK_linkfunctoenvstream(reusemosekenv, MSK_STREAM_LOG, (MSKuserhandle_t) messagehdlr, printstr) );
    863#if MSK_VERSION_MAJOR < 8
    864 MOSEK_CALL( MSK_initenv(reusemosekenv) );
    865#endif
    866 }
    867 (*lpi)->mosekenv = reusemosekenv;
    868 (*lpi)->lpid = numlp++;
    869
    870 /* remember address of numlp and reusemosekenv, in case they are thread-local and SCIPlpiFree is called from different thread */
    871 (*lpi)->numlp = &numlp;
    872 (*lpi)->reusemosekenv = &reusemosekenv;
    873
    874#else
    875
    876 MOSEK_CALL( MSK_makeenv(&(*lpi)->mosekenv, NULL) );
    877 MOSEK_CALL( MSK_linkfunctoenvstream((*lpi)->mosekenv, MSK_STREAM_LOG, (MSKuserhandle_t) messagehdlr, printstr) );
    878#if MSK_VERSION_MAJOR < 8
    879 MOSEK_CALL( MSK_initenv((*lpi)->mosekenv) );
    880#endif
    881#endif
    882
    883 MOSEK_CALL( MSK_makeemptytask((*lpi)->mosekenv, &((*lpi)->task)) );
    884
    885 MOSEK_CALL( MSK_linkfunctotaskstream((*lpi)->task, MSK_STREAM_LOG, (MSKuserhandle_t) messagehdlr, printstr) );
    886
    887 MOSEK_CALL( MSK_putobjsense((*lpi)->task, SENSE2MOSEK(objsen)) );
    888 MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_SIM_MAX_NUM_SETBACKS, SETBACK_LIMIT) );
    889 MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_FREE_SIMPLEX) );
    890 MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_SIM_DEGEN, DEGEN_LEVEL) );
    891 MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_SIM_SWITCH_OPTIMIZER, MSK_ON) );
    892 MOSEK_CALL( MSK_puttaskname((*lpi)->task, (char*) name) );
    893 MOSEK_CALL( MSK_putobjname((*lpi)->task, "obj") );
    894
    895 /* disable errors for huge values */
    896 MOSEK_CALL( MSK_putdouparam((*lpi)->task, MSK_DPAR_DATA_TOL_AIJ_HUGE, MSK_INFINITY * 2)); /* not clear why the *2 is needed */
    897 MOSEK_CALL( MSK_putdouparam((*lpi)->task, MSK_DPAR_DATA_TOL_C_HUGE, MSK_INFINITY));
    898
    899 /* disable warnings for large values */
    900 MOSEK_CALL( MSK_putdouparam((*lpi)->task, MSK_DPAR_DATA_TOL_AIJ_LARGE, MSK_INFINITY * 2));
    901 MOSEK_CALL( MSK_putdouparam((*lpi)->task, MSK_DPAR_DATA_TOL_CJ_LARGE, MSK_INFINITY));
    902
    903 /* disable warnings for large bounds */
    904 MOSEK_CALL( MSK_putdouparam((*lpi)->task, MSK_DPAR_DATA_TOL_BOUND_WRN, MSK_INFINITY));
    905
    906 (*lpi)->optimizecount = 0;
    907 (*lpi)->termcode = MSK_RES_OK;
    908 (*lpi)->itercount = 0;
    909 (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
    910 (*lpi)->scaling = 1;
    911 (*lpi)->lastalgo = MSK_OPTIMIZER_FREE;
    912 (*lpi)->skx = NULL;
    913 (*lpi)->skc = NULL;
    914 (*lpi)->bkx = NULL;
    915 (*lpi)->bkc = NULL;
    916 (*lpi)->aptre = NULL;
    917 (*lpi)->skxsize = 0;
    918 (*lpi)->skcsize = 0;
    919 (*lpi)->bkxsize = 0;
    920 (*lpi)->bkcsize = 0;
    921 (*lpi)->aptresize = 0;
    922 (*lpi)->lastsolvetype = (MSKsoltypee) -1;
    923 (*lpi)->lpinfo = FALSE;
    924 (*lpi)->restrictselectdef = 50;
    925 (*lpi)->fromscratch = FALSE;
    926 (*lpi)->clearstate = FALSE;
    927 (*lpi)->messagehdlr = messagehdlr;
    928
    929 invalidateSolution(*lpi);
    930
    931 MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_LOG, MSK_OFF) );
    932 MOSEK_CALL( MSK_putintparam((*lpi)->task, MSK_IPAR_LOG_SIM, MSK_OFF) );
    933
    934 return SCIP_OKAY;
    935}
    936
    937/** deletes an LP problem object */
    939 SCIP_LPI** lpi /**< pointer to an LP interface structure */
    940 )
    941{
    942 assert(lpi != NULL);
    943 assert(*lpi != NULL);
    944
    945 SCIPdebugMessage("Calling SCIPlpiFree (%d)\n", (*lpi)->lpid);
    946
    947 MOSEK_CALL( MSK_deletetask(&(*lpi)->task) );
    948
    949 BMSfreeMemoryArrayNull(&(*lpi)->aptre);
    950 BMSfreeMemoryArrayNull(&(*lpi)->bkx);
    951 BMSfreeMemoryArrayNull(&(*lpi)->bkc);
    952 BMSfreeMemoryArrayNull(&(*lpi)->skx);
    953 BMSfreeMemoryArrayNull(&(*lpi)->skc);
    954
    955#ifdef SCIP_REUSEENV
    956 /* decrement the numlp that belongs to the thread where SCIPlpiCreate was called */
    957 assert(*(*lpi)->numlp > 0);
    958 --(*(*lpi)->numlp);
    959 /* if numlp reached zero, then also free the Mosek environment (that belongs to the thread where SCIPlpiCreate was called) */
    960 if( *(*lpi)->numlp == 0 )
    961 {
    962 /* free reused environment */
    963 MOSEK_CALL( MSK_deleteenv((*lpi)->reusemosekenv) );
    964 *(*lpi)->reusemosekenv = NULL;
    965 }
    966#else
    967 MOSEK_CALL( MSK_deleteenv(&(*lpi)->mosekenv) );
    968#endif
    969
    970 BMSfreeMemory(lpi);
    971
    972 return SCIP_OKAY;
    973}
    974
    975/*
    976 * Modification Methods
    977 */
    978
    979
    980/** copies LP data with column matrix into LP solver */
    982 SCIP_LPI* lpi, /**< LP interface structure */
    983 SCIP_OBJSEN objsen, /**< objective sense */
    984 int ncols, /**< number of columns */
    985 const SCIP_Real* obj, /**< objective function values of columns */
    986 const SCIP_Real* lb, /**< lower bounds of columns */
    987 const SCIP_Real* ub, /**< upper bounds of columns */
    988 char** colnames, /**< column names, or NULL */
    989 int nrows, /**< number of rows */
    990 const SCIP_Real* lhs, /**< left hand sides of rows */
    991 const SCIP_Real* rhs, /**< right hand sides of rows */
    992 char** rownames, /**< row names, or NULL */
    993 int nnonz, /**< number of nonzero elements in the constraint matrix */
    994 const int* beg, /**< start index of each column in ind- and val-array */
    995 const int* ind, /**< row indices of constraint matrix entries */
    996 const SCIP_Real* val /**< values of constraint matrix entries */
    997 )
    998{
    999#ifndef NDEBUG
    1000 {
    1001 int j;
    1002 for( j = 0; j < nnonz; j++ )
    1003 assert( val[j] != 0.0 );
    1004 }
    1005#endif
    1006
    1007 assert(lpi != NULL);
    1008 assert(lpi->mosekenv != NULL);
    1009 assert(lpi->task != NULL);
    1010 assert(lhs != NULL);
    1011 assert(rhs != NULL);
    1012 assert(obj != NULL);
    1013 assert(lb != NULL);
    1014 assert(ub != NULL);
    1015 assert(beg != NULL);
    1016 assert(ind != NULL);
    1017 assert(val != NULL);
    1018
    1019 SCIPdebugMessage("Calling SCIPlpiLoadColLP (%d)\n", lpi->lpid);
    1020
    1021 invalidateSolution(lpi);
    1022
    1023#if DEBUG_CHECK_DATA > 0
    1024 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiLoadColLP") );
    1025#endif
    1026
    1027 if (nrows > 0)
    1028 {
    1029 SCIP_CALL( ensureBkcMem(lpi, nrows) );
    1030 generateMskBoundkeys(nrows, lhs, rhs, lpi->bkc);
    1031 }
    1032
    1033 if (ncols > 0)
    1034 {
    1035 SCIP_CALL( ensureBkxMem(lpi, ncols) );
    1036 generateMskBoundkeys(ncols, lb, ub, lpi->bkx);
    1037
    1038 SCIP_CALL( ensureAptreMem(lpi, ncols) );
    1039 SCIP_CALL( getEndptrs(ncols, beg, nnonz, lpi->aptre) );
    1040 }
    1041
    1042 MOSEK_CALL( MSK_inputdata(lpi->task, nrows, ncols, nrows, ncols, obj, 0.0, beg, lpi->aptre, ind, val,
    1043 lpi->bkc, lhs, rhs, lpi->bkx, lb, ub) );
    1044
    1045 MOSEK_CALL( MSK_putobjsense(lpi->task, SENSE2MOSEK(objsen)) );
    1046
    1047 if( colnames != NULL )
    1048 {
    1049 int c;
    1050
    1051 for( c = 0; c < ncols; c++ )
    1052 {
    1053 MOSEK_CALL( MSK_putvarname(lpi->task, c, colnames[c]) );
    1054 }
    1055 }
    1056
    1057 if( rownames != NULL )
    1058 {
    1059 int r;
    1060
    1061 for( r = 0; r < nrows; r++ )
    1062 {
    1063 MOSEK_CALL( MSK_putconname(lpi->task, r, rownames[r]) );
    1064 }
    1065 }
    1066
    1067#if DEBUG_CHECK_DATA > 0
    1068 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiLoadColLP") );
    1069#endif
    1070
    1071 return SCIP_OKAY;
    1072}
    1073
    1074/** adds columns to the LP */
    1076 SCIP_LPI* lpi, /**< LP interface structure */
    1077 int ncols, /**< number of columns to be added */
    1078 const SCIP_Real* obj, /**< objective function values of new columns */
    1079 const SCIP_Real* lb, /**< lower bounds of new columns */
    1080 const SCIP_Real* ub, /**< upper bounds of new columns */
    1081 char** colnames, /**< column names, or NULL */
    1082 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
    1083 const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
    1084 const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
    1085 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
    1086 )
    1087{
    1088#if MSK_VERSION_MAJOR < 7
    1089 const int* aptrb;
    1090#endif
    1091
    1092 int oldcols;
    1093
    1094 assert(lpi != NULL);
    1095 assert(lpi->mosekenv != NULL);
    1096 assert(lpi->task != NULL);
    1097 assert(obj != NULL);
    1098 assert(lb != NULL);
    1099 assert(ub != NULL);
    1100 assert(nnonz == 0 || beg != NULL);
    1101 assert(nnonz == 0 || ind != NULL);
    1102 assert(nnonz == 0 || val != NULL);
    1103 assert(nnonz >= 0);
    1104 assert(ncols >= 0);
    1105
    1106 SCIPdebugMessage("Calling SCIPlpiAddCols (%d)\n", lpi->lpid);
    1107
    1108 invalidateSolution(lpi);
    1109
    1110#if DEBUG_CHECK_DATA > 0
    1111 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiAddCols") );
    1112#endif
    1113
    1114 if (ncols == 0)
    1115 return SCIP_OKAY;
    1116
    1117 SCIP_CALL( ensureBkxMem(lpi, ncols) );
    1118 generateMskBoundkeys(ncols, lb, ub, lpi->bkx);
    1119
    1120 MOSEK_CALL( MSK_getnumvar(lpi->task, &oldcols) );
    1121
    1122 MOSEK_CALL( MSK_appendvars(lpi->task, ncols) );
    1123 MOSEK_CALL( MSK_putcslice(lpi->task, oldcols, oldcols+ncols, obj) );
    1124 MOSEK_CALL( MSK_putvarboundslice(lpi->task, oldcols, oldcols+ncols, lpi->bkx, lb, ub) );
    1125
    1126 if( nnonz > 0 )
    1127 {
    1128#ifndef NDEBUG
    1129 /* perform check that no new rows are added - this is forbidden */
    1130 int nrows;
    1131 int j;
    1132
    1133 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    1134 for (j = 0; j < nnonz; ++j)
    1135 {
    1136 assert( 0 <= ind[j] && ind[j] < nrows );
    1137 assert( val[j] != 0.0 );
    1138 }
    1139#endif
    1140
    1141 SCIP_CALL( ensureAptreMem(lpi, ncols) );
    1142 SCIP_CALL( getEndptrs(ncols, beg, nnonz, lpi->aptre) );
    1143 MOSEK_CALL( MSK_putacolslice(lpi->task, oldcols, oldcols+ncols, beg, lpi->aptre, ind, val) );
    1144 }
    1145
    1146 if( colnames != NULL )
    1147 {
    1148 int c;
    1149
    1150 for( c = 0; c < ncols; c++ )
    1151 {
    1152 MOSEK_CALL( MSK_putvarname(lpi->task, c, colnames[c]) );
    1153 }
    1154 }
    1155
    1156#if DEBUG_CHECK_DATA > 0
    1157 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiAddCols") );
    1158#endif
    1159
    1160 return SCIP_OKAY;
    1161}
    1162
    1163/** deletes all columns in the given range from LP */
    1165 SCIP_LPI* lpi, /**< LP interface structure */
    1166 int firstcol, /**< first column to be deleted */
    1167 int lastcol /**< last column to be deleted */
    1168 )
    1169{
    1170 int* sub;
    1171
    1172 assert(lpi != NULL);
    1173 assert(lpi->mosekenv != NULL);
    1174 assert(lpi->task != NULL);
    1175 assert(firstcol >= 0);
    1176 assert(firstcol <= lastcol + 1);
    1177#ifndef NDEBUG
    1178 {
    1179 int ncols;
    1180 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    1181 assert(lastcol < ncols);
    1182 }
    1183#endif
    1184
    1185 SCIPdebugMessage("Calling SCIPlpiDelCols (%d)\n", lpi->lpid);
    1186
    1187 /* handle empty range */
    1188 if( firstcol > lastcol )
    1189 return SCIP_OKAY;
    1190
    1191 invalidateSolution(lpi);
    1192
    1193#if DEBUG_CHECK_DATA > 0
    1194 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelCols") );
    1195#endif
    1196
    1197 SCIP_CALL( getIndicesRange(firstcol, lastcol, &sub) );
    1198
    1199 MOSEK_CALL( MSK_removevars(lpi->task, lastcol-firstcol+1, sub) );
    1200
    1201 BMSfreeMemoryArray(&sub);
    1202
    1203#if DEBUG_CHECK_DATA > 0
    1204 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelCols") );
    1205#endif
    1206
    1207 return SCIP_OKAY;
    1208}
    1209
    1210/** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
    1212 SCIP_LPI* lpi, /**< LP interface structure */
    1213 int* dstat /**< deletion status of columns
    1214 * input: 1 if column should be deleted, 0 if not
    1215 * output: new position of column, -1 if column was deleted */
    1216 )
    1217{
    1218 int* sub = NULL;
    1219 int count;
    1220 int ncols;
    1221 int col;
    1222 int i;
    1223
    1224 assert(lpi != NULL);
    1225 assert(lpi->mosekenv != NULL);
    1226 assert(lpi->task != NULL);
    1227 assert(dstat != NULL);
    1228
    1229 SCIPdebugMessage("Calling SCIPlpiDelColset (%d)\n", lpi->lpid);
    1230
    1231 invalidateSolution(lpi);
    1232
    1233#if DEBUG_CHECK_DATA > 0
    1234 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelColset") );
    1235#endif
    1236
    1237 MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
    1238
    1239 SCIP_CALL( getIndicesFromDense(dstat, ncols, &count, &sub) );
    1240
    1241 col = 0;
    1242 for( i = 0; i < ncols; i++)
    1243 {
    1244 if (dstat[i] == 1)
    1245 {
    1246 dstat[i] = -1;
    1247 }
    1248 else
    1249 {
    1250 dstat[i] = col;
    1251 col++;
    1252 }
    1253 }
    1254
    1255 if (count > 0)
    1256 {
    1257 SCIPdebugMessage("Deleting %d vars %d, ...\n", count, sub[0]);
    1258 MOSEK_CALL( MSK_removevars(lpi->task, count, sub) );
    1259 BMSfreeMemoryArray(&sub);
    1260 }
    1261
    1262#if DEBUG_CHECK_DATA > 0
    1263 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelColset") );
    1264#endif
    1265
    1266 return SCIP_OKAY;
    1267}
    1268
    1269/** adds rows to the LP */
    1271 SCIP_LPI* lpi, /**< LP interface structure */
    1272 int nrows, /**< number of rows to be added */
    1273 const SCIP_Real* lhs, /**< left hand sides of new rows */
    1274 const SCIP_Real* rhs, /**< right hand sides of new rows */
    1275 char** rownames, /**< row names, or NULL */
    1276 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
    1277 const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
    1278 const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
    1279 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
    1280 )
    1281{
    1282 int oldrows;
    1283
    1284 assert(lpi != NULL);
    1285 assert(lpi->mosekenv != NULL);
    1286 assert(lpi->task != NULL);
    1287 assert(nnonz == 0 || beg != NULL);
    1288 assert(nnonz == 0 || ind != NULL);
    1289 assert(nnonz == 0 || val != NULL);
    1290
    1291 SCIPdebugMessage("Calling SCIPlpiAddRows (%d)\n", lpi->lpid);
    1292
    1293 invalidateSolution(lpi);
    1294
    1295#if DEBUG_CHECK_DATA > 0
    1296 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiAddRows") );
    1297#endif
    1298
    1299 if (nrows == 0)
    1300 return SCIP_OKAY;
    1301
    1302 SCIP_CALL( ensureBkcMem(lpi, nrows) );
    1303
    1304 generateMskBoundkeys(nrows, lhs, rhs, lpi->bkc);
    1305
    1306 MOSEK_CALL( MSK_getnumcon(lpi->task, &oldrows) );
    1307
    1308 MOSEK_CALL( MSK_appendcons(lpi->task, nrows) );
    1309 MOSEK_CALL( MSK_putconboundslice(lpi->task, oldrows, oldrows+nrows, lpi->bkc, lhs, rhs) );
    1310
    1311 if( nnonz > 0 )
    1312 {
    1313#ifndef NDEBUG
    1314 /* perform check that no new cols are added - this is forbidden */
    1315 int ncols;
    1316 int j;
    1317
    1318 MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
    1319 for (j = 0; j < nnonz; ++j)
    1320 {
    1321 assert( val[j] != 0.0 );
    1322 assert( 0 <= ind[j] && ind[j] < ncols );
    1323 }
    1324#endif
    1325
    1326 SCIP_CALL( ensureAptreMem(lpi, nrows) );
    1327 SCIP_CALL( getEndptrs(nrows, beg, nnonz, lpi->aptre) );
    1328 MOSEK_CALL( MSK_putarowslice(lpi->task, oldrows, oldrows+nrows, beg, lpi->aptre, ind, val) );
    1329 }
    1330
    1331 if( rownames != NULL )
    1332 {
    1333 int r;
    1334
    1335 for( r = 0; r < nrows; r++ )
    1336 {
    1337 MOSEK_CALL( MSK_putconname(lpi->task, r, rownames[r]) );
    1338 }
    1339 }
    1340
    1341#if DEBUG_CHECK_DATA > 0
    1342 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiAddRows") );
    1343#endif
    1344
    1345 return SCIP_OKAY;
    1346}
    1347
    1348/** deletes all rows in the given range from LP */
    1350 SCIP_LPI* lpi, /**< LP interface structure */
    1351 int firstrow, /**< first row to be deleted */
    1352 int lastrow /**< last row to be deleted */
    1353 )
    1354{
    1355 int* sub;
    1356
    1357 assert(lpi != NULL);
    1358 assert(lpi->mosekenv != NULL);
    1359 assert(lpi->task != NULL);
    1360 assert(firstrow >= 0);
    1361 assert(firstrow <= lastrow + 1);
    1362#ifndef NDEBUG
    1363 {
    1364 int nrows;
    1365 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    1366 assert(lastrow < nrows);
    1367 }
    1368#endif
    1369
    1370 SCIPdebugMessage("Calling SCIPlpiDelRows (%d)\n", lpi->lpid);
    1371
    1372 /* handle empty range */
    1373 if( firstrow > lastrow )
    1374 return SCIP_OKAY;
    1375
    1376 invalidateSolution(lpi);
    1377
    1378#if DEBUG_CHECK_DATA > 0
    1379 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelRows") );
    1380#endif
    1381
    1382 SCIP_CALL( getIndicesRange(firstrow, lastrow, &sub) );
    1383
    1384 SCIPdebugMessage("Deleting cons %d to %d\n", firstrow, lastrow);
    1385
    1386 MOSEK_CALL( MSK_removecons(lpi->task, lastrow-firstrow+1, sub) );
    1387
    1388 BMSfreeMemoryArray(&sub);
    1389
    1390#if DEBUG_CHECK_DATA > 0
    1391 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelRows") );
    1392#endif
    1393
    1394 return SCIP_OKAY;
    1395}
    1396
    1397/** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
    1399 SCIP_LPI* lpi, /**< LP interface structure */
    1400 int* dstat /**< deletion status of rows
    1401 * input: 1 if row should be deleted, 0 if not
    1402 * output: new position of row, -1 if row was deleted */
    1403 )
    1404{
    1405 int* sub;
    1406 int count;
    1407 int nrows;
    1408 int row;
    1409 int i;
    1410
    1411 assert(lpi != NULL);
    1412 assert(lpi->mosekenv != NULL);
    1413 assert(lpi->task != NULL);
    1414
    1415 SCIPdebugMessage("Calling SCIPlpiDelRowset (%d)\n", lpi->lpid);
    1416
    1417 invalidateSolution(lpi);
    1418
    1419#if DEBUG_CHECK_DATA > 0
    1420 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelRowset") );
    1421#endif
    1422
    1423 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    1424
    1425 sub = NULL;
    1426 SCIP_CALL( getIndicesFromDense(dstat, nrows, &count, &sub) );
    1427
    1428 row = 0;
    1429 for( i = 0; i < nrows; i++ )
    1430 {
    1431 if (dstat[i] == 1)
    1432 {
    1433 dstat[i] = -1;
    1434 }
    1435 else
    1436 {
    1437 dstat[i] = row;
    1438 row++;
    1439 }
    1440 }
    1441
    1442 if (count > 0)
    1443 {
    1444 SCIPdebugMessage("Deleting %d cons %d, ...\n", count, sub[0]);
    1445 MOSEK_CALL( MSK_removecons(lpi->task, count, sub) );
    1446 BMSfreeMemoryArray(&sub);
    1447 }
    1448
    1449#if DEBUG_CHECK_DATA > 0
    1450 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiDelRowset end") );
    1451#endif
    1452
    1453 return SCIP_OKAY;
    1454}
    1455
    1456/** clears the whole LP */
    1458 SCIP_LPI* lpi /**< LP interface structure */
    1459 )
    1460{
    1461 int nrows;
    1462 int ncols;
    1463
    1464 assert(lpi != NULL);
    1465 assert(lpi->mosekenv != NULL);
    1466 assert(lpi->task != NULL);
    1467
    1468 SCIPdebugMessage("Calling SCIPlpiClear (%d)\n", lpi->lpid);
    1469
    1470 invalidateSolution(lpi);
    1471
    1472 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    1473 MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
    1474
    1475 SCIP_CALL( SCIPlpiDelRows(lpi, 0, nrows - 1) );
    1476 SCIP_CALL( SCIPlpiDelCols(lpi, 0, ncols - 1) );
    1477
    1478 return SCIP_OKAY;
    1479}
    1480
    1481/** changes lower and upper bounds of columns */
    1483 SCIP_LPI* lpi, /**< LP interface structure */
    1484 int ncols, /**< number of columns to change bounds for */
    1485 const int* ind, /**< column indices or NULL if ncols is zero */
    1486 const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
    1487 const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
    1488 )
    1489{
    1490 int i;
    1491
    1492 assert(lpi != NULL);
    1493 assert(lpi->mosekenv != NULL);
    1494 assert(lpi->task != NULL);
    1495 assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
    1496
    1497 SCIPdebugMessage("Calling SCIPlpiChgBounds (%d)\n", lpi->lpid);
    1498 if( ncols <= 0 )
    1499 return SCIP_OKAY;
    1500
    1501 invalidateSolution(lpi);
    1502
    1503#if DEBUG_CHECK_DATA > 0
    1504 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgBounds") );
    1505#endif
    1506
    1507 /* @todo This test could be integrated into generateMskBoundkeys, but then this function needs to be able to return an
    1508 * error, which requires some rewriting. */
    1509 for (i = 0; i < ncols; ++i)
    1510 {
    1511 if ( SCIPlpiIsInfinity(lpi, lb[i]) )
    1512 {
    1513 SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
    1514 return SCIP_LPERROR;
    1515 }
    1516 if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
    1517 {
    1518 SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
    1519 return SCIP_LPERROR;
    1520 }
    1521 }
    1522
    1523 SCIP_CALL( ensureBkxMem(lpi, ncols) );
    1524
    1525 generateMskBoundkeys(ncols, lb, ub, lpi->bkx);
    1526#if MSK_VERSION_MAJOR < 9
    1527 MOSEK_CALL( MSK_putboundlist(lpi->task, MSK_ACC_VAR, ncols, ind, lpi->bkx, lb, ub) );
    1528#else
    1529 MOSEK_CALL( MSK_putvarboundlist(lpi->task, ncols, ind, lpi->bkx, lb, ub) );
    1530#endif
    1531
    1532#if DEBUG_CHECK_DATA > 0
    1533 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgBounds") );
    1534#endif
    1535
    1536 return SCIP_OKAY;
    1537}
    1538
    1539/** changes left and right hand sides of rows */
    1541 SCIP_LPI* lpi, /**< LP interface structure */
    1542 int nrows, /**< number of rows to change sides for */
    1543 const int* ind, /**< row indices */
    1544 const SCIP_Real* lhs, /**< new values for left hand sides */
    1545 const SCIP_Real* rhs /**< new values for right hand sides */
    1546 )
    1547{
    1548 assert(lpi != NULL);
    1549 assert(lpi->mosekenv != NULL);
    1550 assert(lpi->task != NULL);
    1551 assert(ind != NULL);
    1552
    1553 if( nrows <= 0 )
    1554 return SCIP_OKAY;
    1555
    1556 invalidateSolution(lpi);
    1557
    1558 SCIPdebugMessage("Calling SCIPlpiChgSides (%d)\n", lpi->lpid);
    1559
    1560#if DEBUG_CHECK_DATA > 0
    1561 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgSides") );
    1562#endif
    1563
    1564 SCIP_CALL( ensureBkcMem(lpi, nrows) );
    1565
    1566 generateMskBoundkeys(nrows, lhs, rhs, lpi->bkc);
    1567#if MSK_VERSION_MAJOR < 9
    1568 MOSEK_CALL( MSK_putboundlist(lpi->task, MSK_ACC_CON, nrows, ind, lpi->bkc, lhs, rhs) );
    1569#else
    1570 MOSEK_CALL( MSK_putconboundlist(lpi->task, nrows, ind, lpi->bkc, lhs, rhs) );
    1571#endif
    1572
    1573#if DEBUG_CHECK_DATA > 0
    1574 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgSides") );
    1575#endif
    1576
    1577 return SCIP_OKAY;
    1578}
    1579
    1580/** changes a single coefficient */
    1582 SCIP_LPI* lpi, /**< LP interface structure */
    1583 int row, /**< row number of coefficient to change */
    1584 int col, /**< column number of coefficient to change */
    1585 SCIP_Real newval /**< new value of coefficient */
    1586 )
    1587{
    1588 assert(lpi != NULL);
    1589 assert(lpi->mosekenv != NULL);
    1590 assert(lpi->task != NULL);
    1591
    1592 SCIPdebugMessage("Calling SCIPlpiChgCoef (%d)\n", lpi->lpid);
    1593
    1594 invalidateSolution(lpi);
    1595
    1596#if DEBUG_CHECK_DATA > 0
    1597 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgCoef") );
    1598#endif
    1599
    1600 MOSEK_CALL( MSK_putaij(lpi->task, row, col, newval) );
    1601
    1602#if DEBUG_CHECK_DATA > 0
    1603 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgCoef") );
    1604#endif
    1605
    1606 return SCIP_OKAY;
    1607}
    1608
    1609/** changes the objective sense */
    1611 SCIP_LPI* lpi, /**< LP interface structure */
    1612 SCIP_OBJSEN objsen /**< new objective sense */
    1613 )
    1614{
    1615 assert(lpi != NULL);
    1616 assert(lpi->mosekenv != NULL);
    1617 assert(lpi->task != NULL);
    1618
    1619 SCIPdebugMessage("Calling SCIPlpiChgObjsen (%d)\n", lpi->lpid);
    1620
    1621 invalidateSolution(lpi);
    1622
    1623 MOSEK_CALL( MSK_putobjsense(lpi->task, SENSE2MOSEK(objsen)) );
    1624
    1625 return SCIP_OKAY;
    1626}
    1627
    1628/** changes objective values of columns in the LP */
    1630 SCIP_LPI* lpi, /**< LP interface structure */
    1631 int ncols, /**< number of columns to change objective value for */
    1632 const int* ind, /**< column indices to change objective value for */
    1633 const SCIP_Real* obj /**< new objective values for columns */
    1634 )
    1635{
    1636 assert(lpi != NULL);
    1637 assert(lpi->mosekenv != NULL);
    1638 assert(lpi->task != NULL);
    1639 assert(ind != NULL);
    1640 assert(obj != NULL);
    1641
    1642 SCIPdebugMessage("Calling SCIPlpiChgObj (%d)\n", lpi->lpid);
    1643
    1644 invalidateSolution(lpi);
    1645
    1646#if DEBUG_CHECK_DATA > 0
    1647 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiChgObj") );
    1648#endif
    1649
    1650 MOSEK_CALL( MSK_putclist(lpi->task, ncols, ind, obj) );
    1651
    1652#if DEBUG_CHECK_DATA > 0
    1653 SCIP_CALL( scip_checkdata(lpi,"SCIPlpiChgObj") );
    1654#endif
    1655
    1656 return SCIP_OKAY;
    1657}
    1658
    1659/** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
    1661 SCIP_LPI* lpi, /**< LP interface structure */
    1662 int row, /**< row number to scale */
    1663 SCIP_Real scaleval /**< scaling multiplier */
    1664 )
    1665{
    1666 int nnonz;
    1667 int* sub;
    1668 double* val;
    1669 MSKboundkeye bkc;
    1670 double blc;
    1671 double buc;
    1672
    1673 assert(lpi != NULL);
    1674 assert(lpi->mosekenv != NULL);
    1675 assert(lpi->task != NULL);
    1676
    1677 SCIPdebugMessage("Calling SCIPlpiScaleRow (%d)\n", lpi->lpid);
    1678
    1679 invalidateSolution(lpi);
    1680
    1681#if DEBUG_CHECK_DATA > 0
    1682 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiScaleRow") );
    1683#endif
    1684
    1685 assert(scaleval != 0);
    1686
    1687 MOSEK_CALL( MSK_getarownumnz(lpi->task, row, &nnonz) );
    1688
    1689 if (nnonz != 0)
    1690 {
    1691 SCIP_ALLOC( BMSallocMemoryArray(&sub, nnonz) );
    1692 SCIP_ALLOC( BMSallocMemoryArray(&val, nnonz) );
    1693
    1694 MOSEK_CALL( MSK_getarow(lpi->task, row, &nnonz, sub, val) );
    1695 scale_vec(nnonz, val, scaleval);
    1696 MOSEK_CALL( MSK_putarow(lpi->task, row, nnonz, sub, val) );
    1697
    1698 BMSfreeMemoryArray(&val);
    1699 BMSfreeMemoryArray(&sub);
    1700 }
    1701
    1702#if MSK_VERSION_MAJOR < 9
    1703 MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_CON, row, &bkc, &blc, &buc) );
    1704 scale_bound(&bkc, &blc, &buc, scaleval);
    1705 MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_CON, row, bkc, blc, buc) );
    1706#else
    1707 MOSEK_CALL( MSK_getconbound(lpi->task, row, &bkc, &blc, &buc) );
    1708 scale_bound(&bkc, &blc, &buc, scaleval);
    1709 MOSEK_CALL( MSK_putconbound(lpi->task, row, bkc, blc, buc) );
    1710#endif
    1711
    1712#if DEBUG_CHECK_DATA > 0
    1713 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiScaleRow") );
    1714#endif
    1715
    1716 return SCIP_OKAY;
    1717}
    1718
    1719/** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
    1720 * are divided by the scalar; for negative scalars, the column's bounds are switched
    1721 */
    1723 SCIP_LPI* lpi, /**< LP interface structure */
    1724 int col, /**< column number to scale */
    1725 SCIP_Real scaleval /**< scaling multiplier */
    1726 )
    1727{
    1728 int nnonz;
    1729 int *sub = NULL;
    1730 double *val = NULL;
    1731 MSKboundkeye bkx;
    1732 double blx, bux, c;
    1733
    1734 assert(lpi != NULL);
    1735 assert(lpi->mosekenv != NULL);
    1736 assert(lpi->task != NULL);
    1737
    1738 SCIPdebugMessage("Calling SCIPlpiScaleCol (%d)\n", lpi->lpid);
    1739
    1740 invalidateSolution(lpi);
    1741
    1742#if DEBUG_CHECK_DATA > 0
    1743 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiScaleCol") );
    1744#endif
    1745
    1746 assert(scaleval != 0);
    1747 MOSEK_CALL( MSK_getacolnumnz(lpi->task, col, &nnonz) );
    1748
    1749 if (nnonz != 0)
    1750 {
    1751 SCIP_ALLOC( BMSallocMemoryArray(&sub, nnonz) );
    1752 SCIP_ALLOC( BMSallocMemoryArray(&val, nnonz) );
    1753
    1754 MOSEK_CALL( MSK_getacol(lpi->task, col, &nnonz, sub, val) );
    1755 scale_vec(nnonz, val, scaleval);
    1756 MOSEK_CALL( MSK_putacol(lpi->task, col, nnonz, sub, val) );
    1757
    1758 BMSfreeMemoryArray(&val);
    1759 BMSfreeMemoryArray(&sub);
    1760 }
    1761
    1762#if MSK_VERSION_MAJOR < 9
    1763 MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_VAR, col, &bkx, &blx, &bux) );
    1764 scale_bound(&bkx, &blx, &bux, 1.0/scaleval);
    1765 MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, bkx, blx, bux) );
    1766#else
    1767 MOSEK_CALL( MSK_getvarbound(lpi->task, col, &bkx, &blx, &bux) );
    1768 scale_bound(&bkx, &blx, &bux, 1.0/scaleval);
    1769 MOSEK_CALL( MSK_putvarbound(lpi->task, col, bkx, blx, bux) );
    1770#endif
    1771
    1772 MOSEK_CALL( MSK_getcslice(lpi->task, col, col+1, &c) );
    1773 MOSEK_CALL( MSK_putcj(lpi->task, col, c*scaleval) );
    1774
    1775#if DEBUG_CHECK_DATA > 0
    1776 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiScaleCol") );
    1777#endif
    1778
    1779 return SCIP_OKAY;
    1780}
    1781
    1782
    1783/*
    1784 * Data Accessing Methods
    1785 */
    1786
    1787
    1788/** gets the number of rows in the LP */
    1790 SCIP_LPI* lpi, /**< LP interface structure */
    1791 int* nrows /**< pointer to store the number of rows */
    1792 )
    1793{
    1794 assert(lpi != NULL);
    1795 assert(lpi->mosekenv != NULL);
    1796 assert(lpi->task != NULL);
    1797 assert(nrows != NULL);
    1798
    1799 SCIPdebugMessage("Calling SCIPlpiGetNRows (%d)\n", lpi->lpid);
    1800
    1801 MOSEK_CALL( MSK_getnumcon(lpi->task, nrows) );
    1802
    1803 return SCIP_OKAY;
    1804}
    1805
    1806/** gets the number of columns in the LP */
    1808 SCIP_LPI* lpi, /**< LP interface structure */
    1809 int* ncols /**< pointer to store the number of cols */
    1810 )
    1811{
    1812 assert(lpi != NULL);
    1813 assert(lpi->mosekenv != NULL);
    1814 assert(lpi->task != NULL);
    1815 assert(ncols != NULL);
    1816
    1817 SCIPdebugMessage("Calling SCIPlpiGetNCols (%d)\n", lpi->lpid);
    1818
    1819 MOSEK_CALL( MSK_getnumvar(lpi->task, ncols) );
    1820
    1821 return SCIP_OKAY;
    1822}
    1823
    1824/** gets the number of nonzero elements in the LP constraint matrix */
    1826 SCIP_LPI* lpi, /**< LP interface structure */
    1827 int* nnonz /**< pointer to store the number of nonzeros */
    1828 )
    1829{
    1830 assert(lpi != NULL);
    1831 assert(lpi->mosekenv != NULL);
    1832 assert(lpi->task != NULL);
    1833 assert(nnonz != NULL);
    1834
    1835 SCIPdebugMessage("Calling SCIPlpiGetNNonz (%d)\n", lpi->lpid);
    1836
    1837 MOSEK_CALL( MSK_getnumanz(lpi->task, nnonz) );
    1838
    1839 return SCIP_OKAY;
    1840}
    1841
    1842/** get a slice of a row or column */
    1843static
    1845 SCIP_LPI* lpi, /**< LP interface structure */
    1846 SCIP_Bool iscon, /**< whether we are requesting a slice of a constraint or column */
    1847 int first, /**< first index */
    1848 int last, /**< last index */
    1849 int* nnonz, /**< pointer to store the number of nonzeros */
    1850 int* beg, /**< array for begins of indices/values */
    1851 int* ind, /**< array of row/column indices */
    1852 double* val /**< array of values */
    1853 )
    1854{
    1855 assert(lpi != NULL);
    1856 assert(lpi->mosekenv != NULL);
    1857 assert(lpi->task != NULL);
    1858 assert(first <= last);
    1859
    1860 SCIPdebugMessage("Calling SCIPlpiGetNNonz (%d)\n", lpi->lpid);
    1861
    1862#if DEBUG_CHECK_DATA > 0
    1863 SCIP_CALL( scip_checkdata(lpi, "getASlice") );
    1864#endif
    1865
    1866 if( nnonz != 0 )
    1867 {
    1868#if MSK_VERSION_MAJOR <= 9
    1869 int surplus;
    1870#endif
    1871
    1872 assert(beg != NULL);
    1873 assert(ind != NULL);
    1874 assert(val != NULL);
    1875
    1876 SCIP_CALL( ensureAptreMem(lpi, last - first + 1) );
    1877
    1878#if MSK_VERSION_MAJOR < 9
    1879 MOSEK_CALL( MSK_getaslicenumnz(lpi->task, iscon ? MSK_ACC_CON : MSK_ACC_VAR, first, last+1, nnonz) );
    1880 surplus = *nnonz;
    1881 MOSEK_CALL( MSK_getaslice(lpi->task, iscon ? MSK_ACC_CON : MSK_ACC_VAR, first, last+1, *nnonz, &surplus, beg, lpi->aptre, ind, val) );
    1882 assert(surplus == 0);
    1883#else
    1884 if( iscon )
    1885 {
    1886 MOSEK_CALL( MSK_getarowslicenumnz(lpi->task, first, last+1, nnonz) );
    1887#if MSK_VERSION_MAJOR == 9
    1888 surplus = *nnonz;
    1889 MOSEK_CALL( MSK_getarowslice(lpi->task, first, last+1, *nnonz, &surplus, beg, lpi->aptre, ind, val) );
    1890 assert(surplus == 0);
    1891#else
    1892 MOSEK_CALL( MSK_getarowslice(lpi->task, first, last+1, *nnonz, beg, lpi->aptre, ind, val) );
    1893#endif
    1894 }
    1895 else
    1896 {
    1897 MOSEK_CALL( MSK_getacolslicenumnz(lpi->task, first, last+1, nnonz) );
    1898#if MSK_VERSION_MAJOR == 9
    1899 surplus = *nnonz;
    1900 MOSEK_CALL( MSK_getacolslice(lpi->task, first, last+1, *nnonz, &surplus, beg, lpi->aptre, ind, val) );
    1901 assert(surplus == 0);
    1902#else
    1903 MOSEK_CALL( MSK_getacolslice(lpi->task, first, last+1, *nnonz, beg, lpi->aptre, ind, val) );
    1904#endif
    1905 }
    1906#endif
    1907 }
    1908
    1909#if DEBUG_CHECK_DATA > 0
    1910 SCIP_CALL( scip_checkdata(lpi, "getASlice") );
    1911#endif
    1912
    1913 return SCIP_OKAY;
    1914}
    1915
    1916/** gets columns from LP problem object; the arrays have to be large enough to store all values;
    1917 * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
    1918 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
    1919 */
    1921 SCIP_LPI* lpi, /**< LP interface structure */
    1922 int firstcol, /**< first column to get from LP */
    1923 int lastcol, /**< last column to get from LP */
    1924 SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
    1925 SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
    1926 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
    1927 int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
    1928 int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
    1929 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
    1930 )
    1931{
    1932 assert(lpi != NULL);
    1933 assert(lpi->mosekenv != NULL);
    1934 assert(lpi->task != NULL);
    1935 assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
    1936 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
    1937 assert(firstcol >= 0);
    1938 assert(firstcol <= lastcol + 1);
    1939#ifndef NDEBUG
    1940 {
    1941 int ncols;
    1942 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    1943 assert(lastcol < ncols);
    1944 }
    1945#endif
    1946
    1947 SCIPdebugMessage("Calling SCIPlpiGetCols (%d)\n", lpi->lpid);
    1948
    1949 SCIP_CALL( SCIPlpiGetBounds(lpi, firstcol, lastcol, lb, ub) );
    1950 SCIP_CALL( getASlice(lpi, FALSE, firstcol, lastcol, nnonz, beg, ind, val) );
    1951
    1952 return SCIP_OKAY;
    1953}
    1954
    1955/** gets rows from LP problem object; the arrays have to be large enough to store all values.
    1956 * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
    1957 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
    1958 */
    1960 SCIP_LPI* lpi, /**< LP interface structure */
    1961 int firstrow, /**< first row to get from LP */
    1962 int lastrow, /**< last row to get from LP */
    1963 SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
    1964 SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
    1965 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
    1966 int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
    1967 int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
    1968 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
    1969 )
    1970{
    1971 assert(lpi != NULL);
    1972 assert(lpi->mosekenv != NULL);
    1973 assert(lpi->task != NULL);
    1974 assert((lhs != NULL && rhs != NULL) || (lhs == NULL && rhs == NULL));
    1975 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
    1976 assert(firstrow >= 0);
    1977 assert(firstrow <= lastrow + 1);
    1978#ifndef NDEBUG
    1979 {
    1980 int nrows;
    1981 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    1982 assert(lastrow < nrows);
    1983 }
    1984#endif
    1985
    1986 SCIPdebugMessage("Calling SCIPlpiGetRows (%d)\n", lpi->lpid);
    1987
    1988#if DEBUG_CHECK_DATA > 0
    1989 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetRows") );
    1990#endif
    1991
    1992 SCIP_CALL( SCIPlpiGetSides(lpi, firstrow, lastrow, lhs, rhs) );
    1993 SCIP_CALL( getASlice(lpi, TRUE, firstrow, lastrow, nnonz, beg, ind, val) );
    1994
    1995#if DEBUG_CHECK_DATA > 0
    1996 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetRows") );
    1997#endif
    1998
    1999 return SCIP_OKAY;
    2000}
    2001
    2002/** gets column names */
    2004 SCIP_LPI* lpi, /**< LP interface structure */
    2005 int firstcol, /**< first column to get name from LP */
    2006 int lastcol, /**< last column to get name from LP */
    2007 char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
    2008 char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
    2009 int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
    2010 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
    2011 )
    2012{ /*lint --e{715}*/
    2013 assert(lpi != NULL);
    2014 assert(lpi->mosekenv != NULL);
    2015 assert(lpi->task != NULL);
    2016 assert(colnames != NULL || namestoragesize == 0);
    2017 assert(namestorage != NULL || namestoragesize == 0);
    2018 assert(namestoragesize >= 0);
    2019 assert(storageleft != NULL);
    2020 assert(firstcol >= 0);
    2021 assert(firstcol <= lastcol + 1);
    2022#ifndef NDEBUG
    2023 {
    2024 int ncols;
    2025 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2026 assert(lastcol < ncols);
    2027 }
    2028#endif
    2029
    2030 SCIPerrorMessage("SCIPlpiGetColNames() has not been implemented yet.\n");
    2031
    2032 return SCIP_LPERROR;
    2033}
    2034
    2035/** gets row names */
    2037 SCIP_LPI* lpi, /**< LP interface structure */
    2038 int firstrow, /**< first row to get name from LP */
    2039 int lastrow, /**< last row to get name from LP */
    2040 char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
    2041 char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
    2042 int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
    2043 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
    2044 )
    2045{ /*lint --e{715}*/
    2046 assert(lpi != NULL);
    2047 assert(lpi->mosekenv != NULL);
    2048 assert(lpi->task != NULL);
    2049 assert(rownames != NULL || namestoragesize == 0);
    2050 assert(namestorage != NULL || namestoragesize == 0);
    2051 assert(namestoragesize >= 0);
    2052 assert(storageleft != NULL);
    2053 assert(firstrow >= 0);
    2054 assert(firstrow <= lastrow + 1);
    2055#ifndef NDEBUG
    2056 {
    2057 int nrows;
    2058 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    2059 assert(lastrow < nrows);
    2060 }
    2061#endif
    2062
    2063 SCIPerrorMessage("SCIPlpiGetRowNames() has not been implemented yet.\n");
    2064
    2065 return SCIP_LPERROR;
    2066}
    2067
    2068/** gets the objective sense of the LP */
    2070 SCIP_LPI* lpi, /**< LP interface structure */
    2071 SCIP_OBJSEN* objsen /**< pointer to store objective sense */
    2072 )
    2073{
    2074 MSKobjsensee mskobjsen;
    2075
    2076 assert(lpi != NULL);
    2077 assert(lpi->mosekenv != NULL);
    2078 assert(lpi->task != NULL);
    2079 assert(objsen != NULL);
    2080
    2081 SCIPdebugMessage("Calling SCIPlpiGetObjsen (%d)\n", lpi->lpid);
    2082
    2083 MOSEK_CALL( MSK_getobjsense(lpi->task, &mskobjsen) );
    2084 *objsen = (mskobjsen == MSK_OBJECTIVE_SENSE_MINIMIZE ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE);
    2085
    2086 return SCIP_OKAY;
    2087}
    2088
    2089/** gets objective coefficients from LP problem object */
    2091 SCIP_LPI* lpi, /**< LP interface structure */
    2092 int firstcol, /**< first column to get objective coefficient for */
    2093 int lastcol, /**< last column to get objective coefficient for */
    2094 SCIP_Real* vals /**< array to store objective coefficients */
    2095 )
    2096{
    2097 assert(lpi != NULL);
    2098 assert(lpi->mosekenv != NULL);
    2099 assert(lpi->task != NULL);
    2100 assert(vals != NULL);
    2101 assert(firstcol >= 0);
    2102 assert(firstcol <= lastcol + 1);
    2103#ifndef NDEBUG
    2104 {
    2105 int ncols;
    2106 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2107 assert(lastcol < ncols);
    2108 }
    2109#endif
    2110
    2111 SCIPdebugMessage("Calling SCIPlpiGetObj (%d)\n", lpi->lpid);
    2112
    2113 MOSEK_CALL( MSK_getcslice(lpi->task, firstcol, lastcol+1, vals) );
    2114
    2115 return SCIP_OKAY;
    2116}
    2117
    2118/** gets current bounds from LP problem object */
    2120 SCIP_LPI* lpi, /**< LP interface structure */
    2121 int firstcol, /**< first column to get bounds for */
    2122 int lastcol, /**< last column to get bounds for */
    2123 SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
    2124 SCIP_Real* ubs /**< array to store upper bound values, or NULL */
    2125 )
    2126{
    2127 assert(lpi != NULL);
    2128 assert(lpi->mosekenv != NULL);
    2129 assert(lpi->task != NULL);
    2130 assert(firstcol >= 0);
    2131 assert(firstcol <= lastcol + 1);
    2132#ifndef NDEBUG
    2133 {
    2134 int ncols;
    2135 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    2136 assert(lastcol < ncols);
    2137 }
    2138#endif
    2139
    2140 SCIPdebugMessage("Calling SCIPlpiGetBounds (%d)\n", lpi->lpid);
    2141
    2142#if DEBUG_CHECK_DATA > 0
    2143 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetBounds") );
    2144#endif
    2145
    2146#if MSK_VERSION_MAJOR < 9
    2147 MOSEK_CALL( MSK_getboundslice(lpi->task, MSK_ACC_VAR, firstcol, lastcol+1, NULL, lbs, ubs) );
    2148#else
    2149 MOSEK_CALL( MSK_getvarboundslice(lpi->task, firstcol, lastcol+1, NULL, lbs, ubs) );
    2150#endif
    2151
    2152 return SCIP_OKAY;
    2153}
    2154
    2155/** gets current row sides from LP problem object */
    2157 SCIP_LPI* lpi, /**< LP interface structure */
    2158 int firstrow, /**< first row to get sides for */
    2159 int lastrow, /**< last row to get sides for */
    2160 SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
    2161 SCIP_Real* rhss /**< array to store right hand side values, or NULL */
    2162 )
    2163{
    2164 assert(lpi != NULL);
    2165 assert(lpi->mosekenv != NULL);
    2166 assert(lpi->task != NULL);
    2167 assert(firstrow >= 0);
    2168 assert(firstrow <= lastrow + 1);
    2169#ifndef NDEBUG
    2170 {
    2171 int nrows;
    2172 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    2173 assert(lastrow < nrows);
    2174 }
    2175#endif
    2176
    2177 SCIPdebugMessage("Calling SCIPlpiGetSides (%d)\n", lpi->lpid);
    2178
    2179#if DEBUG_CHECK_DATA > 0
    2180 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetSides") );
    2181#endif
    2182
    2183#if MSK_VERSION_MAJOR < 9
    2184 MOSEK_CALL( MSK_getboundslice(lpi->task, MSK_ACC_CON, firstrow, lastrow+1, NULL, lhss, rhss) );
    2185#else
    2186 MOSEK_CALL( MSK_getconboundslice(lpi->task, firstrow, lastrow+1, NULL, lhss, rhss) );
    2187#endif
    2188
    2189#if DEBUG_CHECK_DATA > 0
    2190 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetSides") );
    2191#endif
    2192
    2193 return SCIP_OKAY;
    2194}
    2195
    2196/** gets a single coefficient */
    2198 SCIP_LPI* lpi, /**< LP interface structure */
    2199 int row, /**< row number of coefficient */
    2200 int col, /**< column number of coefficient */
    2201 SCIP_Real* val /**< pointer to store the value of the coefficient */
    2202 )
    2203{
    2204 assert(lpi != NULL);
    2205 assert(lpi->mosekenv != NULL);
    2206 assert(lpi->task != NULL);
    2207 assert(val != NULL);
    2208
    2209 SCIPdebugMessage("Calling SCIPlpiGetCoef (%d)\n", lpi->lpid);
    2210
    2211#if DEBUG_CHECK_DATA > 0
    2212 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetCoef") );
    2213#endif
    2214
    2215 MOSEK_CALL( MSK_getaij(lpi->task, row, col, val) );
    2216
    2217#if DEBUG_CHECK_DATA > 0
    2218 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiGetCoef") );
    2219#endif
    2220
    2221 return SCIP_OKAY;
    2222}
    2223
    2224/*
    2225 * Solving Methods
    2226 */
    2227
    2228
    2229/** gets the internal solution status of the solver */
    2230static
    2232 SCIP_LPI* lpi, /**< LP interface structure */
    2233 MSKprostae* prosta, /**< pointer to store the problem status */
    2234 MSKsolstae* solsta /**< pointer to store the solution status */
    2235 )
    2236{
    2237 assert(lpi != NULL);
    2238 assert(lpi->mosekenv != NULL);
    2239 assert(lpi->task != NULL);
    2240
    2241 MOSEK_CALL( MSK_getsolutionstatus(lpi->task, lpi->lastsolvetype, prosta, solsta) );
    2242
    2243 return SCIP_OKAY;
    2244}
    2245
    2246/** helper method to filter out numerical problems */
    2247static
    2249 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    2250 MSKrescodee* termcode, /**< pointer to store output termination code */
    2251 MSKrescodee res /**< input result of call to Mosek function */
    2252 )
    2253{ /*lint --e{715}*/
    2254 assert( termcode != NULL );
    2255
    2256#if ASSERT_ON_NUMERICAL_TROUBLES > 0
    2257 if ( res == MSK_RES_TRM_MAX_NUM_SETBACKS || res == MSK_RES_TRM_NUMERICAL_PROBLEM )
    2258 {
    2259 SCIPmessagePrintWarning(messagehdlr, "Return code %d.\n", res);
    2260 assert(0);
    2261 *termcode = res;
    2262 return MSK_RES_OK;
    2263 }
    2264#else
    2265 SCIP_UNUSED(messagehdlr);
    2266#endif
    2267
    2268 if ( res == MSK_RES_TRM_MAX_ITERATIONS || res == MSK_RES_TRM_MAX_TIME
    2269 || res == MSK_RES_TRM_OBJECTIVE_RANGE || res == MSK_RES_TRM_STALL )
    2270 {
    2271 *termcode = res;
    2272 res = MSK_RES_OK;
    2273 }
    2274 else
    2275 *termcode = MSK_RES_OK;
    2276
    2277 return res;
    2278}
    2279
    2280/** solve problem with the simplex algorithm */
    2281static
    2283 SCIP_LPI* lpi /**< LP interface structure */
    2284 )
    2285{
    2286 int itercount_primal;
    2287 int itercount_dual;
    2288 int gotbasicsol;
    2289 int presolve;
    2290 int maxiter;
    2291 MSKprostae prosta;
    2292 MSKsolstae solsta;
    2293 double pobj, dobj;
    2294
    2295 assert(lpi != NULL);
    2296 assert(lpi->mosekenv != NULL);
    2297 assert(lpi->task != NULL);
    2298
    2299 invalidateSolution(lpi);
    2300 lpi->lastsolvetype = MSK_SOL_BAS;
    2301
    2302 /* store original settings */
    2303 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, &presolve) );
    2304 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, &maxiter) );
    2305
    2306 /* set some paramters */
    2307#if DEBUG_EASY_REPRODUCE
    2308 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_AUTO_SORT_A_BEFORE_OPT, MSK_ON) );
    2309 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_OFF) );
    2310#else
    2311 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
    2312#endif
    2313
    2314 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_AUTO_UPDATE_SOL_INFO, MSK_OFF) );
    2315
    2316#if FORCE_MOSEK_LOG
    2317 if( lpi->optimizecount > WRITE_ABOVE )
    2318 {
    2319 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG_SIM, 4) );
    2320 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG_SIM_FREQ, 1) );
    2321 }
    2322 else
    2323 {
    2324 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG_SIM, 4) );
    2325 }
    2326#endif
    2327
    2328 MOSEK_CALL( MSK_solutiondef(lpi->task, MSK_SOL_BAS, &gotbasicsol) );
    2329
    2330 if( gotbasicsol )
    2331 {
    2332 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, MSK_PRESOLVE_MODE_OFF) );
    2333 }
    2334 else
    2335 {
    2336 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, MSK_PRESOLVE_MODE_ON) );
    2337 }
    2338
    2339#if ALWAYS_SOLVE_PRIMAL_FORM > 0
    2340 /* always solve the primal formulation */
    2341 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SOLVE_FORM, MSK_SOLVE_PRIMAL) );
    2342#endif
    2343
    2344#if DEBUG_CHECK_DATA > 0
    2345 SCIP_CALL( scip_checkdata(lpi, "SolveWSimplex") );
    2346#endif
    2347
    2348 if( gotbasicsol && maxiter < 20000 )
    2349 {
    2350 /* Since max iter often is set, we switch off restricted pricing */
    2351 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION, 0) );
    2352 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION, 0) );
    2353 }
    2354 else
    2355 {
    2356 /* otherwise use default value */
    2357 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION, lpi->restrictselectdef) );
    2358 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION, lpi->restrictselectdef) );
    2359 }
    2360
    2361#if FORCE_NO_MAXITER > 0
    2362 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, 2000000000) );
    2363#endif
    2364
    2365#if DEBUG_CHECK_DATA > 0
    2366 SCIP_CALL( scip_checkdata(lpi, "Begin optimize with simplex") );
    2367#endif
    2368
    2369#if FORCE_MOSEK_SUMMARY > 1
    2370 if( lpi->optimizecount > WRITE_ABOVE )
    2371 {
    2372 MOSEK_CALL( MSK_solutionsummary(lpi->task, MSK_STREAM_LOG) );
    2373 }
    2374#endif
    2375
    2376 /* perform actual optimization */
    2377 MOSEK_CALL( filterTRMrescode(lpi->messagehdlr, &lpi->termcode, MSK_optimize(lpi->task)) );
    2378
    2379#if MSK_VERSION_MAJOR < 10
    2380 /* resolve with aggressive scaling if the maximal number of setbacks has been reached */
    2381 if( lpi->termcode == MSK_RES_TRM_MAX_NUM_SETBACKS )
    2382 {
    2383 int scaling;
    2384
    2385 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_SCALING, &scaling) );
    2386 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, MSK_SCALING_AGGRESSIVE) );
    2387 MOSEK_CALL( filterTRMrescode(lpi->messagehdlr, &lpi->termcode, MSK_optimize(lpi->task)) );
    2388 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, scaling) );
    2389 }
    2390#endif
    2391
    2392#if FORCE_MOSEK_SUMMARY
    2393 if( lpi->optimizecount > WRITE_ABOVE )
    2394 {
    2395 MOSEK_CALL( MSK_solutionsummary(lpi->task, MSK_STREAM_LOG) );
    2396 }
    2397#else
    2398 if( lpi->lpinfo )
    2399 {
    2400 MOSEK_CALL( MSK_solutionsummary(lpi->task, MSK_STREAM_LOG) );
    2401 }
    2402#endif
    2403
    2404#if DEBUG_CHECK_DATA > 0
    2405 SCIP_CALL( scip_checkdata(lpi, "End optimize with simplex") );
    2406#endif
    2407
    2408 /* set parameters to their original values */
    2409 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, presolve) );
    2410 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, maxiter) );
    2411
    2412 /* obtain iteration count */
    2413 MOSEK_CALL( MSK_getintinf(lpi->task, MSK_IINF_SIM_PRIMAL_ITER, &itercount_primal) );
    2414 MOSEK_CALL( MSK_getintinf(lpi->task, MSK_IINF_SIM_DUAL_ITER, &itercount_dual) );
    2415
    2416 lpi->itercount = itercount_primal + itercount_dual;
    2417
    2418 /* get solution information */
    2419 MOSEK_CALL( MSK_getprimalobj(lpi->task, MSK_SOL_BAS, &pobj) );
    2420 MOSEK_CALL( MSK_getdualobj(lpi->task, MSK_SOL_BAS, &dobj) );
    2421
    2422 MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, &prosta, &solsta) );
    2423
    2424 SCIPdebugMessage("maxiter = %d, termcode = %d, prosta = %d, solsta = %d, objval = %g : %g, iter = %d+%d\n",
    2425 maxiter, lpi->termcode, prosta, solsta, pobj, dobj, itercount_primal, itercount_dual);
    2426
    2427 switch (solsta)
    2428 {
    2429 case MSK_SOL_STA_OPTIMAL:
    2430 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
    2431 case MSK_SOL_STA_PRIM_FEAS:
    2432 case MSK_SOL_STA_DUAL_FEAS:
    2433 case MSK_SOL_STA_PRIM_INFEAS_CER:
    2434 case MSK_SOL_STA_DUAL_INFEAS_CER:
    2435 if (lpi->termcode == MSK_RES_OK)
    2436 lpi->solved = TRUE;
    2437 break;
    2438
    2439 case MSK_SOL_STA_UNKNOWN:
    2440 /* Mosek seems to have status unknown on the following termination codes */
    2441 assert( lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS || lpi->termcode == MSK_RES_TRM_MAX_TIME ||
    2442 lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE || lpi->termcode == MSK_RES_TRM_STALL ||
    2443 lpi->termcode == MSK_RES_OK );
    2444
    2445 if ( lpi->termcode != MSK_RES_TRM_MAX_ITERATIONS && lpi->termcode != MSK_RES_TRM_MAX_TIME &&
    2446 lpi->termcode != MSK_RES_TRM_OBJECTIVE_RANGE )
    2447 {
    2448 SCIPmessagePrintWarning(lpi->messagehdlr, "Numerical problem: simplex[%d] returned solsta = %d.\n", lpi->optimizecount, solsta);
    2449 lpi->termcode = MSK_RES_TRM_NUMERICAL_PROBLEM;
    2450#if ASSERT_ON_WARNING
    2451 assert(0);
    2452#endif
    2453 }
    2454 break;
    2455
    2456#if MSK_VERSION_MAJOR < 9
    2457 case MSK_SOL_STA_NEAR_OPTIMAL:
    2458 case MSK_SOL_STA_NEAR_PRIM_FEAS:
    2459 case MSK_SOL_STA_NEAR_DUAL_FEAS:
    2460 case MSK_SOL_STA_NEAR_PRIM_AND_DUAL_FEAS:
    2461 case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
    2462 case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
    2463
    2464 assert(lpi->termcode == MSK_RES_OK);
    2465
    2466 SCIPmessagePrintWarning(lpi->messagehdlr, "Simplex[%d] returned solsta = %d (numerical problem).\n", lpi->optimizecount, solsta);
    2467 lpi->termcode = MSK_RES_TRM_NUMERICAL_PROBLEM;
    2468#if ASSERT_ON_WARNING
    2469 assert(0);
    2470#endif
    2471 break;
    2472#endif
    2473
    2474 case MSK_SOL_STA_INTEGER_OPTIMAL:
    2475#if MSK_VERSION_MAJOR < 9
    2476 case MSK_SOL_STA_NEAR_INTEGER_OPTIMAL:
    2477#endif
    2478 default:
    2479#if SHOW_ERRORS
    2480 SCIPerrorMessage("Simplex[%d] returned solsta = %d\n", lpi->optimizecount, solsta);
    2481#endif
    2482
    2483#if ASSERT_ON_WARNING
    2484 assert(0);
    2485#endif
    2486
    2487 return SCIP_LPERROR;
    2488 } /*lint !e788*/
    2489
    2490 switch (prosta)
    2491 {
    2492 /* already handled above */
    2493 case MSK_PRO_STA_PRIM_AND_DUAL_FEAS:
    2494 case MSK_PRO_STA_PRIM_FEAS:
    2495 case MSK_PRO_STA_DUAL_FEAS:
    2496 case MSK_PRO_STA_PRIM_AND_DUAL_INFEAS:
    2497 case MSK_PRO_STA_PRIM_INFEAS:
    2498 case MSK_PRO_STA_DUAL_INFEAS:
    2499 case MSK_PRO_STA_UNKNOWN:
    2500 break;
    2501
    2502#if MSK_VERSION_MAJOR < 9
    2503 case MSK_PRO_STA_NEAR_PRIM_AND_DUAL_FEAS:
    2504 case MSK_PRO_STA_NEAR_PRIM_FEAS:
    2505 case MSK_PRO_STA_NEAR_DUAL_FEAS:
    2506#endif
    2507 case MSK_PRO_STA_ILL_POSED:
    2508 case MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED:
    2509 assert(lpi->termcode == MSK_RES_OK);
    2510
    2511 SCIPmessagePrintWarning(lpi->messagehdlr, "Simplex[%d] returned prosta = %d\n", lpi->optimizecount, prosta);
    2512 lpi->termcode = MSK_RES_TRM_NUMERICAL_PROBLEM;
    2513 invalidateSolution(lpi);
    2514#if ASSERT_ON_WARNING
    2515 assert(0);
    2516#endif
    2517 break;
    2518
    2519 default:
    2520#if SHOW_ERRORS
    2521 SCIPerrorMessage("Simplex[%d] returned prosta = %d\n", lpi->optimizecount, prosta);
    2522#endif
    2523
    2524#if ASSERT_ON_WARNING
    2525 assert(0);
    2526#endif
    2527
    2528 return SCIP_LPERROR;
    2529 } /*lint !e788*/
    2530
    2531 /* todo: replace numbers by constants, e.g., tolerances */
    2532#if SHOW_RELATIVE_OPTIMAL_GAP
    2533 if ( solsta == MSK_SOL_STA_OPTIMAL && fabs(pobj) + fabs(dobj) > 1.0e-6 && fabs(pobj-dobj) > 0.0001*(fabs(pobj) + fabs(dobj)))
    2534 {
    2535 SCIPerrorMessage("Simplex[%d] returned optimal solution with different objvals %g != %g reldiff %.2g%%\n",
    2536 lpi->optimizecount, pobj, dobj, 100.0 * fabs(pobj-dobj)/ MAX(fabs(pobj), fabs(dobj))); /*lint !e666*/
    2537 }
    2538#endif
    2539
    2540 /* The optimizer terminated with an objective value outside the objective range. */
    2541 if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
    2542 {
    2543 if (solsta != MSK_SOL_STA_DUAL_FEAS && solsta != MSK_SOL_STA_OPTIMAL && solsta != MSK_SOL_STA_PRIM_AND_DUAL_FEAS)
    2544 {
    2545 SCIPerrorMessage("[%d] Terminated on objective range without dual feasible solsta.\n", lpi->optimizecount);
    2546
    2547 /* solve again with barrier */
    2549 }
    2550 }
    2551
    2552 /* if the simplex took too many iterations, solve again with barrier */
    2553 if (maxiter >= 2000000000)
    2554 {
    2555 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, maxiter) );
    2556
    2557 if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
    2558 {
    2559 SCIPmessagePrintWarning(lpi->messagehdlr, "Simplex[%d] failed to terminate in 10000 iterations, switching to interior point\n",
    2560 lpi->optimizecount);
    2561
    2563 }
    2564 }
    2565
    2566#if DEBUG_DO_INTPNT_FEAS_CHECK
    2567 if (solsta == MSK_SOL_STA_PRIM_INFEAS_CER || solsta == MSK_SOL_STA_DUAL_INFEAS_CER)
    2568 {
    2569 SCIPdebugMessage("Checking infeasibility[%d]... ", lpi->optimizecount);
    2570
    2571 SCIP_CALL( SCIPlpiSolveBarrier(lpi, true) );
    2572
    2573 MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, &prosta, &solsta) );
    2574
    2575 if (solsta == MSK_SOL_STA_PRIM_INFEAS_CER || solsta == MSK_SOL_STA_DUAL_INFEAS_CER)
    2576 {
    2577 SCIPdebugPrintf("ok\n");
    2578 }
    2579 else
    2580 {
    2581 SCIPdebugPrintf("wrong [%d] prosta = %d, solsta = %d\n", lpi->optimizecount, prosta, solsta);
    2582 }
    2583 }
    2584#endif
    2585
    2586#if DEBUG_PRINT_STAT > 0
    2587 SCIPdebugMessage("Max iter stat : Count %d branchup = %d branchlo = %d primal %d dual %d\n",
    2588 lpi->optimizecount, numstrongbranchmaxiterup, numstrongbranchmaxiterdo, numprimalmaxiter, numdualmaxiter);
    2589 SCIPdebugMessage("Objcut iter stat : Count %d branchup = %d branchlo = %d primal %d dual %d\n",
    2590 lpi->optimizecount, numstrongbranchobjup, numstrongbranchobjdo, numprimalobj, numdualobj);
    2591#endif
    2592
    2593#if DEBUG_CHECK_DATA > 0
    2594 SCIP_CALL( scip_checkdata(lpi, "SolveWSimplex") );
    2595#endif
    2596
    2597 return SCIP_OKAY;
    2598}
    2599
    2600/** calls primal simplex to solve the LP */
    2602 SCIP_LPI* lpi /**< LP interface structure */
    2603 )
    2604{
    2605 assert(lpi != NULL);
    2606 assert(lpi->mosekenv != NULL);
    2607 assert(lpi->task != NULL);
    2608
    2609 lpi->optimizecount++;
    2610
    2611 SCIPdebugMessage("Calling SCIPlpiSolvePrimal[%d] (%d) ", lpi->optimizecount, lpi->lpid);
    2612
    2613 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
    2614
    2615 /* Set warmstarting information in MOSEK. We only have status keys (recalculate dual solution without dual superbasics) */
    2616 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, lpi->fromscratch || lpi->clearstate ?
    2617 MSK_SIM_HOTSTART_NONE : MSK_SIM_HOTSTART_STATUS_KEYS) );
    2618 lpi->clearstate = FALSE;
    2619
    2620#if DEBUG_CHECK_DATA > 0
    2621 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiSolvePrimal") );
    2622#endif
    2623
    2624 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_PRIMAL_SIMPLEX) );
    2625 lpi->lastalgo = MSK_OPTIMIZER_PRIMAL_SIMPLEX;
    2626
    2627#if WRITE_PRIMAL > 0
    2628 if( lpi->optimizecount > WRITE_ABOVE )
    2629 {
    2630 char fname[40];
    2631 snprintf(fname, 40, "primal_%d.lp", lpi->optimizecount);
    2632 SCIPdebugMessage("\nWriting lp %s\n", fname);
    2633 /*MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_GENERIC_NAMES, MSK_ON) );*/
    2634 MSK_writedata(lpi->task, fname);
    2635 }
    2636#endif
    2637
    2638 SCIP_CALL( SolveWSimplex(lpi) );
    2639
    2640#ifdef SCIP_DISABLED_CODE
    2641 /* the following code is unclear: Why should the resolve change anything ?????? */
    2642 if ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE )
    2643 {
    2644 MSKsolstae solsta;
    2645
    2646 MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, NULL, &solsta) );
    2647
    2648 if( solsta != MSK_SOL_STA_PRIM_FEAS )
    2649 {
    2650 SCIP_CALL( SolveWSimplex(lpi) );
    2651 }
    2652 }
    2653#endif
    2654
    2655#if DEBUG_PRINT_STAT > 0
    2656 if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
    2657 ++numprimalobj;
    2658#endif
    2659
    2660#if DEBUG_PRINT_STAT > 0
    2661 if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
    2662 ++numprimalmaxiter;
    2663#endif
    2664
    2665#if DEBUG_CHECK_DATA > 0
    2666 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiSolvePrimal") );
    2667#endif
    2668
    2669 return SCIP_OKAY;
    2670}
    2671
    2672/** calls dual simplex to solve the LP */
    2674 SCIP_LPI* lpi /**< LP interface structure */
    2675 )
    2676{
    2677 assert(lpi != NULL);
    2678 assert(lpi->mosekenv != NULL);
    2679 assert(lpi->task != NULL);
    2680
    2681 lpi->optimizecount++;
    2682
    2683 SCIPdebugMessage("Calling SCIPlpiSolveDual[%d] (%d)\n", lpi->optimizecount, lpi->lpid);
    2684
    2685/* MSK_IPAR_SIM_INTEGER is removed in Mosek 8.1 */
    2686#if (MSK_VERSION_MAJOR < 8) || (MSK_VERSION_MAJOR == 8 && MSK_VERSION_MINOR == 0)
    2687 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_INTEGER, MSK_ON) );
    2688#endif
    2689 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
    2690
    2691 /* Set warmstarting information in MOSEK. We only have status keys (recalculate dual solution without dual superbasics) */
    2692 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, (lpi->fromscratch || lpi->clearstate) ?
    2693 MSK_SIM_HOTSTART_NONE : MSK_SIM_HOTSTART_STATUS_KEYS) );
    2694 lpi->clearstate = FALSE;
    2695
    2696 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_DUAL_SIMPLEX) );
    2697 lpi->lastalgo = MSK_OPTIMIZER_DUAL_SIMPLEX;
    2698
    2699#if WRITE_DUAL > 0
    2700 if( lpi->optimizecount > WRITE_ABOVE )
    2701 {
    2702 char fname[40];
    2703 snprintf(fname,40,"dual_%d.lp", lpi->optimizecount);
    2704 SCIPdebugMessage("\nWriting lp %s\n", fname);
    2705 MSK_writedata(lpi->task, fname);
    2706 }
    2707#endif
    2708
    2709 SCIP_CALL( SolveWSimplex(lpi) );
    2710
    2711#ifdef SCIP_DISABLED_CODE
    2712 /* the following code is unclear: Why should the resolve change anything ?????? */
    2713 if ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE )
    2714 {
    2715 MSKsolstae solsta;
    2716
    2717 MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, NULL, &solsta) );
    2718
    2719 if( solsta != MSK_SOL_STA_DUAL_FEAS )
    2720 {
    2721 SCIP_CALL( SolveWSimplex(lpi) );
    2722 }
    2723 }
    2724#endif
    2725
    2726#if DEBUG_PRINT_STAT > 0
    2727 if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
    2728 ++numdualobj;
    2729#endif
    2730
    2731#if DEBUG_PRINT_STAT > 0
    2732 if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
    2733 ++numdualmaxiter;
    2734#endif
    2735
    2736 return SCIP_OKAY;
    2737}
    2738
    2739/** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
    2741 SCIP_LPI* lpi, /**< LP interface structure */
    2742 SCIP_Bool crossover /**< perform crossover */
    2743 )
    2744{
    2745 MSKprostae prosta;
    2746 MSKsolstae solsta;
    2747
    2748 assert(lpi != NULL);
    2749 assert(lpi->mosekenv != NULL);
    2750 assert(lpi->task != NULL);
    2751
    2752 lpi->optimizecount++;
    2753
    2754 invalidateSolution(lpi);
    2755 lpi->lastsolvetype = crossover ? MSK_SOL_BAS : MSK_SOL_ITR;
    2756
    2757#if FORCE_MOSEK_LOG
    2758 if( lpi->optimizecount > WRITE_ABOVE )
    2759 {
    2760 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, 4) );
    2761 }
    2762 else
    2763 {
    2764 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, 0) );
    2765 }
    2766#endif
    2767
    2768 SCIPdebugMessage("Calling SCIPlpiSolveBarrier[%d] (%d) ", lpi->optimizecount, lpi->lpid);
    2769
    2770#if DEBUG_CHECK_DATA > 0
    2771 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiSolveBarrier") );
    2772#endif
    2773
    2774#ifdef SCIP_DISABLED_CODE
    2775 /* The parameter exists in MOSEK, but as of version 8, it is not in use and the interior-point solver is never warmstarted */
    2776 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_HOTSTART, (lpi->fromscratch || lpi->clearstate) ?
    2777 MSK_SIM_HOTSTART_NONE : MSK_INTPNT_HOTSTART_PRIMAL_DUAL) );
    2778#endif
    2779 lpi->clearstate = FALSE;
    2780
    2781 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_BASIS, crossover ? MSK_BI_ALWAYS : MSK_BI_NEVER) );
    2782 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_INTPNT) );
    2783 lpi->lastalgo = MSK_OPTIMIZER_INTPNT;
    2784
    2785#if MSK_VERSION_MAJOR >= 9
    2786 MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_INTPNT_CO_TOL_NEAR_REL, NEAR_REL_TOLERANCE) );
    2787#endif
    2788
    2789#if WRITE_INTPNT > 0
    2790 if( lpi->optimizecount > WRITE_ABOVE )
    2791 {
    2792 char fname[40];
    2793 snprintf(fname,40,"intpnt_%d.lp", lpi->optimizecount);
    2794 SCIPdebugMessage("\nWriting lp %s\n", fname);
    2795 /*MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_GENERIC_NAMES, MSK_ON) );*/
    2796 MSK_writedata(lpi->task, fname);
    2797 }
    2798#endif
    2799
    2800 MOSEK_CALL( filterTRMrescode(lpi->messagehdlr, &lpi->termcode, MSK_optimize(lpi->task)) );
    2801
    2802#if DEBUG_PRINT_STAT > 0
    2803 if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
    2804 ++numdualmaxiter;
    2805#endif
    2806
    2807 MOSEK_CALL( MSK_getintinf(lpi->task, MSK_IINF_INTPNT_ITER, &lpi->itercount) );
    2808
    2809 MOSEK_CALL( MSK_getsolutionstatus(lpi->task, lpi->lastsolvetype, &prosta, &solsta) );
    2810 SCIPdebugMessage("termcode = %d, prosta = %d, solsta = %d, iter = %d\n",
    2811 lpi->termcode, prosta, solsta, lpi->itercount);
    2812
    2813 switch (solsta)
    2814 {
    2815 case MSK_SOL_STA_OPTIMAL:
    2816 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
    2817 case MSK_SOL_STA_PRIM_FEAS:
    2818 case MSK_SOL_STA_DUAL_FEAS:
    2819 case MSK_SOL_STA_PRIM_INFEAS_CER:
    2820 case MSK_SOL_STA_DUAL_INFEAS_CER:
    2821 if (lpi->termcode == MSK_RES_OK)
    2822 lpi->solved = TRUE;
    2823 break;
    2824 case MSK_SOL_STA_UNKNOWN:
    2825#if MSK_VERSION_MAJOR < 9
    2826 case MSK_SOL_STA_NEAR_OPTIMAL:
    2827 case MSK_SOL_STA_NEAR_PRIM_FEAS:
    2828 case MSK_SOL_STA_NEAR_DUAL_FEAS:
    2829 case MSK_SOL_STA_NEAR_PRIM_AND_DUAL_FEAS:
    2830 case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
    2831 case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
    2832#endif
    2833 SCIPmessagePrintWarning(lpi->messagehdlr, "Barrier[%d] returned solsta = %d\n", lpi->optimizecount, solsta);
    2834
    2835 if (lpi->termcode == MSK_RES_OK)
    2836 lpi->termcode = MSK_RES_TRM_NUMERICAL_PROBLEM;
    2837
    2838#if ASSERT_ON_WARNING
    2839 assert(0);
    2840#endif
    2841 break;
    2842 case MSK_SOL_STA_INTEGER_OPTIMAL:
    2843#if MSK_VERSION_MAJOR < 9
    2844 case MSK_SOL_STA_NEAR_INTEGER_OPTIMAL:
    2845#endif
    2846 default:
    2847#if SHOW_ERRORS
    2848 SCIPerrorMessage("Barrier[%d] returned solsta = %d\n", lpi->optimizecount, solsta);
    2849#endif
    2850
    2851#if ASSERT_ON_WARNING
    2852 assert(0);
    2853#endif
    2854
    2855 return SCIP_LPERROR;
    2856 } /*lint !e788*/
    2857
    2858 switch (prosta)
    2859 {
    2860 case MSK_PRO_STA_PRIM_AND_DUAL_FEAS:
    2861 case MSK_PRO_STA_PRIM_FEAS:
    2862 case MSK_PRO_STA_DUAL_FEAS:
    2863 case MSK_PRO_STA_PRIM_AND_DUAL_INFEAS:
    2864 case MSK_PRO_STA_PRIM_INFEAS:
    2865 case MSK_PRO_STA_DUAL_INFEAS:
    2866 break;
    2867 case MSK_PRO_STA_UNKNOWN:
    2868#if MSK_VERSION_MAJOR < 9
    2869 case MSK_PRO_STA_NEAR_PRIM_AND_DUAL_FEAS:
    2870 case MSK_PRO_STA_NEAR_PRIM_FEAS:
    2871 case MSK_PRO_STA_NEAR_DUAL_FEAS:
    2872#endif
    2873 case MSK_PRO_STA_ILL_POSED:
    2874 case MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED:
    2875 SCIPmessagePrintWarning(lpi->messagehdlr, "Barrier[%d] returned prosta = %d\n", lpi->optimizecount, prosta);
    2876
    2877 if (lpi->termcode == MSK_RES_OK)
    2878 lpi->termcode = MSK_RES_TRM_NUMERICAL_PROBLEM;
    2879
    2880 invalidateSolution(lpi);
    2881
    2882#if ASSERT_ON_WARNING
    2883 assert(0);
    2884#endif
    2885 break;
    2886 default:
    2887#if SHOW_ERRORS
    2888 SCIPerrorMessage("Barrier[%d] returned prosta = %d\n", lpi->optimizecount, prosta);
    2889#endif
    2890
    2891#if ASSERT_ON_WARNING
    2892 assert(0);
    2893#endif
    2894
    2895 return SCIP_LPERROR;
    2896 } /*lint !e788*/
    2897
    2898#if DEBUG_CHECK_DATA > 0
    2899 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiSolveBarrier") );
    2900#endif
    2901
    2902 return SCIP_OKAY;
    2903}
    2904
    2905/** start strong branching - call before any strong branching */
    2907 SCIP_LPI* lpi /**< LP interface structure */
    2908 )
    2909{ /*lint --e{715}*/
    2910 assert(lpi != NULL);
    2911 assert(lpi->mosekenv != NULL);
    2912 assert(lpi->task != NULL);
    2913
    2914 /* currently do nothing */
    2915 return SCIP_OKAY;
    2916}
    2917
    2918/** end strong branching - call after any strong branching */
    2920 SCIP_LPI* lpi /**< LP interface structure */
    2921 )
    2922{ /* lint --e{715}*/
    2923 assert(lpi != NULL);
    2924 /* assert(MosekEnv != NULL);
    2925 assert(lpi->task != NULL); */
    2926
    2927 /* currently do nothing */
    2928 return SCIP_OKAY;
    2929}
    2930
    2931/** performs strong branching iterations on all candidates
    2932 *
    2933 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    2934 */
    2935static
    2937 SCIP_LPI* lpi, /**< LP interface structure */
    2938 int col, /**< column to apply strong branching on */
    2939 SCIP_Real psol, /**< current primal solution value of column */
    2940 int itlim, /**< iteration limit for strong branchings */
    2941 SCIP_Real* down, /**< stores dual bound after branching column down */
    2942 SCIP_Real* up, /**< stores dual bound after branching column up */
    2943 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    2944 * otherwise, it can only be used as an estimate value */
    2945 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    2946 * otherwise, it can only be used as an estimate value */
    2947 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    2948 )
    2949{
    2950 MSKobjsensee objsen;
    2951 int olditerlim;
    2952 int oldselection;
    2953 int oldhotstart;
    2954
    2955 double bound;
    2956 int ncols;
    2957 int nrows;
    2958 MSKboundkeye bkx;
    2959 double blx;
    2960 double bux;
    2961 double newub;
    2962 double newlb;
    2963
    2964 assert(lpi != NULL);
    2965 assert(lpi->mosekenv != NULL);
    2966 assert(lpi->task != NULL);
    2967
    2968 SCIPdebugMessage("Calling SCIPlpiStrongbranch (%d)\n", lpi->lpid);
    2969
    2970#if DEBUG_CHECK_DATA > 0
    2971 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiStrongbranch") );
    2972#endif
    2973
    2974 if (lpi->termcode != MSK_RES_OK)
    2975 {
    2976 SCIPmessagePrintWarning(lpi->messagehdlr, "SB Warning: Previous termcode is %d\n", lpi->termcode);
    2977 }
    2978
    2979 MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
    2980 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    2981
    2982 SCIP_CALL( getbase(lpi, ncols, nrows) );
    2983
    2984 MOSEK_CALL( MSK_getobjsense(lpi->task, &objsen) );
    2985 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, &olditerlim) );
    2986 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, &oldselection) );
    2987 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, &oldhotstart) );
    2988
    2989 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, itlim) );
    2990 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, STRONGBRANCH_PRICING) );
    2991
    2992 if (objsen == MSK_OBJECTIVE_SENSE_MINIMIZE)
    2993 {
    2994 MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, &bound) );
    2995 }
    2996 else /* objsen == MSK_OBJECTIVE_SENSE_MAX */
    2997 {
    2998 MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, &bound) );
    2999 }
    3000
    3001#if MSK_VERSION_MAJOR < 9
    3002 MOSEK_CALL( MSK_getbound(lpi->task, MSK_ACC_VAR, col, &bkx, &blx, &bux) );
    3003#else
    3004 MOSEK_CALL( MSK_getvarbound(lpi->task, col, &bkx, &blx, &bux) );
    3005#endif
    3006
    3007 *iter = 0;
    3008
    3009 newub = EPSCEIL(psol-1.0, 1e-06);
    3010
    3011 if (newub < blx - 0.5) /* infeasible */
    3012 {
    3013 *down = bound;
    3014 *downvalid = TRUE;
    3015 }
    3016 else
    3017 {
    3018 MSKboundkeye newbk;
    3019
    3020 if (IS_NEGINF(blx))
    3021 newbk = MSK_BK_UP;
    3022 else if (EPSEQ(blx, newub,1.0e-6))
    3023 {
    3024 newbk = MSK_BK_FX;
    3025 newub = blx;
    3026 }
    3027 else
    3028 newbk = MSK_BK_RA;
    3029
    3030#if MSK_VERSION_MAJOR < 9
    3031 MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, newbk, blx, newub) );
    3032#else
    3033 MOSEK_CALL( MSK_putvarbound(lpi->task, col, newbk, blx, newub) );
    3034#endif
    3035
    3037
    3038 *iter += lpi->itercount;
    3039
    3040 if (SCIPlpiIsStable(lpi))
    3041 *downvalid = TRUE;
    3042 else
    3043 *downvalid = FALSE;
    3044
    3045 if (SCIPlpiExistsPrimalRay(lpi))
    3046 {
    3047 SCIPmessagePrintWarning(lpi->messagehdlr, "SB ERROR: Lp [%d] is dual infeasible\n", lpi->optimizecount);
    3048
    3049 *down = -1e20;
    3050 *downvalid = FALSE;
    3051 }
    3052 else if (SCIPlpiExistsDualRay(lpi))
    3053 {
    3054 *down = bound;
    3055 }
    3056 else
    3057 {
    3058 SCIP_Bool pfeas;
    3059 SCIP_Bool dfeas;
    3060
    3061 SCIP_CALL( SCIPlpiGetSolFeasibility(lpi, &pfeas, &dfeas) );
    3062
    3063 if (!dfeas)
    3064 {
    3065 SCIPmessagePrintWarning(lpi->messagehdlr, "SB ERROR: Lp [%d] is not dual feasible\n", lpi->optimizecount);
    3066
    3067 *down = -1e20;
    3068 *downvalid = FALSE;
    3069 }
    3070 else
    3071 {
    3072 MOSEK_CALL( MSK_getdualobj(lpi->task, lpi->lastsolvetype, down) );
    3073 }
    3074 }
    3075
    3076#if DEBUG_PRINT_STAT > 0
    3077 if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
    3078 ++numstrongbranchobjup;
    3079
    3080 if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
    3081 ++numstrongbranchmaxiterup;
    3082#endif
    3083 }
    3084
    3085 /* Reset basis solution before doing the up branch */
    3086#if MSK_VERSION_MAJOR < 9
    3087 MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, bkx, blx, bux) );
    3088#else
    3089 MOSEK_CALL( MSK_putvarbound(lpi->task, col, bkx, blx, bux) );
    3090#endif
    3091 SCIP_CALL( setbase(lpi) );
    3092
    3093 newlb = EPSFLOOR(psol+1.0, 1e-06);
    3094 if (newlb > bux + 0.5) /* infeasible */
    3095 {
    3096 *up = bound;
    3097 *upvalid = TRUE;
    3098 }
    3099 else
    3100 {
    3101 MSKboundkeye newbk;
    3102
    3103 if (IS_POSINF(bux))
    3104 newbk = MSK_BK_LO;
    3105 else if (EPSEQ(bux, newlb,1.0e-6))
    3106 {
    3107 newbk = MSK_BK_FX;
    3108 newlb = bux;
    3109 }
    3110 else
    3111 newbk = MSK_BK_RA;
    3112
    3113#if MSK_VERSION_MAJOR < 9
    3114 MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, newbk, newlb, bux) );
    3115#else
    3116 MOSEK_CALL( MSK_putvarbound(lpi->task, col, newbk, newlb, bux) );
    3117#endif
    3119
    3120 *iter += lpi->itercount;
    3121
    3122 if (SCIPlpiIsStable(lpi))
    3123 *upvalid = TRUE;
    3124 else
    3125 *upvalid = FALSE;
    3126
    3127 if (SCIPlpiExistsPrimalRay(lpi))
    3128 {
    3129 *up = -1e20;
    3130 *upvalid = FALSE;
    3131 }
    3132 else if (SCIPlpiExistsDualRay(lpi))
    3133 {
    3134 *up = bound;
    3135 }
    3136 else
    3137 {
    3138 SCIP_Bool pfeas;
    3139 SCIP_Bool dfeas;
    3140
    3141 SCIP_CALL( SCIPlpiGetSolFeasibility(lpi, &pfeas, &dfeas) );
    3142
    3143 if (!dfeas)
    3144 {
    3145 SCIPmessagePrintWarning(lpi->messagehdlr, "SB ERROR: Lp [%d] is not dual feasible\n", lpi->optimizecount);
    3146
    3147 *up = -1e20;
    3148 *upvalid = FALSE;
    3149 }
    3150 else
    3151 {
    3152 MOSEK_CALL( MSK_getdualobj(lpi->task, lpi->lastsolvetype, up) );
    3153 }
    3154 }
    3155
    3156#if DEBUG_PRINT_STAT > 0
    3157 if (lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE)
    3158 ++numstrongbranchobjdo;
    3159
    3160 if (lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS)
    3161 ++numstrongbranchmaxiterdo;
    3162#endif
    3163 }
    3164
    3165#if MSK_VERSION_MAJOR < 9
    3166 MOSEK_CALL( MSK_putbound(lpi->task, MSK_ACC_VAR, col, bkx, blx, bux) );
    3167#else
    3168 MOSEK_CALL( MSK_putvarbound(lpi->task, col, bkx, blx, bux) );
    3169#endif
    3170 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, olditerlim) );
    3171 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, oldselection) );
    3172 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART, oldhotstart) );
    3173
    3174 SCIP_CALL( setbase(lpi) );
    3175
    3176 invalidateSolution(lpi);
    3177
    3178 lpi->termcode = MSK_RES_OK;
    3179 lpi->itercount = 0;
    3180
    3181#if DEBUG_CHECK_DATA > 0
    3182 SCIP_CALL( scip_checkdata(lpi, "SCIPlpiStrongbranch") );
    3183#endif
    3184
    3185 SCIPdebugMessage("End SCIPlpiStrongbranch (%d)\n", lpi->lpid);
    3186
    3187 return SCIP_OKAY;
    3188}
    3189
    3190/** performs strong branching iterations on one @b fractional candidate
    3191 *
    3192 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    3193 */
    3195 SCIP_LPI* lpi, /**< LP interface structure */
    3196 int col, /**< column to apply strong branching on */
    3197 SCIP_Real psol, /**< fractional current primal solution value of column */
    3198 int itlim, /**< iteration limit for strong branchings */
    3199 SCIP_Real* down, /**< stores dual bound after branching column down */
    3200 SCIP_Real* up, /**< stores dual bound after branching column up */
    3201 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    3202 * otherwise, it can only be used as an estimate value */
    3203 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    3204 * otherwise, it can only be used as an estimate value */
    3205 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    3206 )
    3207{
    3208 /* pass call on to lpiStrongbranch() */
    3209 SCIP_CALL( SCIPlpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
    3210
    3211 return SCIP_OKAY;
    3212}
    3213
    3214/** performs strong branching iterations on given @b fractional candidates
    3215 *
    3216 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    3217 */
    3219 SCIP_LPI* lpi, /**< LP interface structure */
    3220 int* cols, /**< columns to apply strong branching on */
    3221 int ncols, /**< number of columns */
    3222 SCIP_Real* psols, /**< fractional current primal solution values of columns */
    3223 int itlim, /**< iteration limit for strong branchings */
    3224 SCIP_Real* down, /**< stores dual bounds after branching columns down */
    3225 SCIP_Real* up, /**< stores dual bounds after branching columns up */
    3226 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
    3227 * otherwise, they can only be used as an estimate values */
    3228 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
    3229 * otherwise, they can only be used as an estimate values */
    3230 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    3231 )
    3232{
    3233 int j;
    3234
    3235 assert( cols != NULL );
    3236 assert( psols != NULL );
    3237 assert( down != NULL );
    3238 assert( up != NULL );
    3239 assert( downvalid != NULL );
    3240 assert( upvalid != NULL );
    3241 assert( down != NULL );
    3242
    3243 if ( iter != NULL )
    3244 *iter = 0;
    3245
    3246 for (j = 0; j < ncols; ++j)
    3247 {
    3248 /* pass call on to lpiStrongbranch() */
    3249 SCIP_CALL( SCIPlpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
    3250 }
    3251 return SCIP_OKAY;
    3252}
    3253
    3254/** performs strong branching iterations on one candidate with @b integral value
    3255 *
    3256 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    3257 */
    3259 SCIP_LPI* lpi, /**< LP interface structure */
    3260 int col, /**< column to apply strong branching on */
    3261 SCIP_Real psol, /**< current integral primal solution value of column */
    3262 int itlim, /**< iteration limit for strong branchings */
    3263 SCIP_Real* down, /**< stores dual bound after branching column down */
    3264 SCIP_Real* up, /**< stores dual bound after branching column up */
    3265 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
    3266 * otherwise, it can only be used as an estimate value */
    3267 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
    3268 * otherwise, it can only be used as an estimate value */
    3269 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    3270 )
    3271{
    3272 /* pass call on to lpiStrongbranch() */
    3273 SCIP_CALL( SCIPlpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
    3274
    3275 return SCIP_OKAY;
    3276}
    3277
    3278/** performs strong branching iterations on given candidates with @b integral values
    3279 *
    3280 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    3281 */
    3283 SCIP_LPI* lpi, /**< LP interface structure */
    3284 int* cols, /**< columns to apply strong branching on */
    3285 int ncols, /**< number of columns */
    3286 SCIP_Real* psols, /**< current integral primal solution values of columns */
    3287 int itlim, /**< iteration limit for strong branchings */
    3288 SCIP_Real* down, /**< stores dual bounds after branching columns down */
    3289 SCIP_Real* up, /**< stores dual bounds after branching columns up */
    3290 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
    3291 * otherwise, they can only be used as an estimate values */
    3292 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
    3293 * otherwise, they can only be used as an estimate values */
    3294 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
    3295 )
    3296{
    3297 int j;
    3298
    3299 assert( cols != NULL );
    3300 assert( psols != NULL );
    3301 assert( down != NULL );
    3302 assert( up != NULL );
    3303 assert( downvalid != NULL );
    3304 assert( upvalid != NULL );
    3305 assert( down != NULL );
    3306
    3307 if ( iter != NULL )
    3308 *iter = 0;
    3309
    3310 for (j = 0; j < ncols; ++j)
    3311 {
    3312 /* pass call on to lpiStrongbranch() */
    3313 SCIP_CALL( SCIPlpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
    3314 }
    3315 return SCIP_OKAY;
    3316}
    3317
    3318
    3319/*
    3320 * Solution Information Methods
    3321 */
    3322
    3323
    3324/** returns whether a solve method was called after the last modification of the LP */
    3326 SCIP_LPI* lpi /**< LP interface structure */
    3327 )
    3328{
    3329 assert(lpi != NULL);
    3330
    3331 return lpi->solved;
    3332}
    3333
    3334/** gets information about primal and dual feasibility of the current LP solution
    3335 *
    3336 * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
    3337 * returns true. If the LP is changed, this information might be invalidated.
    3338 *
    3339 * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
    3340 * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
    3341 * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
    3342 * the problem might actually be feasible).
    3343 */
    3345 SCIP_LPI* lpi, /**< LP interface structure */
    3346 SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
    3347 SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
    3348 )
    3349{
    3350 MSKprostae prosta;
    3351
    3352 assert( lpi != NULL );
    3353 assert( lpi->mosekenv != NULL );
    3354 assert( lpi->task != NULL );
    3355 assert( primalfeasible != NULL );
    3356 assert( dualfeasible != NULL );
    3357
    3358 SCIPdebugMessage("Calling SCIPlpiGetSolFeasibility (%d)\n", lpi->lpid);
    3359
    3360 MOSEK_CALL( MSK_getsolutionstatus(lpi->task, lpi->lastsolvetype, &prosta, NULL) );
    3361
    3362 switch (prosta)
    3363 {
    3364 case MSK_PRO_STA_PRIM_AND_DUAL_FEAS:
    3365 *primalfeasible = TRUE;
    3366 *dualfeasible = TRUE;
    3367 break;
    3368 case MSK_PRO_STA_PRIM_FEAS:
    3369 *primalfeasible = TRUE;
    3370 *dualfeasible = FALSE;
    3371 break;
    3372 case MSK_PRO_STA_DUAL_FEAS:
    3373 *primalfeasible = FALSE;
    3374 *dualfeasible = TRUE;
    3375 break;
    3376 case MSK_PRO_STA_DUAL_INFEAS:
    3377 /* assume that we have a primal solution if we used the primal simplex */
    3378 *primalfeasible = (lpi->lastalgo == MSK_OPTIMIZER_PRIMAL_SIMPLEX);
    3379 *dualfeasible = FALSE;
    3380 break;
    3381 case MSK_PRO_STA_UNKNOWN:
    3382 case MSK_PRO_STA_PRIM_INFEAS:
    3383 case MSK_PRO_STA_PRIM_AND_DUAL_INFEAS:
    3384 case MSK_PRO_STA_ILL_POSED:
    3385#if MSK_VERSION_MAJOR < 9
    3386 case MSK_PRO_STA_NEAR_PRIM_AND_DUAL_FEAS:
    3387 case MSK_PRO_STA_NEAR_PRIM_FEAS:
    3388 case MSK_PRO_STA_NEAR_DUAL_FEAS:
    3389#endif
    3390 case MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED:
    3391 *primalfeasible = FALSE;
    3392 *dualfeasible = FALSE;
    3393 break;
    3394 default:
    3395 return SCIP_LPERROR;
    3396 } /*lint !e788*/
    3397
    3398 return SCIP_OKAY;
    3399}
    3400
    3401/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
    3402 * this does not necessarily mean, that the solver knows and can return the primal ray
    3403 */
    3405 SCIP_LPI* lpi /**< LP interface structure */
    3406 )
    3407{
    3408 MSKprostae prosta;
    3409 MSKsolstae solsta;
    3410
    3411 assert(lpi != NULL);
    3412 assert(lpi->mosekenv != NULL);
    3413 assert(lpi->task != NULL);
    3414
    3415 SCIPdebugMessage("Calling SCIPlpiExistsPrimalRay (%d)\n", lpi->lpid);
    3416
    3417 SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, &solsta) );
    3418
    3419 return ( solsta == MSK_SOL_STA_DUAL_INFEAS_CER
    3420 || prosta == MSK_PRO_STA_DUAL_INFEAS
    3421 || prosta == MSK_PRO_STA_PRIM_AND_DUAL_INFEAS );
    3422}
    3423
    3424/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
    3425 * and the solver knows and can return the primal ray
    3426 */
    3428 SCIP_LPI* lpi /**< LP interface structure */
    3429 )
    3430{
    3431 MSKsolstae solsta;
    3432
    3433 assert(lpi != NULL);
    3434 assert(lpi->mosekenv != NULL);
    3435 assert(lpi->task != NULL);
    3436
    3437 SCIPdebugMessage("Calling SCIPlpiHasPrimalRay (%d)\n", lpi->lpid);
    3438
    3439 SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
    3440
    3441 return (solsta == MSK_SOL_STA_DUAL_INFEAS_CER);
    3442}
    3443
    3444/** returns TRUE iff LP is proven to be primal unbounded */
    3446 SCIP_LPI* lpi /**< LP interface structure */
    3447 )
    3448{ /*lint --e{715}*/
    3449 MSKsolstae solsta;
    3450
    3451 assert(lpi != NULL);
    3452 assert(lpi->mosekenv != NULL);
    3453 assert(lpi->task != NULL);
    3454
    3455 SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
    3456
    3457 /* assume primal solution and ray is available if we used the primal simplex and the dual is proven to be infeasible */
    3458 return (solsta == MSK_SOL_STA_DUAL_INFEAS_CER && lpi->lastalgo == MSK_OPTIMIZER_PRIMAL_SIMPLEX);
    3459}
    3460
    3461/** returns TRUE iff LP is proven to be primal infeasible */
    3463 SCIP_LPI* lpi /**< LP interface structure */
    3464 )
    3465{
    3466 assert(lpi != NULL);
    3467 assert(lpi->mosekenv != NULL);
    3468 assert(lpi->task != NULL);
    3469
    3470 return SCIPlpiExistsDualRay(lpi);
    3471}
    3472
    3473/** returns TRUE iff LP is proven to be primal feasible */
    3475 SCIP_LPI* lpi /**< LP interface structure */
    3476 )
    3477{
    3478 MSKprostae prosta;
    3479
    3480 assert(lpi != NULL);
    3481 assert(lpi->mosekenv != NULL);
    3482 assert(lpi->task != NULL);
    3483
    3484 SCIPdebugMessage("Calling SCIPlpiIsPrimalFeasible (%d)\n", lpi->lpid);
    3485
    3486 SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, NULL) );
    3487
    3488 return (prosta == MSK_PRO_STA_PRIM_FEAS || prosta == MSK_PRO_STA_PRIM_AND_DUAL_FEAS || (prosta == MSK_PRO_STA_DUAL_INFEAS && lpi->lastalgo == MSK_OPTIMIZER_PRIMAL_SIMPLEX));
    3489}
    3490
    3491/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
    3492 * this does not necessarily mean, that the solver knows and can return the dual ray
    3493 */
    3495 SCIP_LPI* lpi /**< LP interface structure */
    3496 )
    3497{
    3498 MSKprostae prosta;
    3499 MSKsolstae solsta;
    3500
    3501 assert(lpi != NULL);
    3502 assert(lpi->mosekenv != NULL);
    3503 assert(lpi->task != NULL);
    3504
    3505 SCIPdebugMessage("Calling SCIPlpiExistsDualRay (%d)\n", lpi->lpid);
    3506
    3507 SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, &solsta) );
    3508
    3509 return ( solsta == MSK_SOL_STA_PRIM_INFEAS_CER
    3510 || prosta == MSK_PRO_STA_PRIM_INFEAS
    3511 || prosta == MSK_PRO_STA_PRIM_AND_DUAL_INFEAS );
    3512}
    3513
    3514/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
    3515 * and the solver knows and can return the dual ray
    3516 */
    3518 SCIP_LPI* lpi /**< LP interface structure */
    3519 )
    3520{
    3521 MSKsolstae solsta;
    3522
    3523 assert(lpi != NULL);
    3524 assert(lpi->mosekenv != NULL);
    3525 assert(lpi->task != NULL);
    3526
    3527 SCIPdebugMessage("Calling SCIPlpiHasDualRay (%d)\n", lpi->lpid);
    3528
    3529 SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
    3530
    3531 return (solsta == MSK_SOL_STA_PRIM_INFEAS_CER);
    3532}
    3533
    3534/** returns TRUE iff LP is proven to be dual unbounded */
    3536 SCIP_LPI* lpi /**< LP interface structure */
    3537 )
    3538{ /*lint --e{715}*/
    3539 assert(lpi != NULL);
    3540 assert(lpi->mosekenv != NULL);
    3541 assert(lpi->task != NULL);
    3542
    3543 return FALSE;
    3544}
    3545
    3546/** returns TRUE iff LP is proven to be dual infeasible */
    3548 SCIP_LPI* lpi /**< LP interface structure */
    3549 )
    3550{
    3551 assert(lpi != NULL);
    3552 assert(lpi->mosekenv != NULL);
    3553 assert(lpi->task != NULL);
    3554
    3555 return SCIPlpiExistsPrimalRay(lpi);
    3556}
    3557
    3558/** returns TRUE iff LP is proven to be dual feasible */
    3560 SCIP_LPI* lpi /**< LP interface structure */
    3561 )
    3562{
    3563 MSKprostae prosta;
    3564
    3565 assert(lpi != NULL);
    3566 assert(lpi->mosekenv != NULL);
    3567 assert(lpi->task != NULL);
    3568
    3569 SCIPdebugMessage("Calling SCIPlpiIsDualFeasible (%d)\n", lpi->lpid);
    3570
    3571 SCIP_ABORT_FALSE( getSolutionStatus(lpi, &prosta, NULL) );
    3572
    3573 return (prosta == MSK_PRO_STA_DUAL_FEAS || prosta == MSK_PRO_STA_PRIM_AND_DUAL_FEAS);
    3574}
    3575
    3576/** returns TRUE iff LP was solved to optimality */
    3578 SCIP_LPI* lpi /**< LP interface structure */
    3579 )
    3580{
    3581 MSKsolstae solsta;
    3582
    3583 assert(lpi != NULL);
    3584 assert(lpi->mosekenv != NULL);
    3585 assert(lpi->task != NULL);
    3586
    3587 SCIPdebugMessage("Calling SCIPlpiIsOptimal (%d)\n", lpi->lpid);
    3588
    3589 SCIP_ABORT_FALSE( getSolutionStatus(lpi, NULL, &solsta) );
    3590
    3591 return (solsta == MSK_SOL_STA_OPTIMAL);
    3592}
    3593
    3594/** returns TRUE iff current LP solution is stable
    3595 *
    3596 * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
    3597 * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
    3598 * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
    3599 * SCIPlpiIsStable() should return false.
    3600 */
    3602 SCIP_LPI* lpi /**< LP interface structure */
    3603 )
    3604{
    3605 assert(lpi != NULL);
    3606 assert(lpi->mosekenv != NULL);
    3607 assert(lpi->task != NULL);
    3608
    3609 /* if an objective limit is set and Mosek claims that it is exceeded, we should check that this is indeed the case;
    3610 * if not this points at numerical instability; note that this aligns with an assert in lp.c */
    3611 if( SCIPlpiIsObjlimExc(lpi) )
    3612 {
    3613 MSKobjsensee objsen;
    3614 SCIP_Real objlimit;
    3615 SCIP_Real objvalue;
    3616 MSKrescodee res;
    3617
    3618 res = MSK_getobjsense(lpi->task, &objsen);
    3619 if ( res != MSK_RES_OK )
    3620 return FALSE;
    3621
    3622 if ( objsen == MSK_OBJECTIVE_SENSE_MINIMIZE )
    3623 {
    3624 res = MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, &objlimit);
    3625 }
    3626 else /* objsen == MSK_OBJECTIVE_SENSE_MAX */
    3627 {
    3628 res = MSK_getdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, &objlimit);
    3629 }
    3630 if ( res != MSK_RES_OK )
    3631 return FALSE;
    3632
    3633 if ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE )
    3634 {
    3635 /* if we reached the objective limit, return this value */
    3636 res = MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, &objvalue);
    3637 }
    3638 else
    3639 {
    3640 /* otherwise get the value from Mosek */
    3641 res = MSK_getprimalobj(lpi->task, lpi->lastsolvetype, &objvalue);
    3642 }
    3643 if ( res != MSK_RES_OK )
    3644 return FALSE;
    3645
    3646 if ( objsen == MSK_OBJECTIVE_SENSE_MAXIMIZE )
    3647 {
    3648 objlimit *= -1.0;
    3649 objvalue *= -1.0;
    3650 }
    3651 if ( ! SCIPlpiIsInfinity(lpi, objlimit) && MOSEK_relDiff(objvalue, objlimit) < -1e-9 ) /*lint !e666*/
    3652 return FALSE;
    3653 }
    3654
    3655 return ( lpi->termcode == MSK_RES_OK
    3656 || lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS
    3657 || lpi->termcode == MSK_RES_TRM_MAX_TIME
    3658 || lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE );
    3659}
    3660
    3661/** returns TRUE iff the objective limit was reached */
    3663 SCIP_LPI* lpi /**< LP interface structure */
    3664 )
    3665{
    3666 assert(lpi != NULL);
    3667 assert(lpi->mosekenv != NULL);
    3668 assert(lpi->task != NULL);
    3669
    3670 return ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE );
    3671}
    3672
    3673/** returns TRUE iff the iteration limit was reached */
    3675 SCIP_LPI* lpi /**< LP interface structure */
    3676 )
    3677{
    3678 assert(lpi != NULL);
    3679 assert(lpi->mosekenv != NULL);
    3680 assert(lpi->task != NULL);
    3681
    3682 return ( lpi->termcode == MSK_RES_TRM_MAX_ITERATIONS );
    3683}
    3684
    3685/** returns TRUE iff the time limit was reached */
    3687 SCIP_LPI* lpi /**< LP interface structure */
    3688 )
    3689{
    3690 assert(lpi != NULL);
    3691 assert(lpi->mosekenv != NULL);
    3692 assert(lpi->task != NULL);
    3693
    3694 return ( lpi->termcode == MSK_RES_TRM_MAX_TIME );
    3695}
    3696
    3697/** returns the internal solution status of the solver */
    3699 SCIP_LPI* lpi /**< LP interface structure */
    3700 )
    3701{
    3702 MSKsolstae solsta;
    3703 SCIP_RETCODE retcode;
    3704
    3705 assert(lpi != NULL);
    3706 assert(lpi->mosekenv != NULL);
    3707 assert(lpi->task != NULL);
    3708
    3709 SCIPdebugMessage("Calling SCIPlpiGetInternalStatus (%d)\n", lpi->lpid);
    3710
    3711 retcode = getSolutionStatus(lpi, NULL, &solsta);
    3712 if ( retcode != SCIP_OKAY )
    3713 return 0;
    3714
    3715 return (int) solsta;
    3716}
    3717
    3718/** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
    3720 SCIP_LPI* lpi, /**< LP interface structure */
    3721 SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
    3722 )
    3723{
    3724 assert(lpi != NULL);
    3725 assert(lpi->mosekenv != NULL);
    3726 assert(lpi->task != NULL);
    3727 assert(success != NULL);
    3728
    3729 SCIPdebugMessage("Calling SCIPlpiIgnoreInstability (%d)\n", lpi->lpid);
    3730
    3731 *success = FALSE;
    3732
    3733 return SCIP_OKAY;
    3734}
    3735
    3736/** gets objective value of solution */
    3738 SCIP_LPI* lpi, /**< LP interface structure */
    3739 SCIP_Real* objval /**< stores the objective value */
    3740 )
    3741{
    3742 assert(lpi != NULL);
    3743 assert(lpi->mosekenv != NULL);
    3744 assert(lpi->task != NULL);
    3745 assert(objval != NULL);
    3746
    3747 SCIPdebugMessage("Calling SCIPlpiGetObjval (%d)\n", lpi->lpid);
    3748
    3749 /* TODO: tjek lighed med dual objektiv i de fleste tilfaelde. */
    3750
    3751 if ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE )
    3752 {
    3753 /* if we reached the objective limit, return this value */
    3754 MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, objval) );
    3755 }
    3756 else
    3757 {
    3758 /* otherwise get the value from Mosek */
    3759 MOSEK_CALL( MSK_getprimalobj(lpi->task, lpi->lastsolvetype, objval) );
    3760 }
    3761
    3762 return SCIP_OKAY;
    3763}
    3764
    3765/** gets primal and dual solution vectors for feasible LPs
    3766 *
    3767 * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
    3768 * SCIPlpiIsOptimal() returns true.
    3769 */
    3771 SCIP_LPI* lpi, /**< LP interface structure */
    3772 SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
    3773 SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
    3774 SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
    3775 SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
    3776 SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
    3777 )
    3778{
    3779 MSKsolstae solsta;
    3780 double* sux = NULL;
    3781 int ncols = 0;
    3782 int i;
    3783
    3784 assert(lpi != NULL);
    3785 assert(lpi->mosekenv != NULL);
    3786 assert(lpi->task != NULL);
    3787
    3788 SCIPdebugMessage("Calling SCIPlpiGetSol (%d)\n", lpi->lpid);
    3789
    3790 if ( objval != NULL )
    3791 {
    3792 if ( lpi->termcode == MSK_RES_TRM_OBJECTIVE_RANGE )
    3793 {
    3794 /* if we reached the objective limit, return this value */
    3795 MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, objval) );
    3796 }
    3797 else
    3798 {
    3799 /* otherwise get the value from Mosek */
    3800 MOSEK_CALL( MSK_getprimalobj(lpi->task, lpi->lastsolvetype, objval) );
    3801 }
    3802 }
    3803
    3804 if( redcost )
    3805 {
    3806 MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
    3807 SCIP_ALLOC( BMSallocMemoryArray(&sux, ncols) );
    3808 }
    3809
    3810 if ( primsol != NULL && lpi->lastalgo == MSK_OPTIMIZER_PRIMAL_SIMPLEX )
    3811 {
    3812 /* If the status shows that the dual is infeasible this is due to the primal being unbounded. In this case, we need
    3813 * to compute a feasible solution by setting the objective to 0.
    3814 */
    3815 MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, NULL, &solsta) );
    3816 if ( solsta == MSK_SOL_STA_DUAL_INFEAS_CER )
    3817 {
    3818 SCIP_Real* objcoefs;
    3819 int j;
    3820
    3821 MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
    3822 SCIP_ALLOC( BMSallocMemoryArray(&objcoefs, ncols) );
    3823
    3824 /* store old objective coefficients and set them to 0 */
    3825 for (j = 0; j < ncols; ++j)
    3826 {
    3827 MOSEK_CALL( MSK_getcj(lpi->task, j, &objcoefs[j]) );
    3828 MOSEK_CALL( MSK_putcj(lpi->task, j, 0.0) );
    3829 }
    3830
    3831 /* solve problem again */
    3832 SCIP_CALL( SolveWSimplex(lpi) );
    3833
    3834 /* At this point we assume that the problem is feasible, since we previously ran the primal simplex and it
    3835 * produced a ray.
    3836 */
    3837
    3838 /* get primal solution */
    3839 MOSEK_CALL( MSK_getsolution(lpi->task, lpi->lastsolvetype, NULL, NULL, NULL, NULL, NULL, activity,
    3840 primsol, NULL, NULL, NULL, NULL, NULL, NULL) );
    3841
    3842 /* restore objective */
    3843 MOSEK_CALL( MSK_putcslice(lpi->task, 0, ncols, objcoefs) );
    3844
    3845 /* resolve to restore original status */
    3846 SCIP_CALL( SolveWSimplex(lpi) );
    3847
    3848 BMSfreeMemoryArray(&objcoefs);
    3849 }
    3850 else
    3851 {
    3852 MOSEK_CALL( MSK_getsolution(lpi->task, lpi->lastsolvetype, NULL, NULL, NULL, NULL, NULL, activity,
    3853 primsol, dualsol, NULL, NULL, redcost, sux, NULL) );
    3854 }
    3855 }
    3856 else
    3857 {
    3858 MOSEK_CALL( MSK_getsolution(lpi->task, lpi->lastsolvetype, NULL, NULL, NULL, NULL, NULL, activity,
    3859 primsol, dualsol, NULL, NULL, redcost, sux, NULL) );
    3860 }
    3861
    3862 /* the reduced costs are given by the difference of the slx and sux variables (third and second to last parameters) */
    3863 if( redcost )
    3864 {
    3865 for( i = 0; i < ncols; i++ )
    3866 {
    3867 assert(sux != NULL);
    3868 redcost[i] -= sux[i];
    3869 }
    3870 BMSfreeMemoryArray(&sux);
    3871 }
    3872
    3873 return SCIP_OKAY;
    3874}
    3875
    3876/** gets primal ray for unbounded LPs */
    3878 SCIP_LPI* lpi, /**< LP interface structure */
    3879 SCIP_Real* ray /**< primal ray */
    3880 )
    3881{
    3882 assert(lpi != NULL);
    3883 assert(lpi->mosekenv != NULL);
    3884 assert(lpi->task != NULL);
    3885 assert(ray != NULL);
    3886
    3887 SCIPdebugMessage("Calling SCIPlpiGetPrimalRay (%d)\n", lpi->lpid);
    3888
    3889 MOSEK_CALL( MSK_getsolution(lpi->task, lpi->lastsolvetype, NULL, NULL, NULL, NULL, NULL, NULL, ray,
    3890 NULL, NULL, NULL, NULL, NULL, NULL) );
    3891
    3892 return SCIP_OKAY;
    3893}
    3894
    3895/** gets dual Farkas proof for infeasibility */
    3897 SCIP_LPI* lpi, /**< LP interface structure */
    3898 SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
    3899 )
    3900{
    3901 assert(lpi != NULL);
    3902 assert(lpi->mosekenv != NULL);
    3903 assert(lpi->task != NULL);
    3904 assert(dualfarkas != NULL);
    3905
    3906 SCIPdebugMessage("Calling SCIPlpiGetDualfarkas (%d)\n", lpi->lpid);
    3907
    3908 MOSEK_CALL( MSK_getsolution(lpi->task, lpi->lastsolvetype, NULL, NULL, NULL, NULL, NULL, NULL, NULL, dualfarkas,
    3909 NULL, NULL, NULL, NULL, NULL) );
    3910
    3911 return SCIP_OKAY;
    3912}
    3913
    3914/** gets the number of LP iterations of the last solve call */
    3916 SCIP_LPI* lpi, /**< LP interface structure */
    3917 int* iterations /**< pointer to store the number of iterations of the last solve call */
    3918 )
    3919{
    3920 assert(lpi != NULL);
    3921 assert(lpi->mosekenv != NULL);
    3922 assert(lpi->task != NULL);
    3923 assert(iterations != NULL);
    3924
    3925 SCIPdebugMessage("Calling SCIPlpiGetIterations (%d)\n", lpi->lpid);
    3926
    3927 *iterations = lpi->itercount;
    3928
    3929 return SCIP_OKAY;
    3930}
    3931
    3932/** gets information about the quality of an LP solution
    3933 *
    3934 * Such information is usually only available, if also a (maybe not optimal) solution is available.
    3935 * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
    3936 */
    3938 SCIP_LPI* lpi, /**< LP interface structure */
    3939 SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
    3940 SCIP_Real* quality /**< pointer to store quality number */
    3941 )
    3942{ /*lint --e{715}*/
    3943 assert(lpi != NULL);
    3944 assert(lpi->mosekenv != NULL);
    3945 assert(lpi->task != NULL);
    3946 assert(quality != NULL);
    3947 SCIP_UNUSED(qualityindicator);
    3948
    3949 *quality = SCIP_INVALID;
    3950
    3951 return SCIP_OKAY;
    3952}
    3953
    3954/** handle singular basis */
    3955static
    3957 SCIP_LPI* lpi, /**< LP interface structure */
    3958 int* basis, /**< array of basis indices */
    3959 MSKrescodee res /**< result */
    3960 )
    3961{
    3962 if (res == MSK_RES_ERR_BASIS_SINGULAR)
    3963 {
    3965
    3966 MOSEK_CALL( MSK_initbasissolve(lpi->task, basis) );
    3967 }
    3968 else
    3969 {
    3970 MOSEK_CALL( res );
    3971 }
    3972
    3973 return SCIP_OKAY;
    3974}
    3975
    3976
    3977/*
    3978 * LP Basis Methods
    3979 */
    3980
    3981/** convert Mosek basis status to SCIP basis status
    3982 *
    3983 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    3984 */
    3985static
    3987 SCIP_LPI* lpi, /**< LP interface structure */
    3988 SCIP_Bool iscon, /**< whether constraints/variables are considered */
    3989 MSKstakeye* sk, /**< status array of Mosek */
    3990 int n, /**< size */
    3991 int* stat /**< status array of SCIP */
    3992 )
    3993{
    3994 int i;
    3995
    3996 assert(lpi->lastsolvetype == MSK_SOL_BAS);
    3997
    3998 for( i = 0; i < n; i++ )
    3999 {
    4000 double sl;
    4001 double su;
    4002
    4003 switch (sk[i])
    4004 {
    4005 case MSK_SK_BAS:
    4006 stat[i] = (int)SCIP_BASESTAT_BASIC;
    4007 break;
    4008 case MSK_SK_SUPBAS:
    4009 stat[i] = (int)SCIP_BASESTAT_ZERO;
    4010 break;
    4011 case MSK_SK_FIX:
    4012#if MSK_VERSION_MAJOR < 9
    4013 MOSEK_CALL( MSK_getsolutioni(lpi->task, iscon ? MSK_ACC_CON : MSK_ACC_VAR, i, MSK_SOL_BAS, NULL, NULL, &sl, &su, NULL) );
    4014#else
    4015 if( iscon )
    4016 {
    4017 MOSEK_CALL( MSK_getslcslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
    4018 MOSEK_CALL( MSK_getsucslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
    4019 }
    4020 else
    4021 {
    4022 MOSEK_CALL( MSK_getslxslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
    4023 MOSEK_CALL( MSK_getsuxslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
    4024 }
    4025#endif
    4026
    4027 if (sl < su) /* Negative reduced cost */
    4028 stat[i] = (int)SCIP_BASESTAT_UPPER;
    4029 else
    4030 stat[i] = (int)SCIP_BASESTAT_LOWER;
    4031 break;
    4032 case MSK_SK_UNK:
    4033 stat[i] = (int)SCIP_BASESTAT_LOWER;
    4034 break;
    4035 case MSK_SK_INF:
    4036 stat[i] = (int)SCIP_BASESTAT_LOWER;
    4037 break;
    4038 case MSK_SK_LOW:
    4039 stat[i] = (int)SCIP_BASESTAT_LOWER;
    4040 break;
    4041 case MSK_SK_UPR:
    4042 stat[i] = (int)SCIP_BASESTAT_UPPER;
    4043 break;
    4044#if MSK_VERSION_MAJOR < 10
    4045 case MSK_SK_END:
    4046 break;
    4047#endif
    4048 default:
    4049 SCIPABORT();
    4050 return SCIP_INVALIDDATA; /*lint !e527*/
    4051 } /*lint !e788*/
    4052 }
    4053
    4054 return SCIP_OKAY;
    4055}
    4056
    4057/** convert Mosek to SCIP basis status - slack variables
    4058 *
    4059 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    4060 */
    4061static
    4063 SCIP_LPI* lpi, /**< LP interface structure */
    4064 SCIP_Bool iscon, /**< whether constraints or variables are accessed */
    4065 MSKstakeye* sk, /**< Mosek basis status */
    4066 int m, /**< size */
    4067 int* stat /**< status array */
    4068 )
    4069{
    4070 int i;
    4071
    4072 assert(lpi->lastsolvetype == MSK_SOL_BAS);
    4073
    4074 for( i = 0; i < m; i++ )
    4075 {
    4076 double sl;
    4077 double su;
    4078 switch (sk[i])
    4079 {
    4080 case MSK_SK_BAS:
    4081 stat[i] = (int)SCIP_BASESTAT_BASIC;
    4082 break;
    4083 case MSK_SK_SUPBAS:
    4084 stat[i] = (int)SCIP_BASESTAT_ZERO;
    4085 break;
    4086 case MSK_SK_FIX:
    4087#if MSK_VERSION_MAJOR < 9
    4088 MOSEK_CALL( MSK_getsolutioni(lpi->task, iscon ? MSK_ACC_CON : MSK_ACC_VAR, i, MSK_SOL_BAS, NULL, NULL, &sl, &su, NULL) );
    4089#else
    4090 if( iscon )
    4091 {
    4092 MOSEK_CALL( MSK_getslcslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
    4093 MOSEK_CALL( MSK_getsucslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
    4094 }
    4095 else
    4096 {
    4097 MOSEK_CALL( MSK_getslxslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
    4098 MOSEK_CALL( MSK_getsuxslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
    4099 }
    4100#endif
    4101
    4102 if (sl < su) /* Negative reduced cost */
    4103 stat[i] = (int)SCIP_BASESTAT_UPPER;
    4104 else
    4105 stat[i] = (int)SCIP_BASESTAT_LOWER;
    4106 break;
    4107 case MSK_SK_UNK:
    4108 case MSK_SK_INF:
    4109 case MSK_SK_UPR:
    4110 stat[i] = (int)SCIP_BASESTAT_UPPER;
    4111 break;
    4112 case MSK_SK_LOW:
    4113 stat[i] = (int)SCIP_BASESTAT_LOWER;
    4114 break;
    4115#if MSK_VERSION_MAJOR < 10
    4116 case MSK_SK_END:
    4117#endif
    4118 default:
    4119 SCIPABORT();
    4120 return SCIP_INVALIDDATA; /*lint !e527*/
    4121 } /*lint !e788*/
    4122 }
    4123
    4124 return SCIP_OKAY;
    4125}
    4126
    4127/** convert SCIP to Mosek basis status */
    4128static
    4130 const int* stat, /**< SCIP status array */
    4131 int n, /**< size of array */
    4132 MSKstakeye* resstat /**< resulting Mosek status array */
    4133 )
    4134{
    4135 int i;
    4136 for( i = 0; i < n; i++ )
    4137 {
    4138 switch (stat[i])
    4139 {
    4141 resstat[i] = MSK_SK_LOW;
    4142 break;
    4144 resstat[i] = MSK_SK_BAS;
    4145 break;
    4147 resstat[i] = MSK_SK_UPR;
    4148 break;
    4149 case SCIP_BASESTAT_ZERO:
    4150 resstat[i] = MSK_SK_SUPBAS;
    4151 break;
    4152 default:
    4153 SCIPABORT();
    4154 }
    4155 }
    4156}
    4157
    4158/** convert SCIP to Mosek basis status - slack variables */
    4159static
    4161 const int* stat, /**< SCIP status array */
    4162 int n, /**< size of array */
    4163 MSKstakeye* resstat /**< resulting Mosek status array */
    4164 )
    4165{
    4166 /* slacks are stored as -1 in Mosek, i.e., bounds are reversed compared to SCIP */
    4167 int i;
    4168
    4169 for( i = 0; i < n; i++ )
    4170 {
    4171 switch (stat[i])
    4172 {
    4174 resstat[i] = MSK_SK_UPR; /* Reversed */
    4175 break;
    4177 resstat[i] = MSK_SK_BAS;
    4178 break;
    4180 resstat[i] = MSK_SK_LOW; /* Reversed */
    4181 break;
    4182 case SCIP_BASESTAT_ZERO:
    4183 resstat[i] = MSK_SK_SUPBAS;
    4184 break;
    4185 default:
    4186 SCIPABORT();
    4187 }
    4188 }
    4189}
    4190
    4191/** gets current basis status for columns and rows; arrays must be large enough to store the basis status
    4192 *
    4193 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    4194 */
    4196 SCIP_LPI* lpi, /**< LP interface structure */
    4197 int* cstat, /**< array to store column basis status, or NULL */
    4198 int* rstat /**< array to store row basis status, or NULL */
    4199 )
    4200{
    4201 int nrows;
    4202 int ncols;
    4203
    4204 assert(lpi != NULL);
    4205 assert(lpi->mosekenv != NULL);
    4206 assert(lpi->task != NULL);
    4207 assert(lpi->lastsolvetype == MSK_SOL_BAS);
    4208
    4209 SCIPdebugMessage("Calling SCIPlpiGetBase (%d)\n", lpi->lpid);
    4210
    4211 MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
    4212 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    4213
    4214 SCIP_CALL( getbase(lpi, ncols, nrows) );
    4215
    4216 if (cstat)
    4217 {
    4218 SCIP_CALL( convertstat_mosek2scip(lpi, FALSE, lpi->skx, ncols, cstat) );
    4219 }
    4220
    4221 if (rstat)
    4222 {
    4223 SCIP_CALL( convertstat_mosek2scip_slack(lpi, TRUE, lpi->skc, nrows, rstat) );
    4224 }
    4225
    4226 return SCIP_OKAY;
    4227}
    4228
    4229/** sets current basis status for columns and rows */
    4231 SCIP_LPI* lpi, /**< LP interface structure */
    4232 const int* cstat, /**< array with column basis status */
    4233 const int* rstat /**< array with row basis status */
    4234 )
    4235{
    4236 int nrows;
    4237 int ncols;
    4238
    4239 assert(lpi != NULL);
    4240 assert(lpi->mosekenv != NULL);
    4241 assert(lpi->task != NULL);
    4242
    4243 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
    4244 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
    4245
    4246 assert(cstat != NULL || ncols == 0);
    4247 assert(rstat != NULL || nrows == 0);
    4248
    4249 SCIPdebugMessage("Calling SCIPlpiSetBase (%d)\n", lpi->lpid);
    4250
    4251 SCIP_CALL( ensureStateMem(lpi, ncols, nrows) );
    4252
    4253 convertstat_scip2mosek(cstat, ncols, lpi->skx);
    4254 convertstat_scip2mosek_slack(rstat, nrows, lpi->skc);
    4255
    4256 SCIP_CALL( setbase(lpi) );
    4257
    4258 invalidateSolution(lpi);
    4259
    4260 return SCIP_OKAY;
    4261}
    4262
    4263/** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
    4265 SCIP_LPI* lpi, /**< LP interface structure */
    4266 int* bind /**< pointer to store basis indices ready to keep number of rows entries */
    4267 )
    4268{
    4269 int nrows;
    4270 int i;
    4271
    4272 assert(lpi != NULL);
    4273 assert(lpi->mosekenv != NULL);
    4274 assert(lpi->task != NULL);
    4275 assert(bind != NULL);
    4276
    4277 SCIPdebugMessage("Calling SCIPlpiGetBasisInd (%d)\n", lpi->lpid);
    4278
    4279 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    4280
    4281 SCIP_CALL( handle_singular(lpi, bind, MSK_initbasissolve(lpi->task, bind)) );
    4282
    4283 for (i = 0; i < nrows; i++ )
    4284 {
    4285 if (bind[i] < nrows) /* row bind[i] is basic */
    4286 bind[i] = -1 - bind[i];
    4287 else /* column bind[i]-nrows is basic */
    4288 bind[i] = bind[i] - nrows;
    4289 }
    4290
    4291 return SCIP_OKAY;
    4292}
    4293
    4294/** get row of inverse basis matrix B^-1
    4295 *
    4296 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    4297 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    4298 * see also the explanation in lpi.h.
    4299 *
    4300 * @todo check that the result is in terms of the LP interface definition
    4301 *
    4302 * @todo check if this should invalidate the solution
    4303 */
    4305 SCIP_LPI* lpi, /**< LP interface structure */
    4306 int r, /**< row number */
    4307 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
    4308 int* inds, /**< array to store the non-zero indices, or NULL */
    4309 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    4310 * (-1: if we do not store sparsity information) */
    4311 )
    4312{
    4313 int nrows;
    4314 int i;
    4315
    4316 assert(lpi != NULL);
    4317 assert(lpi->mosekenv != NULL);
    4318 assert(lpi->task != NULL);
    4319 assert(coef != NULL);
    4320
    4321 SCIPdebugMessage("Calling SCIPlpiGetBInvRow (%d)\n", lpi->lpid);
    4322
    4323 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    4324
    4325 /* set coefficient for slack variables to be 1 instead of -1 */
    4326 MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_ON) );
    4327
    4328 /* prepare basis in Mosek, since we do not need the basis ourselves, we set the return parameter to NULL */
    4329 SCIP_CALL( handle_singular(lpi, NULL, MSK_initbasissolve(lpi->task, NULL)) );
    4330
    4331 /* initialize rhs of system to be a dense +/- unit vector (needed for MSK_solvewithbasis()) */
    4332 for (i = 0; i < nrows; ++i)
    4333 coef[i] = 0.0;
    4334 coef[r] = 1.0; /* unit vector e_r */
    4335
    4336 /* check whether we require a dense or sparse result vector */
    4337 if ( ninds != NULL && inds != NULL )
    4338 {
    4339 *ninds = 1;
    4340 inds[0]= r;
    4341
    4342 /* solve transposed system */
    4343#if MSK_VERSION_MAJOR < 10
    4344 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, ninds, inds, coef) );
    4345#else
    4346 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, *ninds, inds, coef, ninds) );
    4347#endif
    4348 assert( *ninds <= nrows );
    4349 }
    4350 else
    4351 {
    4352 int* sub;
    4353 int numnz;
    4354
    4355 SCIP_ALLOC( BMSallocMemoryArray(&sub, nrows) );
    4356
    4357 numnz = 1;
    4358 sub[0] = r;
    4359
    4360 /* solve transposed system */
    4361#if MSK_VERSION_MAJOR < 10
    4362 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, &numnz, sub, coef) );
    4363#else
    4364 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 1, numnz, sub, coef, &numnz) );
    4365#endif
    4366 assert( numnz <= nrows );
    4367
    4368 BMSfreeMemoryArray(&sub);
    4369 }
    4370 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
    4371
    4372 SCIPdebugMessage("End SCIPlpiGetBInvRow (%d)\n", lpi->lpid);
    4373
    4374 return SCIP_OKAY;
    4375}
    4376
    4377/** get column of inverse basis matrix B^-1
    4378 *
    4379 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    4380 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    4381 * see also the explanation in lpi.h.
    4382 *
    4383 * @todo check that the result is in terms of the LP interface definition
    4384 *
    4385 * @todo check if this should invalidate the solution
    4386 */
    4388 SCIP_LPI* lpi, /**< LP interface structure */
    4389 int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
    4390 * you have to call SCIPlpiGetBasisInd() to get the array which links the
    4391 * B^-1 column numbers to the row and column numbers of the LP!
    4392 * c must be between 0 and nrows-1, since the basis has the size
    4393 * nrows * nrows */
    4394 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
    4395 int* inds, /**< array to store the non-zero indices, or NULL */
    4396 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    4397 * (-1: if we do not store sparsity information) */
    4398 )
    4399{
    4400 int nrows;
    4401 int i;
    4402
    4403 assert(lpi != NULL);
    4404 assert(lpi->mosekenv != NULL);
    4405 assert(lpi->task != NULL);
    4406 assert(coef != NULL);
    4407
    4408 SCIPdebugMessage("Calling SCIPlpiGetBInvCol (%d)\n", lpi->lpid);
    4409
    4410 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    4411
    4412 /* set coefficient for slack variables to be 1 instead of -1 */
    4413 MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_ON) );
    4414
    4415 /* prepare basis in Mosek, since we do not need the basis ourselves, we set the return parameter to NULL */
    4416 SCIP_CALL( handle_singular(lpi, NULL, MSK_initbasissolve(lpi->task, NULL)) );
    4417
    4418 /* initialize rhs of system to be a dense +/- unit vector (needed for MSK_solvewithbasis()) */
    4419 for (i = 0; i < nrows; ++i)
    4420 coef[i] = 0.0;
    4421 coef[c] = 1.0; /* unit vector e_c */
    4422
    4423 /* check whether we require a dense or sparse result vector */
    4424 if ( ninds != NULL && inds != NULL )
    4425 {
    4426 *ninds = 1;
    4427 inds[0]= c;
    4428
    4429#if MSK_VERSION_MAJOR < 10
    4430 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, ninds, inds, coef) );
    4431#else
    4432 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, *ninds, inds, coef, ninds) );
    4433#endif
    4434 assert( *ninds <= nrows );
    4435 }
    4436 else
    4437 {
    4438 int* sub;
    4439 int numnz;
    4440
    4441 SCIP_ALLOC( BMSallocMemoryArray(&sub, nrows) );
    4442
    4443 numnz = 1;
    4444 sub[0]= c;
    4445
    4446#if MSK_VERSION_MAJOR < 10
    4447 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, &numnz, sub, coef) );
    4448#else
    4449 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, numnz, sub, coef, &numnz) );
    4450#endif
    4451 assert( numnz <= nrows );
    4452
    4453 BMSfreeMemoryArray(&sub);
    4454 }
    4455 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
    4456
    4457 return SCIP_OKAY;
    4458}
    4459
    4460/** get row of inverse basis matrix times constraint matrix B^-1 * A
    4461 *
    4462 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
    4463 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
    4464 * see also the explanation in lpi.h.
    4465 *
    4466 * @todo check that the result is in terms of the LP interface definition
    4467 *
    4468 * @todo check if this should invalidate the solution
    4469 */
    4471 SCIP_LPI* lpi, /**< LP interface structure */
    4472 int row, /**< row number */
    4473 const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
    4474 SCIP_Real* coef, /**< vector to return coefficients of the row */
    4475 int* inds, /**< array to store the non-zero indices, or NULL */
    4476 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    4477 * (-1: if we do not store sparsity information) */
    4478 )
    4479{ /*lint --e{715}*/
    4480 int nrows;
    4481 int ncols;
    4482 int numnz;
    4483 int* csub;
    4484 int didalloc = 0;
    4485 double* cval;
    4486 double* binv;
    4487 int i;
    4488 int k;
    4489
    4490 assert(lpi != NULL);
    4491 assert(lpi->mosekenv != NULL);
    4492 assert(lpi->task != NULL);
    4493 assert(coef != NULL);
    4494 SCIP_UNUSED(inds);
    4495
    4496 SCIPdebugMessage("Calling SCIPlpiGetBInvARow (%d)\n", lpi->lpid);
    4497
    4498 /* currently only return dense result */
    4499 if ( ninds != NULL )
    4500 *ninds = -1;
    4501
    4502 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    4503 MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
    4504
    4505 SCIP_ALLOC( BMSallocMemoryArray(&csub, nrows) );
    4506 SCIP_ALLOC( BMSallocMemoryArray(&cval, nrows) );
    4507
    4508 if( binvrow == NULL )
    4509 {
    4510 didalloc = 1;
    4511
    4512 /* get dense vector */
    4513 SCIP_ALLOC( BMSallocMemoryArray(&binv, nrows) );
    4514 SCIP_CALL( SCIPlpiGetBInvRow(lpi, row, binv, NULL, NULL) );
    4515 }
    4516 else
    4517 binv = (SCIP_Real*)binvrow;
    4518
    4519 /* binvrow*A */
    4520 for (i = 0; i < ncols; ++i)
    4521 {
    4522 MOSEK_CALL( MSK_getacol(lpi->task, i, &numnz, csub, cval) );
    4523
    4524 /* compute dense vector */
    4525 coef[i] = 0.0;
    4526 for (k = 0; k < numnz; ++k)
    4527 {
    4528 assert( 0 <= csub[k] && csub[k] < nrows );
    4529 coef[i] += binv[csub[k]] * cval[k];
    4530 }
    4531 }
    4532
    4533 /* free memory arrays */
    4534 BMSfreeMemoryArray(&cval);
    4535 BMSfreeMemoryArray(&csub);
    4536
    4537 if ( didalloc > 0 )
    4538 {
    4539 BMSfreeMemoryArray(&binv);
    4540 }
    4541
    4542 return SCIP_OKAY;
    4543}
    4544
    4545/** get column of inverse basis matrix times constraint matrix B^-1 * A
    4546 *
    4547 * @todo check if this should invalidate the solution
    4548 */
    4550 SCIP_LPI* lpi, /**< LP interface structure */
    4551 int c, /**< column number */
    4552 SCIP_Real* coef, /**< vector to return coefficients of the columnn */
    4553 int* inds, /**< array to store the non-zero indices, or NULL */
    4554 int* ninds /**< pointer to store the number of non-zero indices, or NULL
    4555 * (-1: if we do not store sparsity information) */
    4556 )
    4557{ /*lint --e{715}*/
    4558 SCIP_Real* val;
    4559 int nrows;
    4560 int numnz;
    4561 int i;
    4562
    4563 assert(lpi != NULL);
    4564 assert(lpi->mosekenv != NULL);
    4565 assert(lpi->task != NULL);
    4566 assert(coef != NULL);
    4567
    4568 SCIPdebugMessage("Calling SCIPlpiGetBInvACol (%d)\n", lpi->lpid);
    4569
    4570 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    4571 MOSEK_CALL( MSK_getacolnumnz(lpi->task, c, &numnz) );
    4572 SCIP_ALLOC( BMSallocMemoryArray(&val, numnz+1) );
    4573
    4574 /* set coefficient for slack variables to be 1 instead of -1 */
    4575 MOSEK_CALL( MSK_putnaintparam(lpi->task, MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_, MSK_ON) );
    4576
    4577 /* prepare basis in Mosek, since we do not need the basis ourselves, we set the return parameter to NULL */
    4578 SCIP_CALL( handle_singular(lpi, NULL, MSK_initbasissolve(lpi->task, NULL)) );
    4579
    4580 /* init coefficients */
    4581 for (i = 0; i < nrows; ++i)
    4582 coef[i] = 0.0;
    4583
    4584 /* check whether we require a dense or sparse result vector */
    4585 if ( ninds != NULL && inds != NULL )
    4586 {
    4587 /* fill column into dense vector */
    4588 MOSEK_CALL( MSK_getacol(lpi->task, c, &numnz, inds, val) );
    4589 for (i = 0; i < numnz; ++i)
    4590 {
    4591 assert( 0 <= inds[i] && inds[i] < nrows );
    4592 coef[inds[i]] = val[i];
    4593 }
    4594
    4595 *ninds = numnz;
    4596
    4597#if MSK_VERSION_MAJOR < 10
    4598 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, ninds, inds, coef) );
    4599#else
    4600 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, *ninds, inds, coef, ninds) );
    4601#endif
    4602 assert( *ninds <= nrows );
    4603 }
    4604 else
    4605 {
    4606 int* sub;
    4607 SCIP_ALLOC( BMSallocMemoryArray(&sub, nrows) );
    4608
    4609 /* fill column into dense vector */
    4610 MOSEK_CALL( MSK_getacol(lpi->task, c, &numnz, sub, val) );
    4611 for (i = 0; i < numnz; ++i)
    4612 {
    4613 assert( 0 <= sub[i] && sub[i] < nrows );
    4614 coef[sub[i]] = val[i];
    4615 }
    4616
    4617#if MSK_VERSION_MAJOR < 10
    4618 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, &numnz, sub, coef) );
    4619#else
    4620 MOSEK_CALL( MSK_solvewithbasis(lpi->task, 0, numnz, sub, coef, &numnz) );
    4621#endif
    4622
    4623 if ( ninds != NULL )
    4624 *ninds = numnz;
    4625
    4626 BMSfreeMemoryArray(&sub);
    4627 }
    4628
    4629 BMSfreeMemoryArray(&val);
    4630 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_HOTSTART_LU, MSK_ON) );
    4631
    4632 return SCIP_OKAY;
    4633}
    4634
    4635
    4636/*
    4637 * LP State Methods
    4638 */
    4639
    4640/** creates LPi state information object */
    4641static
    4643 SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
    4644 BMS_BLKMEM* blkmem, /**< block memory */
    4645 int ncols, /**< number of columns to store */
    4646 int nrows /**< number of rows to store */
    4647 )
    4648{
    4649 assert(lpistate != NULL);
    4650 assert(blkmem != NULL);
    4651 assert(ncols >= 0);
    4652 assert(nrows >= 0);
    4653
    4654 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
    4655 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->skx, colpacketNum(ncols)) );
    4656 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->skc, rowpacketNum(nrows)) );
    4657
    4658 (*lpistate)->solsta = MSK_SOL_STA_UNKNOWN;
    4659 (*lpistate)->num = -1;
    4660 (*lpistate)->ncols = ncols;
    4661 (*lpistate)->nrows = nrows;
    4662
    4663 return SCIP_OKAY;
    4664}
    4665
    4666/** frees LPi state information */
    4667static
    4669 SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
    4670 BMS_BLKMEM* blkmem /**< block memory */
    4671 )
    4672{
    4673 assert(blkmem != NULL);
    4674 assert(lpistate != NULL);
    4675 assert(*lpistate != NULL);
    4676
    4677 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->skx, colpacketNum((*lpistate)->ncols));
    4678 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->skc, rowpacketNum((*lpistate)->nrows));
    4679 BMSfreeBlockMemory(blkmem, lpistate);
    4680}
    4681
    4682#ifndef NDEBUG
    4683/** check state
    4684 *
    4685 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    4686 */
    4687static
    4689 SCIP_LPI* lpi, /**< LP interface structure */
    4690 int n, /**< number of rows or columns */
    4691 MSKstakeye* sk, /**< basis status */
    4692 SCIP_Bool isrow /**< whether rows/columns are considered */
    4693 )
    4694{
    4695 char xc;
    4696 int i;
    4697
    4698 assert(lpi != NULL);
    4699 assert(lpi->lastsolvetype == MSK_SOL_BAS);
    4700
    4701#ifdef SCIP_DEBUG
    4702 if( !isrow )
    4703 xc = 'x';
    4704 else
    4705 xc = 'c';
    4706#endif
    4707
    4708 /* printout for all except LOW, UPR, FIX and BAS with sl[xc]==su[xc] */
    4709 for( i = 0; i < n; i++ )
    4710 {
    4711 double sl;
    4712 double su;
    4713 switch (sk[i])
    4714 {
    4715 case MSK_SK_UNK:
    4716 SCIPdebugMessage("STATE[%d]: %c[%d] = unk\n", lpi->optimizecount, xc, i);
    4717 break;
    4718 case MSK_SK_BAS:
    4719 /* the following function is deprecated */
    4720#if MSK_VERSION_MAJOR < 9
    4721 MOSEK_CALL( MSK_getsolutioni(lpi->task, isrow ? MSK_ACC_CON : MSK_ACC_VAR, i, MSK_SOL_BAS, NULL, NULL, &sl, &su, NULL) );
    4722#else
    4723 if( isrow )
    4724 {
    4725 MOSEK_CALL( MSK_getslcslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
    4726 MOSEK_CALL( MSK_getsucslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
    4727 }
    4728 else
    4729 {
    4730 MOSEK_CALL( MSK_getslxslice(lpi->task, MSK_SOL_BAS, i, i+1, &sl ) );
    4731 MOSEK_CALL( MSK_getsuxslice(lpi->task, MSK_SOL_BAS, i, i+1, &su ) );
    4732 }
    4733#endif
    4734 if (fabs(sl-su) > DEBUG_CHECK_STATE_TOL)
    4735 {
    4736 SCIPdebugMessage("STATE[%d]: %c[%d] = bas, sl%c = %g, su%c = %g\n", lpi->optimizecount, xc, i, xc, sl, xc, su);
    4737 }
    4738 break;
    4739 case MSK_SK_SUPBAS:
    4740 SCIPdebugMessage("STATE[%d]: %c[%d] = supbas\n", lpi->optimizecount, xc, i);
    4741 break;
    4742 case MSK_SK_LOW:
    4743 case MSK_SK_UPR:
    4744 case MSK_SK_FIX:
    4745 break;
    4746 case MSK_SK_INF:
    4747 SCIPdebugMessage("STATE[%d]: %c[%d] = inf\n", lpi->optimizecount, xc, i);
    4748 break;
    4749 default:
    4750 SCIPdebugMessage("STATE[%d]: %c[%d] = unknown status <%d>\n", lpi->optimizecount, xc, i, sk[i]);
    4751 break;
    4752 } /*lint !e788*/
    4753 }
    4754
    4755 return SCIP_OKAY;
    4756}
    4757
    4758/** check state
    4759 *
    4760 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    4761 */
    4762static
    4764 SCIP_LPI* lpi, /**< LP interface structure */
    4765 int ncols, /**< number of columns */
    4766 int nrows /**< number of rows */
    4767 )
    4768{
    4769 assert(lpi != NULL);
    4770 assert(lpi->lastsolvetype == MSK_SOL_BAS);
    4771
    4772 SCIP_CALL( checkState1(lpi, ncols, lpi->skx, FALSE) );
    4773 SCIP_CALL( checkState1(lpi, nrows, lpi->skc, TRUE) );
    4774
    4775 return SCIP_OKAY;
    4776 }
    4777#endif
    4778
    4779/** store row and column basis status in a packed LPi state object
    4780 *
    4781 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    4782 */
    4783static
    4785 SCIP_LPI* lpi, /**< LP interface structure */
    4786 SCIP_LPISTATE* lpistate /**< pointer to LPi state data */
    4787 )
    4788{
    4789 int *skxi = (int *) lpi->skx; /* Used as temp. buffer */
    4790 int *skci = (int *) lpi->skc; /* Used as temp. buffer */
    4791
    4792 assert(sizeof(int) == sizeof(MSKstakeye)); /*lint !e506*/
    4793 assert(lpi != NULL);
    4794 assert(lpistate != NULL);
    4795 assert(lpi->lastsolvetype == MSK_SOL_BAS);
    4796
    4797 SCIP_CALL( convertstat_mosek2scip(lpi, FALSE, lpi->skx, lpistate->ncols, skxi) );
    4798 SCIP_CALL( convertstat_mosek2scip_slack(lpi, TRUE, lpi->skc, lpistate->nrows, skci) );
    4799
    4800 SCIPencodeDualBit(skxi, lpistate->skx, lpistate->ncols);
    4801 SCIPencodeDualBit(skci, lpistate->skc, lpistate->nrows);
    4802
    4803 return SCIP_OKAY;
    4804}
    4805
    4806/** unpacks row and column basis status from a packed LPi state object */
    4807static
    4809 const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
    4810 MSKstakeye* skx, /**< basis status for columns */
    4811 MSKstakeye* skc /**< basis status for rows */
    4812 )
    4813{
    4814 assert(sizeof(int) == sizeof(MSKstakeye)); /*lint !e506*/
    4815
    4816 SCIPdecodeDualBit(lpistate->skx, (int*) skx, lpistate->ncols);
    4817 SCIPdecodeDualBit(lpistate->skc, (int*) skc, lpistate->nrows);
    4818
    4819 convertstat_scip2mosek((int*) skx, lpistate->ncols, skx);
    4820 convertstat_scip2mosek_slack((int*) skc, lpistate->nrows, skc);
    4821}
    4822
    4823/** stores LP state (like basis information) into lpistate object
    4824 *
    4825 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    4826 */
    4828 SCIP_LPI* lpi, /**< LP interface structure */
    4829 BMS_BLKMEM* blkmem, /**< block memory */
    4830 SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
    4831 )
    4832{
    4833 int gotbasicsol;
    4834 int nrows;
    4835 int ncols;
    4836
    4837 assert(lpi != NULL);
    4838 assert(lpi->mosekenv != NULL);
    4839 assert(lpi->task != NULL);
    4840 assert(lpistate != NULL);
    4841 assert(blkmem != NULL);
    4842 assert(lpi->lastsolvetype == MSK_SOL_BAS);
    4843
    4844 SCIPdebugMessage("Calling SCIPlpiGetState (%d)\n", lpi->lpid);
    4845
    4846 *lpistate = NULL;
    4847
    4848 MOSEK_CALL( MSK_solutiondef(lpi->task, MSK_SOL_BAS, &gotbasicsol) );
    4849
    4850 if ( gotbasicsol == 0 || SCIPlpiExistsDualRay(lpi) || lpi->clearstate )
    4851 return SCIP_OKAY;
    4852
    4853 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    4854 MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
    4855
    4856 /* allocate lpistate data */
    4857 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
    4858
    4859 lpistate[0]->num = lpi->optimizecount;
    4860
    4861 MOSEK_CALL( MSK_getsolutionstatus(lpi->task, MSK_SOL_BAS, NULL, &lpistate[0]->solsta) );
    4862
    4863 SCIP_CALL( getbase(lpi, ncols, nrows) );
    4864
    4865#ifndef NDEBUG
    4866 SCIP_CALL( checkState(lpi, ncols, nrows) );
    4867#endif
    4868
    4869 SCIP_CALL( lpistatePack(lpi, lpistate[0]) );
    4870
    4871 SCIPdebugMessage("Store into state from iter : %d\n", lpi->optimizecount);
    4872
    4873 /* if (r != SCIP_OKAY)
    4874 * lpistateFree(lpistate, blkmem );
    4875 */
    4876
    4877 return SCIP_OKAY;
    4878}
    4879
    4880/** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
    4881 * columns and rows since the state was stored with SCIPlpiGetState()
    4882 */
    4884 SCIP_LPI* lpi, /**< LP interface structure */
    4885 BMS_BLKMEM* blkmem, /**< block memory */
    4886 const SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
    4887 )
    4888{ /*lint --e{715}*/
    4889 int nrows;
    4890 int ncols;
    4891 int i;
    4892
    4893 assert(lpi != NULL);
    4894 assert(lpi->mosekenv != NULL);
    4895 assert(lpi->task != NULL);
    4896 assert(blkmem != NULL);
    4897#ifdef SCIP_DISABLED_CODE
    4898 assert(lpi->lastsolvetype == MSK_SOL_BAS);
    4899#endif
    4900
    4901 if (lpistate == NULL)
    4902 {
    4903 SCIPdebugMessage("Setting NULL state\n");
    4904 return SCIP_OKAY;
    4905 }
    4906
    4907 if (lpistate->nrows == 0 || lpistate->ncols == 0)
    4908 return SCIP_OKAY;
    4909
    4910 MOSEK_CALL( MSK_getnumcon(lpi->task, &nrows) );
    4911 MOSEK_CALL( MSK_getnumvar(lpi->task, &ncols) );
    4912 assert(lpistate->nrows <= nrows);
    4913 assert(lpistate->ncols <= ncols);
    4914
    4915 SCIP_CALL( ensureStateMem(lpi, ncols, nrows) );
    4916
    4917#ifdef SCIP_DISABLED_CODE
    4918 SCIP_CALL( getbase(lpi, ncols, nrows) ); /* Why do we need to get the basis ????? */
    4919#endif
    4920
    4921 lpistateUnpack(lpistate, lpi->skx, lpi->skc);
    4922
    4923 /* extend the basis to the current LP beyond the previously existing columns */
    4924 for (i = lpistate->ncols; i < ncols; ++i)
    4925 {
    4926 SCIP_Real lb;
    4927 SCIP_Real ub;
    4928#if MSK_VERSION_MAJOR < 9
    4929 MOSEK_CALL( MSK_getboundslice(lpi->task, MSK_ACC_VAR, i, i, NULL, &lb, &ub) );
    4930#else
    4931 MOSEK_CALL( MSK_getvarboundslice(lpi->task, i, i, NULL, &lb, &ub) );
    4932#endif
    4933 if ( SCIPlpiIsInfinity(lpi, REALABS(lb)) )
    4934 {
    4935 /* if lower bound is +/- infinity -> try upper bound */
    4936 if ( SCIPlpiIsInfinity(lpi, REALABS(ub)) )
    4937 lpi->skx[i] = MSK_SK_SUPBAS; /* variable is free (super basic) */
    4938 else
    4939 lpi->skx[i] = MSK_SK_UPR; /* use finite upper bound */
    4940 }
    4941 else
    4942 lpi->skx[i] = MSK_SK_LOW; /* use finite lower bound */
    4943 }
    4944 for (i = lpistate->nrows; i < nrows; ++i)
    4945 lpi->skc[i] = MSK_SK_BAS;
    4946
    4947 /* load basis information into MOSEK */
    4948 SCIP_CALL( setbase(lpi) );
    4949
    4950 invalidateSolution(lpi);
    4951
    4952 SCIPdebugMessage("Store from state into task iter : %d with solsta : %d\n", lpistate->num, lpistate->solsta);
    4953
    4954 return SCIP_OKAY;
    4955}
    4956
    4957/** clears current LPi state (like basis information) of the solver */
    4959 SCIP_LPI* lpi /**< LP interface structure */
    4960 )
    4961{
    4962 assert(lpi != NULL);
    4963 assert(lpi->mosekenv != NULL);
    4964 assert(lpi->task != NULL);
    4965
    4966 lpi->clearstate = TRUE;
    4967
    4968 return SCIP_OKAY;
    4969}
    4970
    4971/** frees LP state information */
    4973 SCIP_LPI* lpi, /**< LP interface structure */
    4974 BMS_BLKMEM* blkmem, /**< block memory */
    4975 SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
    4976 )
    4977{ /*lint --e{715}*/
    4978 assert(lpi != NULL);
    4979 assert(lpi->mosekenv != NULL);
    4980 assert(lpi->task != NULL);
    4981 assert(lpistate != NULL);
    4982 assert(blkmem != NULL);
    4983
    4984 SCIPdebugMessage("Calling SCIPlpiFreeState (%d)\n", lpi->lpid);
    4985
    4986 if( *lpistate != NULL )
    4987 {
    4988 lpistateFree(lpistate, blkmem);
    4989 }
    4990
    4991 return SCIP_OKAY;
    4992}
    4993
    4994/** checks whether the given LP state contains simplex basis information */
    4996 SCIP_LPI* lpi, /**< LP interface structure */
    4997 SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
    4998 )
    4999{ /*lint --e{715}*/
    5000 assert(lpi != NULL);
    5001 assert(lpi->mosekenv != NULL);
    5002 assert(lpi->task != NULL);
    5003
    5004 SCIPdebugMessage("Calling SCIPlpiHasStateBasis (%d)\n", lpi->lpid);
    5005
    5006 return ( lpistate != NULL && lpistate->num >= 0);
    5007}
    5008
    5009/** reads LP state (like basis information) from a file
    5010 *
    5011 * @note last solve call must have been either simplex or barrier with crossover or base must have been set manually
    5012 */
    5014 SCIP_LPI* lpi, /**< LP interface structure */
    5015 const char* fname /**< file name */
    5016 )
    5017{
    5018 assert(lpi != NULL);
    5019 assert(lpi->mosekenv != NULL);
    5020 assert(lpi->task != NULL);
    5021 assert(fname != NULL);
    5022
    5023 SCIPdebugMessage("reading LP state from file <%s>\n", fname);
    5024
    5025 lpi->clearstate = FALSE;
    5026
    5027 MOSEK_CALL( MSK_readsolution(lpi->task, MSK_SOL_BAS, fname) );
    5028
    5029 return SCIP_OKAY;
    5030}
    5031
    5032/** writes LPi state (i.e. basis information) to a file */
    5034 SCIP_LPI* lpi, /**< LP interface structure */
    5035 const char* fname /**< file name */
    5036 )
    5037{
    5038 int v;
    5039 int nvars;
    5040 int c = 0;
    5041 int nconss;
    5042 SCIP_Bool emptyname = FALSE;
    5043 char name[SCIP_MAXSTRLEN];
    5044
    5045 assert(lpi != NULL);
    5046 assert(lpi->mosekenv != NULL);
    5047 assert(lpi->task != NULL);
    5048 assert(fname != NULL);
    5049 assert(lpi->lastsolvetype == MSK_SOL_BAS);
    5050
    5051 SCIPdebugMessage("writing LP state to file <%s>\n", fname);
    5052
    5053 if( lpi->clearstate )
    5054 {
    5055 SCIPdebugMessage("No LP state written, since it was cleared after the last solve \n");
    5056 return SCIP_OKAY;
    5057 }
    5058
    5059 /* If any rows or columns have empty names, MOSEK will make up names like C1 and X1, but will no
    5060 * longer recognize them when reading the same state file back in, therefore we return an error in
    5061 * this case
    5062 */
    5063 MOSEK_CALL( MSK_getnumvar(lpi->task, &nvars) );
    5064 for( v = 0; v < nvars; v++ )
    5065 {
    5066 MOSEK_CALL( MSK_getvarname(lpi->task, v, SCIP_MAXSTRLEN, name) );
    5067 if( strcmp(name, "") == 0 )
    5068 {
    5069 emptyname = TRUE;
    5070 break;
    5071 }
    5072 }
    5073 if( !emptyname )
    5074 {
    5075 MOSEK_CALL( MSK_getnumcon(lpi->task, &nconss) );
    5076 for( c = 0; c < nconss; c++ )
    5077 {
    5078 MOSEK_CALL( MSK_getconname(lpi->task, c, SCIP_MAXSTRLEN, name) );
    5079 if( strcmp(name, "") == 0 )
    5080 {
    5081 emptyname = TRUE;
    5082 break;
    5083 }
    5084 }
    5085 }
    5086
    5087 if( emptyname )
    5088 {
    5089 SCIPmessagePrintWarning(lpi->messagehdlr, "Writing LP state with unnamed %s %d, using default"
    5090 " names instead. Note that this state cannot be read back in later!\n",
    5091 v < nvars ? "variable" : "constraint", v < nvars ? v : c);
    5092 }
    5093
    5094 /* set parameter to be able to write */
    5095 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_HEAD, MSK_ON) );
    5096 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_VARIABLES, MSK_ON) );
    5097 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_SOL_CONSTRAINTS, MSK_ON) );
    5098
    5099 MOSEK_CALL( MSK_writesolution(lpi->task, MSK_SOL_BAS, fname) );
    5100
    5101 return SCIP_OKAY;
    5102}
    5103
    5104/**@} */
    5105
    5106/*
    5107 * LP Pricing Norms Methods
    5108 */
    5109
    5110/**@name LP Pricing Norms Methods */
    5111/**@{ */
    5112
    5113/** stores LPi pricing norms information
    5114 * @todo should we store norm information?
    5115 */
    5117 SCIP_LPI* lpi, /**< LP interface structure */
    5118 BMS_BLKMEM* blkmem, /**< block memory */
    5119 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
    5120 )
    5121{ /*lint --e{715}*/
    5122 assert(lpi != NULL);
    5123 assert(lpi->mosekenv != NULL);
    5124 assert(lpi->task != NULL);
    5125 assert(lpinorms != NULL);
    5126 assert(blkmem != NULL);
    5127
    5128 (*lpinorms) = NULL;
    5129
    5130 return SCIP_OKAY;
    5131}
    5132
    5133/** loads LPi pricing norms into solver; note that the LP might have been extended with additional
    5134 * columns and rows since the state was stored with SCIPlpiGetNorms()
    5135 */
    5137 SCIP_LPI* lpi, /**< LP interface structure */
    5138 BMS_BLKMEM* blkmem, /**< block memory */
    5139 const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
    5140 )
    5141{ /*lint --e{715}*/
    5142 assert(lpi != NULL);
    5143 SCIP_UNUSED(blkmem);
    5144 assert(lpinorms == NULL);
    5145
    5146 /* no work necessary */
    5147 return SCIP_OKAY;
    5148}
    5149
    5150/** frees pricing norms information */
    5152 SCIP_LPI* lpi, /**< LP interface structure */
    5153 BMS_BLKMEM* blkmem, /**< block memory */
    5154 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
    5155 )
    5156{ /*lint --e{715}*/
    5157 assert(lpi != NULL);
    5158 SCIP_UNUSED(blkmem);
    5159 assert(lpinorms == NULL);
    5160
    5161 /* no work necessary */
    5162 return SCIP_OKAY;
    5163}
    5164
    5165/**@} */
    5166
    5167/*
    5168 * Parameter Methods
    5169 */
    5170
    5171/** constant array containing the parameter names */
    5172static const char* paramname[] = {
    5173 "SCIP_LPPAR_FROMSCRATCH", /* solver should start from scratch at next call? */
    5174 "SCIP_LPPAR_FASTMIP", /* fast mip setting of LP solver */
    5175 "SCIP_LPPAR_SCALING", /* which scaling should LP solver use? */
    5176 "SCIP_LPPAR_PRESOLVING", /* should LP solver use presolving? */
    5177 "SCIP_LPPAR_PRICING", /* pricing strategy */
    5178 "SCIP_LPPAR_LPINFO", /* should LP solver output information to the screen? */
    5179 "SCIP_LPPAR_FEASTOL", /* feasibility tolerance for primal variables and slacks */
    5180 "SCIP_LPPAR_DUALFEASTOL", /* feasibility tolerance for dual variables and reduced costs */
    5181 "SCIP_LPPAR_BARRIERCONVTOL", /* convergence tolerance used in barrier algorithm */
    5182 "SCIP_LPPAR_OBJLIM", /* objective limit (stop if objective is known be larger/smaller than limit for min/max-imization) */
    5183 "SCIP_LPPAR_LPITLIM", /* LP iteration limit, greater than or equal 0 */
    5184 "SCIP_LPPAR_LPTILIM", /* LP time limit, positive */
    5185 "SCIP_LPPAR_MARKOWITZ", /* Markowitz tolerance */
    5186 "SCIP_LPPAR_ROWREPSWITCH", /* simplex algorithm shall use row representation of the basis
    5187 * if number of rows divided by number of columns exceeds this value */
    5188 "SCIP_LPPAR_THREADS", /* number of threads used to solve the LP */
    5189 "SCIP_LPPAR_CONDITIONLIMIT", /* maximum condition number of LP basis counted as stable */
    5190 "SCIP_LPPAR_TIMING", /* type of timer (1 - cpu, 2 - wallclock, 0 - off) */
    5191 "SCIP_LPPAR_RANDOMSEED", /* inital random seed, e.g. for perturbations in the simplex (0: LP default) */
    5192 "SCIP_LPPAR_POLISHING", /* set solution polishing (0 - disable, 1 - enable) */
    5193 "SCIP_LPPAR_REFACTOR" /* set refactorization interval (0 - automatic) */
    5194};
    5195
    5196/** method mapping parameter index to parameter name */
    5197static
    5198const char* paramty2str(
    5199 SCIP_LPPARAM type
    5200 )
    5201{ /*lint --e{641}*/
    5202 /* check whether the parameters are in the right order */
    5203 /*lint --e{506}*/
    5204 assert(SCIP_LPPAR_FROMSCRATCH == 0); /* solver should start from scratch at next call? */
    5205 assert(SCIP_LPPAR_FASTMIP == 1); /* fast mip setting of LP solver */
    5206 assert(SCIP_LPPAR_SCALING == 2); /* which scaling should LP solver use? */
    5207 assert(SCIP_LPPAR_PRESOLVING == 3); /* should LP solver use presolving? */
    5208 assert(SCIP_LPPAR_PRICING == 4); /* pricing strategy */
    5209 assert(SCIP_LPPAR_LPINFO == 5); /* should LP solver output information to the screen? */
    5210 assert(SCIP_LPPAR_FEASTOL == 6); /* feasibility tolerance for primal variables and slacks */
    5211 assert(SCIP_LPPAR_DUALFEASTOL == 7); /* feasibility tolerance for dual variables and reduced costs */
    5212 assert(SCIP_LPPAR_BARRIERCONVTOL == 8); /* convergence tolerance used in barrier algorithm */
    5213 assert(SCIP_LPPAR_OBJLIM == 9); /* objective limit (stop if objective is known be larger/smaller than limit for min/max-imization) */
    5214 assert(SCIP_LPPAR_LPITLIM == 10); /* LP iteration limit, greater than or equal 0 */
    5215 assert(SCIP_LPPAR_LPTILIM == 11); /* LP time limit, positive */
    5216 assert(SCIP_LPPAR_MARKOWITZ == 12); /* Markowitz tolerance */
    5217 assert(SCIP_LPPAR_ROWREPSWITCH == 13); /* row representation switch */
    5218 assert(SCIP_LPPAR_THREADS == 14); /* number of threads used to solve the LP */
    5219 assert(SCIP_LPPAR_CONDITIONLIMIT == 15); /* maximum condition number of LP basis counted as stable */
    5220 assert(SCIP_LPPAR_TIMING == 16); /* type of timer (1 - cpu, 2 - wallclock, 0 - off) */
    5221 assert(SCIP_LPPAR_RANDOMSEED == 17); /* inital random seed, e.g. for perturbations in the simplex (0: LP default) */
    5222 assert(SCIP_LPPAR_POLISHING == 18); /* set solution polishing (0 - disable, 1 - enable) */
    5223 assert(SCIP_LPPAR_REFACTOR == 19); /* set refactorization interval (0 - automatic) */
    5224
    5225 return paramname[type];
    5226}
    5227
    5228/** gets integer parameter of LP */
    5230 SCIP_LPI* lpi, /**< LP interface structure */
    5231 SCIP_LPPARAM type, /**< parameter number */
    5232 int* ival /**< buffer to store the parameter value */
    5233 )
    5234{ /*lint --e{641}*/
    5235 assert(lpi != NULL);
    5236 assert(lpi->mosekenv != NULL);
    5237 assert(lpi->task != NULL);
    5238 assert(ival != NULL);
    5239
    5240 SCIPdebugMessage("getting int parameter %s\n", paramty2str(type));
    5241
    5242 switch (type)
    5243 {
    5244 case SCIP_LPPAR_FROMSCRATCH: /* solver should start from scratch at next call? */
    5245 *ival = (int) lpi->fromscratch;
    5246 break;
    5247 case SCIP_LPPAR_FASTMIP: /* fast mip setting of LP solver */
    5248 return SCIP_PARAMETERUNKNOWN;
    5249 case SCIP_LPPAR_SCALING: /* should LP solver use scaling? */
    5250 *ival = lpi->scaling;
    5251 break;
    5252 case SCIP_LPPAR_PRESOLVING: /* should LP solver use presolving? */
    5253 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_PRESOLVE_USE, ival) );
    5254 *ival = (*ival != MSK_PRESOLVE_MODE_OFF);
    5255 break;
    5256 case SCIP_LPPAR_PRICING: /* pricing strategy */
    5257 *ival = lpi->pricing;
    5258 break;
    5259 case SCIP_LPPAR_LPINFO: /* should LP solver output information to the screen? */
    5260 *ival = (int) lpi->lpinfo;
    5261 break;
    5262 case SCIP_LPPAR_LPITLIM: /* LP iteration limit */
    5263 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, ival) );
    5264 break;
    5265 case SCIP_LPPAR_THREADS: /* number of threads */
    5266 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_NUM_THREADS, ival) );
    5267 break;
    5268 case SCIP_LPPAR_REFACTOR: /* refactorization interval */
    5269 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_SIM_REFACTOR_FREQ, ival) );
    5270 break;
    5271 default:
    5272 return SCIP_PARAMETERUNKNOWN;
    5273 } /*lint !e788*/
    5274
    5275 return SCIP_OKAY;
    5276}
    5277
    5278/** sets integer parameter of LP */
    5280 SCIP_LPI* lpi, /**< LP interface structure */
    5281 SCIP_LPPARAM type, /**< parameter number */
    5282 int ival /**< parameter value */
    5283 )
    5284{
    5285 static int pricing[7] =
    5286 {
    5287 (int)MSK_SIM_SELECTION_SE, /**< mosek pricing for SCIP_PRICING_LPIDEFAULT */
    5288 (int)MSK_SIM_SELECTION_FREE, /**< mosek pricing for SCIP_PRICING_AUTO */
    5289 (int)MSK_SIM_SELECTION_FULL, /**< mosek pricing for SCIP_PRICING_FULL */
    5290 (int)MSK_SIM_SELECTION_PARTIAL, /**< mosek pricing for SCIP_PRICING_PARTIAL */
    5291 (int)MSK_SIM_SELECTION_SE, /**< mosek pricing for SCIP_PRICING_STEEP */
    5292 (int)MSK_SIM_SELECTION_ASE, /**< mosek pricing for SCIP_PRICING_STEEPQSTART */
    5293 (int)MSK_SIM_SELECTION_DEVEX, /**< mosek pricing for SCIP_PRICING_DEVEX */
    5294 };
    5295
    5296 /*lint --e{506}*/
    5297 assert((int)SCIP_PRICING_LPIDEFAULT == 0);
    5298 assert((int)SCIP_PRICING_AUTO == 1);
    5299 assert((int)SCIP_PRICING_FULL == 2);
    5300 assert((int)SCIP_PRICING_PARTIAL == 3);
    5301 assert((int)SCIP_PRICING_STEEP == 4);
    5302 assert((int)SCIP_PRICING_STEEPQSTART == 5);
    5303 assert((int)SCIP_PRICING_DEVEX == 6);
    5304
    5305 assert(lpi != NULL);
    5306 assert(lpi->mosekenv != NULL);
    5307 assert(lpi->task != NULL);
    5308
    5309 SCIPdebugMessage("Calling SCIPlpiSetIntpar (%d) Parameter=<%s> Value=<%d>\n", lpi->lpid, paramty2str(type), ival);
    5310
    5311 switch (type)
    5312 {
    5313 case SCIP_LPPAR_FROMSCRATCH: /* solver should start from scratch at next call? */
    5314 lpi->fromscratch = (SCIP_Bool) ival;
    5315 break;
    5316 case SCIP_LPPAR_FASTMIP: /* fast mip setting of LP solver */
    5317 return SCIP_PARAMETERUNKNOWN;
    5318 case SCIP_LPPAR_SCALING: /* should LP solver use scaling? */
    5319 assert( ival >= 0 && ival <= 2 );
    5320 lpi->scaling = ival;
    5321 if( ival == 0 )
    5322 {
    5323 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, MSK_SCALING_NONE) );
    5324 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_SCALING, MSK_SCALING_NONE) );
    5325 }
    5326#if MSK_VERSION_MAJOR < 10
    5327 else if( ival == 1 )
    5328 {
    5329 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, MSK_SCALING_FREE) );
    5330 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_SCALING, MSK_SCALING_FREE) );
    5331 }
    5332 else
    5333 {
    5334 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, MSK_SCALING_AGGRESSIVE) );
    5335 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_SCALING, MSK_SCALING_AGGRESSIVE) );
    5336 }
    5337#else
    5338 else
    5339 {
    5340 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_SCALING, MSK_SCALING_FREE) );
    5341 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_INTPNT_SCALING, MSK_SCALING_FREE) );
    5342 }
    5343#endif
    5344
    5345 break;
    5346 case SCIP_LPPAR_PRESOLVING: /* should LP solver use presolving? */
    5347 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_PRESOLVE_USE,
    5348 ival ? MSK_PRESOLVE_MODE_FREE : MSK_PRESOLVE_MODE_OFF) );
    5349 break;
    5350 case SCIP_LPPAR_PRICING: /* pricing strategy */
    5351 assert(ival >= 0 && ival <= (int)SCIP_PRICING_DEVEX);
    5352 lpi->pricing = (SCIP_PRICING)ival;
    5353
    5354 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_PRIMAL_SELECTION, pricing[ival]) );
    5355 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_DUAL_SELECTION, pricing[ival]) );
    5356
    5357 /* for certain pricing values, do not use restricted pricing */
    5358 if( lpi->pricing == SCIP_PRICING_PARTIAL || lpi->pricing == SCIP_PRICING_AUTO )
    5359 lpi->restrictselectdef = 50;
    5360 else
    5361 lpi->restrictselectdef = 0;
    5362
    5363 break;
    5364 case SCIP_LPPAR_LPINFO:
    5365 /* should LP solver output information to the screen? */
    5366#if FORCE_MOSEK_LOG
    5367 SCIPdebugMessage("Ignoring log setting!\n");
    5368#else
    5369 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG, ival ? 4 : MSK_OFF) );
    5370 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_LOG_SIM, ival ? 4 : MSK_OFF) );
    5371#endif
    5372 lpi->lpinfo = (SCIP_Bool) ival;
    5373 break;
    5374 case SCIP_LPPAR_LPITLIM: /* LP iteration limit */
    5375#if DEBUG_PARAM_SETTING
    5376 if( ival )
    5377 {
    5378 SCIPdebugMessage("Setting max iter to : %d\n", ival);
    5379 }
    5380#endif
    5381 /* 0 <= ival, 0 stopping immediately */
    5382 assert( ival >= 0 );
    5383 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_MAX_ITERATIONS, ival) );
    5384 break;
    5385 case SCIP_LPPAR_THREADS: /* number of threads (0 => MOSEK chooses) */
    5386 assert(ival >= 0);
    5387 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_NUM_THREADS, ival) );
    5388 break;
    5389 case SCIP_LPPAR_REFACTOR: /* refactorization interval */
    5390 assert(ival >= 0);
    5391 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_SIM_REFACTOR_FREQ, ival) );
    5392 break;
    5393 default:
    5394 return SCIP_PARAMETERUNKNOWN;
    5395 } /*lint !e788*/
    5396
    5397 return SCIP_OKAY;
    5398}
    5399
    5400/** gets floating point parameter of LP */
    5402 SCIP_LPI* lpi, /**< LP interface structure */
    5403 SCIP_LPPARAM type, /**< parameter number */
    5404 SCIP_Real* dval /**< buffer to store the parameter value */
    5405 )
    5406{
    5407 assert(lpi != NULL);
    5408 assert(lpi->mosekenv != NULL);
    5409 assert(lpi->task != NULL);
    5410 assert(dval != NULL);
    5411
    5412 SCIPdebugMessage("getting real parameter %s\n", paramty2str(type));
    5413
    5414 switch (type)
    5415 {
    5416 case SCIP_LPPAR_FEASTOL: /* feasibility tolerance for primal variables and slacks */
    5417 MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_BASIS_TOL_X, dval) );
    5418 break;
    5419 case SCIP_LPPAR_DUALFEASTOL: /* feasibility tolerance for dual variables and reduced costs */
    5420 MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_BASIS_TOL_S, dval) );
    5421 break;
    5422 case SCIP_LPPAR_BARRIERCONVTOL: /* convergence tolerance used in barrier algorithm */
    5423 MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_INTPNT_TOL_REL_GAP, dval) );
    5424 break;
    5425 case SCIP_LPPAR_OBJLIM: /* objective limit */
    5426 {
    5427 MSKobjsensee objsen;
    5428 MOSEK_CALL( MSK_getobjsense(lpi->task, &objsen) );
    5429 if (objsen == MSK_OBJECTIVE_SENSE_MINIMIZE)
    5430 {
    5431 MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, dval) );
    5432 }
    5433 else /* objsen == MSK_OBJECTIVE_SENSE_MAX */
    5434 {
    5435 MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, dval) );
    5436 }
    5437 break;
    5438 }
    5439 case SCIP_LPPAR_LPTILIM: /* LP time limit */
    5440 MOSEK_CALL( MSK_getdouparam(lpi->task, MSK_DPAR_OPTIMIZER_MAX_TIME, dval) );
    5441 break;
    5442 case SCIP_LPPAR_MARKOWITZ: /* Markowitz tolerance */
    5443 default:
    5444 return SCIP_PARAMETERUNKNOWN;
    5445 } /*lint !e788*/
    5446
    5447 return SCIP_OKAY;
    5448}
    5449
    5450/** sets floating point parameter of LP */
    5452 SCIP_LPI* lpi, /**< LP interface structure */
    5453 SCIP_LPPARAM type, /**< parameter number */
    5454 SCIP_Real dval /**< parameter value */
    5455 )
    5456{
    5457 assert(lpi != NULL);
    5458 assert(lpi->mosekenv != NULL);
    5459 assert(lpi->task != NULL);
    5460
    5461 SCIPdebugMessage("setting real parameter %s to %g\n", paramty2str(type), dval);
    5462
    5463 /**@todo Limits shouldn't be hardcoded */
    5464
    5465 switch (type)
    5466 {
    5467 case SCIP_LPPAR_FEASTOL: /* feasibility tolerance for primal variables and slacks */
    5468 assert( dval > 0.0 );
    5469 /* 1e-9 <= dval <= inf */
    5470 if( dval < 1e-9 )
    5471 dval = 1e-9;
    5472
    5473 MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_BASIS_TOL_X, dval) );
    5474 break;
    5475 case SCIP_LPPAR_DUALFEASTOL: /* feasibility tolerance for dual variables and reduced costs */
    5476 assert( dval > 0.0 );
    5477 /* 1e-9 <= dval <= inf */
    5478 if( dval < 1e-9 )
    5479 dval = 1e-9;
    5480
    5481 MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_BASIS_TOL_S, dval) );
    5482 break;
    5483 case SCIP_LPPAR_BARRIERCONVTOL: /* convergence tolerance used in barrier algorithm */
    5484 /* 1e-14 <= dval <= inf */
    5485 assert( dval >= 0.0 );
    5486 if( dval < 1e-14 )
    5487 dval = 1e-14;
    5488
    5489 MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_INTPNT_TOL_REL_GAP, dval) );
    5490 break;
    5491 case SCIP_LPPAR_OBJLIM: /* objective limit */
    5492 {
    5493 /* no restriction on dval */
    5494 MSKobjsensee objsen;
    5495 MOSEK_CALL( MSK_getobjsense(lpi->task, &objsen) );
    5496 if (objsen == MSK_OBJECTIVE_SENSE_MINIMIZE)
    5497 {
    5498 MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_UPPER_OBJ_CUT, dval) );
    5499 }
    5500 else /* objsen == MSK_OBJECTIVE_SENSE_MAX */
    5501 {
    5502 MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_LOWER_OBJ_CUT, dval) );
    5503 }
    5504 break;
    5505 }
    5506 case SCIP_LPPAR_LPTILIM: /* LP time limit */
    5507 assert( dval > 0.0 );
    5508 /* mosek requires 0 <= dval
    5509 *
    5510 * However for consistency we assert the timelimit to be strictly positive.
    5511 */
    5512 MOSEK_CALL( MSK_putdouparam(lpi->task, MSK_DPAR_OPTIMIZER_MAX_TIME, dval) );
    5513 break;
    5514 case SCIP_LPPAR_MARKOWITZ: /* Markowitz tolerance */
    5515 default:
    5516 return SCIP_PARAMETERUNKNOWN;
    5517 } /*lint !e788*/
    5518
    5519 return SCIP_OKAY;
    5520}
    5521
    5522/** interrupts the currently ongoing lp solve or disables the interrupt */
    5524 SCIP_LPI* lpi, /**< LP interface structure */
    5525 SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
    5526 )
    5527{
    5528 /*lint --e{715}*/
    5529 assert(lpi != NULL);
    5530
    5531 return SCIP_OKAY;
    5532}
    5533
    5534
    5535/*
    5536 * Numerical Methods
    5537 */
    5538
    5539
    5540/** returns value treated as infinity in the LP solver */
    5542 SCIP_LPI* lpi /**< LP interface structure */
    5543 )
    5544{ /*lint --e{715}*/
    5545 assert(lpi != NULL);
    5546 assert(lpi->mosekenv != NULL);
    5547 assert(lpi->task != NULL);
    5548
    5549 return MSK_INFINITY;
    5550}
    5551
    5552/** checks if given value is treated as infinity in the LP solver */
    5554 SCIP_LPI* lpi, /**< LP interface structure */
    5555 SCIP_Real val /**< value to be checked for infinity */
    5556 )
    5557{ /*lint --e{715}*/
    5558 assert(lpi != NULL);
    5559 assert(lpi->mosekenv != NULL);
    5560 assert(lpi->task != NULL);
    5561
    5562 return IS_POSINF(val);
    5563}
    5564
    5565
    5566/*
    5567 * File Interface Methods
    5568 */
    5569
    5570
    5571/** reads LP from a file */
    5573 SCIP_LPI* lpi, /**< LP interface structure */
    5574 const char* fname /**< file name */
    5575 )
    5576{
    5577#if MSK_VERSION_MAJOR < 9
    5578 int olddataformat;
    5579#endif
    5580
    5581 assert(lpi != NULL);
    5582 assert(lpi->mosekenv != NULL);
    5583 assert(lpi->task != NULL);
    5584 assert(fname != NULL);
    5585
    5586 SCIPdebugMessage("Calling SCIPlpiReadLP (%d), filename <%s>\n", lpi->lpid, fname);
    5587
    5588#if MSK_VERSION_MAJOR < 9
    5589 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, &olddataformat) );
    5590 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, MSK_DATA_FORMAT_LP) );
    5591 MOSEK_CALL( MSK_readdata(lpi->task, fname) );
    5592 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_READ_DATA_FORMAT, olddataformat) );
    5593#else
    5594 MOSEK_CALL( MSK_readdataformat(lpi->task, fname, MSK_DATA_FORMAT_LP, MSK_COMPRESS_FREE) );
    5595#endif
    5596
    5597 return SCIP_OKAY;
    5598}
    5599
    5600/** writes LP to a file */
    5602 SCIP_LPI* lpi, /**< LP interface structure */
    5603 const char* fname /**< file name */
    5604 )
    5605{
    5606#if MSK_VERSION_MAJOR < 9
    5607 int olddataformat;
    5608#endif
    5609
    5610 assert(lpi != NULL);
    5611 assert(lpi->mosekenv != NULL);
    5612 assert(lpi->task != NULL);
    5613 assert(fname != NULL);
    5614#if MSK_VERSION_MAJOR >= 9
    5615 /* Mosek 9 derives file format from given filename */
    5616 assert(strstr(fname, ".lp") != NULL);
    5617#endif
    5618
    5619 SCIPdebugMessage("Calling SCIPlpiWriteLP (%d), filename <%s>\n", lpi->lpid, fname);
    5620
    5621#if MSK_VERSION_MAJOR < 9
    5622 MOSEK_CALL( MSK_getintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, &olddataformat) );
    5623 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, MSK_DATA_FORMAT_LP) );
    5624 MOSEK_CALL( MSK_writedata(lpi->task, fname) );
    5625 MOSEK_CALL( MSK_putintparam(lpi->task, MSK_IPAR_WRITE_DATA_FORMAT, olddataformat) );
    5626#else
    5627 MOSEK_CALL( MSK_writedata(lpi->task, fname) );
    5628#endif
    5629
    5630 return SCIP_OKAY;
    5631}
    static long bound
    void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
    Definition: bitencode.c:308
    void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
    Definition: bitencode.c:238
    packing single and dual bit values
    unsigned int SCIP_DUALPACKET
    Definition: bitencode.h:42
    SCIP_Real * r
    Definition: circlepacking.c:59
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_UNUSED(x)
    Definition: def.h:409
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define SCIP_Real
    Definition: def.h:156
    #define EPSEQ(x, y, eps)
    Definition: def.h:183
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define EPSCEIL(x, eps)
    Definition: def.h:192
    #define SCIPABORT()
    Definition: def.h:327
    #define EPSFLOOR(x, eps)
    Definition: def.h:191
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
    Definition: lpi_msk.c:1540
    SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
    Definition: lpi_msk.c:4883
    SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_msk.c:4549
    static SCIP_RETCODE convertstat_mosek2scip_slack(SCIP_LPI *lpi, SCIP_Bool iscon, MSKstakeye *sk, int m, int *stat)
    Definition: lpi_msk.c:4062
    SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
    Definition: lpi_msk.c:5401
    SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
    Definition: lpi_msk.c:5541
    SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3662
    SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
    Definition: lpi_msk.c:1610
    static void lpistateUnpack(const SCIP_LPISTATE *lpistate, MSKstakeye *skx, MSKstakeye *skc)
    Definition: lpi_msk.c:4808
    SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
    Definition: lpi_msk.c:5553
    SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
    Definition: lpi_msk.c:1457
    SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
    Definition: lpi_msk.c:4958
    static SCIP_RETCODE getSolutionStatus(SCIP_LPI *lpi, MSKprostae *prosta, MSKsolstae *solsta)
    Definition: lpi_msk.c:2231
    SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3494
    SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3404
    SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
    Definition: lpi_msk.c:4195
    SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_msk.c:5013
    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:1270
    static MSKrescodee filterTRMrescode(SCIP_MESSAGEHDLR *messagehdlr, MSKrescodee *termcode, MSKrescodee res)
    Definition: lpi_msk.c:2248
    SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
    Definition: lpi_msk.c:3877
    SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
    Definition: lpi_msk.c:5229
    SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_msk.c:5601
    SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
    Definition: lpi_msk.c:794
    SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3547
    static SCIP_RETCODE checkState1(SCIP_LPI *lpi, int n, MSKstakeye *sk, SCIP_Bool isrow)
    Definition: lpi_msk.c:4688
    static SCIP_RETCODE lpistatePack(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
    Definition: lpi_msk.c:4784
    static SCIP_RETCODE SolveWSimplex(SCIP_LPI *lpi)
    Definition: lpi_msk.c:2282
    SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
    Definition: lpi_msk.c:5451
    static SCIP_RETCODE checkState(SCIP_LPI *lpi, int ncols, int nrows)
    Definition: lpi_msk.c:4763
    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:3194
    SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
    Definition: lpi_msk.c:5136
    SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
    Definition: lpi_msk.c:1825
    SCIP_Bool SCIPlpiHasPrimalSolve(void)
    Definition: lpi_msk.c:809
    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:3258
    SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
    Definition: lpi_msk.c:2119
    SCIP_Bool SCIPlpiHasBarrierSolve(void)
    Definition: lpi_msk.c:825
    SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
    Definition: lpi_msk.c:3896
    SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
    Definition: lpi_msk.c:3737
    SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
    Definition: lpi_msk.c:1722
    int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3698
    static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
    Definition: lpi_msk.c:4668
    SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
    Definition: lpi_msk.c:2906
    SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
    Definition: lpi_msk.c:3344
    static SCIP_RETCODE getASlice(SCIP_LPI *lpi, SCIP_Bool iscon, int first, int last, int *nnonz, int *beg, int *ind, double *val)
    Definition: lpi_msk.c:1844
    SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lpi_msk.c:5151
    SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3674
    SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
    Definition: lpi_msk.c:1482
    SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3445
    SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
    Definition: lpi_msk.c:3719
    SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_msk.c:5033
    SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
    Definition: lpi_msk.c:938
    static SCIP_RETCODE handle_singular(SCIP_LPI *lpi, int *basis, MSKrescodee res)
    Definition: lpi_msk.c:3956
    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:3218
    SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
    Definition: lpi_msk.c:2197
    SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3474
    SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
    Definition: lpi_msk.c:5572
    SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
    Definition: lpi_msk.c:3937
    SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3559
    SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
    Definition: lpi_msk.c:5116
    SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3686
    SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
    Definition: lpi_msk.c:4995
    SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
    Definition: lpi_msk.c:5279
    const char * SCIPlpiGetSolverName(void)
    Definition: lpi_msk.c:766
    SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
    Definition: lpi_msk.c:4230
    SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3427
    SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_msk.c:4304
    SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
    Definition: lpi_msk.c:1349
    static SCIP_RETCODE SCIPlpiStrongbranch(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
    Definition: lpi_msk.c:2936
    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:1920
    SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_msk.c:4387
    SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
    Definition: lpi_msk.c:2003
    SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int row, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
    Definition: lpi_msk.c:4470
    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:1959
    SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3325
    const char * SCIPlpiGetSolverDesc(void)
    Definition: lpi_msk.c:774
    SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
    Definition: lpi_msk.c:2740
    static void convertstat_scip2mosek(const int *stat, int n, MSKstakeye *resstat)
    Definition: lpi_msk.c:4129
    SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3577
    SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
    Definition: lpi_msk.c:2036
    SCIP_Bool SCIPlpiHasDualSolve(void)
    Definition: lpi_msk.c:817
    SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
    Definition: lpi_msk.c:2919
    SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
    Definition: lpi_msk.c:2156
    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:3282
    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:3770
    SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3517
    SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
    Definition: lpi_msk.c:1211
    SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
    Definition: lpi_msk.c:2090
    SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lpi_msk.c:4972
    SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3462
    SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
    Definition: lpi_msk.c:2673
    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:1075
    static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
    Definition: lpi_msk.c:4642
    SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
    Definition: lpi_msk.c:2601
    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:981
    SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3535
    static SCIP_RETCODE convertstat_mosek2scip(SCIP_LPI *lpi, SCIP_Bool iscon, MSKstakeye *sk, int n, int *stat)
    Definition: lpi_msk.c:3986
    SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
    Definition: lpi_msk.c:3915
    SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
    Definition: lpi_msk.c:4264
    SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
    Definition: lpi_msk.c:843
    static void convertstat_scip2mosek_slack(const int *stat, int n, MSKstakeye *resstat)
    Definition: lpi_msk.c:4160
    void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
    Definition: lpi_msk.c:782
    SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
    Definition: lpi_msk.c:1629
    SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
    Definition: lpi_msk.c:2069
    SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
    Definition: lpi_msk.c:3601
    SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
    Definition: lpi_msk.c:1807
    SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
    Definition: lpi_msk.c:5523
    SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
    Definition: lpi_msk.c:1164
    SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
    Definition: lpi_msk.c:1398
    SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
    Definition: lpi_msk.c:1660
    SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
    Definition: lpi_msk.c:1789
    SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
    Definition: lpi_msk.c:4827
    SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
    Definition: lpi_msk.c:1581
    interface methods for specific LP solvers
    SCIP_DUALPACKET ROWPACKET
    Definition: lpi_clp.cpp:128
    SCIP_DUALPACKET COLPACKET
    Definition: lpi_clp.cpp:126
    static SCIP_RETCODE getIndicesRange(int first, int last, int **sub)
    Definition: lpi_msk.c:561
    static void MSKAPI printstr(MSKuserhandle_t handle, const char *str)
    Definition: lpi_msk.c:268
    static SCIP_RETCODE getEndptrs(int n, const int *beg, int nnonz, MSKint32t *aptre)
    Definition: lpi_msk.c:527
    #define MOSEK_relDiff(val1, val2)
    Definition: lpi_msk.c:96
    static SCIP_RETCODE setbase(SCIP_LPI *lpi)
    Definition: lpi_msk.c:732
    static void generateMskBoundkeys(int n, const double *lb, const double *ub, MSKboundkeye *bk)
    Definition: lpi_msk.c:476
    static int rowpacketNum(int nrows)
    Definition: lpi_msk.c:259
    #define IS_POSINF(x)
    Definition: lpi_msk.c:94
    static const char * paramname[]
    Definition: lpi_msk.c:5172
    static SCIP_RETCODE getbase(SCIP_LPI *lpi, int ncols, int nrows)
    Definition: lpi_msk.c:713
    static SCIP_RETCODE ensureBkxMem(SCIP_LPI *lpi, int ncols)
    Definition: lpi_msk.c:408
    #define DEBUG_CHECK_STATE_TOL
    Definition: lpi_msk.c:120
    static MSKenv_t reusemosekenv
    Definition: lpi_msk.c:107
    SCIP_DUALPACKET ROWPACKET
    Definition: lpi_msk.c:199
    static void scale_bound(MSKboundkeye *bk, double *bl, double *bu, double s)
    Definition: lpi_msk.c:641
    #define SETBACK_LIMIT
    Definition: lpi_msk.c:128
    #define COLS_PER_PACKET
    Definition: lpi_msk.c:198
    static SCIP_RETCODE ensureAptreMem(SCIP_LPI *lpi, int n)
    Definition: lpi_msk.c:446
    static int numlp
    Definition: lpi_msk.c:108
    #define IS_NEGINF(x)
    Definition: lpi_msk.c:95
    #define SCIP_ABORT_FALSE(x)
    Definition: lpi_msk.c:82
    #define MOSEK_CALL(x)
    Definition: lpi_msk.c:69
    enum MSKoptimizertype_enum MSKoptimizertype
    Definition: lpi_msk.c:67
    #define DEGEN_LEVEL
    Definition: lpi_msk.c:137
    SCIP_DUALPACKET COLPACKET
    Definition: lpi_msk.c:197
    static SCIP_RETCODE getIndicesFromDense(int *dstat, int n, int *count, int **sub)
    Definition: lpi_msk.c:583
    #define SENSE2MOSEK(objsen)
    Definition: lpi_msk.c:65
    static void scale_vec(int len, double *vec, double s)
    Definition: lpi_msk.c:626
    static int colpacketNum(int ncols)
    Definition: lpi_msk.c:250
    static const char * paramty2str(SCIP_LPPARAM type)
    Definition: lpi_msk.c:5198
    #define STRONGBRANCH_PRICING
    Definition: lpi_msk.c:129
    static SCIP_RETCODE ensureStateMem(SCIP_LPI *lpi, int ncols, int nrows)
    Definition: lpi_msk.c:684
    static MSKrescodee MSK_getsolutionstatus(MSKtask_t task, MSKsoltypee whichsol, MSKprostae *prosta, MSKsolstae *solsta)
    Definition: lpi_msk.c:223
    static SCIP_RETCODE ensureBkcMem(SCIP_LPI *lpi, int nrows)
    Definition: lpi_msk.c:427
    #define ROWS_PER_PACKET
    Definition: lpi_msk.c:200
    #define mskname
    Definition: lpi_msk.c:757
    static void invalidateSolution(SCIP_LPI *lpi)
    Definition: lpi_msk.c:465
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSfreeBlockMemory(mem, ptr)
    Definition: memory.h:465
    #define BMSallocBlockMemory(mem, ptr)
    Definition: memory.h:451
    #define BMSreallocMemoryArray(ptr, num)
    Definition: memory.h:127
    #define BMSallocMemoryArray(ptr, num)
    Definition: memory.h:123
    #define BMSfreeMemoryArray(ptr)
    Definition: memory.h:147
    #define BMSallocBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:454
    #define BMSfreeBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:467
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSfreeMemoryArrayNull(ptr)
    Definition: memory.h:148
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
    Definition: message.c:594
    void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
    Definition: message.c:427
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    #define SCIPdebugPrintf
    Definition: pub_message.h:99
    static SCIP_RETCODE presolve(SCIP *scip, SCIP_Bool *unbounded, SCIP_Bool *infeasible, SCIP_Bool *vanished)
    Definition: scip_solve.c:1138
    MSKsolstae solsta
    Definition: lpi_msk.c:206
    COLPACKET * skx
    Definition: lpi_msk.c:209
    ROWPACKET * skc
    Definition: lpi_msk.c:210
    int itercount
    Definition: lpi_msk.c:173
    SCIP_Bool solved
    Definition: lpi_clp.cpp:114
    SCIP_Bool clearstate
    Definition: lpi_cpx.c:172
    MSKstakeye * skc
    Definition: lpi_msk.c:179
    MSKoptimizertype lastalgo
    Definition: lpi_msk.c:177
    int skxsize
    Definition: lpi_msk.c:183
    int lpid
    Definition: lpi_msk.c:176
    int optimizecount
    Definition: lpi_msk.c:171
    MSKrescodee termcode
    Definition: lpi_msk.c:172
    MSKint32t * aptre
    Definition: lpi_msk.c:182
    MSKenv_t * reusemosekenv
    Definition: lpi_msk.c:168
    MSKsoltypee lastsolvetype
    Definition: lpi_msk.c:188
    MSKenv_t mosekenv
    Definition: lpi_msk.c:165
    MSKboundkeye * bkc
    Definition: lpi_msk.c:181
    int * numlp
    Definition: lpi_grb.c:160
    int bkxsize
    Definition: lpi_msk.c:185
    int aptresize
    Definition: lpi_msk.c:187
    SCIP_Bool fromscratch
    Definition: lpi_cpx.c:171
    int scaling
    Definition: lpi_msk.c:175
    int bkcsize
    Definition: lpi_msk.c:186
    MSKtask_t task
    Definition: lpi_msk.c:170
    MSKstakeye * skx
    Definition: lpi_msk.c:178
    SCIP_PRICING pricing
    Definition: lpi_clp.cpp:112
    int skcsize
    Definition: lpi_msk.c:184
    int restrictselectdef
    Definition: lpi_msk.c:193
    MSKboundkeye * bkx
    Definition: lpi_msk.c:180
    SCIP_MESSAGEHDLR * messagehdlr
    Definition: lpi_cpx.c:185
    SCIP_Bool lpinfo
    Definition: lpi_msk.c:192
    @ SCIP_PRICING_STEEPQSTART
    Definition: type_lpi.h:83
    @ SCIP_PRICING_AUTO
    Definition: type_lpi.h:79
    @ SCIP_PRICING_DEVEX
    Definition: type_lpi.h:84
    @ SCIP_PRICING_STEEP
    Definition: type_lpi.h:82
    @ SCIP_PRICING_FULL
    Definition: type_lpi.h:80
    @ SCIP_PRICING_LPIDEFAULT
    Definition: type_lpi.h:78
    @ SCIP_PRICING_PARTIAL
    Definition: type_lpi.h:81
    enum SCIP_Pricing SCIP_PRICING
    Definition: type_lpi.h:86
    enum SCIP_LPParam SCIP_LPPARAM
    Definition: type_lpi.h:73
    @ SCIP_LPPAR_PRICING
    Definition: type_lpi.h:54
    @ SCIP_LPPAR_REFACTOR
    Definition: type_lpi.h:71
    @ SCIP_LPPAR_THREADS
    Definition: type_lpi.h:66
    @ SCIP_LPPAR_LPINFO
    Definition: type_lpi.h:55
    @ SCIP_LPPAR_POLISHING
    Definition: type_lpi.h:70
    @ SCIP_LPPAR_SCALING
    Definition: type_lpi.h:52
    @ SCIP_LPPAR_TIMING
    Definition: type_lpi.h:68
    @ SCIP_LPPAR_LPTILIM
    Definition: type_lpi.h:61
    @ SCIP_LPPAR_BARRIERCONVTOL
    Definition: type_lpi.h:58
    @ SCIP_LPPAR_PRESOLVING
    Definition: type_lpi.h:53
    @ SCIP_LPPAR_CONDITIONLIMIT
    Definition: type_lpi.h:67
    @ SCIP_LPPAR_RANDOMSEED
    Definition: type_lpi.h:69
    @ SCIP_LPPAR_FASTMIP
    Definition: type_lpi.h:51
    @ SCIP_LPPAR_DUALFEASTOL
    Definition: type_lpi.h:57
    @ SCIP_LPPAR_FROMSCRATCH
    Definition: type_lpi.h:50
    @ SCIP_LPPAR_MARKOWITZ
    Definition: type_lpi.h:62
    @ SCIP_LPPAR_FEASTOL
    Definition: type_lpi.h:56
    @ SCIP_LPPAR_LPITLIM
    Definition: type_lpi.h:60
    @ SCIP_LPPAR_ROWREPSWITCH
    Definition: type_lpi.h:63
    @ SCIP_LPPAR_OBJLIM
    Definition: type_lpi.h:59
    @ SCIP_BASESTAT_BASIC
    Definition: type_lpi.h:92
    @ SCIP_BASESTAT_UPPER
    Definition: type_lpi.h:93
    @ SCIP_BASESTAT_LOWER
    Definition: type_lpi.h:91
    @ SCIP_BASESTAT_ZERO
    Definition: type_lpi.h:94
    enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
    Definition: type_lpi.h:104
    @ SCIP_OBJSEN_MAXIMIZE
    Definition: type_lpi.h:42
    @ SCIP_OBJSEN_MINIMIZE
    Definition: type_lpi.h:43
    enum SCIP_ObjSen SCIP_OBJSEN
    Definition: type_lpi.h:45
    @ SCIP_LPERROR
    Definition: type_retcode.h:49
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_PARAMETERUNKNOWN
    Definition: type_retcode.h:55
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63