69 #include "blockmemshell/memory.h"
71 #include "scip/pub_misc.h"
80 #define MIN_PENALTYPARAM 1e5
81 #define MAX_PENALTYPARAM 1e10
82 #define PENALTYPARAM_FACTOR 1e6
83 #define MAX_MAXPENALTYPARAM 1e15
84 #define MAXPENALTYPARAM_FACTOR 1e6
85 #define TOLERANCE_FACTOR 0.1
86 #define PENALTYBOUNDTOL 1E-3
88 #define INFEASFEASTOLCHANGE 0.1
89 #define INFEASMINFEASTOL 1E-9
90 #define CONVERT_ABSOLUTE_TOLERANCES TRUE
93 struct SCIP_SDPiSolver
95 SCIP_MESSAGEHDLR* messagehdlr;
102 int* inputtomosekmapper;
105 int* mosektoinputmapper;
106 SCIP_Real* fixedvarsval;
107 SCIP_Real fixedvarsobjcontr;
119 SCIP_Real sdpsolverfeastol;
126 MSKrescodee terminationcode;
128 SCIP_Bool timelimitinitial;
139 #define MOSEK_CALL(x) do \
141 int _mosekerrorcode_; \
142 if ( (_mosekerrorcode_ = (x)) != MSK_RES_OK ) \
144 SCIPerrorMessage("MOSEK-Error <%d> in function call.\n", _mosekerrorcode_); \
145 return SCIP_LPERROR; \
151 #define MOSEK_CALL_BOOL(x) do \
153 int _mosekerrorcode_; \
154 if ( (_mosekerrorcode_ = (x)) != MSK_RES_OK ) \
156 SCIPerrorMessage("MOSEK-Error <%d> in function call.\n", _mosekerrorcode_); \
163 #define MOSEK_CALLM(x) do \
165 int _mosekerrorcode_; \
166 if ( (_mosekerrorcode_ = (x)) != MSK_RES_OK ) \
168 SCIPerrorMessage("MOSEK-Error <%d> in function call.\n", _mosekerrorcode_); \
169 return SCIP_NOMEMORY; \
175 #define BMS_CALL(x) do \
179 SCIPerrorMessage("No memory in function call.\n"); \
180 return SCIP_NOMEMORY; \
186 #define TIMEOFDAY_CALL(x) do \
189 if ( (_errorcode_ = (x)) != 0 ) \
191 SCIPerrorMessage("Error in gettimeofday! \n"); \
198 #define CHECK_IF_SOLVED(sdpisolver) do \
200 if (!(sdpisolver->solved)) \
202 SCIPerrorMessage("Tried to access solution information for SDP %d ahead of solving!\n", sdpisolver->sdpcounter); \
203 return SCIP_LPERROR; \
209 #define CHECK_IF_SOLVED_BOOL(sdpisolver) do \
211 if (!(sdpisolver->solved)) \
213 SCIPerrorMessage("Tried to access solution information for SDP %d ahead of solving!\n", sdpisolver->sdpcounter); \
239 assert( sdpisolver != NULL );
240 assert( lb < ub + sdpisolver->feastol );
242 return (ub-lb <= sdpisolver->epsilon);
245 #define isFixed(sdpisolver,lb,ub) (ub-lb <= sdpisolver->epsilon)
255 char name[SCIP_MAXSTRLEN];
266 MSKrescodee rescodee;
271 rescodee = MSK_getversion(&major, &minor, &build, &revision);
273 if ( rescodee != MSK_RES_OK )
277 snprintfreturn = SCIPsnprintf(
name, SCIP_MAXSTRLEN,
"MOSEK %d.%d.%d.%d", major, minor, build, revision);
278 assert( snprintfreturn < SCIP_MAXSTRLEN );
280 (void) SCIPsnprintf(
name, SCIP_MAXSTRLEN,
"MOSEK %d.%d.%d.%d", major, minor, build, revision);
291 return "Homogeneous and self-dual interior-point solver for semidefinite programming developed by MOSEK ApS"
292 "(http://www.mosek.com)";
305 assert( sdpisolver != NULL );
338 SCIP_MESSAGEHDLR* messagehdlr,
343 assert( sdpisolver != NULL );
344 assert( blkmem != NULL );
345 assert( bufmem != NULL );
347 SCIPdebugMessage(
"Calling SCIPsdpiCreate \n");
349 BMS_CALL( BMSallocBlockMemory(blkmem, sdpisolver) );
351 (*sdpisolver)->messagehdlr = messagehdlr;
352 (*sdpisolver)->blkmem = blkmem;
353 (*sdpisolver)->bufmem = bufmem;
355 MOSEK_CALLM( MSK_makeenv(&((*sdpisolver)->mskenv), NULL) );
358 (*sdpisolver)->msktask = NULL;
360 (*sdpisolver)->nvars = 0;
361 (*sdpisolver)->nactivevars = 0;
362 (*sdpisolver)->inputtomosekmapper = NULL;
363 (*sdpisolver)->mosektoinputmapper = NULL;
364 (*sdpisolver)->fixedvarsval = NULL;
365 (*sdpisolver)->fixedvarsobjcontr = 0.0;
366 (*sdpisolver)->objcoefs = NULL;
367 (*sdpisolver)->nvarbounds = 0;
368 (*sdpisolver)->varboundpos = NULL;
369 (*sdpisolver)->solved = FALSE;
370 (*sdpisolver)->sdpcounter = 0;
372 (*sdpisolver)->epsilon = 1e-9;
373 (*sdpisolver)->gaptol = 1e-4;
374 (*sdpisolver)->feastol = 1e-6;
375 (*sdpisolver)->sdpsolverfeastol = 1e-6;
377 (*sdpisolver)->sdpinfo = FALSE;
378 (*sdpisolver)->nthreads = -1;
379 (*sdpisolver)->timelimit = FALSE;
380 (*sdpisolver)->timelimitinitial = FALSE;
390 assert( sdpisolver != NULL );
391 assert( *sdpisolver != NULL );
393 SCIPdebugMessage(
"Freeing SDPISolver\n");
395 if ( ((*sdpisolver)->msktask) != NULL )
397 MOSEK_CALL( MSK_deletetask(&((*sdpisolver)->msktask)) );
400 if ( ((*sdpisolver)->mskenv) != NULL )
402 MOSEK_CALL( MSK_deleteenv(&((*sdpisolver)->mskenv)) );
405 BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->varboundpos, 2 * (*sdpisolver)->nactivevars);
406 BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->inputtomosekmapper, (*sdpisolver)->nvars);
407 BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->mosektoinputmapper, (*sdpisolver)->nactivevars);
408 BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->fixedvarsval, (*sdpisolver)->nvars - (*sdpisolver)->nactivevars);
409 BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->objcoefs, (*sdpisolver)->nactivevars);
411 BMSfreeBlockMemory((*sdpisolver)->blkmem, sdpisolver);
421 assert( sdpisolver != NULL );
423 sdpisolver->sdpcounter++;
433 assert( sdpisolver != NULL );
435 SCIPdebugMessage(
"Resetting counter of SDP-Interface from %d to 0.\n", sdpisolver->sdpcounter);
436 sdpisolver->sdpcounter = 0;
473 int* sdpconstnblocknonz,
477 SCIP_Real** sdpconstval,
479 int** sdpnblockvarnonz,
489 int* blockindchanges,
506 return SCIPsdpiSolverLoadAndSolveWithPenalty(sdpisolver, 0.0, TRUE, FALSE, nvars, obj, lb, ub, nsdpblocks, sdpblocksizes, sdpnblockvars, sdpconstnnonz,
507 sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, sdpnnonz, sdpnblockvarnonz, sdpvar, sdprow, sdpcol, sdpval, indchanges,
508 nremovedinds, blockindchanges, nremovedblocks, nlpcons, noldlpcons, lplhs, lprhs, rownactivevars, lpnnonz, lprow, lpcol, lpval, start,
509 startsettings, timelimit, NULL, NULL);
533 SCIP_Real penaltyparam,
544 int* sdpconstnblocknonz,
548 SCIP_Real** sdpconstval,
550 int** sdpnblockvarnonz,
560 int* blockindchanges,
577 SCIP_Bool* penaltybound
589 SCIP_Real* mosekvarbounds;
593 int* vartolhsrhsmapper;
597 int* mosekblocksizes;
604 struct timeval starttime;
605 struct timeval currenttime;
606 SCIP_Real startseconds;
607 SCIP_Real currentseconds;
608 SCIP_Real elapsedtime;
609 #ifdef SCIP_MORE_DEBUG
613 char varname[SCIP_MAXSTRLEN];
615 #if CONVERT_ABSOLUTE_TOLERANCES
616 SCIP_Real maxrhscoef;
619 assert( sdpisolver != NULL );
620 assert( sdpisolver->mskenv != NULL );
621 assert( penaltyparam > -1 * sdpisolver->epsilon );
622 assert( penaltyparam < sdpisolver->epsilon || ( feasorig != NULL ) );
624 assert( obj != NULL );
625 assert( lb != NULL );
626 assert( ub != NULL );
627 assert( nsdpblocks >= 0 );
628 assert( nsdpblocks == 0 || sdpblocksizes != NULL );
629 assert( nsdpblocks == 0 || sdpnblockvars != NULL );
630 assert( sdpconstnnonz >= 0 );
631 assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstnblocknonz != NULL );
632 assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstrow != NULL );
633 assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstcol != NULL );
634 assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstval != NULL );
635 assert( sdpnnonz >= 0 );
636 assert( nsdpblocks == 0 || sdpnblockvarnonz != NULL );
637 assert( nsdpblocks == 0 || sdpvar != NULL );
638 assert( nsdpblocks == 0 || sdprow != NULL );
639 assert( nsdpblocks == 0 || sdpcol != NULL );
640 assert( nsdpblocks == 0 || sdpval != NULL );
641 assert( nsdpblocks == 0 || indchanges != NULL );
642 assert( nsdpblocks == 0 || nremovedinds != NULL );
643 assert( nsdpblocks == 0 || blockindchanges != NULL );
644 assert( 0 <= nremovedblocks && nremovedblocks <= nsdpblocks );
645 assert( nlpcons >= 0 );
646 assert( noldlpcons >= nlpcons );
647 assert( nlpcons == 0 || lplhs != NULL );
648 assert( nlpcons == 0 || lprhs != NULL );
649 assert( nlpcons == 0 || rownactivevars != NULL );
650 assert( lpnnonz >= 0 );
651 assert( nlpcons == 0 || lprow != NULL );
652 assert( nlpcons == 0 || lpcol != NULL );
653 assert( nlpcons == 0 || lpval != NULL );
656 if ( timelimit <= 0.0 )
658 sdpisolver->timelimit = TRUE;
659 sdpisolver->timelimitinitial = TRUE;
660 sdpisolver->solved = FALSE;
663 sdpisolver->timelimit = FALSE;
664 sdpisolver->timelimitinitial = FALSE;
665 sdpisolver->feasorig = FALSE;
671 #if CONVERT_ABSOLUTE_TOLERANCES
676 if ((sdpisolver->msktask) != NULL)
678 MOSEK_CALL( MSK_deletetask(&(sdpisolver->msktask)) );
680 if ( penaltyparam < sdpisolver->epsilon )
682 MOSEK_CALLM( MSK_maketask(sdpisolver->mskenv, nvars, nsdpblocks - nremovedblocks + nlpcons + 2 * nvars, &(sdpisolver->msktask)) );
686 MOSEK_CALLM( MSK_maketask(sdpisolver->mskenv, nvars + 1, nsdpblocks - nremovedblocks + nlpcons + 2 * nvars, &(sdpisolver->msktask)) );
689 #ifdef SCIP_MORE_DEBUG
690 MOSEK_CALL( MSK_linkfunctotaskstream (sdpisolver->msktask, MSK_STREAM_LOG, NULL,
printstr) );
693 if ( sdpisolver->sdpinfo )
695 MOSEK_CALL( MSK_linkfunctotaskstream (sdpisolver->msktask, MSK_STREAM_LOG, NULL,
printstr) );
700 if ( sdpisolver->nthreads > 0 )
702 MOSEK_CALL( MSK_putintparam(sdpisolver->msktask, MSK_IPAR_NUM_THREADS, sdpisolver->nthreads) );
707 if ( penaltyparam < sdpisolver->epsilon )
708 SCIPdebugMessage(
"Inserting Data into MOSEK for SDP (%d) \n", ++sdpisolver->sdpcounter);
710 SCIPdebugMessage(
"Inserting Data again into MOSEK for SDP (%d) \n", sdpisolver->sdpcounter);
713 sdpisolver->penalty = (penaltyparam < sdpisolver->epsilon) ? FALSE : TRUE;
714 sdpisolver->rbound = rbound;
718 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->inputtomosekmapper), sdpisolver->nvars, nvars) );
719 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->mosektoinputmapper), sdpisolver->nactivevars, nvars) );
720 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->fixedvarsval), sdpisolver->nvars - sdpisolver->nactivevars, nvars) );
721 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->objcoefs), sdpisolver->nactivevars, nvars) );
723 oldnactivevars = sdpisolver->nactivevars;
724 sdpisolver->nvars = nvars;
725 sdpisolver->nactivevars = 0;
729 sdpisolver->fixedvarsobjcontr = 0.0;
730 for (i = 0; i < nvars; i++)
732 if (
isFixed(sdpisolver, lb[i], ub[i]) )
734 sdpisolver->fixedvarsobjcontr += obj[i] * lb[i];
735 sdpisolver->fixedvarsval[nfixedvars] = lb[i];
737 sdpisolver->inputtomosekmapper[i] = -nfixedvars;
738 SCIPdebugMessage(
"Fixing variable %d locally to %f for SDP %d in MOSEK\n", i, lb[i], sdpisolver->sdpcounter);
742 sdpisolver->mosektoinputmapper[sdpisolver->nactivevars] = i;
743 sdpisolver->inputtomosekmapper[i] = sdpisolver->nactivevars;
744 sdpisolver->objcoefs[sdpisolver->nactivevars] = obj[i];
745 sdpisolver->nactivevars++;
746 #ifdef SCIP_MORE_DEBUG
747 SCIPdebugMessage(
"Variable %d becomes variable %d for SDP %d in MOSEK\n", i, sdpisolver->inputtomosekmapper[i], sdpisolver->sdpcounter);
751 assert( sdpisolver->nactivevars + nfixedvars == sdpisolver->nvars );
755 sdpisolver->fixedvarsobjcontr = 0.0;
758 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->objcoefs), nvars, sdpisolver->nactivevars) );
759 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->fixedvarsval), nvars, nfixedvars) );
760 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->mosektoinputmapper), nvars, sdpisolver->nactivevars) );
763 sdpisolver->nvarbounds = 0;
764 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekvarbounds, 2 * sdpisolver->nactivevars) );
766 if ( sdpisolver->nactivevars != oldnactivevars )
768 if ( sdpisolver->varboundpos == NULL )
770 BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->varboundpos), 2 * sdpisolver->nactivevars) );
774 BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->varboundpos), 2 * oldnactivevars, 2 * sdpisolver->nactivevars) );
777 assert( sdpisolver->varboundpos != NULL );
779 for (i = 0; i < sdpisolver->nactivevars; i++)
781 assert( 0 <= sdpisolver->mosektoinputmapper[i] && sdpisolver->mosektoinputmapper[i] < nvars );
784 mosekvarbounds[sdpisolver->nvarbounds] = lb[sdpisolver->mosektoinputmapper[i]];
785 sdpisolver->varboundpos[sdpisolver->nvarbounds] = -(i + 1);
786 (sdpisolver->nvarbounds)++;
790 mosekvarbounds[sdpisolver->nvarbounds] = -1 * ub[sdpisolver->mosektoinputmapper[i]];
791 sdpisolver->varboundpos[sdpisolver->nvarbounds] = +(i + 1);
792 (sdpisolver->nvarbounds)++;
800 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &vartorowmapper, 2*noldlpcons) );
802 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &vartolhsrhsmapper, 2*noldlpcons) );
807 for (i = 0; i < noldlpcons; i++)
809 assert( newpos <= nlpcons );
810 if ( rownactivevars[i] >= 2 )
814 vartorowmapper[pos] = -(i+1);
815 vartolhsrhsmapper[pos] = newpos;
818 #if CONVERT_ABSOLUTE_TOLERANCES
820 if ( REALABS(lplhs[newpos]) > maxrhscoef )
821 maxrhscoef = REALABS(lplhs[newpos]);
827 vartorowmapper[pos] = i+1;
828 vartolhsrhsmapper[pos] = newpos;
831 #if CONVERT_ABSOLUTE_TOLERANCES
833 if ( REALABS(lprhs[newpos]) > maxrhscoef )
834 maxrhscoef = REALABS(lprhs[newpos]);
841 assert( nlpvars <= 2*nlpcons );
847 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekblocksizes, nsdpblocks - nremovedblocks) );
849 for (b = 0; b < nsdpblocks; b++)
851 if ( blockindchanges[b] > -1 )
853 assert( 0 <= blockindchanges[b] && blockindchanges[b] <= b && (b - blockindchanges[b]) <= (nsdpblocks - nremovedblocks) );
854 mosekblocksizes[b - blockindchanges[b]] = sdpblocksizes[b] - nremovedinds[b];
857 MOSEK_CALLM( MSK_appendbarvars(sdpisolver->msktask, nsdpblocks - nremovedblocks, mosekblocksizes) );
861 MOSEK_CALLM( MSK_appendvars(sdpisolver->msktask, nlpvars + sdpisolver->nvarbounds) );
864 for (v = 0; v < nlpvars + sdpisolver->nvarbounds; v++)
866 MOSEK_CALL( MSK_putvarbound(sdpisolver->msktask, v, MSK_BK_LO, 0.0, (
double) MSK_DPAR_DATA_TOL_BOUND_INF) );
870 MOSEK_CALLM( MSK_appendcons(sdpisolver->msktask, (penaltyparam < sdpisolver->epsilon) ? sdpisolver->nactivevars : sdpisolver->nactivevars + 1) );
875 if ( sdpconstnnonz > 0 )
877 for (b = 0; b < nsdpblocks; b++)
879 if ( blockindchanges[b] > -1 )
882 if ( nremovedinds[b] > 0 )
884 int* moseksdpconstrow;
885 int* moseksdpconstcol;
887 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &moseksdpconstrow, sdpconstnblocknonz[b]) );
888 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &moseksdpconstcol, sdpconstnblocknonz[b]) );
890 for (k = 0; k < sdpconstnblocknonz[b]; k++)
893 assert( -1 < indchanges[b][sdpconstrow[b][k]] && indchanges[b][sdpconstrow[b][k]] <= sdpconstrow[b][k] );
894 assert( -1 < indchanges[b][sdpconstcol[b][k]] && indchanges[b][sdpconstcol[b][k]] <= sdpconstcol[b][k] );
896 assert( 0 <= sdpconstrow[b][k] && sdpconstrow[b][k] <= sdpblocksizes[b] );
897 assert( 0 <= sdpconstcol[b][k] && sdpconstcol[b][k] <= sdpblocksizes[b] );
899 moseksdpconstrow[k] = sdpconstrow[b][k] - indchanges[b][sdpconstrow[b][k]];
900 moseksdpconstcol[k] = sdpconstcol[b][k] - indchanges[b][sdpconstcol[b][k]];
902 #if CONVERT_ABSOLUTE_TOLERANCES
904 if ( REALABS(sdpconstval[b][k]) > maxrhscoef )
905 maxrhscoef = REALABS(sdpconstval[b][k]);
909 MOSEK_CALL( MSK_appendsparsesymmat(sdpisolver->msktask, mosekblocksizes[b - blockindchanges[b]], sdpconstnblocknonz[b],
910 moseksdpconstrow, moseksdpconstcol, sdpconstval[b], &ind) );
912 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &moseksdpconstcol);
913 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &moseksdpconstrow);
917 MOSEK_CALL( MSK_appendsparsesymmat(sdpisolver->msktask, mosekblocksizes[b - blockindchanges[b]], sdpconstnblocknonz[b],
918 sdpconstrow[b], sdpconstcol[b], sdpconstval[b], &ind) );
920 MOSEK_CALL( MSK_putbarcj(sdpisolver->msktask, i, 1, &ind, &one) );
928 for (i = 0; i < nlpvars; i++)
930 if ( vartorowmapper[i] > 0 )
932 MOSEK_CALL( MSK_putcj(sdpisolver->msktask, i, -1 * lprhs[vartolhsrhsmapper[i]]) );
933 #ifdef SCIP_MORE_DEBUG
935 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN,
"rhs-%d", vartorowmapper[i] - 1);
936 MOSEK_CALL( MSK_putvarname ( sdpisolver->msktask, i, varname) );
941 assert( vartorowmapper[i] < 0 );
942 MOSEK_CALL( MSK_putcj(sdpisolver->msktask, i, lplhs[vartolhsrhsmapper[i]]) );
943 #ifdef SCIP_MORE_DEBUG
945 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN,
"lhs-%d", -1 * vartorowmapper[i] - 1);
946 MOSEK_CALL( MSK_putvarname ( sdpisolver->msktask, i, varname) );
952 for (i = 0; i < sdpisolver->nvarbounds; i++)
954 MOSEK_CALL( MSK_putcj(sdpisolver->msktask, nlpvars + i, mosekvarbounds[i]) );
955 #ifdef SCIP_MORE_DEBUG
956 if ( sdpisolver->varboundpos[i] < 0 )
959 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN,
"lb-%d", sdpisolver->mosektoinputmapper[-1 * sdpisolver->varboundpos[i] - 1]);
960 MOSEK_CALL( MSK_putvarname ( sdpisolver->msktask, nlpvars + i, varname) );
964 assert( sdpisolver->varboundpos[i] > 0 );
966 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN,
"ub-%d", sdpisolver->mosektoinputmapper[sdpisolver->varboundpos[i] - 1]);
967 MOSEK_CALL( MSK_putvarname ( sdpisolver->msktask, nlpvars + i, varname) );
972 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &mosekvarbounds);
975 MOSEK_CALL( MSK_putobjsense(sdpisolver->msktask, MSK_OBJECTIVE_SENSE_MAXIMIZE) );
980 for (b = 0; b < nsdpblocks; b++)
982 if ( blockindchanges[b] > -1 )
984 for (blockvar = 0; blockvar < sdpnblockvars[b]; blockvar++)
986 v = sdpisolver->inputtomosekmapper[sdpvar[b][blockvar]];
991 assert( v < sdpisolver->nactivevars );
993 if ( nremovedinds[b] > 0 )
995 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekrow, sdpnblockvarnonz[b][blockvar]) );
996 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekcol, sdpnblockvarnonz[b][blockvar]) );
998 for (k = 0; k < sdpnblockvarnonz[b][blockvar]; k++)
1001 assert( -1 < indchanges[b][sdprow[b][blockvar][k]] && indchanges[b][sdprow[b][blockvar][k]] <= sdprow[b][blockvar][k] );
1002 assert( -1 < indchanges[b][sdpcol[b][blockvar][k]] && indchanges[b][sdpcol[b][blockvar][k]] <= sdpcol[b][blockvar][k] );
1004 assert( 0 <= sdprow[b][blockvar][k] && sdprow[b][blockvar][k] < sdpblocksizes[b] );
1005 assert( 0 <= sdpcol[b][blockvar][k] && sdpcol[b][blockvar][k] < sdpblocksizes[b] );
1007 mosekrow[k] = sdprow[b][blockvar][k] - indchanges[b][sdprow[b][blockvar][k]];
1008 mosekcol[k] = sdpcol[b][blockvar][k] - indchanges[b][sdpcol[b][blockvar][k]];
1011 MOSEK_CALL( MSK_appendsparsesymmat(sdpisolver->msktask, mosekblocksizes[b - blockindchanges[b]], (
long long) sdpnblockvarnonz[b][blockvar],
1012 mosekrow, mosekcol, sdpval[b][blockvar], &ind) );
1014 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &mosekcol);
1015 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &mosekrow);
1019 MOSEK_CALL( MSK_appendsparsesymmat(sdpisolver->msktask, mosekblocksizes[b - blockindchanges[b]], (
long long) sdpnblockvarnonz[b][blockvar],
1020 sdprow[b][blockvar], sdpcol[b][blockvar], sdpval[b][blockvar], &ind) );
1023 MOSEK_CALL( MSK_putbaraij(sdpisolver->msktask, v, b - blockindchanges[b], (
long long) 1, &ind, &one) );
1030 if ( penaltyparam >= sdpisolver->epsilon )
1032 int* identityindices;
1033 SCIP_Real* identityvalues;
1035 for (b = 0; b < nsdpblocks; b++)
1037 if ( blockindchanges[b] > -1 )
1039 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &identityindices, mosekblocksizes[b - blockindchanges[b]]) );
1040 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &identityvalues, mosekblocksizes[b - blockindchanges[b]]) );
1042 for (i = 0; i < mosekblocksizes[b - blockindchanges[b]]; i++)
1044 identityindices[i] = i;
1045 identityvalues[i] = 1.0;
1047 MOSEK_CALL( MSK_appendsparsesymmat(sdpisolver->msktask, mosekblocksizes[b - blockindchanges[b]], (
long long) mosekblocksizes[b - blockindchanges[b]],
1048 identityindices, identityindices, identityvalues, &ind) );
1049 MOSEK_CALL( MSK_putbaraij(sdpisolver->msktask, sdpisolver->nactivevars, b - blockindchanges[b], (
long long) 1, &ind, &one) );
1051 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &identityvalues);
1052 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &identityindices);
1058 if ( penaltyparam < sdpisolver->epsilon )
1060 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekrow, lpnnonz) );
1061 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekval, lpnnonz) );
1066 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekrow, lpnnonz + 1) );
1067 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &mosekval, lpnnonz + 1) );
1071 for (i = 0; i < nlpvars; i++)
1073 if ( vartorowmapper[i] < 0 )
1078 while (ind < lpnnonz && lprow[ind] < -1 * vartorowmapper[i] - 1)
1081 while (ind < lpnnonz && lprow[ind] == -1 * vartorowmapper[i] - 1)
1083 v = sdpisolver->inputtomosekmapper[lpcol[ind]];
1086 mosekrow[mosekind] = v;
1087 mosekval[mosekind] = lpval[ind];
1092 assert( mosekind <= lpnnonz );
1096 assert( vartorowmapper[i] > 0 );
1098 if ( i > 0 && vartorowmapper[i] == -1 * vartorowmapper[i - 1] )
1102 for (j = 0; j < (penaltyparam < sdpisolver->epsilon ? mosekind : mosekind - 1); j++)
1111 while (lprow[ind] < vartorowmapper[i] - 1)
1113 while (ind < lpnnonz && lprow[ind] == vartorowmapper[i] - 1)
1115 v = sdpisolver->inputtomosekmapper[lpcol[ind]];
1118 mosekrow[mosekind] = v;
1119 mosekval[mosekind] = -1 * lpval[ind];
1124 assert( mosekind <= lpnnonz );
1129 if ( penaltyparam >= sdpisolver->epsilon )
1133 if ( ! (i > 0 && vartorowmapper[i] == -1 * vartorowmapper[i - 1] ))
1135 mosekrow[mosekind] = sdpisolver->nactivevars;
1136 mosekval[mosekind] = 1.0;
1139 assert( mosekind <= lpnnonz + 1 );
1142 MOSEK_CALL( MSK_putacol(sdpisolver->msktask, i, mosekind, mosekrow, mosekval) );
1145 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &mosekval);
1146 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &mosekrow);
1149 for (i = 0; i < sdpisolver->nvarbounds; i++)
1151 if ( sdpisolver->varboundpos[i] < 0 )
1154 row =-1 * sdpisolver->varboundpos[i] - 1;
1160 assert( sdpisolver->varboundpos[i] > 0 );
1161 row = sdpisolver->varboundpos[i] - 1;
1164 MOSEK_CALL( MSK_putacol(sdpisolver->msktask, nlpvars + i, 1, &row, &val) );
1168 for (i = 0; i < sdpisolver->nactivevars; i++)
1172 MOSEK_CALL( MSK_putconbound(sdpisolver->msktask, i, MSK_BK_FX, obj[sdpisolver->mosektoinputmapper[i]], obj[sdpisolver->mosektoinputmapper[i]]) );
1176 MOSEK_CALL( MSK_putconbound(sdpisolver->msktask, i, MSK_BK_FX, 0.0, 0.0) );
1178 #ifdef SCIP_MORE_DEBUG
1180 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN,
"var-%d", sdpisolver->mosektoinputmapper[i]);
1181 MOSEK_CALL( MSK_putconname ( sdpisolver->msktask, i, varname) );
1186 if ( penaltyparam >= sdpisolver->epsilon )
1190 MOSEK_CALL( MSK_putconbound(sdpisolver->msktask, sdpisolver->nactivevars, MSK_BK_UP, (
double) -1 * MSK_DPAR_DATA_TOL_BOUND_INF, penaltyparam) );
1194 MOSEK_CALL( MSK_putconbound(sdpisolver->msktask, sdpisolver->nactivevars, MSK_BK_FX, penaltyparam, penaltyparam) );
1199 #ifdef SCIP_DEBUG_PRINTTOFILE
1204 #ifdef SCIP_MORE_DEBUG
1205 MOSEK_CALL( MSK_getnumcon (sdpisolver->msktask, &nmosekconss) );
1206 MOSEK_CALL( MSK_getnumvar (sdpisolver->msktask, &nmosekvars) );
1207 MOSEK_CALL( MSK_getnumcone (sdpisolver->msktask, &nmosekcones) );
1209 MOSEK_CALL( MSK_printdata (sdpisolver->msktask, MSK_STREAM_LOG, 0, nmosekconss, 0, nmosekvars, 0, nmosekcones, 1, 1, 1, 1, 1, 1, 1, 1) );
1210 #ifdef SCIP_PRINT_PARAMETERS
1211 MOSEK_CALL( MSK_printparam (sdpisolver->msktask) );
1216 startseconds = (SCIP_Real) starttime.tv_sec + (SCIP_Real) starttime.tv_usec / 1e6;
1219 currentseconds = (SCIP_Real) currenttime.tv_sec + (SCIP_Real) currenttime.tv_usec / 1e6;
1221 elapsedtime = currentseconds - startseconds;
1223 if ( timelimit <= elapsedtime )
1225 sdpisolver->timelimit = TRUE;
1226 sdpisolver->solved = FALSE;
1235 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_PFEAS, sdpisolver->gaptol) );
1236 #if CONVERT_ABSOLUTE_TOLERANCES
1237 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_DFEAS, sdpisolver->sdpsolverfeastol / (1 + maxrhscoef)) );
1238 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_INFEAS, sdpisolver->sdpsolverfeastol / (1 + maxrhscoef)) );
1239 SCIPdebugMessage(
"Setting relative feasibility tolerance for MOSEK to %.10f / %f = %.12f\n", sdpisolver->sdpsolverfeastol,
1240 1+maxrhscoef, sdpisolver->sdpsolverfeastol / (1 + maxrhscoef));
1242 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_DFEAS, sdpisolver->sdpsolverfeastol) );
1243 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_INFEAS, sdpisolver->sdpsolverfeastol) );
1245 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_MU_RED, sdpisolver->gaptol) );
1246 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_REL_GAP, sdpisolver->gaptol) );
1250 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_OPTIMIZER_MAX_TIME, timelimit - elapsedtime) );
1256 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_UPPER_OBJ_CUT, sdpisolver->objlimit) );
1260 MOSEK_CALL( MSK_optimizetrm(sdpisolver->msktask, &(sdpisolver->terminationcode)) );
1262 if ( sdpisolver->sdpinfo )
1264 MOSEK_CALL( MSK_optimizersummary(sdpisolver->msktask, MSK_STREAM_LOG) );
1265 MOSEK_CALL( MSK_analyzesolution(sdpisolver->msktask, MSK_STREAM_LOG, MSK_SOL_ITR) );
1268 SCIPdebugMessage(
"Solving problem using MOSEK, return code %d\n", sdpisolver->terminationcode);
1270 sdpisolver->solved = TRUE;
1272 sdpisolver->nsdpcalls = 1;
1273 MOSEK_CALL( MSK_getnaintinf(sdpisolver->msktask,
"MSK_IINF_INTPNT_ITER", &(sdpisolver->niterations)) );
1277 #if CONVERT_ABSOLUTE_TOLERANCES
1278 feastol = sdpisolver->sdpsolverfeastol / (1 + maxrhscoef);
1280 feastol = sdpisolver->sdpsolverfeastol;
1285 SCIP_Real* solvector;
1287 SCIP_Bool infeasible;
1291 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &solvector, nvars) );
1292 nvarspointer = nvars;
1294 assert( nvarspointer == nvars );
1297 SCIP_CALL(
SCIPsdpSolcheckerCheck(sdpisolver->bufmem, nvars, lb, ub, nsdpblocks, sdpblocksizes, sdpnblockvars, sdpconstnnonz,
1298 sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, sdpnnonz, sdpnblockvarnonz, sdpvar, sdprow, sdpcol, sdpval,
1299 indchanges, nremovedinds, blockindchanges, nlpcons, noldlpcons, lplhs, lprhs, rownactivevars, lpnnonz, lprow, lpcol, lpval,
1300 solvector, sdpisolver->feastol, sdpisolver->epsilon, &infeasible) );
1302 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &solvector);
1306 SCIPdebugMessage(
"Solution feasible for MOSEK but outside feasibility tolerance, changing MOSEK feasibility tolerance from %f to %f\n",
1313 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_DFEAS, feastol) );
1314 MOSEK_CALL( MSK_putdouparam(sdpisolver->msktask, MSK_DPAR_INTPNT_CO_TOL_INFEAS, feastol) );
1317 startseconds = (SCIP_Real) starttime.tv_sec + (SCIP_Real) starttime.tv_usec / 1e6;
1320 currentseconds = (SCIP_Real) currenttime.tv_sec + (SCIP_Real) currenttime.tv_usec / 1e6;
1322 elapsedtime = currentseconds - startseconds;
1324 if ( timelimit <= elapsedtime )
1326 sdpisolver->timelimit = TRUE;
1327 sdpisolver->solved = FALSE;
1331 MOSEK_CALL( MSK_optimizetrm(sdpisolver->msktask, &(sdpisolver->terminationcode)) );
1333 if ( sdpisolver->sdpinfo )
1335 MOSEK_CALL( MSK_optimizersummary(sdpisolver->msktask, MSK_STREAM_LOG) );
1336 MOSEK_CALL( MSK_analyzesolution(sdpisolver->msktask, MSK_STREAM_LOG, MSK_SOL_ITR) );
1340 sdpisolver->nsdpcalls++;
1341 MOSEK_CALL( MSK_getnaintinf(sdpisolver->msktask,
"MSK_IINF_INTPNT_ITER", &newiterations) );
1342 sdpisolver->niterations += newiterations;
1346 sdpisolver->solved = FALSE;
1347 SCIPmessagePrintInfo(sdpisolver->messagehdlr,
"MOSEK failed to reach required feasibility tolerance! \n");
1357 if ( penaltyparam >= sdpisolver->epsilon && ( ! sdpisolver->timelimit ) && ( sdpisolver->terminationcode != MSK_RES_TRM_MAX_TIME ) )
1359 SCIP_Real* moseksol;
1360 SCIP_Real trace = 0.0;
1363 assert( feasorig != NULL );
1366 BMSallocBufferMemoryArray(sdpisolver->bufmem, &moseksol, sdpisolver->nactivevars + 1);
1368 MOSEK_CALL( MSK_gety(sdpisolver->msktask, MSK_SOL_ITR, moseksol) );
1370 *feasorig = (moseksol[sdpisolver->nactivevars] < sdpisolver->feastol);
1375 sdpisolver->feasorig = *feasorig;
1378 if ( ! *feasorig && penaltybound != NULL )
1381 SCIPdebugMessage(
"Solution not feasible in original problem, r = %f\n", moseksol[sdpisolver->nactivevars]);
1386 for (b = 0; b < nsdpblocks; b++)
1388 if ( blockindchanges[b] > -1 )
1393 size = sdpblocksizes[b] - nremovedinds[b];
1395 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &X, 0.5 * size * (size + 1)) );
1396 MOSEK_CALL( MSK_getbarxj(sdpisolver->msktask, MSK_SOL_ITR, b - blockindchanges[b], X) );
1399 for (i = 0; i < size; i++)
1402 ind = 0.5 * i * (i + 3);
1403 assert( ind < 0.5 * size * (size + 1) );
1407 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &X);
1412 BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &x, nlpvars + sdpisolver->nvarbounds) );
1414 MOSEK_CALL( MSK_getxx(sdpisolver->msktask, MSK_SOL_ITR, x) );
1416 for (i = 0; i < nlpvars; i++)
1419 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &x);
1424 if ( penaltybound != NULL )
1425 *penaltybound = TRUE;
1426 SCIPdebugMessage(
"Tr(X) = %f == %f = Gamma, penalty formulation not exact, Gamma should be increased or problem is infeasible\n",
1427 trace, penaltyparam);
1429 else if ( penaltybound != NULL )
1430 *penaltybound = FALSE;
1432 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &moseksol);
1436 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &mosekblocksizes);
1439 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &vartolhsrhsmapper);
1440 BMSfreeBufferMemoryArrayNull(sdpisolver->bufmem, &vartorowmapper);
1462 assert( sdpisolver != NULL );
1464 return sdpisolver->solved;
1479 assert( sdpisolver != NULL );
1482 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1486 case MSK_SOL_STA_UNKNOWN:
1487 case MSK_SOL_STA_PRIM_FEAS:
1488 case MSK_SOL_STA_DUAL_FEAS:
1489 case MSK_SOL_STA_NEAR_OPTIMAL:
1490 case MSK_SOL_STA_NEAR_PRIM_FEAS:
1491 case MSK_SOL_STA_NEAR_DUAL_FEAS:
1492 case MSK_SOL_STA_NEAR_PRIM_AND_DUAL_FEAS:
1493 case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
1494 case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
1496 case MSK_SOL_STA_OPTIMAL:
1497 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1498 case MSK_SOL_STA_PRIM_INFEAS_CER:
1499 case MSK_SOL_STA_DUAL_INFEAS_CER:
1502 SCIPdebugMessage(
"Unknown return code in SCIPsdpiSolverFeasibilityKnown\n");
1510 SCIP_Bool* primalfeasible,
1511 SCIP_Bool* dualfeasible
1516 assert( sdpisolver != NULL );
1517 assert( primalfeasible != NULL );
1518 assert( dualfeasible != NULL );
1521 MOSEK_CALL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1525 case MSK_SOL_STA_OPTIMAL:
1526 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1527 *primalfeasible = TRUE;
1528 *dualfeasible = TRUE;
1530 case MSK_SOL_STA_PRIM_INFEAS_CER:
1531 *primalfeasible = FALSE;
1532 *dualfeasible = TRUE;
1534 case MSK_SOL_STA_DUAL_INFEAS_CER:
1535 *primalfeasible = TRUE;
1536 *dualfeasible = FALSE;
1539 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1540 return SCIP_LPERROR;
1554 assert( sdpisolver != NULL );
1557 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1561 case MSK_SOL_STA_DUAL_INFEAS_CER:
1563 case MSK_SOL_STA_OPTIMAL:
1564 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1565 case MSK_SOL_STA_PRIM_INFEAS_CER:
1568 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1582 assert( sdpisolver != NULL );
1585 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1589 case MSK_SOL_STA_PRIM_INFEAS_CER:
1591 case MSK_SOL_STA_OPTIMAL:
1592 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1593 case MSK_SOL_STA_DUAL_INFEAS_CER:
1596 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1610 assert( sdpisolver != NULL );
1613 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1617 case MSK_SOL_STA_OPTIMAL:
1618 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1619 case MSK_SOL_STA_DUAL_INFEAS_CER:
1621 case MSK_SOL_STA_PRIM_INFEAS_CER:
1624 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1638 assert( sdpisolver != NULL );
1641 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1645 case MSK_SOL_STA_PRIM_INFEAS_CER:
1647 case MSK_SOL_STA_OPTIMAL:
1648 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1649 case MSK_SOL_STA_DUAL_INFEAS_CER:
1652 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1666 assert( sdpisolver != NULL );
1669 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1673 case MSK_SOL_STA_DUAL_INFEAS_CER:
1675 case MSK_SOL_STA_OPTIMAL:
1676 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1677 case MSK_SOL_STA_PRIM_INFEAS_CER:
1680 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1694 assert( sdpisolver != NULL );
1697 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1701 case MSK_SOL_STA_OPTIMAL:
1702 case MSK_SOL_STA_PRIM_AND_DUAL_FEAS:
1703 case MSK_SOL_STA_PRIM_INFEAS_CER:
1705 case MSK_SOL_STA_DUAL_INFEAS_CER:
1708 SCIPdebugMessage(
"MOSEK does not know about feasibility of solutions\n");
1719 assert( sdpisolver != NULL );
1721 if ( sdpisolver->timelimit )
1726 return sdpisolver->terminationcode == MSK_RES_OK;
1734 assert( sdpisolver != NULL );
1737 return sdpisolver->terminationcode == MSK_RES_TRM_OBJECTIVE_RANGE;
1745 assert( sdpisolver != NULL );
1748 return sdpisolver->terminationcode == MSK_RES_TRM_MAX_ITERATIONS;
1756 assert( sdpisolver != NULL );
1758 if ( sdpisolver->timelimit )
1761 if ( ! sdpisolver->solved )
1764 return sdpisolver->terminationcode == MSK_RES_TRM_MAX_TIME;
1781 assert( sdpisolver != NULL );
1783 if ( ! sdpisolver->solved )
1786 if ( sdpisolver->timelimit )
1789 switch ( sdpisolver->terminationcode )
1793 case MSK_RES_TRM_MAX_NUM_SETBACKS:
1794 case MSK_RES_TRM_NUMERICAL_PROBLEM:
1795 case MSK_RES_TRM_STALL:
1797 case MSK_RES_TRM_OBJECTIVE_RANGE:
1799 case MSK_RES_TRM_MAX_ITERATIONS:
1801 case MSK_RES_TRM_MAX_TIME:
1815 assert( sdpisolver != NULL );
1817 if ( sdpisolver->timelimit )
1822 if ( sdpisolver->terminationcode != MSK_RES_OK )
1825 MOSEK_CALL_BOOL( MSK_getsolsta(sdpisolver->msktask, MSK_SOL_ITR, &solstat) );
1827 if ( solstat != MSK_SOL_STA_OPTIMAL )
1839 assert( sdpisolver != NULL );
1841 if ( sdpisolver->timelimit )
1844 if ( ! sdpisolver->solved )
1856 SCIPdebugMessage(
"Not implemented yet\n");
1857 return SCIP_LPERROR;
1866 SCIP_Real* moseksol;
1868 assert( sdpisolver != NULL );
1870 assert( objval != NULL );
1872 if ( sdpisolver->penalty && ( ! sdpisolver->feasorig ) )
1876 MOSEK_CALL( MSK_getdualobj(sdpisolver->msktask, MSK_SOL_ITR, objval) );
1884 BMSallocBufferMemoryArray(sdpisolver->bufmem, &moseksol, sdpisolver->penalty ? sdpisolver->nactivevars + 1 : sdpisolver->nactivevars);
1885 MOSEK_CALL( MSK_gety(sdpisolver->msktask, MSK_SOL_ITR, moseksol) );
1888 for (v = 0; v < sdpisolver->nactivevars; v++)
1890 if ( REALABS(moseksol[v]) > sdpisolver->epsilon )
1891 *objval += moseksol[v] * sdpisolver->objcoefs[v];
1896 *objval += sdpisolver->fixedvarsobjcontr;
1898 if ( ( ! sdpisolver->penalty ) || sdpisolver->feasorig)
1900 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &moseksol);
1919 SCIP_Real* moseksol;
1921 assert( sdpisolver != NULL );
1923 assert( dualsollength != NULL );
1925 if ( *dualsollength > 0 )
1927 assert( dualsol != NULL );
1928 if ( *dualsollength < sdpisolver->nvars )
1930 SCIPdebugMessage(
"The given array in SCIPsdpiSolverGetSol only had length %d, but %d was needed", *dualsollength, sdpisolver->nvars);
1931 *dualsollength = sdpisolver->nvars;
1936 BMSallocBufferMemoryArray(sdpisolver->bufmem, &moseksol, sdpisolver->penalty ? sdpisolver->nactivevars + 1 : sdpisolver->nactivevars);
1938 MOSEK_CALL( MSK_gety(sdpisolver->msktask, MSK_SOL_ITR, moseksol) );
1941 for (v = 0; v < sdpisolver->nvars; v++)
1943 if ( sdpisolver->inputtomosekmapper[v] >= 0 )
1944 dualsol[v] = moseksol[sdpisolver->inputtomosekmapper[v]];
1948 assert( -sdpisolver->inputtomosekmapper[v] <= sdpisolver->nvars - sdpisolver->nactivevars );
1949 dualsol[v] = sdpisolver->fixedvarsval[(-1 * sdpisolver->inputtomosekmapper[v]) - 1];
1954 if ( objval != NULL )
1956 if ( sdpisolver->penalty && ( ! sdpisolver->feasorig ))
1960 MOSEK_CALL( MSK_getdualobj(sdpisolver->msktask, MSK_SOL_ITR, objval) );
1967 for (v = 0; v < sdpisolver->nactivevars; v++)
1969 if ( REALABS(moseksol[v]) > sdpisolver->epsilon )
1970 *objval += moseksol[v] * sdpisolver->objcoefs[v];
1975 *objval += sdpisolver->fixedvarsobjcontr;
1978 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &moseksol);
1980 else if ( objval != NULL )
2003 SCIP_Real* primalvars;
2007 assert( sdpisolver != NULL );
2009 assert( arraylength != NULL );
2010 assert( lbvars != NULL );
2011 assert( ubvars != NULL );
2014 if ( *arraylength < sdpisolver->nvars )
2016 *arraylength = sdpisolver->nvars;
2017 SCIPdebugMessage(
"Insufficient length of array in SCIPsdpiSolverGetPrimalBoundVars (gave %d, needed %d)\n", *arraylength, sdpisolver->nvars);
2022 for (i = 0; i < sdpisolver->nvars; i++)
2029 MOSEK_CALL( MSK_getnumvar(sdpisolver->msktask, &nprimalvars) );
2031 BMSallocBufferMemoryArray(sdpisolver->bufmem, &primalvars, nprimalvars);
2033 MOSEK_CALL( MSK_getxx(sdpisolver->msktask, MSK_SOL_ITR, primalvars) );
2036 assert( sdpisolver->nvarbounds <= 2 * sdpisolver->nvars );
2038 for (i = 0; i < sdpisolver->nvarbounds; i++)
2040 if ( sdpisolver->varboundpos[i] < 0 )
2044 lbvars[sdpisolver->mosektoinputmapper[-1 * sdpisolver->varboundpos[i] -1]] = primalvars[nprimalvars - sdpisolver->nvarbounds + i];
2050 assert( sdpisolver->varboundpos[i] > 0 );
2053 ubvars[sdpisolver->mosektoinputmapper[sdpisolver->varboundpos[i] - 1]] = primalvars[nprimalvars - sdpisolver->nvarbounds + i];
2057 BMSfreeBufferMemoryArray(sdpisolver->bufmem, &primalvars);
2069 if ( sdpisolver->timelimitinitial )
2073 *iterations = sdpisolver->niterations;
2085 assert( calls != NULL );
2087 *calls = sdpisolver->timelimitinitial ? 0 : sdpisolver->nsdpcalls;
2098 assert( sdpisolver != NULL );
2099 assert( usedsetting != NULL );
2103 else if ( sdpisolver->penalty )
2147 assert( sdpisolver != NULL );
2148 assert( dval != NULL );
2153 *dval = sdpisolver->epsilon;
2156 *dval = sdpisolver->gaptol;
2159 *dval = sdpisolver->feastol;
2162 *dval = sdpisolver->sdpsolverfeastol;
2165 *dval = sdpisolver->objlimit;
2168 return SCIP_PARAMETERUNKNOWN;
2181 assert( sdpisolver != NULL );
2186 sdpisolver->epsilon = dval;
2187 SCIPdebugMessage(
"Setting sdpisolver epsilon to %f.\n", dval);
2190 sdpisolver->gaptol = dval;
2191 SCIPdebugMessage(
"Setting sdpisolver gaptol to %f.\n", dval);
2194 sdpisolver->feastol = dval;
2195 SCIPdebugMessage(
"Setting sdpisolver feastol to %f.\n", dval);
2198 sdpisolver->sdpsolverfeastol = dval;
2199 SCIPdebugMessage(
"Setting sdpisolver sdpsolverfeastol to %f.\n", dval);
2202 SCIPdebugMessage(
"Setting sdpisolver objlimit to %f.\n", dval);
2203 sdpisolver->objlimit = dval;
2206 return SCIP_PARAMETERUNKNOWN;
2219 assert( sdpisolver != NULL );
2224 *ival = (int) sdpisolver->sdpinfo;
2225 SCIPdebugMessage(
"Getting sdpisolver information output (%d).\n", *ival);
2228 *ival = sdpisolver->nthreads;
2229 SCIPdebugMessage(
"Getting sdpisolver number of threads: %d.\n", *ival);
2232 return SCIP_PARAMETERUNKNOWN;
2245 assert( sdpisolver != NULL );
2250 sdpisolver->nthreads = ival;
2251 SCIPdebugMessage(
"Setting sdpisolver number of threads to %d.\n", ival);
2254 assert( 0 <= ival && ival <= 1 );
2255 sdpisolver->sdpinfo = (SCIP_Bool) ival;
2256 SCIPdebugMessage(
"Setting sdpisolver information output (%d).\n", ival);
2259 return SCIP_PARAMETERUNKNOWN;
2271 SCIPdebugMessage(
"Lambdastar parameter not used by MOSEK");
2280 SCIP_Real* penaltyparam
2285 assert( sdpisolver != NULL );
2286 assert( penaltyparam != NULL );
2302 SCIPdebugMessage(
"Setting penaltyparameter to %f.\n", compval);
2303 *penaltyparam = compval;
2311 SCIP_Real penaltyparam,
2312 SCIP_Real* maxpenaltyparam
2317 assert( sdpisolver != NULL );
2318 assert( maxpenaltyparam != NULL );
2324 *maxpenaltyparam = compval;
2325 SCIPdebugMessage(
"Setting maximum penaltyparameter to %f.\n", compval);
2354 SCIPdebugMessage(
"Not implemented yet\n");
2355 return SCIP_LPERROR;
2364 assert( sdpisolver != NULL );
2365 assert( fname != NULL );
2367 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)
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 *start, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit)
#define TIMEOFDAY_CALL(x)
SCIP_RETCODE SCIPsdpiSolverGetIterations(SCIP_SDPISOLVER *sdpisolver, int *iterations)
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_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_Real SCIPsdpiSolverGetDefaultSdpiSolverFeastol(void)
SCIP_Bool SCIPsdpiSolverIsObjlimExc(SCIP_SDPISOLVER *sdpisolver)
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_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 *start, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit, SCIP_Bool *feasorig, SCIP_Bool *penaltybound)
SCIP_Bool SCIPsdpiSolverIsIterlimExc(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)
enum SCIP_SDPParam SCIP_SDPPARAM
SCIP_Bool SCIPsdpiSolverIsDualUnbounded(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiSolverIsTimelimExc(SCIP_SDPISOLVER *sdpisolver)
char name[SCIP_MAXSTRLEN]
SCIP_Bool SCIPsdpiSolverFeasibilityKnown(SCIP_SDPISOLVER *sdpisolver)