69 #include "blockmemshell/memory.h" 71 #include "scip/pub_misc.h" 74 #include "scip/pub_message.h" 82 #define MIN_PENALTYPARAM 1e5 83 #define MAX_PENALTYPARAM 1e10 84 #define PENALTYPARAM_FACTOR 1e6 85 #define MAX_MAXPENALTYPARAM 1e15 86 #define MAXPENALTYPARAM_FACTOR 1e6 87 #define PENALTYBOUNDTOL 1E-3 89 #define INFEASFEASTOLCHANGE 0.1 90 #define INFEASMINFEASTOL 1E-9 92 #define CONVERT_ABSOLUTE_TOLERANCES TRUE 93 #if MSK_VERSION_MAJOR >= 9 94 #define NEAR_REL_TOLERANCE 1.0 98 struct SCIP_SDPiSolver
100 SCIP_MESSAGEHDLR* messagehdlr;
107 int* inputtomosekmapper;
110 int* mosektoinputmapper;
111 SCIP_Real* fixedvarsval;
112 SCIP_Real fixedvarsobjcontr;
124 SCIP_Real sdpsolverfeastol;
131 MSKrescodee terminationcode;
133 SCIP_Bool timelimitinitial;
145 #define MOSEK_CALL(x) do \ 147 MSKrescodee _mosekerrorcode_; \ 148 if ( (_mosekerrorcode_ = (x)) != MSK_RES_OK ) \ 150 SCIPerrorMessage("MOSEK-Error <%d> in function call.\n", (int)_mosekerrorcode_); \ 151 return SCIP_LPERROR; \ 157 #define MOSEK_CALL_BOOL(x) do \ 159 MSKrescodee _mosekerrorcode_; \ 160 if ( (_mosekerrorcode_ = (x)) != MSK_RES_OK ) \ 162 SCIPerrorMessage("MOSEK-Error <%d> in function call.\n", (int)_mosekerrorcode_); \ 169 #define MOSEK_CALLM(x) do \ 171 MSKrescodee _mosekerrorcode_; \ 172 if ( (_mosekerrorcode_ = (x)) != MSK_RES_OK ) \ 174 SCIPerrorMessage("MOSEK-Error <%d> in function call.\n", (int)_mosekerrorcode_); \ 175 return SCIP_NOMEMORY; \ 181 #define BMS_CALL(x) do \ 185 SCIPerrorMessage("No memory in function call.\n"); \ 186 return SCIP_NOMEMORY; \ 192 #define TIMEOFDAY_CALL(x) do \ 196 SCIPerrorMessage("Error in gettimeofday! \n"); \ 203 #define CHECK_IF_SOLVED(sdpisolver) do \ 205 if (!(sdpisolver->solved)) \ 207 SCIPerrorMessage("Tried to access solution information for SDP %d ahead of solving!\n", sdpisolver->sdpcounter); \ 208 return SCIP_LPERROR; \ 214 #define CHECK_IF_SOLVED_BOOL(sdpisolver) do \ 216 if (!(sdpisolver->solved)) \ 218 SCIPerrorMessage("Tried to access solution information for SDP %d ahead of solving!\n", sdpisolver->sdpcounter); \ 229 #
if MSK_VERSION_MAJOR >= 9
248 assert( sdpisolver != NULL );
249 assert( lb < ub + sdpisolver->feastol );
251 return (ub-lb <= sdpisolver->epsilon);
254 #define isFixed(sdpisolver,lb,ub) (ub-lb <= sdpisolver->epsilon) 265 char name[SCIP_MAXSTRLEN];
272 MSKrescodee rescodee;
275 #if MSK_VERSION_MAJOR < 9 283 #if MSK_VERSION_MAJOR < 9 284 rescodee = MSK_getversion(&majorver, &minorver, &build, &revision);
286 rescodee = MSK_getversion(&majorver, &minorver, &revision);
289 if ( rescodee != MSK_RES_OK )
293 #if MSK_VERSION_MAJOR < 9 294 snprintfreturn = SCIPsnprintf(
name, SCIP_MAXSTRLEN,
"MOSEK %d.%d.%d.%d", majorver, minorver, build, revision);
296 snprintfreturn = SCIPsnprintf(
name, SCIP_MAXSTRLEN,
"MOSEK %d.%d.%d", majorver, minorver, revision);
298 assert( snprintfreturn < SCIP_MAXSTRLEN );
300 #if MSK_VERSION_MAJOR < 9 301 (void) SCIPsnprintf(
name, SCIP_MAXSTRLEN,
"MOSEK %d.%d.%d.%d", majorver, minorver, build, revision);
303 (void) SCIPsnprintf(
name, SCIP_MAXSTRLEN,
"MOSEK %d.%d.%d", majorver, minorver, revision);
315 return "Homogeneous and self-dual interior-point solver for semidefinite programming developed by MOSEK ApS" 316 "(http://www.mosek.com)";
329 assert( sdpisolver != NULL );
378 SCIP_MESSAGEHDLR* messagehdlr,
383 assert( sdpisolver != NULL );
384 assert( blkmem != NULL );
385 assert( bufmem != NULL );
387 SCIPdebugMessage(
"Calling SCIPsdpiCreate \n");
389 BMS_CALL( BMSallocBlockMemory(blkmem, sdpisolver) );
391 (*sdpisolver)->messagehdlr = messagehdlr;
392 (*sdpisolver)->blkmem = blkmem;
393 (*sdpisolver)->bufmem = bufmem;
395 MOSEK_CALLM( MSK_makeenv(&((*sdpisolver)->mskenv), NULL) );
398 (*sdpisolver)->msktask = NULL;
400 (*sdpisolver)->nvars = 0;
401 (*sdpisolver)->nactivevars = 0;
402 (*sdpisolver)->inputtomosekmapper = NULL;
403 (*sdpisolver)->mosektoinputmapper = NULL;
404 (*sdpisolver)->fixedvarsval = NULL;
405 (*sdpisolver)->fixedvarsobjcontr = 0.0;
406 (*sdpisolver)->objcoefs = NULL;
407 (*sdpisolver)->nvarbounds = 0;
408 (*sdpisolver)->varboundpos = NULL;
409 (*sdpisolver)->solved = FALSE;
410 (*sdpisolver)->sdpcounter = 0;
412 (*sdpisolver)->epsilon = 1e-9;
413 (*sdpisolver)->gaptol = 1e-4;
414 (*sdpisolver)->feastol = 1e-6;
415 (*sdpisolver)->sdpsolverfeastol = 1e-6;
417 (*sdpisolver)->sdpinfo = FALSE;
418 (*sdpisolver)->nthreads = -1;
419 (*sdpisolver)->timelimit = FALSE;
420 (*sdpisolver)->timelimitinitial = FALSE;
430 assert( sdpisolver != NULL );
431 assert( *sdpisolver != NULL );
433 SCIPdebugMessage(
"Freeing SDPISolver\n");
435 if ( (*sdpisolver)->msktask != NULL )
437 MOSEK_CALL( MSK_deletetask(&((*sdpisolver)->msktask)) );
440 if ( (*sdpisolver)->mskenv != NULL )
442 MOSEK_CALL( MSK_deleteenv(&((*sdpisolver)->mskenv)) );
445 BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->varboundpos, 2 * (*sdpisolver)->nactivevars);
446 BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->inputtomosekmapper, (*sdpisolver)->nvars);
447 BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->mosektoinputmapper, (*sdpisolver)->nactivevars);
448 BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->fixedvarsval, (*sdpisolver)->nvars - (*sdpisolver)->nactivevars);
449 BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->objcoefs, (*sdpisolver)->nactivevars);
451 BMSfreeBlockMemory((*sdpisolver)->blkmem, sdpisolver);
461 assert( sdpisolver != NULL );
463 sdpisolver->sdpcounter++;
473 assert( sdpisolver != NULL );
475 SCIPdebugMessage(
"Resetting counter of SDP-Interface from %d to 0.\n", sdpisolver->sdpcounter);
476 sdpisolver->sdpcounter = 0;
516 int* sdpconstnblocknonz,
520 SCIP_Real** sdpconstval,
522 int** sdpnblockvarnonz,
532 int* blockindchanges,
544 int* startZnblocknonz,
550 SCIP_Real** startZval,
552 int* startXnblocknonz,
558 SCIP_Real** startXval,
565 return SCIPsdpiSolverLoadAndSolveWithPenalty(sdpisolver, 0.0, TRUE, FALSE, nvars, obj, lb, ub, nsdpblocks, sdpblocksizes, sdpnblockvars, sdpconstnnonz,
566 sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, sdpnnonz, sdpnblockvarnonz, sdpvar, sdprow, sdpcol, sdpval, indchanges,
567 nremovedinds, blockindchanges, nremovedblocks, nlpcons, noldlpcons, lplhs, lprhs, rownactivevars, lpnnonz, lprow, lpcol, lpval,
568 starty, startZnblocknonz, startZrow, startZcol, startZval, startXnblocknonz, startXrow, startXcol, startXval, startsettings,
569 timelimit, NULL, NULL);
596 SCIP_Real penaltyparam,
607 int* sdpconstnblocknonz,
611 SCIP_Real** sdpconstval,
613 int** sdpnblockvarnonz,
623 int* blockindchanges,
635 int* startZnblocknonz,
641 SCIP_Real** startZval,
643 int* startXnblocknonz,
649 SCIP_Real** startXval,
656 SCIP_Bool* penaltybound
668 SCIP_Real* mosekvarbounds;
672 int* vartolhsrhsmapper;
676 int* mosekblocksizes;
683 struct timeval starttime;
684 struct timeval currenttime;
685 SCIP_Real startseconds;
686 SCIP_Real currentseconds;
687 SCIP_Real elapsedtime;
689 #ifdef SCIP_MORE_DEBUG 693 char varname[SCIP_MAXSTRLEN];
695 #if CONVERT_ABSOLUTE_TOLERANCES 696 SCIP_Real maxrhscoef;
699 assert( sdpisolver != NULL );
700 assert( sdpisolver->mskenv != NULL );
701 assert( penaltyparam > -1 * sdpisolver->epsilon );
702 assert( penaltyparam < sdpisolver->epsilon || ( feasorig != NULL ) );
704 assert( obj != NULL );
705 assert( lb != NULL );
706 assert( ub != NULL );
707 assert( nsdpblocks >= 0 );
708 assert( nsdpblocks == 0 || sdpblocksizes != NULL );
709 assert( nsdpblocks == 0 || sdpnblockvars != NULL );
710 assert( sdpconstnnonz >= 0 );
711 assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstnblocknonz != NULL );
712 assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstrow != NULL );
713 assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstcol != NULL );
714 assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstval != NULL );
715 assert( sdpnnonz >= 0 );
716 assert( nsdpblocks == 0 || sdpnblockvarnonz != NULL );
717 assert( nsdpblocks == 0 || sdpvar != NULL );
718 assert( nsdpblocks == 0 || sdprow != NULL );
719 assert( nsdpblocks == 0 || sdpcol != NULL );
720 assert( nsdpblocks == 0 || sdpval != NULL );
721 assert( nsdpblocks == 0 || indchanges != NULL );
722 assert( nsdpblocks == 0 || nremovedinds != NULL );
723 assert( nsdpblocks == 0 || blockindchanges != NULL );
724 assert( 0 <= nremovedblocks && nremovedblocks <= nsdpblocks );
725 assert( nlpcons >= 0 );
726 assert( noldlpcons >= nlpcons );
727 assert( nlpcons == 0 || lplhs != NULL );
728 assert( nlpcons == 0 || lprhs != NULL );
729 assert( nlpcons == 0 || rownactivevars != NULL );
730 assert( lpnnonz >= 0 );
731 assert( nlpcons == 0 || lprow != NULL );
732 assert( nlpcons == 0 || lpcol != NULL );
733 assert( nlpcons == 0 || lpval != NULL );
736 if ( timelimit <= 0.0 )
738 sdpisolver->timelimit = TRUE;
739 sdpisolver->timelimitinitial = TRUE;
740 sdpisolver->solved = FALSE;
743 sdpisolver->timelimit = FALSE;
744 sdpisolver->timelimitinitial = FALSE;
745 sdpisolver->feasorig = FALSE;
751 #if CONVERT_ABSOLUTE_TOLERANCES 756 if ((sdpisolver->msktask) != NULL)
758 MOSEK_CALL( MSK_deletetask(&(sdpisolver->msktask)) );
760 if ( penaltyparam < sdpisolver->epsilon )
762 MOSEK_CALLM( MSK_maketask(sdpisolver->mskenv, nvars, nsdpblocks - nremovedblocks + nlpcons + 2 * nvars, &(sdpisolver->msktask)) );
766 MOSEK_CALLM( MSK_maketask(sdpisolver->mskenv, nvars + 1, nsdpblocks - nremovedblocks + nlpcons + 2 * nvars, &(sdpisolver->msktask)) );
769 #if MSK_VERSION_MAJOR >= 9 770 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_NEAR_REL, NEAR_REL_TOLERANCE) );
773 #ifdef SCIP_MORE_DEBUG 774 MOSEK_CALL( MSK_linkfunctotaskstream (sdpisolver->msktask, MSK_STREAM_LOG, NULL,
printstr) );
777 if ( sdpisolver->sdpinfo )
779 MOSEK_CALL( MSK_linkfunctotaskstream (sdpisolver->msktask, MSK_STREAM_LOG, NULL,
printstr) );
784 if ( sdpisolver->nthreads > 0 )
786 MOSEK_CALL( MSK_putintparam(sdpisolver->msktask, MSK_IPAR_NUM_THREADS, sdpisolver->nthreads) );
791 if ( penaltyparam < sdpisolver->epsilon )
792 SCIPdebugMessage(
"Inserting Data into MOSEK for SDP (%d) \n", ++sdpisolver->sdpcounter);
794 SCIPdebugMessage(
"Inserting Data again into MOSEK for SDP (%d) \n", sdpisolver->sdpcounter);
797 sdpisolver->penalty = (penaltyparam < sdpisolver->epsilon) ? FALSE : TRUE;
798 sdpisolver->rbound = rbound;
802 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->inputtomosekmapper), sdpisolver->nvars, nvars) );
803 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->mosektoinputmapper), sdpisolver->nactivevars, nvars) );
804 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->fixedvarsval), sdpisolver->nvars - sdpisolver->nactivevars, nvars) );
805 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->objcoefs), sdpisolver->nactivevars, nvars) );
807 oldnactivevars = sdpisolver->nactivevars;
808 sdpisolver->nvars = nvars;
809 sdpisolver->nactivevars = 0;
813 sdpisolver->fixedvarsobjcontr = 0.0;
814 for (i = 0; i < nvars; i++)
816 if (
isFixed(sdpisolver, lb[i], ub[i]) )
818 sdpisolver->fixedvarsobjcontr += obj[i] * lb[i];
819 sdpisolver->fixedvarsval[nfixedvars] = lb[i];
821 sdpisolver->inputtomosekmapper[i] = -nfixedvars;
822 SCIPdebugMessage(
"Fixing variable %d locally to %f for SDP %d in MOSEK\n", i, lb[i], sdpisolver->sdpcounter);
826 sdpisolver->mosektoinputmapper[sdpisolver->nactivevars] = i;
827 sdpisolver->inputtomosekmapper[i] = sdpisolver->nactivevars;
828 sdpisolver->objcoefs[sdpisolver->nactivevars] = obj[i];
829 sdpisolver->nactivevars++;
830 #ifdef SCIP_MORE_DEBUG 831 SCIPdebugMessage(
"Variable %d becomes variable %d for SDP %d in MOSEK\n", i, sdpisolver->inputtomosekmapper[i], sdpisolver->sdpcounter);
835 assert( sdpisolver->nactivevars + nfixedvars == sdpisolver->nvars );
839 sdpisolver->fixedvarsobjcontr = 0.0;
842 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->objcoefs), nvars, sdpisolver->nactivevars) );
843 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->fixedvarsval), nvars, nfixedvars) );
844 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->mosektoinputmapper), nvars, sdpisolver->nactivevars) );
847 sdpisolver->nvarbounds = 0;
848 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekvarbounds, 2 * sdpisolver->nactivevars) );
850 if ( sdpisolver->nactivevars != oldnactivevars )
852 if ( sdpisolver->varboundpos == NULL )
854 BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->varboundpos), 2 * sdpisolver->nactivevars) );
858 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->varboundpos), 2 * oldnactivevars, 2 * sdpisolver->nactivevars) );
861 assert( sdpisolver->varboundpos != NULL );
863 for (i = 0; i < sdpisolver->nactivevars; i++)
865 assert( 0 <= sdpisolver->mosektoinputmapper[i] && sdpisolver->mosektoinputmapper[i] < nvars );
868 mosekvarbounds[sdpisolver->nvarbounds] = lb[sdpisolver->mosektoinputmapper[i]];
869 sdpisolver->varboundpos[sdpisolver->nvarbounds] = -(i + 1);
870 (sdpisolver->nvarbounds)++;
874 mosekvarbounds[sdpisolver->nvarbounds] = -1 * ub[sdpisolver->mosektoinputmapper[i]];
875 sdpisolver->varboundpos[sdpisolver->nvarbounds] = +(i + 1);
876 (sdpisolver->nvarbounds)++;
884 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &vartorowmapper, 2*noldlpcons) );
886 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &vartolhsrhsmapper, 2*noldlpcons) );
891 for (i = 0; i < noldlpcons; i++)
893 assert( newpos <= nlpcons );
894 if ( rownactivevars[i] >= 2 )
898 vartorowmapper[pos] = -(i+1);
899 vartolhsrhsmapper[pos] = newpos;
902 #if CONVERT_ABSOLUTE_TOLERANCES 904 if ( REALABS(lplhs[newpos]) > maxrhscoef )
905 maxrhscoef = REALABS(lplhs[newpos]);
911 vartorowmapper[pos] = i+1;
912 vartolhsrhsmapper[pos] = newpos;
915 #if CONVERT_ABSOLUTE_TOLERANCES 917 if ( REALABS(lprhs[newpos]) > maxrhscoef )
918 maxrhscoef = REALABS(lprhs[newpos]);
925 assert( nlpvars <= 2*nlpcons );
931 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekblocksizes, nsdpblocks - nremovedblocks) );
933 for (b = 0; b < nsdpblocks; b++)
935 if ( blockindchanges[b] > -1 )
937 assert( 0 <= blockindchanges[b] && blockindchanges[b] <= b && (b - blockindchanges[b]) <= (nsdpblocks - nremovedblocks) );
938 mosekblocksizes[b - blockindchanges[b]] = sdpblocksizes[b] - nremovedinds[b];
941 MOSEK_CALLM( MSK_appendbarvars(sdpisolver->msktask, nsdpblocks - nremovedblocks, mosekblocksizes) );
945 MOSEK_CALLM( MSK_appendvars(sdpisolver->msktask, nlpvars + sdpisolver->nvarbounds) );
948 for (v = 0; v < nlpvars + sdpisolver->nvarbounds; v++)
950 MOSEK_CALL( MSK_putvarbound(sdpisolver->msktask, v, MSK_BK_LO, 0.0, (
double) MSK_DPAR_DATA_TOL_BOUND_INF) );
954 MOSEK_CALLM( MSK_appendcons(sdpisolver->msktask, (penaltyparam < sdpisolver->epsilon) ? sdpisolver->nactivevars : sdpisolver->nactivevars + 1) );
959 if ( sdpconstnnonz > 0 )
961 for (b = 0; b < nsdpblocks; b++)
963 if ( blockindchanges[b] > -1 )
966 if ( nremovedinds[b] > 0 )
968 int* moseksdpconstrow;
969 int* moseksdpconstcol;
971 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &moseksdpconstrow, sdpconstnblocknonz[b]) );
972 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &moseksdpconstcol, sdpconstnblocknonz[b]) );
974 for (k = 0; k < sdpconstnblocknonz[b]; k++)
977 assert( -1 < indchanges[b][sdpconstrow[b][k]] && indchanges[b][sdpconstrow[b][k]] <= sdpconstrow[b][k] );
978 assert( -1 < indchanges[b][sdpconstcol[b][k]] && indchanges[b][sdpconstcol[b][k]] <= sdpconstcol[b][k] );
980 assert( 0 <= sdpconstrow[b][k] && sdpconstrow[b][k] <= sdpblocksizes[b] );
981 assert( 0 <= sdpconstcol[b][k] && sdpconstcol[b][k] <= sdpblocksizes[b] );
983 moseksdpconstrow[k] = sdpconstrow[b][k] - indchanges[b][sdpconstrow[b][k]];
984 moseksdpconstcol[k] = sdpconstcol[b][k] - indchanges[b][sdpconstcol[b][k]];
986 #if CONVERT_ABSOLUTE_TOLERANCES 988 if ( REALABS(sdpconstval[b][k]) > maxrhscoef )
989 maxrhscoef = REALABS(sdpconstval[b][k]);
993 MOSEK_CALL( MSK_appendsparsesymmat(sdpisolver->msktask, mosekblocksizes[b - blockindchanges[b]], sdpconstnblocknonz[b],
994 moseksdpconstrow, moseksdpconstcol, sdpconstval[b], &ind) );
996 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &moseksdpconstcol);
997 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &moseksdpconstrow);
1001 MOSEK_CALL( MSK_appendsparsesymmat(sdpisolver->msktask, mosekblocksizes[b - blockindchanges[b]], sdpconstnblocknonz[b],
1002 sdpconstrow[b], sdpconstcol[b], sdpconstval[b], &ind) );
1004 MOSEK_CALL( MSK_putbarcj(sdpisolver->msktask, i, 1, &ind, &one) );
1013 for (i = 0; i < nlpvars; i++)
1015 assert( vartolhsrhsmapper != NULL );
1016 if ( vartorowmapper[i] > 0 )
1018 MOSEK_CALL( MSK_putcj(sdpisolver->msktask, i, -1 * lprhs[vartolhsrhsmapper[i]]) );
1019 #ifdef SCIP_MORE_DEBUG 1021 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN,
"rhs-%d", vartorowmapper[i] - 1);
1022 MOSEK_CALL( MSK_putvarname ( sdpisolver->msktask, i, varname) );
1027 assert( vartorowmapper[i] < 0 );
1028 MOSEK_CALL( MSK_putcj(sdpisolver->msktask, i, lplhs[vartolhsrhsmapper[i]]) );
1029 #ifdef SCIP_MORE_DEBUG 1031 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN,
"lhs-%d", -1 * vartorowmapper[i] - 1);
1032 MOSEK_CALL( MSK_putvarname ( sdpisolver->msktask, i, varname) );
1038 for (i = 0; i < sdpisolver->nvarbounds; i++)
1040 MOSEK_CALL( MSK_putcj(sdpisolver->msktask, nlpvars + i, mosekvarbounds[i]) );
1041 #ifdef SCIP_MORE_DEBUG 1042 if ( sdpisolver->varboundpos[i] < 0 )
1045 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN,
"lb-%d", sdpisolver->mosektoinputmapper[-1 * sdpisolver->varboundpos[i] - 1]);
1046 MOSEK_CALL( MSK_putvarname ( sdpisolver->msktask, nlpvars + i, varname) );
1050 assert( sdpisolver->varboundpos[i] > 0 );
1052 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN,
"ub-%d", sdpisolver->mosektoinputmapper[sdpisolver->varboundpos[i] - 1]);
1053 MOSEK_CALL( MSK_putvarname ( sdpisolver->msktask, nlpvars + i, varname) );
1058 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &mosekvarbounds);
1061 MOSEK_CALL( MSK_putobjsense(sdpisolver->msktask, MSK_OBJECTIVE_SENSE_MAXIMIZE) );
1066 for (b = 0; b < nsdpblocks; b++)
1068 if ( blockindchanges[b] > -1 )
1070 for (blockvar = 0; blockvar < sdpnblockvars[b]; blockvar++)
1072 v = sdpisolver->inputtomosekmapper[sdpvar[b][blockvar]];
1077 assert( v < sdpisolver->nactivevars );
1079 if ( nremovedinds[b] > 0 )
1081 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekrow, sdpnblockvarnonz[b][blockvar]) );
1082 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekcol, sdpnblockvarnonz[b][blockvar]) );
1084 for (k = 0; k < sdpnblockvarnonz[b][blockvar]; k++)
1087 assert( -1 < indchanges[b][sdprow[b][blockvar][k]] && indchanges[b][sdprow[b][blockvar][k]] <= sdprow[b][blockvar][k] );
1088 assert( -1 < indchanges[b][sdpcol[b][blockvar][k]] && indchanges[b][sdpcol[b][blockvar][k]] <= sdpcol[b][blockvar][k] );
1090 assert( 0 <= sdprow[b][blockvar][k] && sdprow[b][blockvar][k] < sdpblocksizes[b] );
1091 assert( 0 <= sdpcol[b][blockvar][k] && sdpcol[b][blockvar][k] < sdpblocksizes[b] );
1093 mosekrow[k] = sdprow[b][blockvar][k] - indchanges[b][sdprow[b][blockvar][k]];
1094 mosekcol[k] = sdpcol[b][blockvar][k] - indchanges[b][sdpcol[b][blockvar][k]];
1097 MOSEK_CALL( MSK_appendsparsesymmat(sdpisolver->msktask, mosekblocksizes[b - blockindchanges[b]], (
long long) sdpnblockvarnonz[b][blockvar],
1098 mosekrow, mosekcol, sdpval[b][blockvar], &ind) );
1100 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &mosekcol);
1101 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &mosekrow);
1105 MOSEK_CALL( MSK_appendsparsesymmat(sdpisolver->msktask, mosekblocksizes[b - blockindchanges[b]], (
long long) sdpnblockvarnonz[b][blockvar],
1106 sdprow[b][blockvar], sdpcol[b][blockvar], sdpval[b][blockvar], &ind) );
1109 MOSEK_CALL( MSK_putbaraij(sdpisolver->msktask, v, b - blockindchanges[b], (
long long) 1, &ind, &one) );
1116 if ( penaltyparam >= sdpisolver->epsilon )
1118 int* identityindices;
1119 SCIP_Real* identityvalues;
1121 for (b = 0; b < nsdpblocks; b++)
1123 if ( blockindchanges[b] > -1 )
1125 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &identityindices, mosekblocksizes[b - blockindchanges[b]]) );
1126 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &identityvalues, mosekblocksizes[b - blockindchanges[b]]) );
1128 for (i = 0; i < mosekblocksizes[b - blockindchanges[b]]; i++)
1130 identityindices[i] = i;
1131 identityvalues[i] = 1.0;
1133 MOSEK_CALL( MSK_appendsparsesymmat(sdpisolver->msktask, mosekblocksizes[b - blockindchanges[b]], (
long long) mosekblocksizes[b - blockindchanges[b]],
1134 identityindices, identityindices, identityvalues, &ind) );
1135 MOSEK_CALL( MSK_putbaraij(sdpisolver->msktask, sdpisolver->nactivevars, b - blockindchanges[b], (
long long) 1, &ind, &one) );
1137 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &identityvalues);
1138 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &identityindices);
1144 if ( penaltyparam < sdpisolver->epsilon )
1146 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekrow, lpnnonz) );
1147 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekval, lpnnonz) );
1152 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekrow, lpnnonz + 1) );
1153 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekval, lpnnonz + 1) );
1157 for (i = 0; i < nlpvars; i++)
1159 assert( vartorowmapper != NULL );
1160 if ( vartorowmapper[i] < 0 )
1165 while (ind < lpnnonz && lprow[ind] < -1 * vartorowmapper[i] - 1)
1168 while (ind < lpnnonz && lprow[ind] == -1 * vartorowmapper[i] - 1)
1170 v = sdpisolver->inputtomosekmapper[lpcol[ind]];
1173 mosekrow[mosekind] = v;
1174 mosekval[mosekind] = lpval[ind];
1179 assert( mosekind <= lpnnonz );
1183 assert( vartorowmapper[i] > 0 );
1185 if ( i > 0 && vartorowmapper[i] == -1 * vartorowmapper[i - 1] )
1189 for (j = 0; j < (penaltyparam < sdpisolver->epsilon ? mosekind : mosekind - 1); j++)
1198 while (lprow[ind] < vartorowmapper[i] - 1)
1200 while (ind < lpnnonz && lprow[ind] == vartorowmapper[i] - 1)
1202 v = sdpisolver->inputtomosekmapper[lpcol[ind]];
1205 mosekrow[mosekind] = v;
1206 mosekval[mosekind] = -1 * lpval[ind];
1211 assert( mosekind <= lpnnonz );
1216 if ( penaltyparam >= sdpisolver->epsilon )
1220 if ( ! (i > 0 && vartorowmapper[i] == -1 * vartorowmapper[i - 1] ))
1222 mosekrow[mosekind] = sdpisolver->nactivevars;
1223 mosekval[mosekind] = 1.0;
1226 assert( mosekind <= lpnnonz + 1 );
1229 MOSEK_CALL( MSK_putacol(sdpisolver->msktask, i, mosekind, mosekrow, mosekval) );
1232 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &mosekval);
1233 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &mosekrow);
1236 for (i = 0; i < sdpisolver->nvarbounds; i++)
1238 if ( sdpisolver->varboundpos[i] < 0 )
1241 row =-1 * sdpisolver->varboundpos[i] - 1;
1247 assert( sdpisolver->varboundpos[i] > 0 );
1248 row = sdpisolver->varboundpos[i] - 1;
1251 MOSEK_CALL( MSK_putacol(sdpisolver->msktask, nlpvars + i, 1, &row, &val) );
1255 for (i = 0; i < sdpisolver->nactivevars; i++)
1259 MOSEK_CALL( MSK_putconbound(sdpisolver->msktask, i, MSK_BK_FX, obj[sdpisolver->mosektoinputmapper[i]], obj[sdpisolver->mosektoinputmapper[i]]) );
1263 MOSEK_CALL( MSK_putconbound(sdpisolver->msktask, i, MSK_BK_FX, 0.0, 0.0) );
1265 #ifdef SCIP_MORE_DEBUG 1267 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN,
"var-%d", sdpisolver->mosektoinputmapper[i]);
1268 MOSEK_CALL( MSK_putconname ( sdpisolver->msktask, i, varname) );
1273 if ( penaltyparam >= sdpisolver->epsilon )
1277 MOSEK_CALL( MSK_putconbound(sdpisolver->msktask, sdpisolver->nactivevars, MSK_BK_UP, (
double) -1 * MSK_DPAR_DATA_TOL_BOUND_INF, penaltyparam) );
1281 MOSEK_CALL( MSK_putconbound(sdpisolver->msktask, sdpisolver->nactivevars, MSK_BK_FX, penaltyparam, penaltyparam) );
1286 #ifdef SCIP_DEBUG_PRINTTOFILE 1291 #ifdef SCIP_MORE_DEBUG 1292 #if MSK_VERSION_MAJOR < 9 1293 MOSEK_CALL( MSK_getnumcon (sdpisolver->msktask, &nmosekconss) );
1294 MOSEK_CALL( MSK_getnumvar (sdpisolver->msktask, &nmosekvars) );
1295 MOSEK_CALL( MSK_getnumcone (sdpisolver->msktask, &nmosekcones) );
1297 MOSEK_CALL( MSK_printdata (sdpisolver->msktask, MSK_STREAM_LOG, 0, nmosekconss, 0, nmosekvars, 0, nmosekcones, 1, 1, 1, 1, 1, 1, 1, 1) );
1298 #ifdef SCIP_PRINT_PARAMETERS 1299 MOSEK_CALL( MSK_printparam (sdpisolver->msktask) );
1305 startseconds = (SCIP_Real) starttime.tv_sec + (SCIP_Real) starttime.tv_usec / 1e6;
1308 currentseconds = (SCIP_Real) currenttime.tv_sec + (SCIP_Real) currenttime.tv_usec / 1e6;
1310 elapsedtime = currentseconds - startseconds;
1312 if ( timelimit <= elapsedtime )
1314 sdpisolver->timelimit = TRUE;
1315 sdpisolver->solved = FALSE;
1324 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_PFEAS, sdpisolver->gaptol) );
1325 #if CONVERT_ABSOLUTE_TOLERANCES 1326 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_DFEAS, sdpisolver->sdpsolverfeastol / (1 + maxrhscoef)) );
1327 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_INFEAS, sdpisolver->sdpsolverfeastol / (1 + maxrhscoef)) );
1328 SCIPdebugMessage(
"Setting relative feasibility tolerance for MOSEK to %.10f / %f = %.12f\n", sdpisolver->sdpsolverfeastol,
1329 1+maxrhscoef, sdpisolver->sdpsolverfeastol / (1 + maxrhscoef));
1331 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_DFEAS, sdpisolver->sdpsolverfeastol) );
1332 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_INFEAS, sdpisolver->sdpsolverfeastol) );
1334 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_MU_RED, sdpisolver->gaptol) );
1335 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_REL_GAP, sdpisolver->gaptol) );
1339 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_OPTIMIZER_MAX_TIME, timelimit - elapsedtime) );
1345 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_UPPER_OBJ_CUT, sdpisolver->objlimit) );
1349 MOSEK_CALL( MSK_optimizetrm(sdpisolver->msktask, &(sdpisolver->terminationcode)) );
1351 if ( sdpisolver->sdpinfo )
1353 MOSEK_CALL( MSK_optimizersummary(sdpisolver->msktask, MSK_STREAM_LOG) );
1354 MOSEK_CALL( MSK_analyzesolution(sdpisolver->msktask, MSK_STREAM_LOG, MSK_SOL_ITR) );
1357 SCIPdebugMessage(
"Solving problem using MOSEK, return code %d\n", sdpisolver->terminationcode);
1359 sdpisolver->solved = TRUE;
1361 sdpisolver->nsdpcalls = 1;
1362 MOSEK_CALL( MSK_getnaintinf(sdpisolver->msktask,
"MSK_IINF_INTPNT_ITER", &(sdpisolver->niterations)) );
1366 #if CONVERT_ABSOLUTE_TOLERANCES 1367 feastol = sdpisolver->sdpsolverfeastol / (1 + maxrhscoef);
1369 feastol = sdpisolver->sdpsolverfeastol;
1374 SCIP_Real* solvector;
1376 SCIP_Bool infeasible;
1380 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &solvector, nvars) );
1381 nvarspointer = nvars;
1383 assert( nvarspointer == nvars );
1386 SCIP_CALL(
SCIPsdpSolcheckerCheck(sdpisolver->bufmem, nvars, lb, ub, nsdpblocks, sdpblocksizes, sdpnblockvars, sdpconstnnonz,
1387 sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, sdpnnonz, sdpnblockvarnonz, sdpvar, sdprow, sdpcol, sdpval,
1388 indchanges, nremovedinds, blockindchanges, nlpcons, noldlpcons, lplhs, lprhs, rownactivevars, lpnnonz, lprow, lpcol, lpval,
1389 solvector, sdpisolver->feastol, sdpisolver->epsilon, &infeasible) );
1391 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &solvector);
1395 SCIPdebugMessage(
"Solution feasible for MOSEK but outside feasibility tolerance, changing MOSEK feasibility tolerance from %f to %f\n",
1402 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_DFEAS, feastol) );
1403 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_INFEAS, feastol) );
1406 startseconds = (SCIP_Real) starttime.tv_sec + (SCIP_Real) starttime.tv_usec / 1e6;
1409 currentseconds = (SCIP_Real) currenttime.tv_sec + (SCIP_Real) currenttime.tv_usec / 1e6;
1411 elapsedtime = currentseconds - startseconds;
1413 if ( timelimit <= elapsedtime )
1415 sdpisolver->timelimit = TRUE;
1416 sdpisolver->solved = FALSE;
1420 MOSEK_CALL( MSK_optimizetrm(sdpisolver->msktask, &(sdpisolver->terminationcode)) );
1422 if ( sdpisolver->sdpinfo )
1424 MOSEK_CALL( MSK_optimizersummary(sdpisolver->msktask, MSK_STREAM_LOG) );
1425 MOSEK_CALL( MSK_analyzesolution(sdpisolver->msktask, MSK_STREAM_LOG, MSK_SOL_ITR) );
1429 sdpisolver->nsdpcalls++;
1430 MOSEK_CALL( MSK_getnaintinf(sdpisolver->msktask,
"MSK_IINF_INTPNT_ITER", &newiterations) );
1431 sdpisolver->niterations += newiterations;
1435 sdpisolver->solved = FALSE;
1436 SCIPmessagePrintInfo(sdpisolver->messagehdlr,
"MOSEK failed to reach required feasibility tolerance! \n");
1447 MOSEK_CALL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1448 if ( penaltyparam >= sdpisolver->epsilon && (solstat == MSK_SOL_STA_PRIM_INFEAS_CER) )
1450 assert( feasorig != NULL );
1452 SCIPdebugMessage(
"Penalty Problem unbounded!\n");
1454 else if ( penaltyparam >= sdpisolver->epsilon && ( ! sdpisolver->timelimit ) && ( sdpisolver->terminationcode != MSK_RES_TRM_MAX_TIME ) )
1456 SCIP_Real* moseksol;
1457 SCIP_Real trace = 0.0;
1460 assert( feasorig != NULL );
1463 BMSallocBufferMemoryArray(sdpisolver->bufmem, &moseksol, sdpisolver->nactivevars + 1);
1465 MOSEK_CALL( MSK_gety(sdpisolver->msktask, MSK_SOL_ITR, moseksol) );
1467 *feasorig = (moseksol[sdpisolver->nactivevars] < sdpisolver->feastol);
1472 sdpisolver->feasorig = *feasorig;
1475 if ( ! *feasorig && penaltybound != NULL )
1478 SCIPdebugMessage(
"Solution not feasible in original problem, r = %f\n", moseksol[sdpisolver->nactivevars]);
1483 for (b = 0; b < nsdpblocks; b++)
1485 if ( blockindchanges[b] > -1 )
1490 size = sdpblocksizes[b] - nremovedinds[b];
1492 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &X, 0.5 * size * (size + 1)) );
1493 MOSEK_CALL( MSK_getbarxj(sdpisolver->msktask, MSK_SOL_ITR, b - blockindchanges[b], X) );
1496 for (i = 0; i < size; i++)
1499 ind = i * (i + 3) / 2;
1500 assert( ind < 0.5 * size * (size + 1) );
1504 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &X);
1509 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &x, nlpvars + sdpisolver->nvarbounds) );
1511 MOSEK_CALL( MSK_getxx(sdpisolver->msktask, MSK_SOL_ITR, x) );
1513 for (i = 0; i < nlpvars; i++)
1516 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &x);
1521 assert( penaltybound != NULL );
1522 *penaltybound = TRUE;
1523 SCIPdebugMessage(
"Tr(X) = %f == %f = Gamma, penalty formulation not exact, Gamma should be increased or problem is infeasible\n",
1524 trace, penaltyparam);
1527 *penaltybound = FALSE;
1529 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &moseksol);
1533 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &mosekblocksizes);
1536 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &vartolhsrhsmapper);
1537 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &vartorowmapper);
1559 assert( sdpisolver != NULL );
1561 return sdpisolver->solved;
1576 assert( sdpisolver != NULL );
1579 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1583 case MSK_SOL_STA_UNKNOWN:
1584 case MSK_SOL_STA_PRIM_FEAS:
1585 case MSK_SOL_STA_DUAL_FEAS:
1587 case MSK_SOL_STA_OPTIMAL:
1588 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1589 case MSK_SOL_STA_PRIM_INFEAS_CER:
1590 case MSK_SOL_STA_DUAL_INFEAS_CER:
1593 SCIPdebugMessage(
"Unknown return code in SCIPsdpiSolverFeasibilityKnown\n");
1601 SCIP_Bool* primalfeasible,
1602 SCIP_Bool* dualfeasible
1607 assert( sdpisolver != NULL );
1608 assert( primalfeasible != NULL );
1609 assert( dualfeasible != NULL );
1612 MOSEK_CALL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1616 case MSK_SOL_STA_OPTIMAL:
1617 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1618 *primalfeasible = TRUE;
1619 *dualfeasible = TRUE;
1621 case MSK_SOL_STA_PRIM_INFEAS_CER:
1622 *primalfeasible = FALSE;
1623 *dualfeasible = TRUE;
1625 case MSK_SOL_STA_DUAL_INFEAS_CER:
1626 *primalfeasible = TRUE;
1627 *dualfeasible = FALSE;
1630 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1631 return SCIP_LPERROR;
1646 assert( sdpisolver != NULL );
1649 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1653 case MSK_SOL_STA_DUAL_INFEAS_CER:
1655 case MSK_SOL_STA_OPTIMAL:
1656 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1657 case MSK_SOL_STA_PRIM_INFEAS_CER:
1660 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1675 assert( sdpisolver != NULL );
1678 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1682 case MSK_SOL_STA_PRIM_INFEAS_CER:
1684 case MSK_SOL_STA_OPTIMAL:
1685 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1686 case MSK_SOL_STA_DUAL_INFEAS_CER:
1689 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1704 assert( sdpisolver != NULL );
1707 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1711 case MSK_SOL_STA_OPTIMAL:
1712 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1713 case MSK_SOL_STA_DUAL_INFEAS_CER:
1715 case MSK_SOL_STA_PRIM_INFEAS_CER:
1718 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1733 assert( sdpisolver != NULL );
1736 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1740 case MSK_SOL_STA_PRIM_INFEAS_CER:
1742 case MSK_SOL_STA_OPTIMAL:
1743 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1744 case MSK_SOL_STA_DUAL_INFEAS_CER:
1747 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1762 assert( sdpisolver != NULL );
1765 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1769 case MSK_SOL_STA_DUAL_INFEAS_CER:
1771 case MSK_SOL_STA_OPTIMAL:
1772 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1773 case MSK_SOL_STA_PRIM_INFEAS_CER:
1776 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1791 assert( sdpisolver != NULL );
1794 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1798 case MSK_SOL_STA_OPTIMAL:
1799 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1800 case MSK_SOL_STA_PRIM_INFEAS_CER:
1802 case MSK_SOL_STA_DUAL_INFEAS_CER:
1805 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1816 assert( sdpisolver != NULL );
1818 if ( sdpisolver->timelimit )
1824 if ( sdpisolver->terminationcode == MSK_RES_TRM_STALL )
1829 SCIP_Real gapnormalization;
1831 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1836 case MSK_SOL_STA_UNKNOWN:
1837 case MSK_SOL_STA_PRIM_FEAS:
1838 case MSK_SOL_STA_DUAL_FEAS:
1840 case MSK_SOL_STA_OPTIMAL:
1841 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1842 case MSK_SOL_STA_PRIM_INFEAS_CER:
1843 case MSK_SOL_STA_DUAL_INFEAS_CER:
1845 MOSEK_CALL_BOOL( MSK_getdualobj(sdpisolver->msktask, MSK_SOL_ITR, &dobj) );
1846 MOSEK_CALL_BOOL( MSK_getprimalobj(sdpisolver->msktask, MSK_SOL_ITR, &pobj) );
1848 gapnormalization = dobj > pobj ? (pobj > 1.0 ? pobj : 1.0) : (dobj > 1.0 ? dobj : 1.0);
1849 if ( REALABS((pobj-dobj) / gapnormalization) < sdpisolver->gaptol )
1858 return sdpisolver->terminationcode == MSK_RES_OK;
1866 assert( sdpisolver != NULL );
1869 return sdpisolver->terminationcode == MSK_RES_TRM_OBJECTIVE_RANGE;
1877 assert( sdpisolver != NULL );
1880 return sdpisolver->terminationcode == MSK_RES_TRM_MAX_ITERATIONS;
1888 assert( sdpisolver != NULL );
1890 if ( sdpisolver->timelimit )
1893 if ( ! sdpisolver->solved )
1896 return sdpisolver->terminationcode == MSK_RES_TRM_MAX_TIME;
1914 assert( sdpisolver != NULL );
1916 if ( ! sdpisolver->solved )
1919 if ( sdpisolver->timelimit )
1922 switch ( sdpisolver->terminationcode )
1926 case MSK_RES_TRM_MAX_NUM_SETBACKS:
1927 case MSK_RES_TRM_NUMERICAL_PROBLEM:
1928 case MSK_RES_TRM_STALL:
1930 case MSK_RES_TRM_OBJECTIVE_RANGE:
1932 case MSK_RES_TRM_MAX_ITERATIONS:
1934 case MSK_RES_TRM_MAX_TIME:
1948 assert( sdpisolver != NULL );
1950 if ( sdpisolver->timelimit )
1955 if ( sdpisolver->terminationcode != MSK_RES_OK )
1958 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1960 if ( solstat != MSK_SOL_STA_OPTIMAL )
1973 assert( sdpisolver != NULL );
1975 if ( sdpisolver->timelimit )
1978 if ( ! sdpisolver->solved )
1990 SCIPdebugMessage(
"Not implemented yet\n");
1991 return SCIP_LPERROR;
2000 SCIP_Real* moseksol;
2002 assert( sdpisolver != NULL );
2004 assert( objval != NULL );
2013 if ( sdpisolver->penalty && ( ! sdpisolver->feasorig ) )
2017 MOSEK_CALL( MSK_getdualobj(sdpisolver->msktask, MSK_SOL_ITR, objval) );
2025 BMSallocBufferMemoryArray(sdpisolver->bufmem, &moseksol, sdpisolver->penalty ? sdpisolver->nactivevars + 1 : sdpisolver->nactivevars);
2026 MOSEK_CALL( MSK_gety(sdpisolver->msktask, MSK_SOL_ITR, moseksol) );
2029 for (v = 0; v < sdpisolver->nactivevars; v++)
2030 *objval += moseksol[v] * sdpisolver->objcoefs[v];
2034 *objval += sdpisolver->fixedvarsobjcontr;
2036 if ( ( ! sdpisolver->penalty ) || sdpisolver->feasorig)
2038 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &moseksol);
2057 SCIP_Real* moseksol;
2059 assert( sdpisolver != NULL );
2061 assert( dualsollength != NULL );
2063 if ( *dualsollength > 0 )
2065 assert( dualsol != NULL );
2066 if ( *dualsollength < sdpisolver->nvars )
2068 SCIPdebugMessage(
"The given array in SCIPsdpiSolverGetSol only had length %d, but %d was needed", *dualsollength, sdpisolver->nvars);
2069 *dualsollength = sdpisolver->nvars;
2074 BMSallocBufferMemoryArray(sdpisolver->bufmem, &moseksol, sdpisolver->penalty ? sdpisolver->nactivevars + 1 : sdpisolver->nactivevars);
2076 MOSEK_CALL( MSK_gety(sdpisolver->msktask, MSK_SOL_ITR, moseksol) );
2079 for (v = 0; v < sdpisolver->nvars; v++)
2081 if ( sdpisolver->inputtomosekmapper[v] >= 0 )
2082 dualsol[v] = moseksol[sdpisolver->inputtomosekmapper[v]];
2086 assert( -sdpisolver->inputtomosekmapper[v] <= sdpisolver->nvars - sdpisolver->nactivevars );
2087 dualsol[v] = sdpisolver->fixedvarsval[(-1 * sdpisolver->inputtomosekmapper[v]) - 1];
2092 if ( objval != NULL )
2094 if ( sdpisolver->penalty && ( ! sdpisolver->feasorig ))
2098 MOSEK_CALL( MSK_getdualobj(sdpisolver->msktask, MSK_SOL_ITR, objval) );
2105 for (v = 0; v < sdpisolver->nactivevars; v++)
2106 *objval += moseksol[v] * sdpisolver->objcoefs[v];
2110 *objval += sdpisolver->fixedvarsobjcontr;
2113 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &moseksol);
2115 else if ( objval != NULL )
2127 int* startXnblocknonz
2131 SCIPdebugMessage(
"Not implemented yet\n");
2133 return SCIP_PLUGINNOTFOUND;
2150 int* startXnblocknonz,
2154 SCIP_Real** startXval
2157 SCIPdebugMessage(
"Not implemented yet\n");
2158 return SCIP_LPERROR;
2176 SCIP_Real* primalvars;
2180 assert( sdpisolver != NULL );
2182 assert( arraylength != NULL );
2183 assert( lbvars != NULL );
2184 assert( ubvars != NULL );
2187 if ( *arraylength < sdpisolver->nvars )
2189 *arraylength = sdpisolver->nvars;
2190 SCIPdebugMessage(
"Insufficient length of array in SCIPsdpiSolverGetPrimalBoundVars (gave %d, needed %d)\n", *arraylength, sdpisolver->nvars);
2195 for (i = 0; i < sdpisolver->nvars; i++)
2202 MOSEK_CALL( MSK_getnumvar(sdpisolver->msktask, &nprimalvars) );
2204 BMSallocBufferMemoryArray(sdpisolver->bufmem, &primalvars, nprimalvars);
2206 MOSEK_CALL( MSK_getxx(sdpisolver->msktask, MSK_SOL_ITR, primalvars) );
2209 assert( sdpisolver->nvarbounds <= 2 * sdpisolver->nvars );
2211 for (i = 0; i < sdpisolver->nvarbounds; i++)
2213 if ( sdpisolver->varboundpos[i] < 0 )
2217 lbvars[sdpisolver->mosektoinputmapper[-1 * sdpisolver->varboundpos[i] -1]] = primalvars[nprimalvars - sdpisolver->nvarbounds + i];
2223 assert( sdpisolver->varboundpos[i] > 0 );
2226 ubvars[sdpisolver->mosektoinputmapper[sdpisolver->varboundpos[i] - 1]] = primalvars[nprimalvars - sdpisolver->nvarbounds + i];
2230 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &primalvars);
2239 int* startXnblocknonz
2242 SCIPdebugMessage(
"Not implemented yet\n");
2243 return SCIP_LPERROR;
2255 int* startXnblocknonz,
2259 SCIP_Real** startXval
2262 SCIPdebugMessage(
"Not implemented yet\n");
2263 return SCIP_LPERROR;
2271 SCIPdebugMessage(
"Not implemented yet\n");
2272 return SCIP_INVALID;
2281 if ( sdpisolver->timelimitinitial )
2285 *iterations = sdpisolver->niterations;
2297 assert( calls != NULL );
2299 *calls = sdpisolver->timelimitinitial ? 0 : sdpisolver->nsdpcalls;
2310 assert( sdpisolver != NULL );
2311 assert( usedsetting != NULL );
2315 else if ( sdpisolver->penalty )
2359 assert( sdpisolver != NULL );
2360 assert( dval != NULL );
2365 *dval = sdpisolver->epsilon;
2368 *dval = sdpisolver->gaptol;
2371 *dval = sdpisolver->feastol;
2374 *dval = sdpisolver->sdpsolverfeastol;
2377 *dval = sdpisolver->objlimit;
2380 return SCIP_PARAMETERUNKNOWN;
2393 assert( sdpisolver != NULL );
2398 sdpisolver->epsilon = dval;
2399 SCIPdebugMessage(
"Setting sdpisolver epsilon to %f.\n", dval);
2402 sdpisolver->gaptol = dval;
2403 SCIPdebugMessage(
"Setting sdpisolver gaptol to %f.\n", dval);
2406 sdpisolver->feastol = dval;
2407 SCIPdebugMessage(
"Setting sdpisolver feastol to %f.\n", dval);
2410 sdpisolver->sdpsolverfeastol = dval;
2411 SCIPdebugMessage(
"Setting sdpisolver sdpsolverfeastol to %f.\n", dval);
2414 SCIPdebugMessage(
"Setting sdpisolver objlimit to %f.\n", dval);
2415 sdpisolver->objlimit = dval;
2418 return SCIP_PARAMETERUNKNOWN;
2431 assert( sdpisolver != NULL );
2436 *ival = (int) sdpisolver->sdpinfo;
2437 SCIPdebugMessage(
"Getting sdpisolver information output (%d).\n", *ival);
2440 *ival = sdpisolver->nthreads;
2441 SCIPdebugMessage(
"Getting sdpisolver number of threads: %d.\n", *ival);
2444 return SCIP_PARAMETERUNKNOWN;
2457 assert( sdpisolver != NULL );
2462 sdpisolver->nthreads = ival;
2463 SCIPdebugMessage(
"Setting sdpisolver number of threads to %d.\n", ival);
2466 assert( 0 <= ival && ival <= 1 );
2467 sdpisolver->sdpinfo = (SCIP_Bool) ival;
2468 SCIPdebugMessage(
"Setting sdpisolver information output (%d).\n", ival);
2471 return SCIP_PARAMETERUNKNOWN;
2483 SCIPdebugMessage(
"Lambdastar parameter not used by MOSEK");
2492 SCIP_Real* penaltyparam
2497 assert( sdpisolver != NULL );
2498 assert( penaltyparam != NULL );
2514 SCIPdebugMessage(
"Setting penaltyparameter to %f.\n", compval);
2515 *penaltyparam = compval;
2523 SCIP_Real penaltyparam,
2524 SCIP_Real* maxpenaltyparam
2529 assert( sdpisolver != NULL );
2530 assert( maxpenaltyparam != NULL );
2536 *maxpenaltyparam = compval;
2537 SCIPdebugMessage(
"Setting maximum penaltyparameter to %f.\n", compval);
2566 SCIPdebugMessage(
"Not implemented yet\n");
2567 return SCIP_LPERROR;
2576 assert( sdpisolver != NULL );
2577 assert( fname != NULL );
2579 MOSEK_CALL( MSK_writedata(sdpisolver->msktask, fname) );
SCIP_RETCODE SCIPsdpiSolverCreate(SCIP_SDPISOLVER **sdpisolver, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem)
SCIP_Real SCIPsdpiSolverInfinity(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverIncreaseCounter(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverComputeLambdastar(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxguess)
SCIP_Bool SCIPsdpiSolverWasSolved(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverReadSDP(SCIP_SDPISOLVER *sdpisolver, const char *fname)
#define PENALTYPARAM_FACTOR
SCIP_Bool SCIPsdpiSolverIsConverged(SCIP_SDPISOLVER *sdpisolver)
#define CHECK_IF_SOLVED(sdpisolver)
enum SCIP_SDPSolverSetting SCIP_SDPSOLVERSETTING
SCIP_RETCODE SCIPsdpiSolverResetCounter(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiSolverIsDualFeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverIgnoreInstability(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *success)
int SCIPsdpiSolverGetInternalStatus(SCIP_SDPISOLVER *sdpisolver)
void * SCIPsdpiSolverGetSolverPointer(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverWriteSDP(SCIP_SDPISOLVER *sdpisolver, const char *fname)
interface methods for specific SDP-solvers
SCIP_RETCODE SCIPsdpiSolverComputeMaxPenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Real *maxpenaltyparam)
SCIP_Bool SCIPsdpiSolverIsInfinity(SCIP_SDPISOLVER *sdpisolver, SCIP_Real val)
SCIP_Bool SCIPsdpiSolverIsPrimalFeasible(SCIP_SDPISOLVER *sdpisolver)
#define MAX_MAXPENALTYPARAM
SCIP_RETCODE SCIPsdpiSolverSettingsUsed(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPSOLVERSETTING *usedsetting)
SCIP_RETCODE SCIPsdpiSolverFree(SCIP_SDPISOLVER **sdpisolver)
#define MAXPENALTYPARAM_FACTOR
#define MOSEK_CALL_BOOL(x)
SCIP_Bool SCIPsdpiSolverIsPrimalUnbounded(SCIP_SDPISOLVER *sdpisolver)
#define TIMEOFDAY_CALL(x)
SCIP_RETCODE SCIPsdpiSolverGetIterations(SCIP_SDPISOLVER *sdpisolver, int *iterations)
SCIP_RETCODE SCIPsdpiSolverGetPrimalMatrix(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
SCIP_RETCODE SCIPsdpiSolverLoadAndSolve(SCIP_SDPISOLVER *sdpisolver, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, int noldlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int *rownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit)
SCIP_RETCODE SCIPsdpiSolverComputePenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxcoeff, SCIP_Real *penaltyparam)
SCIP_RETCODE SCIPsdpiSolverSetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int ival)
SCIP_Bool SCIPsdpiSolverIsPrimalInfeasible(SCIP_SDPISOLVER *sdpisolver)
int SCIPsdpiSolverGetDefaultSdpiSolverNpenaltyIncreases(void)
SCIP_Bool SCIPsdpiSolverIsOptimal(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpSolcheckerCheck(BMS_BUFMEM *bufmem, int nvars, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nlpcons, int noldlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int *rownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *solvector, SCIP_Real feastol, SCIP_Real epsilon, SCIP_Bool *infeasible)
#define INFEASFEASTOLCHANGE
SCIP_Real SCIPsdpiSolverGetDefaultSdpiSolverGaptol(void)
SCIP_RETCODE SCIPsdpiSolverGetSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
SCIP_RETCODE SCIPsdpiSolverGetObjval(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval)
checks a given SDP solution for feasibility
static void MSKAPI printstr(void *handle, MSKCONST char str[])
const char * SCIPsdpiSolverGetSolverDesc(void)
SCIP_RETCODE SCIPsdpiSolverGetPreoptimalPrimalNonzeros(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz)
SCIP_Real SCIPsdpiSolverGetDefaultSdpiSolverFeastol(void)
SCIP_Bool SCIPsdpiSolverIsObjlimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetPrimalNonzeros(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz)
static SCIP_Bool isFixed(SCIP_SDPISOLVER *sdpisolver, SCIP_Real lb, SCIP_Real ub)
SCIP_RETCODE SCIPsdpiSolverGetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real *dval)
SCIP_Bool SCIPsdpiSolverIsDualInfeasible(SCIP_SDPISOLVER *sdpisolver)
#define CHECK_IF_SOLVED_BOOL(sdpisolver)
SCIP_Bool SCIPsdpiSolverIsIterlimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_Real SCIPsdpiSolverGetMaxPrimalEntry(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetPrimalBoundVars(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
const char * SCIPsdpiSolverGetSolverName(void)
SCIP_RETCODE SCIPsdpiSolverGetSdpCalls(SCIP_SDPISOLVER *sdpisolver, int *calls)
SCIP_RETCODE SCIPsdpiSolverGetSolFeasibility(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
SCIP_Bool SCIPsdpiSolverIsAcceptable(SCIP_SDPISOLVER *sdpisolver)
struct SCIP_SDPiSolver SCIP_SDPISOLVER
SCIP_RETCODE SCIPsdpiSolverSetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real dval)
SCIP_RETCODE SCIPsdpiSolverGetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int *ival)
SCIP_RETCODE SCIPsdpiSolverGetPreoptimalSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *success, SCIP_Real *dualsol, int *dualsollength, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
enum SCIP_SDPParam SCIP_SDPPARAM
SCIP_Bool SCIPsdpiSolverIsDualUnbounded(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverLoadAndSolveWithPenalty(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Bool withobj, SCIP_Bool rbound, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, int noldlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int *rownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit, SCIP_Bool *feasorig, SCIP_Bool *penaltybound)
SCIP_Bool SCIPsdpiSolverIsTimelimExc(SCIP_SDPISOLVER *sdpisolver)
char name[SCIP_MAXSTRLEN]
SCIP_Bool SCIPsdpiSolverDoesWarmstartNeedPrimal(void)
SCIP_Bool SCIPsdpiSolverFeasibilityKnown(SCIP_SDPISOLVER *sdpisolver)