SCIP-SDP  3.0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sdpisolver_sdpa.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of SCIPSDP - a solving framework for mixed-integer */
4 /* semidefinite programs based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2017 Discrete Optimization, TU Darmstadt */
9 /* */
10 /* */
11 /* This program is free software; you can redistribute it and/or */
12 /* modify it under the terms of the GNU Lesser General Public License */
13 /* as published by the Free Software Foundation; either version 3 */
14 /* of the License, or (at your option) any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU Lesser General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with this program; if not, write to the Free Software */
23 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
24 /* */
25 /* */
26 /* Based on SCIP - Solving Constraint Integer Programs */
27 /* Copyright (C) 2002-2017 Zuse Institute Berlin */
28 /* SCIP is distributed under the terms of the SCIP Academic Licence, */
29 /* see file COPYING in the SCIP distribution. */
30 /* */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32 
33 /* #define SCIP_DEBUG*/
34 /* #define SCIP_MORE_DEBUG *//* shows all added nonzero entries */
35 /* #define SCIP_DEBUG_PRINTTOFILE *//* prints each problem inserted into SDPA to the file sdpa.dat-s and the starting point to sdpa.ini-s */
36 
37 /* #define SDPA_RESETPARAMS */ /* this can be used together with an update to the SDPA source code to prevent memory leaks when using SCIP-SDP with SDPA */
38 
45 /* turn off lint warnings for whole file: */
46 /*lint --e{750,788,818}*/
47 
48 #include <assert.h>
49 
50 #include "sdpi/sdpisolver.h"
51 
52 /* turn off warnings for sdpa (doesn't seem to work) */
53 #pragma GCC diagnostic ignored "-Wstrict-prototypes"
54 #include "sdpa_call.h" /* SDPA callable library interface */
55 #pragma GCC diagnostic warning "-Wstrict-prototypes"
56 
57 #include "blockmemshell/memory.h" /* for memory allocation */
58 #include "scip/def.h" /* for SCIP_Real, _Bool, ... */
59 #include "scip/pub_misc.h" /* for sorting */
60 #include "sdpi/sdpsolchecker.h" /* to check solution with regards to feasibility tolerance */
61 
62 /* local defines */
63 #define GAPTOLCHANGE 1
64 #define FEASTOLCHANGE 1
65 #define PENALTYBOUNDTOL 1E-3
68 #define INFEASFEASTOLCHANGE 0.1
69 #define INFEASMINFEASTOL 1E-9
71 #define MIN_LAMBDASTAR 1e0
72 #define MAX_LAMBDASTAR 1e8
73 #define LAMBDASTAR_FACTOR 1e0
74 #define LAMBDASTAR_TWOPOINTS TRUE
75 #define LAMBDASTAR_THRESHOLD 1e1
76 #define LAMBDASTAR_LOW 1.5
77 #define LAMBDASTAR_HIGH 1e5
79 #define MIN_PENALTYPARAM 1e5
80 #define MAX_PENALTYPARAM 1e12
81 #define PENALTYPARAM_FACTOR 1e1
82 #define MAX_MAXPENALTYPARAM 1e15
83 #define MAXPENALTYPARAM_FACTOR 1e6
86 #define BMS_CALL(x) do \
87  { \
88  if( NULL == (x) ) \
89  { \
90  SCIPerrorMessage("No memory in function call.\n"); \
91  return SCIP_NOMEMORY; \
92  } \
93  } \
94  while( FALSE )
95 
97 #define CHECK_IF_SOLVED(sdpisolver) do \
98  { \
99  if (!(sdpisolver->solved)) \
100  { \
101  SCIPerrorMessage("Tried to access solution information for SDP %d ahead of solving!\n", sdpisolver->sdpcounter); \
102  return SCIP_LPERROR; \
103  } \
104  } \
105  while( FALSE )
106 
108 #define CHECK_IF_SOLVED_BOOL(sdpisolver) do \
109  { \
110  if (!(sdpisolver->solved)) \
111  { \
112  SCIPerrorMessage("Tried to access solution information for SDP %d ahead of solving!\n", sdpisolver->sdpcounter); \
113  return FALSE; \
114  } \
115  } \
116  while( FALSE )
117 
118 
120 struct SCIP_SDPiSolver
121 {
122  SCIP_MESSAGEHDLR* messagehdlr;
123  BMS_BLKMEM* blkmem;
124  BMS_BUFMEM* bufmem;
125  SDPA* sdpa;
126  int nvars;
127  int nactivevars;
128  int* inputtosdpamapper;
131  int* sdpatoinputmapper;
132  SCIP_Real* fixedvarsval;
133  SCIP_Real fixedvarsobjcontr;
134  SCIP_Real* objcoefs;
135  int nvarbounds;
136  int* varboundpos;
138  SCIP_Bool solved;
139  SCIP_Bool timelimit;
140  int sdpcounter;
141  int niterations;
142  int nsdpcalls;
143  SCIP_Real epsilon;
144  SCIP_Real gaptol;
145  SCIP_Real feastol;
146  SCIP_Real sdpsolverfeastol;
147  SCIP_Real objlimit;
148  SCIP_Bool sdpinfo;
149  SCIP_Bool penalty;
150  SCIP_Bool feasorig;
152  SCIP_Bool rbound;
153  SCIP_SDPSOLVERSETTING usedsetting;
154  SCIP_Real lambdastar;
155 };
156 
157 
158 /*
159  * Local Functions
160  */
161 
162 #ifndef NDEBUG
163 
164 static
165 SCIP_Bool isFixed(
166  SCIP_SDPISOLVER* sdpisolver,
167  SCIP_Real lb,
168  SCIP_Real ub
169  )
170 {
171  assert( sdpisolver != NULL );
172  assert( lb < ub + sdpisolver->feastol );
173 
174  return (ub-lb <= sdpisolver->epsilon);
175 }
176 #else
177 #define isFixed(sdpisolver,lb,ub) (ub-lb <= sdpisolver->epsilon)
178 #endif
179 
182 static
183 SCIP_RETCODE checkFeastolAndResolve(
184  SCIP_SDPISOLVER* sdpisolver,
185  SCIP_Real penaltyparam,
186  int nvars,
187  SCIP_Real* lb,
188  SCIP_Real* ub,
189  int nsdpblocks,
190  int* sdpblocksizes,
191  int* sdpnblockvars,
192  int sdpconstnnonz,
193  int* sdpconstnblocknonz,
195  int** sdpconstrow,
196  int** sdpconstcol,
197  SCIP_Real** sdpconstval,
198  int sdpnnonz,
199  int** sdpnblockvarnonz,
201  int** sdpvar,
203  int*** sdprow,
204  int*** sdpcol,
205  SCIP_Real*** sdpval,
206  int** indchanges,
208  int* nremovedinds,
209  int* blockindchanges,
210  int nlpcons,
211  int noldlpcons,
212  SCIP_Real* lplhs,
213  SCIP_Real* lprhs,
214  int* rownactivevars,
215  int lpnnonz,
216  int* lprow,
217  int* lpcol,
218  SCIP_Real* lpval,
219  SCIP_Real* feastol
220  )
221 {
222 #ifdef SCIP_DEBUG
223  char phase_string[15];
224 #endif
225 
226  assert( feastol != NULL );
227 
228  while ( SCIPsdpiSolverIsAcceptable(sdpisolver) && SCIPsdpiSolverIsDualFeasible(sdpisolver) && penaltyparam < sdpisolver->epsilon && *feastol >= INFEASMINFEASTOL )
229  {
230  SCIP_Real* solvector;
231  int nvarspointer;
232  SCIP_Bool infeasible;
233 
234  /* get current solution */
235  BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &solvector, nvars) );
236  nvarspointer = nvars;
237  SCIP_CALL( SCIPsdpiSolverGetSol(sdpisolver, NULL, solvector, &nvarspointer) );
238  assert( nvarspointer == nvars );
239 
240  /* check the solution for feasibility with regards to our tolerance */
241  SCIP_CALL( SCIPsdpSolcheckerCheck(sdpisolver->bufmem, nvars, lb, ub, nsdpblocks, sdpblocksizes, sdpnblockvars, sdpconstnnonz,
242  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, sdpnnonz, sdpnblockvarnonz, sdpvar, sdprow, sdpcol, sdpval,
243  indchanges, nremovedinds, blockindchanges, nlpcons, noldlpcons, lplhs, lprhs, rownactivevars, lpnnonz, lprow, lpcol, lpval,
244  solvector, sdpisolver->feastol, sdpisolver->epsilon, &infeasible) );
245 
246  BMSfreeBufferMemoryArray(sdpisolver->bufmem, &solvector);
247 
248  if ( infeasible )
249  {
250  SCIPdebugMessage("Solution feasible for SDPA but outside feasibility tolerance, changing SDPA feasibility tolerance from %f to %f\n",
251  *feastol, *feastol * INFEASFEASTOLCHANGE);
252  *feastol *= INFEASFEASTOLCHANGE;
253 
254  if ( *feastol >= INFEASMINFEASTOL )
255  {
256  /* update settings */
257  sdpisolver->sdpa->setParameterEpsilonDash(*feastol);
258 
259 #ifdef SCIP_MORE_DEBUG
260  sdpisolver->sdpa->printParameters(stdout);
261 #endif
262  sdpisolver->sdpa->setInitPoint(false);
263 #ifdef SDPA_RESETPARAMS
264  sdpisolver->sdpa->resetParameters();
265 #else
266  sdpisolver->sdpa->initializeSolve();
267 #endif
268  sdpisolver->sdpa->solve();
269 
270  /* update number of SDP-iterations and -calls */
271  sdpisolver->niterations += (int) sdpisolver->sdpa->getIteration();
272  sdpisolver->nsdpcalls += 1;
273 
274 #ifdef SCIP_DEBUG
275  /* print the phase value , i.e. whether solving was successfull */
276  sdpisolver->sdpa->getPhaseString((char*)phase_string);
277  SCIPdebugMessage("SDPA solving finished with status %s (primal and dual here are switched in contrast to our formulation)\n", phase_string);
278 #endif
279  }
280  else
281  {
282  sdpisolver->solved = FALSE;
283  SCIPmessagePrintInfo(sdpisolver->messagehdlr, "SDPA failed to reach required feasibility tolerance! \n");
284  }
285  }
286  else
287  break;
288  }
289  return SCIP_OKAY;
290 }
291 
292 /*
293  * Miscellaneous Methods
294  */
295 
301 const char* SCIPsdpiSolverGetSolverName(
302  void
303  )
304 {/*lint !e1784*/
305  return "SDPA"; /* version number can only be printed to file/stdout */
306 }
307 
309 const char* SCIPsdpiSolverGetSolverDesc(
310  void
311  )
312 {/*lint !e1784*/
313  return "Primal-dual Interior Point Solver for SDPs developed by K. Fujisawa et al. (sdpa.sourceforge.net)";
314 }
315 
323  SCIP_SDPISOLVER* sdpisolver
324  )
325 {/*lint !e1784*/
326  assert( sdpisolver != NULL );
327  return (void*) sdpisolver->sdpa;
328 }
329 
332  void
333  )
334 {
335  return 1E-6;
336 }
337 
340  void
341  )
342 {
343  return 2;
344 }
345 
349 /*
350  * SDPI Creation and Destruction Methods
351  */
352 
357 SCIP_RETCODE SCIPsdpiSolverCreate(
358  SCIP_SDPISOLVER** sdpisolver,
359  SCIP_MESSAGEHDLR* messagehdlr,
360  BMS_BLKMEM* blkmem,
361  BMS_BUFMEM* bufmem
362  )
363 {/*lint !e1784*/
364  assert( sdpisolver != NULL );
365  assert( blkmem != NULL );
366  assert( bufmem != NULL );
367 
368  SCIPdebugMessage("Calling SCIPsdpiCreate \n");
369 
370  BMS_CALL( BMSallocBlockMemory(blkmem, sdpisolver) );
371 
372  (*sdpisolver)->messagehdlr = messagehdlr;
373  (*sdpisolver)->blkmem = blkmem;
374  (*sdpisolver)->bufmem = bufmem;
375 
376  /* this will be properly initialized then calling solve */
377  (*sdpisolver)->sdpa = NULL;
378 
379  (*sdpisolver)->nvars = 0;
380  (*sdpisolver)->nactivevars = 0;
381  (*sdpisolver)->inputtosdpamapper = NULL;
382  (*sdpisolver)->sdpatoinputmapper = NULL;
383  (*sdpisolver)->fixedvarsval = NULL;
384  (*sdpisolver)->fixedvarsobjcontr = 0.0;
385  (*sdpisolver)->objcoefs = NULL;
386  (*sdpisolver)->nvarbounds = 0;
387  (*sdpisolver)->varboundpos = NULL;
388  (*sdpisolver)->solved = FALSE;
389  (*sdpisolver)->timelimit = FALSE;
390  (*sdpisolver)->sdpcounter = 0;
391  (*sdpisolver)->niterations = 0;
392  (*sdpisolver)->nsdpcalls = 0;
393 
394  (*sdpisolver)->epsilon = 1e-9;
395  (*sdpisolver)->gaptol = 1e-4;
396  (*sdpisolver)->feastol = 1e-6;
397  (*sdpisolver)->sdpsolverfeastol = 1e-6;
398  (*sdpisolver)->objlimit = SCIPsdpiSolverInfinity(*sdpisolver);
399  (*sdpisolver)->sdpinfo = FALSE;
400  (*sdpisolver)->usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
401 
402  return SCIP_OKAY;
403 }
404 
406 SCIP_RETCODE SCIPsdpiSolverFree(
407  SCIP_SDPISOLVER** sdpisolver
408  )
409 {/*lint !e1784*/
410  assert( sdpisolver != NULL );
411  assert( *sdpisolver != NULL );
412 
413  SCIPdebugMessage("Freeing SDPISolver\n");
414 
415  /* free SDPA object using destructor and free memory via blockmemshell */
416  if ( (*sdpisolver)->sdpa != NULL)
417  delete (*sdpisolver)->sdpa;
418 
419  BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->varboundpos, 2 * (*sdpisolver)->nactivevars); /*lint !e647*/
420 
421  BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->inputtosdpamapper, (*sdpisolver)->nvars);/*lint !e737*/
422 
423  BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->sdpatoinputmapper, (*sdpisolver)->nactivevars);/*lint !e737*/
424 
425  BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->fixedvarsval, (*sdpisolver)->nvars - (*sdpisolver)->nactivevars); /*lint !e776*/
426 
427  BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->objcoefs, (*sdpisolver)->nactivevars); /*lint !e776*/
428 
429  BMSfreeBlockMemory((*sdpisolver)->blkmem, sdpisolver);
430 
431  return SCIP_OKAY;
432 }
433 
435 SCIP_RETCODE SCIPsdpiSolverIncreaseCounter(
436  SCIP_SDPISOLVER* sdpisolver
437  )
438 {/*lint !e1784*/
439  assert( sdpisolver != NULL );
440 
441  sdpisolver->sdpcounter++;
442 
443  return SCIP_OKAY;
444 }
445 
447 SCIP_RETCODE SCIPsdpiSolverResetCounter(
448  SCIP_SDPISOLVER* sdpisolver
449  )
450 {/*lint !e1784*/
451  assert( sdpisolver != NULL );
452 
453  SCIPdebugMessage("Resetting counter of SDP-Interface from %d to 0.\n", sdpisolver->sdpcounter);
454  sdpisolver->sdpcounter = 0;
455 
456  return SCIP_OKAY;
457 }
458 
462 /*
463  * Solving Methods
464  */
465 
481 SCIP_RETCODE SCIPsdpiSolverLoadAndSolve(
482  SCIP_SDPISOLVER* sdpisolver,
483  int nvars,
484  SCIP_Real* obj,
485  SCIP_Real* lb,
486  SCIP_Real* ub,
487  int nsdpblocks,
488  int* sdpblocksizes,
489  int* sdpnblockvars,
490  int sdpconstnnonz,
491  int* sdpconstnblocknonz,
493  int** sdpconstrow,
494  int** sdpconstcol,
495  SCIP_Real** sdpconstval,
496  int sdpnnonz,
497  int** sdpnblockvarnonz,
499  int** sdpvar,
501  int*** sdprow,
502  int*** sdpcol,
503  SCIP_Real*** sdpval,
504  int** indchanges,
506  int* nremovedinds,
507  int* blockindchanges,
508  int nremovedblocks,
509  int nlpcons,
510  int noldlpcons,
511  SCIP_Real* lplhs,
512  SCIP_Real* lprhs,
513  int* lprownactivevars,
514  int lpnnonz,
515  int* lprow,
516  int* lpcol,
517  SCIP_Real* lpval,
518  SCIP_Real* start,
519  SCIP_SDPSOLVERSETTING startsettings,
521  SCIP_Real timelimit
522  )
523 {/*lint !e1784*/
524  return SCIPsdpiSolverLoadAndSolveWithPenalty(sdpisolver, 0.0, TRUE, FALSE, nvars, obj, lb, ub, nsdpblocks, sdpblocksizes, sdpnblockvars, sdpconstnnonz,
525  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, sdpnnonz, sdpnblockvarnonz, sdpvar, sdprow, sdpcol, sdpval, indchanges,
526  nremovedinds, blockindchanges, nremovedblocks, nlpcons, noldlpcons, lplhs, lprhs, lprownactivevars, lpnnonz, lprow, lpcol, lpval, start,
527  startsettings, timelimit, NULL, NULL);
528 }
529 
550  SCIP_SDPISOLVER* sdpisolver,
551  SCIP_Real penaltyparam,
552  SCIP_Bool withobj,
553  SCIP_Bool rbound,
554  int nvars,
555  SCIP_Real* obj,
556  SCIP_Real* lb,
557  SCIP_Real* ub,
558  int nsdpblocks,
559  int* sdpblocksizes,
560  int* sdpnblockvars,
561  int sdpconstnnonz,
562  int* sdpconstnblocknonz,
564  int** sdpconstrow,
565  int** sdpconstcol,
566  SCIP_Real** sdpconstval,
567  int sdpnnonz,
568  int** sdpnblockvarnonz,
570  int** sdpvar,
572  int*** sdprow,
573  int*** sdpcol,
574  SCIP_Real*** sdpval,
575  int** indchanges,
577  int* nremovedinds,
578  int* blockindchanges,
579  int nremovedblocks,
580  int nlpcons,
581  int noldlpcons,
582  SCIP_Real* lplhs,
583  SCIP_Real* lprhs,
584  int* rownactivevars,
585  int lpnnonz,
586  int* lprow,
587  int* lpcol,
588  SCIP_Real* lpval,
589  SCIP_Real* start,
590  SCIP_SDPSOLVERSETTING startsettings,
592  SCIP_Real timelimit,
593  SCIP_Bool* feasorig,
595  SCIP_Bool* penaltybound
597  )
598 {/*lint !e1784*/
599  SCIP_Real feastol;
600  SCIP_Real* sdpavarbounds;
601  int i;
602  int k;
603  int block;
604  int nfixedvars;
605  bool checkinput; /* should the input be checked for consistency in SDPA ? */
606  int lpconsind;
607  int lastrow;
608  int* rowmapper; /* maps the lhs- and rhs-inequalities of the old LP-cons to their constraint numbers in DSDP */
609  int nlpineqs;
610  int pos;
611  int newpos;
612  int oldnactivevars;
613 #ifdef SCIP_MORE_DEBUG
614  int ind;
615 #endif
616 
617 #ifdef SCIP_DEBUG
618  char phase_string[15];
619 #endif
620 
621  assert( sdpisolver != NULL );
622  assert( penaltyparam > -1 * sdpisolver->epsilon );
623  assert( penaltyparam < sdpisolver->epsilon || ( feasorig != NULL ) );
624  assert( nvars > 0 );
625  assert( obj != NULL );
626  assert( lb != NULL );
627  assert( ub != NULL );
628  assert( nsdpblocks >= 0 );
629  assert( nsdpblocks == 0 || sdpblocksizes != NULL );
630  assert( nsdpblocks == 0 || sdpnblockvars != NULL );
631  assert( sdpconstnnonz >= 0 );
632  assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstnblocknonz != NULL );
633  assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstrow != NULL );
634  assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstcol != NULL );
635  assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstval != NULL );
636  assert( sdpnnonz >= 0 );
637  assert( nsdpblocks == 0 || sdpnblockvarnonz != NULL );
638  assert( nsdpblocks == 0 || sdpvar != NULL );
639  assert( nsdpblocks == 0 || sdprow != NULL );
640  assert( nsdpblocks == 0 || sdpcol != NULL );
641  assert( nsdpblocks == 0 || sdpval != NULL );
642  assert( nsdpblocks == 0 || indchanges != NULL );
643  assert( nsdpblocks == 0 || nremovedinds != NULL );
644  assert( nsdpblocks == 0 || blockindchanges != NULL );
645  assert( 0 <= nremovedblocks && nremovedblocks <= nsdpblocks );
646  assert( nlpcons >= 0 );
647  assert( noldlpcons >= nlpcons );
648  assert( nlpcons == 0 || lplhs != NULL );
649  assert( nlpcons == 0 || lprhs != NULL );
650  assert( nlpcons == 0 || rownactivevars != NULL );
651  assert( lpnnonz >= 0 );
652  assert( nlpcons == 0 || lprow != NULL );
653  assert( nlpcons == 0 || lpcol != NULL );
654  assert( nlpcons == 0 || lpval != NULL );
655 
656  sdpisolver->niterations = 0;
657  sdpisolver->nsdpcalls = 0;
658  sdpisolver->feasorig = FALSE;
659 
660  /* immediately exit if the time limit is negative */
661  if ( timelimit <= 0.0 )
662  {
663  sdpisolver->solved = FALSE;
664  sdpisolver->timelimit = TRUE;
665  return SCIP_OKAY;
666  }
667  else
668  sdpisolver->timelimit = FALSE;
669 
670 #ifndef SCIP_NDEBUG
671  checkinput = false;
672 #else
673  checkinput = true;
674 #endif
675 
676  sdpisolver->usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
677 
678  /* only increase the counter if we don't use the penalty formulation to stay in line with the numbers in the general interface (where this is still the
679  * same SDP) */
680  if ( penaltyparam < sdpisolver->epsilon )
681  SCIPdebugMessage("Inserting Data into SDPA for SDP (%d) \n", ++sdpisolver->sdpcounter);
682  else
683  SCIPdebugMessage("Inserting Data again into SDPA for SDP (%d) \n", sdpisolver->sdpcounter);
684 
685  /* set the penalty and rbound flags accordingly */
686  sdpisolver->penalty = (penaltyparam < sdpisolver->epsilon) ? FALSE : TRUE;
687  sdpisolver->rbound = rbound;
688 
689  /* allocate memory for inputtosdpamapper, sdpatoinputmapper and the fixed variable information, for the latter this will
690  * later be shrinked if the needed size is known */
691  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->inputtosdpamapper), sdpisolver->nvars, nvars) );
692  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->sdpatoinputmapper), sdpisolver->nactivevars, nvars) );
693  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->fixedvarsval), sdpisolver->nvars - sdpisolver->nactivevars, nvars) ); /*lint !e776*/
694  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->objcoefs), sdpisolver->nactivevars, nvars) ); /*lint !e776*/
695 
696  oldnactivevars = sdpisolver->nactivevars; /* we need to save this to realloc the varboundpos-array if needed */
697  sdpisolver->nvars = nvars;
698  sdpisolver->nactivevars = 0;
699  nfixedvars = 0;
700 
701  /* find the fixed variables */
702  sdpisolver->fixedvarsobjcontr = 0.0;
703  for (i = 0; i < nvars; i++)
704  {
705  if ( isFixed(sdpisolver, lb[i], ub[i]) )
706  {
707  sdpisolver->fixedvarsobjcontr += obj[i] * lb[i]; /* this is the value this fixed variable contributes to the objective */
708  sdpisolver->fixedvarsval[nfixedvars] = lb[i]; /* if lb=ub, than this is the value the variable will have in every solution */
709  nfixedvars++;
710  sdpisolver->inputtosdpamapper[i] = -nfixedvars;
711  SCIPdebugMessage("Fixing variable %d locally to %f for SDP %d in SDPA\n", i, lb[i], sdpisolver->sdpcounter);
712  }
713  else
714  {
715  sdpisolver->sdpatoinputmapper[sdpisolver->nactivevars] = i;
716  sdpisolver->objcoefs[sdpisolver->nactivevars] = obj[i];
717  sdpisolver->nactivevars++;
718  sdpisolver->inputtosdpamapper[i] = sdpisolver->nactivevars; /* sdpa starts counting at 1, so we do this after increasing nactivevars */
719 #ifdef SCIP_MORE_DEBUG
720  SCIPdebugMessage("Variable %d becomes variable %d for SDP %d in SDPA\n", i, sdpisolver->inputtosdpamapper[i], sdpisolver->sdpcounter);
721 #endif
722  }
723  }
724  assert( sdpisolver->nactivevars + nfixedvars == sdpisolver->nvars );
725 
726  /* if we want to solve without objective, we reset fixedvarsobjcontr */
727  if ( ! withobj )
728  sdpisolver->fixedvarsobjcontr = 0.0;
729 
730  /* shrink the fixedvars and sdpatoinputmapper arrays to the right size */
731  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->objcoefs), nvars, sdpisolver->nactivevars) );
732  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->fixedvarsval), nvars, nfixedvars) );
733  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->sdpatoinputmapper), nvars, sdpisolver->nactivevars) );
734 
735  /* insert data */
736  if ( sdpisolver->sdpa != 0 )
737  {
738  /* if the SDPA solver has already been created, clear the current problem instance */
739  delete sdpisolver->sdpa;
740  sdpisolver->sdpa = new SDPA();
741  }
742  else
743  sdpisolver->sdpa = new SDPA();
744  assert( sdpisolver->sdpa != 0 );
745 
746  /* initialize settings (this needs to be done before inserting the problem as the initial point depends on the settings) */
747  if ( penaltyparam >= sdpisolver->epsilon || startsettings == SCIP_SDPSOLVERSETTING_STABLE || startsettings == SCIP_SDPSOLVERSETTING_PENALTY )
748  {
749  sdpisolver->sdpa->setParameterType(SDPA::PARAMETER_STABLE_BUT_SLOW); /* if we already had problems with this problem, there is no reason to try fast */
750  /* as we want to solve with stable settings, we also update epsilon and the feasibility tolerance, as we skip the default settings, we multpy twice */
751  sdpisolver->sdpa->setParameterEpsilonStar(GAPTOLCHANGE * GAPTOLCHANGE * sdpisolver->gaptol);
752  sdpisolver->sdpa->setParameterEpsilonDash(FEASTOLCHANGE * FEASTOLCHANGE * sdpisolver->sdpsolverfeastol);
753  feastol = FEASTOLCHANGE * FEASTOLCHANGE * sdpisolver->sdpsolverfeastol;
754  SCIPdebugMessage("Start solving process with stable settings\n");
755  }
756  else if ( startsettings == SCIP_SDPSOLVERSETTING_UNSOLVED || startsettings == SCIP_SDPSOLVERSETTING_FAST)
757  {
758  sdpisolver->sdpa->setParameterType(SDPA::PARAMETER_UNSTABLE_BUT_FAST);
759  sdpisolver->sdpa->setParameterEpsilonStar(sdpisolver->gaptol);
760  sdpisolver->sdpa->setParameterEpsilonDash(sdpisolver->sdpsolverfeastol);
761  feastol = sdpisolver->sdpsolverfeastol;
762  SCIPdebugMessage("Start solving process with fast settings\n");
763  }
764  else if ( startsettings == SCIP_SDPSOLVERSETTING_MEDIUM )
765  {
766  sdpisolver->sdpa->setParameterType(SDPA::PARAMETER_DEFAULT);
767  /* as we want to solve with stable settings, we also update epsilon and the feasibility tolerance, as we skip the default settings, we multpy once */
768  sdpisolver->sdpa->setParameterEpsilonStar(GAPTOLCHANGE * sdpisolver->gaptol);
769  sdpisolver->sdpa->setParameterEpsilonDash(FEASTOLCHANGE * sdpisolver->sdpsolverfeastol);
770  feastol = FEASTOLCHANGE * sdpisolver->sdpsolverfeastol;
771  SCIPdebugMessage("Start solving process with medium settings\n");
772  }
773  else
774  {
775  SCIPdebugMessage("Unknown setting for start-settings: %d!\n", startsettings); \
776  return SCIP_LPERROR;
777  }
778  sdpisolver->sdpa->setParameterLowerBound(-1e20);
779 
780 
781  /* set the objective limit */
782  if ( ! SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit) )
783  sdpisolver->sdpa->setParameterUpperBound(sdpisolver->objlimit);
784  else
785  sdpisolver->sdpa->setParameterUpperBound(1e8);
786 
787  /* increase Lambda Star, this seems to help the numerics */
788  sdpisolver->sdpa->setParameterLambdaStar(sdpisolver->lambdastar);
789 
790 #ifdef SCIP_MORE_DEBUG
791  sdpisolver->sdpa->printParameters(stdout);
792 #endif
793 
794  /* compute number of variable bounds and save them in sdpavarbounds */
795  sdpisolver->nvarbounds = 0;
796  BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &sdpavarbounds, 2 * sdpisolver->nactivevars) ); /*lint !e647*//*lint !e530*/
797 
798  if ( sdpisolver->nactivevars != oldnactivevars )
799  {
800  if ( sdpisolver->varboundpos == NULL )
801  {
802  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->varboundpos), 2 * sdpisolver->nactivevars) ); /*lint !e647*/
803  }
804  else
805  {
806  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->varboundpos), 2 * oldnactivevars, 2 * sdpisolver->nactivevars) ); /*lint !e647*/
807  }
808  }
809  assert( sdpisolver->varboundpos != NULL );
810 
811  for (i = 0; i < sdpisolver->nactivevars; i++)
812  {
813  assert( 0 <= sdpisolver->sdpatoinputmapper[i] && sdpisolver->sdpatoinputmapper[i] < nvars );
814  if ( ! SCIPsdpiSolverIsInfinity(sdpisolver, lb[sdpisolver->sdpatoinputmapper[i]]))
815  {
816  sdpavarbounds[sdpisolver->nvarbounds] = lb[sdpisolver->sdpatoinputmapper[i]];
817  sdpisolver->varboundpos[sdpisolver->nvarbounds] = -(i + 1); /* negative sign means lower bound, i + 1 because sdpa starts counting from one */
818  (sdpisolver->nvarbounds)++;
819  }
820  if ( ! SCIPsdpiSolverIsInfinity(sdpisolver, ub[sdpisolver->sdpatoinputmapper[i]]) )
821  {
822  sdpavarbounds[sdpisolver->nvarbounds] = ub[sdpisolver->sdpatoinputmapper[i]];
823  sdpisolver->varboundpos[sdpisolver->nvarbounds] = +(i + 1); /* positive sign means upper bound, i + 1 because sdpa starts counting from one */
824  (sdpisolver->nvarbounds)++;
825  }
826  }
827 
828  if ( nlpcons > 0 )
829  {
830  /* allocate memory to save which lpconstraints are mapped to which index, entry 2i corresponds to the left hand side of row i, 2i+1 to the rhs */
831  BMS_CALL( BMSallocBufferMemoryArray(sdpisolver->bufmem, &rowmapper, 2*noldlpcons) ); /*lint !e647*//*lint !e530*/
832 
833  /* compute the number of LP constraints after splitting the ranged rows and compute the rowmapper */
834  pos = 1; /* SDPA starts counting the LP-inequalities at one */
835  newpos = 0; /* the position in the lhs and rhs arrays */
836  for (i = 0; i < noldlpcons; i++)
837  {
838  if ( rownactivevars[i] >= 2 )
839  {
840  if ( lplhs[newpos] > - SCIPsdpiSolverInfinity(sdpisolver) )
841  {
842  rowmapper[2*i] = pos; /*lint !e679*/
843  pos++;
844  }
845  else
846  rowmapper[2*i] = -1; /*lint !e679*/
847  if ( lprhs[newpos] < SCIPsdpiSolverInfinity(sdpisolver) )
848  {
849  rowmapper[2*i + 1] = pos; /*lint !e679*/
850  pos++;
851  }
852  else
853  rowmapper[2*i + 1] = -1; /*lint !e679*/
854 
855  newpos++;
856  }
857  else
858  {
859  rowmapper[2*i] = -1; /*lint !e679*/
860  rowmapper[2*i + 1] = -1; /*lint !e679*/
861  }
862  }
863  nlpineqs = pos - 1; /* minus one because we started at one as SDPA wants them numbered one to nlpineqs */
864  assert( nlpineqs <= 2*nlpcons ); /* *2 comes from left- and right-hand-sides */
865  }
866  else
867  nlpineqs = 0;
868 
869  /* if we use a penalty formulation, we need the constraint r >= 0 */
870  if ( penaltyparam >= sdpisolver->epsilon && rbound )
871  sdpisolver->nvarbounds++;
872 
873  if ( sdpisolver->sdpinfo )
874  sdpisolver->sdpa->setDisplay(stdout);
875  else
876  sdpisolver->sdpa->setDisplay(0);
877 
878 #ifdef SCIP_MORE_DEBUG
879  FILE* fpOut = fopen("output.tmp", "w");
880  if ( ! fpOut )
881  exit(-1);
882  sdpisolver->sdpa->setResultFile(fpOut);
883 #endif
884 
885  /* initialize blockstruct */
886  if ( penaltyparam < sdpisolver->epsilon ) /* we initialize this with an exact 0.0 in Solve without penalty */
887  sdpisolver->sdpa->inputConstraintNumber((long long) sdpisolver->nactivevars);/*lint !e747*/
888  else
889  sdpisolver->sdpa->inputConstraintNumber((long long) sdpisolver->nactivevars + 1);/*lint !e747*/ /* the additional variable is r for the penalty formulation */
890 
891  /* if there are any lp-cons/variable-bounds, we get an extra block for those, lastrow - nshifts is the number of lp constraints added */
892  sdpisolver->sdpa->inputBlockNumber((long long) ((nlpineqs + sdpisolver->nvarbounds > 0) ?
893  nsdpblocks - nremovedblocks + 1 : nsdpblocks - nremovedblocks)); /*lint !e834 !e747 !e776*/
894 
895  /* block+1 because SDPA starts counting at 1 */
896  for (block = 0; block < nsdpblocks; block++)
897  {
898  if ( blockindchanges[block] >= 0 )
899  {
900  SCIPdebugMessage("adding block %d to SDPA as block %d with size %d\n",
901  block, block - blockindchanges[block] + 1, sdpblocksizes[block] - nremovedinds[block]); /*lint !e834*/
902  sdpisolver->sdpa->inputBlockSize((long long) block - blockindchanges[block] + 1,/*lint !e747, !e834*/
903  (long long) sdpblocksizes[block] - nremovedinds[block]); /*lint !e834, !e776, !e747*/
904  sdpisolver->sdpa->inputBlockType((long long) block - blockindchanges[block] + 1, SDPA::SDP); /*lint !e834, !e776, !e747*/
905  }
906  }
907  if ( nlpineqs + sdpisolver->nvarbounds > 0 )
908  {
909  /* the last block is the lp block, the size has a negative sign */
910  sdpisolver->sdpa->inputBlockSize((long long) nsdpblocks - nremovedblocks + 1, (long long) -(nlpineqs + sdpisolver->nvarbounds)); /*lint !e834, !e776, !e747*/
911  sdpisolver->sdpa->inputBlockType((long long) nsdpblocks - nremovedblocks + 1, SDPA::LP); /*lint !e834, !e776, !e747*/
912  SCIPdebugMessage("adding LP block to SDPA as block %d with size %d\n", nsdpblocks - nremovedblocks + 1,/*lint !e834*/
913  -(nlpineqs + sdpisolver->nvarbounds)); /*lint !e834*/
914  }
915 
916  sdpisolver->sdpa->initializeUpperTriangleSpace();
917 
918  /* set objective values */
919  for (i = 0; i < sdpisolver->nactivevars; i++)
920  {
921  if ( withobj )
922  {
923  /* insert objective value, SDPA counts from 1 to n instead of 0 to n-1 */
924  sdpisolver->sdpa->inputCVec((long long) i + 1, obj[sdpisolver->sdpatoinputmapper[i]]);/*lint !e747*/
925 #ifdef SCIP_MORE_DEBUG
926  SCIPdebugMessage("inserting objective %f for variable %d which became variable %d in SDPA\n", obj[sdpisolver->sdpatoinputmapper[i]],
927  sdpisolver->sdpatoinputmapper[i], i+1);
928 #endif
929  }
930  if ( penaltyparam >= sdpisolver->epsilon )
931  sdpisolver->sdpa->inputCVec((long long) sdpisolver->nactivevars + 1, penaltyparam);/*lint !e747*/ /* set the objective of the additional var to penaltyparam */
932  }
933 
934  /* if we want to use a starting point we have to tell SDPA to allocate memory for it */
935  if ( start != NULL )
936  sdpisolver->sdpa->setInitPoint(true);
937  else
938  sdpisolver->sdpa->setInitPoint(false);
939 
940  /* start inserting the non-constant SDP-Constraint-Matrices */
941  if ( sdpnnonz > 0 )
942  {
943  int v;
944  int blockvar;
945 
946  assert( nsdpblocks > 0 );
947  assert( sdpnblockvarnonz != NULL );
948  assert( sdpnblockvars != NULL );
949  assert( sdpcol != NULL );
950  assert( sdprow != NULL );
951  assert( sdpval != NULL );
952  assert( sdpvar != NULL );
953  assert( indchanges != NULL );
954  assert( nremovedinds != NULL );
955 
956  for (block = 0; block < nsdpblocks; block++)
957  {
958  /* if the block has no entries, we skip it */
959  if ( blockindchanges[block] == -1 )
960  continue;
961 #ifdef SCIP_MORE_DEBUG
962  SCIPdebugMessage(" -> building block %d, which becomes block %d in SDPA (%d)\n", block, block - blockindchanges[block] + 1,sdpisolver->sdpcounter);
963 #endif
964  /* iterate over all variables in this block */
965  for (blockvar = 0; blockvar < sdpnblockvars[block]; blockvar++)
966  {
967  v = sdpisolver->inputtosdpamapper[sdpvar[block][blockvar]];
968 
969 #ifdef SCIP_MORE_DEBUG
970  SCIPdebugMessage(" -> adding coefficient matrix for variable %d which becomes variable %d in SDPA (%d)\n",
971  sdpvar[block][blockvar], v, sdpisolver->sdpcounter);
972 #endif
973 
974  /* check if the variable is active */
975  if ( v > -1 )
976  {
977  for (k = 0; k < sdpnblockvarnonz[block][blockvar]; k++)
978  {
979  /* rows and cols with active nonzeros should not be removed */
980  assert( indchanges[block][sdprow[block][blockvar][k]] > -1 && indchanges[block][sdpcol[block][blockvar][k]] > -1 );
981 
982  assert( indchanges[block][sdprow[block][blockvar][k]] <= sdprow[block][blockvar][k]);
983  assert( indchanges[block][sdpcol[block][blockvar][k]] <= sdpcol[block][blockvar][k]);
984 
985  assert( 0 <= sdprow[block][blockvar][k] && sdprow[block][blockvar][k] < sdpblocksizes[block] );
986  assert( 0 <= sdpcol[block][blockvar][k] && sdpcol[block][blockvar][k] < sdpblocksizes[block] );
987 
988  /* rows and columns start with one in SDPA, so we have to add 1 to the indices */
989 #ifdef SCIP_MORE_DEBUG
990  SCIPdebugMessage(" -> adding nonzero %g at (%d,%d) (%d)\n",
991  sdpval[block][blockvar][k],
992  sdpcol[block][blockvar][k] - indchanges[block][sdpcol[block][blockvar][k]] + 1,
993  sdprow[block][blockvar][k] - indchanges[block][sdprow[block][blockvar][k]] + 1,
994  sdpisolver->sdpcounter);
995 #endif
996 
997  sdpisolver->sdpa->inputElement((long long) v, (long long) block - blockindchanges[block] + 1, /*lint !e834, !e747*/
998  (long long) sdpcol[block][blockvar][k] - indchanges[block][sdpcol[block][blockvar][k]] + 1, /*lint !e834, !e747*/
999  (long long) sdprow[block][blockvar][k] - indchanges[block][sdprow[block][blockvar][k]] + 1, /*lint !e834, !e747*/
1000  sdpval[block][blockvar][k], checkinput); /*lint !e776 !e834*/
1001  }
1002  }
1003  }
1004  /* insert the identity matrix if we are using a penalty formulation */
1005  if ( penaltyparam >= sdpisolver->epsilon )
1006  {
1007 #ifdef SCIP_MORE_DEBUG
1008  SCIPdebugMessage(" -> adding coefficient matrix for penalty variable r in SDPA (%d)\n", sdpisolver->sdpcounter);
1009 #endif
1010  for (i = 0; i < sdpblocksizes[block] - nremovedinds[block]; i++)
1011  {
1012 #ifdef SCIP_MORE_DEBUG
1013  SCIPdebugMessage(" -> adding nonzero 1.0 at (%d,%d) (%d)\n", i + 1, i + 1, sdpisolver->sdpcounter);
1014 #endif
1015 
1016  sdpisolver->sdpa->inputElement((long long) sdpisolver->nactivevars + 1, (long long) block - blockindchanges[block] + 1, /*lint !e747, !e776, !e834*/
1017  (long long) i + 1, (long long) i + 1, 1.0, checkinput);/*lint !e747*/
1018  }
1019  }
1020  }
1021  }
1022 
1023  /* start inserting the constant matrix */
1024  if ( sdpconstnnonz > 0 )
1025  {
1026  assert( nsdpblocks > 0 );
1027  assert( sdpconstnblocknonz!= NULL );
1028  assert( sdpconstcol != NULL );
1029  assert( sdpconstrow != NULL );
1030  assert( sdpconstval != NULL );
1031 
1032  for (block = 0; block < nsdpblocks; block++)
1033  {
1034  if ( blockindchanges[block] == -1 )
1035  continue;
1036 #ifdef SCIP_MORE_DEBUG
1037  SCIPdebugMessage(" -> building block %d (%d)\n", block + 1, sdpisolver->sdpcounter);
1038 #endif
1039  for (k = 0; k < sdpconstnblocknonz[block]; k++)
1040  {
1041  /* rows and cols with active nonzeros should not be removed */
1042  assert( indchanges[block][sdpconstrow[block][k]] > -1 && indchanges[block][sdpconstcol[block][k]] > -1 );
1043 
1044  assert( indchanges[block][sdpconstrow[block][k]] <= sdpconstrow[block][k]);
1045  assert( indchanges[block][sdpconstcol[block][k]] <= sdpconstcol[block][k]);
1046 
1047  assert (0 <= sdpconstrow[block][k] && sdpconstrow[block][k] < sdpblocksizes[block]);
1048  assert (0 <= sdpconstcol[block][k] && sdpconstcol[block][k] < sdpblocksizes[block]);
1049 
1050  /* rows and columns start with one in SDPA, so we have to add 1 to the indices, the constant matrix is given as variable 0 */
1051 #ifdef SCIP_MORE_DEBUG
1052  SCIPdebugMessage(" -> adding constant nonzero %g at (%d,%d) (%d)\n", sdpconstval[block][k],
1053  sdpconstcol[block][k] - indchanges[block][sdpconstcol[block][k]] + 1,
1054  sdpconstrow[block][k] - indchanges[block][sdpconstrow[block][k]] + 1,
1055  sdpisolver->sdpcounter);
1056 #endif
1057  sdpisolver->sdpa->inputElement((long long) 0, (long long) block - blockindchanges[block] + 1, /*lint !e747, !e776, !e834*/
1058  (long long) sdpconstcol[block][k] - indchanges[block][sdpconstcol[block][k]] + 1, /*lint !e747, !e776, !e834*/
1059  (long long) sdpconstrow[block][k] - indchanges[block][sdpconstrow[block][k]] + 1, /*lint !e747, !e776, !e834*/
1060  sdpconstval[block][k], checkinput);
1061  }
1062  }
1063  }
1064 
1065 #ifdef SCIP_MORE_DEBUG
1066  SCIPdebugMessage(" -> building LP-block %d (%d)\n", nsdpblocks - nremovedblocks + 1, sdpisolver->sdpcounter);
1067 #endif
1068  /* inserting LP nonzeros */
1069  lastrow = -1;
1070  for (i = 0; i < lpnnonz; i++)
1071  {
1072  assert( 0 <= lprow[i] && lprow[i] < noldlpcons );
1073  assert( 0 <= lpcol[i] && lpcol[i] < nvars );
1074  assert( REALABS(lpval[i]) > sdpisolver->epsilon );
1075 
1076  /* if the variable is active and the constraint is more than a bound, we add it */
1077  if ( sdpisolver->inputtosdpamapper[lpcol[i]] > 0 )
1078  {
1079  /* as this is an active variable, there should be at least one in the constraint */
1080  assert( rownactivevars[lprow[i]] > 0 );
1081  if ( rownactivevars[lprow[i]] > 1 )
1082  {
1083  if ( lprow[i] > lastrow ) /* we update the lpcons-counter */
1084  {
1085  lastrow = lprow[i];
1086  /* if we use a penalty formulation, add the r * Identity entry */
1087  if ( penaltyparam >= sdpisolver->epsilon )
1088  {
1089  /* check for the lhs-inequality */
1090  if ( rowmapper[2*lastrow] > -1 ) /*lint !e679*/
1091  {
1092 #ifdef SCIP_MORE_DEBUG
1093  SCIPdebugMessage(" -> adding nonzero 1.0 at (%d,%d) for penalty variable r in SDPA (%d)\n",
1094  rowmapper[2*lastrow], rowmapper[2*lastrow], sdpisolver->sdpcounter);
1095 #endif
1096  /* LP nonzeros are added as diagonal entries of the last block (coming after the last SDP-block, with
1097  * blocks starting at 1, as are rows), the r-variable is variable nactivevars + 1 */
1098  sdpisolver->sdpa->inputElement((long long) sdpisolver->nactivevars + 1, (long long) nsdpblocks - nremovedblocks + 1, /*lint !e747, !e776, !e834*/
1099  (long long) rowmapper[2*lastrow], (long long) rowmapper[2*lastrow], 1.0, checkinput); /*lint !e679, !e747, !e834*/
1100  }
1101 
1102  /* check for the rhs-inequality */
1103  if ( rowmapper[2*lastrow + 1] > -1 ) /*lint !e679*/
1104  {
1105 #ifdef SCIP_MORE_DEBUG
1106  SCIPdebugMessage(" -> adding nonzero 1.0 at (%d,%d) for penalty variable r in SDPA (%d)\n",
1107  rowmapper[2*lastrow + 1], rowmapper[2*lastrow + 1], sdpisolver->sdpcounter);
1108 #endif
1109  /* LP nonzeros are added as diagonal entries of the last block (coming after the last SDP-block, with
1110  * blocks starting at 1, as are rows), the r-variable is variable nactivevars + 1 */
1111  sdpisolver->sdpa->inputElement((long long) sdpisolver->nactivevars + 1, (long long) nsdpblocks - nremovedblocks + 1, /*lint !e747, !e776, !e834*/
1112  (long long) rowmapper[2*lastrow + 1], (long long) rowmapper[2*lastrow + 1], 1.0, checkinput); /*lint !e679, !e747, !e834*/
1113  }
1114  }
1115  }
1116  /* add the lp-nonzero to the lhs-inequality if it exists: */
1117  if ( rowmapper[2*lastrow] > -1 ) /*lint !e679*/
1118  {
1119 #ifdef SCIP_MORE_DEBUG
1120  SCIPdebugMessage(" -> adding nonzero %g at (%d,%d) for variable %d which became variable %d in SDPA (%d)\n",
1121  lpval[i], rowmapper[2*lastrow], rowmapper[2*lastrow], lpcol[i], sdpisolver->inputtosdpamapper[lpcol[i]], sdpisolver->sdpcounter);
1122 #endif
1123  /* LP nonzeros are added as diagonal entries of the last block (coming after the last SDP-block, with blocks starting at 1, as are rows) */
1124  sdpisolver->sdpa->inputElement((long long) sdpisolver->inputtosdpamapper[lpcol[i]], (long long) nsdpblocks - nremovedblocks + 1, /*lint !e747, !e776, !e834*/
1125  (long long) rowmapper[2*lastrow], (long long) rowmapper[2*lastrow], lpval[i], checkinput); /*lint !e679, !e747, !e834*/
1126  }
1127  /* add the lp-nonzero to the rhs-inequality if it exists: */
1128  if ( rowmapper[2*lastrow + 1] > -1 ) /*lint !e679*/
1129  {
1130 #ifdef SCIP_MORE_DEBUG
1131  SCIPdebugMessage(" -> adding nonzero %g at (%d,%d) for variable %d which became variable %d in SDPA (%d)\n",
1132  -1 * lpval[i], rowmapper[2*lastrow + 1], rowmapper[2*lastrow + 1], lpcol[i], sdpisolver->inputtosdpamapper[lpcol[i]], sdpisolver->sdpcounter);
1133 #endif
1134  /* LP nonzeros are added as diagonal entries of the last block (coming after the last SDP-block, with blocks starting at 1, as are rows),
1135  * the -1 comes from the fact that this is a <=-constraint, while SDPA works with >= */
1136  sdpisolver->sdpa->inputElement((long long) sdpisolver->inputtosdpamapper[lpcol[i]], (long long) nsdpblocks - nremovedblocks + 1, /*lint !e747, !e776, !e834*/
1137  (long long) rowmapper[2*lastrow + 1], (long long) rowmapper[2*lastrow + 1], -1 * lpval[i], checkinput); /*lint !e679, !e747, !e834*/
1138  }
1139  }
1140  }
1141  }
1142 
1143  /* inserting LP left- and right-hand-sides for active constraints */
1144  lpconsind = 1; /* this is the same order we used when computing the rowmapper, so we insert at the right positions */
1145  for (i = 0; i < nlpcons; i++)
1146  {
1147  /* check for left-hand side */
1148  if ( lplhs[i] > - SCIPsdpiSolverInfinity(sdpisolver) )
1149  {
1150 #ifdef SCIP_MORE_DEBUG
1151  SCIPdebugMessage(" -> adding lhs %g at (%d,%d) (%d)\n", lplhs[i], lpconsind, lpconsind, sdpisolver->sdpcounter);
1152 #endif
1153  /* LP constraints are added as diagonal entries of the last block, left-hand-side is added as variable zero */
1154  sdpisolver->sdpa->inputElement((long long) 0, (long long) nsdpblocks - nremovedblocks + 1, (long long) lpconsind, /*lint !e747, !e776, !e834*/
1155  (long long) lpconsind, lplhs[i], checkinput);/*lint !e747*/
1156  lpconsind++;
1157  }
1158 
1159  /* check for right-hand side */
1160  if ( lprhs[i] < SCIPsdpiSolverInfinity(sdpisolver) )
1161  {
1162 #ifdef SCIP_MORE_DEBUG
1163  SCIPdebugMessage(" -> adding lhs (originally rhs) %g at (%d,%d) (%d)\n", -1 * lprhs[i], lpconsind, lpconsind, sdpisolver->sdpcounter);
1164 #endif
1165  /* LP constraints are added as diagonal entries of the last block, right-hand side is added as variable zero, the -1 comes from
1166  * the fact, that SDPA uses >=, while the rhs is a <=-constraint */
1167  sdpisolver->sdpa->inputElement((long long) 0, (long long) nsdpblocks - nremovedblocks + 1, (long long) lpconsind, /*lint !e747, !e776, !e834*/
1168  (long long) lpconsind, -1 * lprhs[i], checkinput);/*lint !e747*/
1169  lpconsind++;
1170  }
1171  }
1172 
1173  assert( lpconsind == nlpineqs + 1 ); /* plus one because we started at one as SDPA wants them numbered one to nlpineqs */
1174 
1175  /* print each LP-constraint as one formatted constraint in addition to the single entries inserted into SDPA */
1176 #ifdef SCIP_MORE_DEBUG
1177  lastrow = -1;
1178  ind = -1; /* this is increased once before the first usage */
1179  for (i = 0; i < lpnnonz; i++)
1180  {
1181  /* if the variable is active and the constraint is more than a bound, we added it */
1182  if ( sdpisolver->inputtosdpamapper[lpcol[i]] > 0 )
1183  {
1184  if ( rownactivevars[lprow[i]] > 1 )
1185  {
1186  if ( lprow[i] > lastrow ) /* we finished the old row */
1187  {
1188  if ( lastrow >= 0 )
1189  {
1190  if ( lprhs[ind] < SCIPsdpiSolverInfinity(sdpisolver) )
1191  SCIPmessagePrintInfo(sdpisolver->messagehdlr, " <= %f\n", lprhs[ind]);
1192  else
1193  SCIPmessagePrintInfo(sdpisolver->messagehdlr, "\n");
1194  }
1195  lastrow = lprow[i];
1196  ind++;
1197  if ( lplhs[ind] > - SCIPsdpiSolverInfinity(sdpisolver) )
1198  SCIPmessagePrintInfo(sdpisolver->messagehdlr, "%f <= ", lplhs[ind]);
1199  }
1200  SCIPmessagePrintInfo(sdpisolver->messagehdlr, "+ %f <x%d> ", lpval[i], lpcol[i]);
1201  }
1202  }
1203  }
1204  if ( lastrow >= 0 )
1205  {
1206  if ( lprhs[ind] < SCIPsdpiSolverInfinity(sdpisolver) )
1207  SCIPmessagePrintInfo(sdpisolver->messagehdlr, " <= %f\n", lprhs[ind]);
1208  else
1209  SCIPmessagePrintInfo(sdpisolver->messagehdlr, "\n");
1210  }
1211  assert( ind == nlpcons - 1 ); /* -1 because we start indexing at zero and do not increase after the last row */
1212 #endif
1213 
1214  /* free the memory for the rowmapper */
1215  if ( nlpcons > 0 )
1216  BMSfreeBufferMemoryArray(sdpisolver->bufmem, &rowmapper);/*lint !e647, !e737*/
1217 
1218  /* insert variable bounds, these are also added as LP-constraints and therefore diagonal entries of the LP block
1219  * if we work with the penalty formulation, we get an extra entry for r >= 0, but this we will add afterwards */
1220  for (i = 0; i < ((penaltyparam < sdpisolver->epsilon) || (! rbound) ? sdpisolver->nvarbounds : sdpisolver->nvarbounds - 1); i++)
1221  {
1222  assert( 0 < abs(sdpisolver->varboundpos[i]) && abs(sdpisolver->varboundpos[i] <= sdpisolver->nactivevars) ); /* the indices are already those for SDPA */
1223 
1224  /* for lower bound */
1225  if ( sdpisolver->varboundpos[i] < 0 )
1226  {
1227  /* add it as an lp-constraint for this variable (- because we saved -n for the lower bound), at the position
1228  * (nactivelpcons + 1) + varbound-index, because we have >= the variable has coefficient +1 */
1229  sdpisolver->sdpa->inputElement((long long) -sdpisolver->varboundpos[i], (long long) nsdpblocks - nremovedblocks + 1, /*lint !e747, !e776, !e834*/
1230  (long long) nlpineqs + 1 + i, (long long) nlpineqs + 1 + i, 1.0, checkinput);/*lint !e747*/
1231 
1232  if ( REALABS(sdpavarbounds[i]) > sdpisolver->epsilon )
1233  {
1234  /* the bound is added as the rhs and therefore variable zero */
1235 #ifdef SCIP_MORE_DEBUG
1236  SCIPdebugMessage(" -> adding lower bound %g at (%d,%d) for variable %d which became variable %d in SDPA (%d)\n",
1237  sdpavarbounds[i], nlpineqs + 1 + i, nlpineqs + 1 + i, sdpisolver->sdpatoinputmapper[-sdpisolver->varboundpos[i] - 1],
1238  -sdpisolver->varboundpos[i], sdpisolver->sdpcounter);
1239 #endif
1240  sdpisolver->sdpa->inputElement((long long) 0, (long long) nsdpblocks - nremovedblocks + 1, (long long) nlpineqs + 1 + i, /*lint !e747, !e776, !e834*/
1241  (long long) nlpineqs + 1 + i, sdpavarbounds[i], checkinput);/*lint !e747*/
1242  }
1243  else
1244  {
1245  /* as the bound is zero, we don't need to add a right hand side */
1246 #ifdef SCIP_MORE_DEBUG
1247  SCIPdebugMessage(" -> adding lower bound 0 at (%d,%d) for variable %d which became variable %d in SDPA (%d)\n",
1248  nlpineqs + 1 + i, nlpineqs + 1 + i, sdpisolver->sdpatoinputmapper[-sdpisolver->varboundpos[i] - 1],
1249  -sdpisolver->varboundpos[i], sdpisolver->sdpcounter);
1250 #endif
1251  }
1252  }
1253  else
1254  {
1255  /* this is an upper bound */
1256 
1257  /* add it as an lp-constraint for this variable, at the position nactivelpcons + varbound-index, because we have >= but we
1258  * want <= for the upper bound, we have to multiply by -1 and therefore the variable has coefficient -1 */
1259  sdpisolver->sdpa->inputElement((long long) sdpisolver->varboundpos[i], (long long) nsdpblocks - nremovedblocks + 1, /*lint !e747, !e776, !e834*/
1260  (long long) nlpineqs + 1 + i, (long long) nlpineqs + 1 + i, -1.0, checkinput);/*lint !e747*/
1261 
1262  if ( REALABS(sdpavarbounds[i]) > sdpisolver->epsilon )
1263  {
1264  /* the bound is added as the rhs and therefore variable zero, we multiply by -1 for <= */
1265 #ifdef SCIP_MORE_DEBUG
1266  SCIPdebugMessage(" -> adding upper bound %g at (%d,%d) for variable %d which became variable %d in SDPA (%d)\n",
1267  sdpavarbounds[i], nlpineqs + 1 + i, nlpineqs + 1 + i, sdpisolver->sdpatoinputmapper[sdpisolver->varboundpos[i] - 1],
1268  sdpisolver->varboundpos[i], sdpisolver->sdpcounter);
1269 #endif
1270  sdpisolver->sdpa->inputElement((long long) 0, (long long) nsdpblocks - nremovedblocks + 1, (long long) nlpineqs + 1 + i, /*lint !e747, !e776, !e834*/
1271  (long long) nlpineqs + 1 + i, -sdpavarbounds[i], checkinput);/*lint !e747*/
1272  }
1273  else
1274  {
1275  /* as the bound is zero, we don't need to add a right hand side */
1276 #ifdef SCIP_MORE_DEBUG
1277  SCIPdebugMessage(" -> adding upper bound 0 at (%d,%d) for variable %d which became variable %d in SDPA (%d)\n",
1278  0, nlpineqs + 1 + i, nlpineqs + 1 + i, sdpisolver->sdpatoinputmapper[sdpisolver->varboundpos[i] - 1],
1279  sdpisolver->varboundpos[i]);
1280 #endif
1281  }
1282  }
1283  }
1284 
1285  if ( penaltyparam >= sdpisolver->epsilon && rbound )
1286  {
1287  /* we add the variable bound r >= 0 */
1288  sdpisolver->sdpa->inputElement((long long) sdpisolver->nactivevars + 1, (long long) nsdpblocks - nremovedblocks + 1, /*lint !e747, !e776, !e834*/
1289  (long long) nlpineqs + 1 + i, (long long) nlpineqs + 1 + i, 1.0, checkinput);/*lint !e747*/
1290 #ifdef SCIP_MORE_DEBUG
1291  SCIPdebugMessage(" -> adding lower bound r >= 0 at (%d,%d) in SDPA (%d)\n", nlpineqs + 1 + i, nlpineqs + 1 + i, sdpisolver->sdpcounter);
1292 #endif
1293  }
1294 
1295  /* free the arrays used for counting and saving variable bounds and LP-right-hand-sides */
1296  BMSfreeBufferMemoryArray(sdpisolver->bufmem, &sdpavarbounds); /*lint !e647, !e737*/
1297 
1298  /* transform the matrices to a more efficient form */
1299  sdpisolver->sdpa->initializeUpperTriangle();
1300  sdpisolver->sdpa->initializeSolve();
1301 
1302  /* set the starting solution */
1303  if ( start != NULL && penaltyparam < sdpisolver->epsilon )
1304  {
1305  SCIPdebugMessage("Starting with a previous solution is not yet tested for the interface, only x-vector is given, not y and Z");
1306  for (i = 1; i <= sdpisolver->nactivevars; i++) /* we iterate over the variables in sdpa */
1307  sdpisolver->sdpa->inputInitXVec((long long) i, start[sdpisolver->sdpatoinputmapper[i] - 1]);/*lint !e747*/
1308  }
1309  else if ( penaltyparam >= sdpisolver->epsilon )
1310  SCIPdebugMessage("Skipping insertion of starting point, as this is not yet supported for penalty formulation.\n");
1311 
1312 #ifdef SCIP_DEBUG_PRINTTOFILE
1313  /* if necessary, dump input data and initial point */
1314  sdpisolver->sdpa->writeInputSparse(const_cast<char*>("sdpa.dat-s"), const_cast<char*>("%+8.3e"));
1315  sdpisolver->sdpa->writeInitSparse(const_cast<char*>("sdpa.ini-s"), const_cast<char*>("%+8.3e"));
1316 #endif
1317 
1318  SCIPdebugMessage("Calling SDPA solve (SDP: %d)\n", sdpisolver->sdpcounter);
1319  sdpisolver->sdpa->solve();
1320  sdpisolver->solved = TRUE;
1321 
1322  /* update number of SDP-iterations and -calls */
1323  sdpisolver->niterations += (int) sdpisolver->sdpa->getIteration();
1324  sdpisolver->nsdpcalls += 1;
1325 
1326 #ifdef SCIP_DEBUG
1327  /* print the phase value , i.e. whether solving was successfull */
1328  sdpisolver->sdpa->getPhaseString((char*)phase_string);
1329  SCIPdebugMessage("SDPA solving finished with status %s (primal and dual here are switched in contrast to our formulation)\n", phase_string);
1330 #endif
1331 
1332  /* remember settings */
1333  if ( SCIPsdpiSolverIsAcceptable(sdpisolver) && penaltyparam < sdpisolver->epsilon )
1334  sdpisolver->usedsetting = SCIP_SDPSOLVERSETTING_FAST;
1335  else if ( penaltyparam >= sdpisolver->epsilon )
1336  sdpisolver->usedsetting = SCIP_SDPSOLVERSETTING_PENALTY;
1337 
1338  /* if the problem has been stably solved but did not reach the required feasibility tolerance, even though the solver
1339  * reports feasibility, resolve it with adjusted tolerance */
1340  SCIP_CALL( checkFeastolAndResolve(sdpisolver, penaltyparam, nvars, lb, ub, nsdpblocks, sdpblocksizes, sdpnblockvars, sdpconstnnonz,
1341  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, sdpnnonz, sdpnblockvarnonz, sdpvar, sdprow, sdpcol, sdpval, indchanges,
1342  nremovedinds, blockindchanges, nlpcons, noldlpcons, lplhs, lprhs, rownactivevars, lpnnonz, lprow, lpcol, lpval, &feastol) );
1343 
1344  /* check whether problem has been stably solved, if it wasn't and we didn't yet use the default parametersettings (for the penalty formulation we do so), try
1345  * again with more stable parameters */
1346  if ( ! SCIPsdpiSolverIsAcceptable(sdpisolver) && penaltyparam < sdpisolver->epsilon &&
1347  (startsettings == SCIP_SDPSOLVERSETTING_UNSOLVED || startsettings == SCIP_SDPSOLVERSETTING_FAST) )
1348  {
1349  SCIPdebugMessage("Numerical troubles -- solving SDP %d again ...\n", sdpisolver->sdpcounter);
1350 
1351  /* initialize settings */
1352  sdpisolver->sdpa->setParameterType(SDPA::PARAMETER_DEFAULT);
1353  sdpisolver->sdpa->setParameterEpsilonStar(GAPTOLCHANGE * sdpisolver->gaptol);
1354  sdpisolver->sdpa->setParameterEpsilonDash(FEASTOLCHANGE * sdpisolver->sdpsolverfeastol);
1355  sdpisolver->sdpa->setParameterLowerBound(-1e20);
1356  /* set the objective limit */
1357  if ( ! SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit) )
1358  sdpisolver->sdpa->setParameterUpperBound(sdpisolver->objlimit);
1359  else
1360  sdpisolver->sdpa->setParameterUpperBound(1e8);
1361 
1362  /* increase Lambda Star, this seems to help the numerics */
1363  sdpisolver->sdpa->setParameterLambdaStar(sdpisolver->lambdastar);
1364 
1365 #ifdef SCIP_MORE_DEBUG
1366  sdpisolver->sdpa->printParameters(stdout);
1367 #endif
1368  sdpisolver->sdpa->setInitPoint(false);
1369 #ifdef SDPA_RESETPARAMS
1370  sdpisolver->sdpa->resetParameters();
1371 #else
1372  sdpisolver->sdpa->initializeSolve();
1373 #endif
1374  sdpisolver->sdpa->solve();
1375  sdpisolver->solved = TRUE;
1376 
1377  /* update number of SDP-iterations and -calls */
1378  sdpisolver->niterations += (int) sdpisolver->sdpa->getIteration();
1379  sdpisolver->nsdpcalls += 1;
1380 
1381  /* remember setting */
1382  if ( SCIPsdpiSolverIsAcceptable(sdpisolver) )
1383  sdpisolver->usedsetting = SCIP_SDPSOLVERSETTING_MEDIUM;
1384 
1385 #ifdef SCIP_DEBUG
1386  /* print the phase value , i.e. whether solving was successfull */
1387  sdpisolver->sdpa->getPhaseString((char*)phase_string);
1388  SCIPdebugMessage("SDPA solving finished with status %s (primal and dual here are switched in contrast to our formulation)\n", phase_string);
1389 #endif
1390 
1391  /* if the problem has been stably solved but did not reach the required feasibility tolerance, even though the solver
1392  * reports feasibility, resolve it with adjusted tolerance */
1393  SCIP_CALL( checkFeastolAndResolve(sdpisolver, penaltyparam, nvars, lb, ub, nsdpblocks, sdpblocksizes, sdpnblockvars, sdpconstnnonz,
1394  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, sdpnnonz, sdpnblockvarnonz, sdpvar, sdprow, sdpcol, sdpval, indchanges,
1395  nremovedinds, blockindchanges, nlpcons, noldlpcons, lplhs, lprhs, rownactivevars, lpnnonz, lprow, lpcol, lpval, &feastol) );
1396  }
1397 
1398  /* if we still didn't converge, and did not yet use the stable settings, set the parameters even more conservativly */
1399  if ( (! SCIPsdpiSolverIsAcceptable(sdpisolver)) && penaltyparam < sdpisolver->epsilon &&
1400  (startsettings == SCIP_SDPSOLVERSETTING_UNSOLVED || startsettings == SCIP_SDPSOLVERSETTING_FAST || startsettings == SCIP_SDPSOLVERSETTING_MEDIUM) )
1401  {
1402  SCIPdebugMessage("Numerical troubles -- solving SDP %d again^2 ...\n", sdpisolver->sdpcounter);
1403 
1404  /* initialize settings */
1405  sdpisolver->sdpa->setParameterType(SDPA::PARAMETER_STABLE_BUT_SLOW);
1406  sdpisolver->sdpa->setParameterEpsilonStar(GAPTOLCHANGE * GAPTOLCHANGE * sdpisolver->gaptol);
1407  sdpisolver->sdpa->setParameterEpsilonDash(FEASTOLCHANGE * FEASTOLCHANGE * sdpisolver->sdpsolverfeastol);
1408  sdpisolver->sdpa->setParameterLowerBound(-1e20);
1409  /* set the objective limit */
1410  if ( ! SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit) )
1411  sdpisolver->sdpa->setParameterUpperBound(sdpisolver->objlimit);
1412  else
1413  sdpisolver->sdpa->setParameterUpperBound(1e8);
1414 
1415  /* increase Lambda Star, this seems to help the numerics */
1416  sdpisolver->sdpa->setParameterLambdaStar(sdpisolver->lambdastar);
1417 
1418 #ifdef SCIP_MORE_DEBUG
1419 sdpisolver->sdpa->printParameters(stdout);
1420 #endif
1421  sdpisolver->sdpa->setInitPoint(false);
1422 #ifdef SDPA_RESETPARAMS
1423  sdpisolver->sdpa->resetParameters();
1424 #else
1425  sdpisolver->sdpa->initializeSolve();
1426 #endif
1427  sdpisolver->sdpa->solve();
1428  sdpisolver->solved = TRUE;
1429 
1430  /* update number of SDP-iterations and -calls */
1431  sdpisolver->niterations += (int) sdpisolver->sdpa->getIteration();
1432  sdpisolver->nsdpcalls += 1;
1433 
1434  /* remember setting */
1435  if ( SCIPsdpiSolverIsAcceptable(sdpisolver) )
1436  sdpisolver->usedsetting = SCIP_SDPSOLVERSETTING_STABLE;
1437 
1438 #ifdef SCIP_DEBUG
1439  /* print the phase value , i.e. whether solving was successfull */
1440  sdpisolver->sdpa->getPhaseString((char*)phase_string);
1441  SCIPdebugMessage("SDPA solving finished with status %s (primal and dual here are switched in constrast to our formulation)\n", phase_string);
1442 #endif
1443 
1444  /* if the problem has been stably solved but did not reach the required feasibility tolerance, even though the solver
1445  * reports feasibility, resolve it with adjusted tolerance */
1446  SCIP_CALL( checkFeastolAndResolve(sdpisolver, penaltyparam, nvars, lb, ub, nsdpblocks, sdpblocksizes, sdpnblockvars, sdpconstnnonz,
1447  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, sdpnnonz, sdpnblockvarnonz, sdpvar, sdprow, sdpcol, sdpval, indchanges,
1448  nremovedinds, blockindchanges, nlpcons, noldlpcons, lplhs, lprhs, rownactivevars, lpnnonz, lprow, lpcol, lpval, &feastol) );
1449  }
1450 
1451 #ifdef SCIP_MORE_DEBUG
1452  (void) fclose(fpOut);
1453 #endif
1454 
1455  /* if we solved a penalty formulation, check if the solution is feasible for the original problem (which is the case iff r < feastol) */
1456  if ( penaltyparam >= sdpisolver->epsilon )
1457  {
1458  SCIP_Real* sdpasol;
1459  SCIP_Real* X;
1460  int b;
1461  int nblockssdpa;
1462  int nrow;
1463  SCIP_Real trace = 0.0;
1464 
1465  /* in the second case we have r as an additional variable */
1466  assert( (sdpisolver->nactivevars + 1 == sdpisolver->sdpa->getConstraintNumber()) ); /*lint !e776*/
1467 
1468  sdpasol = sdpisolver->sdpa->getResultXVec();
1469 
1470  /* we get r as the last variable in SDPA */
1471  *feasorig = (sdpasol[sdpisolver->nactivevars] < sdpisolver->feastol); /*lint !e413*/
1472 
1473  /* only set sdpisolver->feasorig to true if we solved with objective, because only in this case we want to compute
1474  * the objective value by hand since it is numerically more stable then the result returned by SDPA */
1475  if ( withobj )
1476  sdpisolver->feasorig = *feasorig;
1477 
1478  /* if r > 0 or we are in debug mode, also check the primal bound */
1479 #ifdef NDEBUG
1480  if ( ! *feasorig && penaltybound != NULL )
1481  {
1482 #endif
1483 
1484  SCIPdebugMessage("Solution not feasible in original problem, r = %f\n", sdpasol[sdpisolver->nactivevars]);
1485 
1486  /* compute Tr(X) */
1487 
1488  /* iterate over all blocks (SDPA starts counting at one and includes the LP block) */
1489  nblockssdpa = (int) sdpisolver->sdpa->getBlockNumber();
1490  for (b = 1; b <= nblockssdpa; b++)
1491  {
1492  /* get the block from SDPA */
1493  X = sdpisolver->sdpa->getResultYMat((long long) b);/*lint !e747*/
1494  nrow = (int) sdpisolver->sdpa->getBlockSize((long long) b);/*lint !e747*/
1495  assert( nrow >= 0 );
1496 
1497  /* if it is the LP-block, we omit the variable bounds as the penalty variable is not added to them */
1498  if ( sdpisolver->sdpa->getBlockType((long long) b) == SDPA::LP )/*lint !e747*/
1499  {
1500  /* iterate over all diagonal entries (until we reach the varbound part), adding them to the trace */
1501  for (i = 0; i < nrow - sdpisolver->nvarbounds; i++)
1502  trace += X[i]; /* get entry (i+1,i+1) for the diagonal matrix X */
1503  }
1504  else
1505  {
1506  /* iterate over all diagonal entries and add them to the trace */
1507  for (i = 0; i < nrow; i++)
1508  trace += X[i + i*nrow];/*lint !e679*/ /* get entry (i+1,i+1) in X */
1509  }
1510  }
1511 
1512  /* if the relative gap is smaller than the tolerance, we return equality */
1513  if ( (penaltyparam - trace) / penaltyparam < PENALTYBOUNDTOL )/*lint !e414*/
1514  {
1515  if ( penaltybound != NULL )
1516  *penaltybound = TRUE;
1517  SCIPdebugMessage("Tr(X) = %f == %f = Gamma, penalty formulation not exact, Gamma should be increased or problem is infeasible\n",
1518  trace, penaltyparam);
1519  }
1520  else if ( penaltybound != NULL )
1521  *penaltybound = FALSE;
1522 
1523 #ifdef NDEBUG
1524  }
1525 #endif
1526  }
1527  return SCIP_OKAY;
1528 }
1529 
1535 /*
1536  * Solution Information Methods
1537  */
1538 
1543 SCIP_Bool SCIPsdpiSolverWasSolved(
1544  SCIP_SDPISOLVER* sdpisolver
1545  )
1546 {/*lint !e1784*/
1547  assert( sdpisolver != NULL );
1548  return sdpisolver->solved;
1549 }
1550 
1558  SCIP_SDPISOLVER* sdpisolver
1559  )
1560 {/*lint !e1784*/
1561  SDPA::PhaseType phasetype;
1562 
1563  assert( sdpisolver != NULL );
1564  assert( sdpisolver->sdpa != NULL);
1565  CHECK_IF_SOLVED_BOOL( sdpisolver );
1566 
1567  phasetype = sdpisolver->sdpa->getPhaseValue();
1568 
1569  if ( phasetype == SDPA::noINFO || phasetype == SDPA::pFEAS || phasetype == SDPA::dFEAS || phasetype == SDPA::pdINF )
1570  return FALSE;
1571 
1572  return TRUE;
1573 }
1574 
1576 SCIP_RETCODE SCIPsdpiSolverGetSolFeasibility(
1577  SCIP_SDPISOLVER* sdpisolver,
1578  SCIP_Bool* primalfeasible,
1579  SCIP_Bool* dualfeasible
1580  )
1581 {/*lint !e1784*/
1582  SDPA::PhaseType phasetype;
1583 
1584  assert( sdpisolver != NULL );
1585  assert( sdpisolver->sdpa != NULL );
1586  assert( primalfeasible != NULL );
1587  assert( dualfeasible != NULL );
1588  CHECK_IF_SOLVED( sdpisolver );
1589 
1590  phasetype = sdpisolver->sdpa->getPhaseValue();
1591 
1592  switch ( phasetype )/*lint --e{788}*/
1593  {
1594  case SDPA::pdOPT:
1595  *primalfeasible = TRUE;
1596  *dualfeasible = TRUE;
1597  break;
1598  case SDPA::pdFEAS:
1599  *primalfeasible = TRUE;
1600  *dualfeasible = TRUE;
1601  break;
1602  case SDPA::pFEAS_dINF:
1603  *primalfeasible = TRUE;
1604  *dualfeasible = FALSE;
1605  break;
1606  case SDPA::pINF_dFEAS:
1607  *primalfeasible = FALSE;
1608  *dualfeasible = TRUE;
1609  break;
1610  case SDPA::pUNBD:
1611  *primalfeasible = TRUE;
1612  *dualfeasible = FALSE;
1613  SCIPdebugMessage("SDPA stopped because dual objective became smaller than lower bound\n");
1614  break;
1615  case SDPA::dUNBD:
1616  *primalfeasible = FALSE;
1617  *dualfeasible = TRUE;
1618  SCIPdebugMessage("SDPA stopped because primal objective became bigger than upper bound\n");
1619  break;
1620  default: /* contains noInfo, pFeas, dFeas, pdInf */
1621  SCIPerrorMessage("SDPA doesn't know if primal and dual solutions are feasible\n");
1622  return SCIP_LPERROR;
1623  }
1624 
1625  return SCIP_OKAY;
1626 }
1627 
1631  SCIP_SDPISOLVER* sdpisolver
1632  )
1633 {/*lint !e1784*/
1634  SDPA::PhaseType phasetype;
1635 
1636  assert( sdpisolver != NULL );
1637  assert( sdpisolver->sdpa != NULL );
1638  CHECK_IF_SOLVED_BOOL( sdpisolver );
1639 
1640  phasetype = sdpisolver->sdpa->getPhaseValue();
1641 
1642  if ( phasetype == SDPA::noINFO || phasetype == SDPA::pFEAS || phasetype == SDPA::pdINF )
1643  {
1644  SCIPdebugMessage("SDPA doesn't know if primal problem is unbounded");
1645  return FALSE;
1646  }
1647  else if ( phasetype == SDPA::pFEAS_dINF )
1648  return TRUE;
1649  else if ( phasetype == SDPA::pUNBD )
1650  {
1651  SCIPdebugMessage("SDPA was stopped because primal objective became bigger than upper bound");
1652  return TRUE;
1653  }
1654 
1655  return FALSE;
1656 }
1657 
1661  SCIP_SDPISOLVER* sdpisolver
1662  )
1663 {/*lint !e1784*/
1664  SDPA::PhaseType phasetype;
1665 
1666  assert( sdpisolver != NULL );
1667  assert( sdpisolver->sdpa != NULL );
1668  CHECK_IF_SOLVED_BOOL( sdpisolver );
1669 
1670  phasetype = sdpisolver->sdpa->getPhaseValue();
1671 
1672  if ( phasetype == SDPA::noINFO || phasetype == SDPA::dFEAS || phasetype == SDPA::pdINF )
1673  {
1674  SCIPdebugMessage("SDPA doesn't know if primal problem is infeasible");
1675  return FALSE;
1676  }
1677  else if ( phasetype == SDPA::pINF_dFEAS )
1678  return TRUE;
1679  else if ( phasetype == SDPA::dUNBD )
1680  {
1681  SCIPdebugMessage("SDPA was stopped because dual objective became smaller than lower bound");
1682  return TRUE;
1683  }
1684 
1685  return FALSE;
1686 }
1687 
1691  SCIP_SDPISOLVER* sdpisolver
1692  )
1693 {/*lint !e1784*/
1694  SDPA::PhaseType phasetype;
1695 
1696  assert( sdpisolver != NULL );
1697  assert( sdpisolver->sdpa != NULL );
1698  CHECK_IF_SOLVED_BOOL( sdpisolver );
1699 
1700  phasetype = sdpisolver->sdpa->getPhaseValue();
1701 
1702  if ( phasetype == SDPA::noINFO || phasetype == SDPA::dFEAS || phasetype == SDPA::pdINF )
1703  {
1704  SCIPdebugMessage("SDPA doesn't know if primal problem is feasible");
1705  return FALSE;
1706  }
1707  else if ( phasetype == SDPA::pFEAS_dINF || phasetype == SDPA::pdOPT || phasetype == SDPA::pFEAS || phasetype == SDPA::pdFEAS )
1708  return TRUE;
1709  else if ( phasetype == SDPA::dUNBD )
1710  {
1711  SCIPdebugMessage("SDPA was stopped because dual objective became smaller than lower bound");
1712  return TRUE;
1713  }
1714 
1715  return FALSE;
1716 }
1717 
1721  SCIP_SDPISOLVER* sdpisolver
1722  )
1723 {/*lint !e1784*/
1724  SDPA::PhaseType phasetype;
1725 
1726  assert( sdpisolver != NULL );
1727  assert( sdpisolver->sdpa != NULL);
1728  CHECK_IF_SOLVED_BOOL( sdpisolver );
1729 
1730  phasetype = sdpisolver->sdpa->getPhaseValue();
1731 
1732  if ( phasetype == SDPA::noINFO || phasetype == SDPA::dFEAS || phasetype == SDPA::pdINF )
1733  {
1734  SCIPdebugMessage("SDPA doesn't know if dual problem is unbounded");
1735  return FALSE;
1736  }
1737  else if ( phasetype == SDPA::pINF_dFEAS )
1738  return TRUE;
1739  else if ( phasetype == SDPA::dUNBD )
1740  {
1741  SCIPdebugMessage("SDPA was stopped because dual objective became smaller than lower bound");
1742  return TRUE;
1743  }
1744 
1745  return FALSE;
1746 }
1747 
1751  SCIP_SDPISOLVER* sdpisolver
1752  )
1753 {/*lint !e1784*/
1754  SDPA::PhaseType phasetype;
1755 
1756  assert( sdpisolver != NULL );
1757  assert( sdpisolver->sdpa != NULL);
1758  CHECK_IF_SOLVED_BOOL( sdpisolver );
1759 
1760  phasetype = sdpisolver->sdpa->getPhaseValue();
1761 
1762  if ( phasetype == SDPA::noINFO || phasetype == SDPA::pFEAS || phasetype == SDPA::pdINF )
1763  {
1764  SCIPdebugMessage("SDPA doesn't know if dual problem is infeasible");
1765  return FALSE;
1766  }
1767  else if ( phasetype == SDPA::pFEAS_dINF )
1768  return TRUE;
1769  else if ( phasetype == SDPA::pUNBD )
1770  {
1771  SCIPdebugMessage("SDPA was stopped because primal objective became bigger than upper bound");
1772  return TRUE;
1773  }
1774 
1775  return FALSE;
1776 }
1777 
1781  SCIP_SDPISOLVER* sdpisolver
1782  )
1783 {/*lint !e1784*/
1784  SDPA::PhaseType phasetype;
1785 
1786  assert( sdpisolver != NULL );
1787  assert( sdpisolver->sdpa != NULL);
1788  CHECK_IF_SOLVED_BOOL( sdpisolver );
1789 
1790  phasetype = sdpisolver->sdpa->getPhaseValue();
1791 
1792  if ( phasetype == SDPA::noINFO || phasetype == SDPA::dFEAS || phasetype == SDPA::pdINF )
1793  {
1794  SCIPdebugMessage("SDPA doesn't know if primal problem is feasible");
1795  return FALSE;
1796  }
1797  else if ( phasetype == SDPA::pINF_dFEAS || phasetype == SDPA::pdOPT || phasetype == SDPA::dFEAS || phasetype == SDPA::pdFEAS )
1798  return TRUE;
1799  else if ( phasetype == SDPA::dUNBD )
1800  {
1801  SCIPdebugMessage("SDPA was stopped because dual objective became smaller than lower bound");
1802  return TRUE;
1803  }
1804 
1805  return FALSE;
1806 }
1807 
1809 SCIP_Bool SCIPsdpiSolverIsConverged(
1810  SCIP_SDPISOLVER* sdpisolver
1811  )
1812 {/*lint !e1784*/
1813  SDPA::PhaseType phasetype;
1814 
1815  assert( sdpisolver != NULL );
1816  assert( sdpisolver->sdpa != NULL );
1817  CHECK_IF_SOLVED_BOOL( sdpisolver );
1818 
1819  phasetype = sdpisolver->sdpa->getPhaseValue();
1820 
1821  if ( phasetype == SDPA::pdOPT )
1822  return TRUE;
1823 
1824  return FALSE;
1825 }
1826 
1828 SCIP_Bool SCIPsdpiSolverIsObjlimExc(
1829  SCIP_SDPISOLVER* sdpisolver
1830  )
1831 {/*lint !e1784*/
1832  SDPA::PhaseType phasetype;
1833 
1834  assert( sdpisolver != NULL );
1835  assert( sdpisolver->sdpa != NULL );
1836  CHECK_IF_SOLVED_BOOL( sdpisolver );
1837 
1838  phasetype = sdpisolver->sdpa->getPhaseValue();
1839 
1840  if ( phasetype == SDPA::pUNBD )
1841  return TRUE;
1842 
1843  return FALSE;
1844 }
1845 
1847 SCIP_Bool SCIPsdpiSolverIsIterlimExc(
1848  SCIP_SDPISOLVER* sdpisolver
1849  )
1850 {/*lint !e1784*/
1851  SDPA::PhaseType phasetype;
1852 
1853  assert( sdpisolver != NULL );
1854  assert( sdpisolver->sdpa != NULL);
1855  CHECK_IF_SOLVED_BOOL( sdpisolver );
1856 
1857  phasetype = sdpisolver->sdpa->getPhaseValue();
1858 
1859  if ( phasetype == SDPA::noINFO || phasetype == SDPA::pFEAS || phasetype == SDPA::dFEAS || phasetype == SDPA::pdFEAS )
1860  {
1861  if ( sdpisolver->sdpa->getParameterMaxIteration() == sdpisolver->sdpa->getIteration() )
1862  return TRUE;
1863  }
1864 
1865  return FALSE;
1866 }
1867 
1869 SCIP_Bool SCIPsdpiSolverIsTimelimExc(
1870  SCIP_SDPISOLVER* sdpisolver
1871  )
1872 {/*lint !e1784*/
1873  assert( sdpisolver != NULL );
1874 
1875  return sdpisolver->timelimit;
1876 }
1877 
1889  SCIP_SDPISOLVER* sdpisolver
1890  )
1891 {/*lint !e1784*/
1892  SDPA::PhaseType phasetype;
1893 
1894  assert( sdpisolver != NULL );
1895  assert( sdpisolver->sdpa != NULL );
1896 
1897  if ( sdpisolver->sdpa == NULL || (! sdpisolver->solved) )
1898  return -1;
1899 
1900  phasetype = sdpisolver->sdpa->getPhaseValue();
1901 
1902  if ( phasetype == SDPA::pdOPT || phasetype == SDPA::pFEAS_dINF || phasetype == SDPA::pINF_dFEAS )
1903  return 0;
1904  if ( phasetype == SDPA::pdINF )
1905  return 1;
1906  if ( phasetype == SDPA::pUNBD)
1907  return 3;
1908  if ( phasetype == SDPA::noINFO || phasetype == SDPA::pFEAS || phasetype == SDPA::dFEAS || phasetype == SDPA::pdFEAS )
1909  return 4;
1910  else /* should include dUNBD */
1911  return 7;
1912 }
1913 
1915 SCIP_Bool SCIPsdpiSolverIsOptimal(
1916  SCIP_SDPISOLVER* sdpisolver
1917  )
1918 {/*lint !e1784*/
1919  SDPA::PhaseType phasetype;
1920 
1921  assert( sdpisolver != NULL );
1922  assert( sdpisolver->sdpa != NULL );
1923 
1924  if ( ! sdpisolver->solved )
1925  return FALSE;
1926 
1927  phasetype = sdpisolver->sdpa->getPhaseValue();
1928 
1929  if ( phasetype == SDPA::pdOPT )
1930  return TRUE;
1931 
1932  return FALSE;
1933 }
1934 
1937 SCIP_Bool SCIPsdpiSolverIsAcceptable(
1938  SCIP_SDPISOLVER* sdpisolver
1939  )
1940 {/*lint !e1784*/
1941  SDPA::PhaseType phasetype;
1942 
1943  assert( sdpisolver != NULL );
1944  assert( sdpisolver->sdpa != NULL );
1945 
1946  if ( sdpisolver->timelimit )
1947  return FALSE;
1948 
1949  if ( ! sdpisolver->solved )
1950  return FALSE;
1951 
1952  phasetype = sdpisolver->sdpa->getPhaseValue();
1953 
1954  /* we are happy if we converged, or we reached the objective limit (pUNBD) or we could show that our problem is
1955  * infeasible [except for numerics], or unbounded */
1956  if ( SCIPsdpiSolverIsConverged(sdpisolver) || phasetype == SDPA::pUNBD || phasetype == SDPA::pINF_dFEAS || phasetype == SDPA::pFEAS_dINF )
1957  return TRUE;
1958 
1959  return FALSE;
1960 }
1961 
1963 SCIP_RETCODE SCIPsdpiSolverIgnoreInstability(
1964  SCIP_SDPISOLVER* sdpisolver,
1965  SCIP_Bool* success
1966  )
1967 {/*lint !e1784*/
1968  SCIPdebugMessage("Not implemented yet\n");
1969 
1970  return SCIP_LPERROR;
1971 }/*lint !e715*/
1972 
1974 SCIP_RETCODE SCIPsdpiSolverGetObjval(
1975  SCIP_SDPISOLVER* sdpisolver,
1976  SCIP_Real* objval
1977  )
1978 {/*lint !e1784*/
1979  assert( sdpisolver != NULL );
1980  assert( sdpisolver->sdpa != NULL );
1981  assert( objval != NULL );
1982  CHECK_IF_SOLVED( sdpisolver );
1983 
1984  if ( sdpisolver->penalty && ( ! sdpisolver->feasorig ) )
1985  {
1986  *objval = sdpisolver->sdpa->getPrimalObj();
1987 #ifndef NDEBUG
1988  SCIP_Real primalval = sdpisolver->sdpa->getDualObj();
1989  SCIP_Real gap = (REALABS(*objval - primalval) / (0.5 * (REALABS(primalval) + REALABS(*objval)))); /* duality gap used in SDPA */
1990  if ( gap > sdpisolver->gaptol )
1991  {
1992  SCIPdebugMessage("Attention: got objective value (before adding values of fixed variables) of %f in SCIPsdpiSolverGetSol, "
1993  "but primal objective is %f with duality gap %f!\n", *objval, primalval, gap );
1994  }
1995 #endif
1996  }
1997  else
1998  {
1999  SCIP_Real* sdpasol;
2000  int v;
2001 
2002  /* since the objective value given by SDPA sometimes differs slightly from the correct value for the given solution,
2003  * we get the solution from SDPA and compute the correct objective value */
2004  assert( (sdpisolver->penalty && sdpisolver->nactivevars + 1 == sdpisolver->sdpa->getConstraintNumber()) || /*lint !e776*/
2005  sdpisolver->nactivevars == sdpisolver->sdpa->getConstraintNumber() ); /* in the second case we have r as an additional variable */
2006  sdpasol = sdpisolver->sdpa->getResultXVec();
2007 
2008  *objval = 0.0;
2009  for (v = 0; v < sdpisolver->nactivevars; v++)
2010  {
2011  if ( REALABS(sdpasol[v]) > sdpisolver->epsilon )
2012  *objval += sdpasol[v] * sdpisolver->objcoefs[v];
2013  }
2014  }
2015 
2016  /* as we didn't add the fixed (lb = ub) variables to sdpa, we have to add their contributions to the objective by hand */
2017  *objval += sdpisolver->fixedvarsobjcontr;
2018 
2019  return SCIP_OKAY;
2020 }
2021 
2026 SCIP_RETCODE SCIPsdpiSolverGetSol(
2027  SCIP_SDPISOLVER* sdpisolver,
2028  SCIP_Real* objval,
2029  SCIP_Real* dualsol,
2030  int* dualsollength
2032  )
2033 {/*lint !e1784*/
2034  SCIP_Real* sdpasol;
2035  int v;
2036 
2037  assert( sdpisolver != NULL );
2038  assert( sdpisolver->sdpa != NULL );
2039  assert( dualsollength != NULL );
2040  CHECK_IF_SOLVED( sdpisolver );
2041 
2042  if ( objval != NULL )
2043  {
2044  if ( sdpisolver->penalty && ( ! sdpisolver->feasorig ) )
2045  {
2046  *objval = sdpisolver->sdpa->getPrimalObj();
2047 #ifndef NDEBUG
2048  SCIP_Real primalval = sdpisolver->sdpa->getDualObj();
2049  SCIP_Real gap = (REALABS(*objval - primalval) / (0.5 * (REALABS(primalval) + REALABS(*objval)))); /* duality gap used in SDPA */
2050  if ( gap > sdpisolver->gaptol )
2051  {
2052  SCIPdebugMessage("Attention: got objective value (before adding values of fixed variables) of %f in SCIPsdpiSolverGetSol, "
2053  "but primal objective is %f with duality gap %f!\n", *objval, primalval, gap );
2054  }
2055 #endif
2056  }
2057  else
2058  {
2059  /* since the objective value given by SDPA sometimes differs slightly from the correct value for the given solution,
2060  * we get the solution from SDPA and compute the correct objective value */
2061  assert( (sdpisolver->penalty && sdpisolver->nactivevars + 1 == sdpisolver->sdpa->getConstraintNumber()) || /*lint !e776*/
2062  sdpisolver->nactivevars == sdpisolver->sdpa->getConstraintNumber() ); /* in the second case we have r as an additional variable */
2063  sdpasol = sdpisolver->sdpa->getResultXVec();
2064 
2065  *objval = 0.0;
2066  for (v = 0; v < sdpisolver->nactivevars; v++)
2067  {
2068  if ( REALABS(sdpasol[v]) > sdpisolver->epsilon )
2069  *objval += sdpasol[v] * sdpisolver->objcoefs[v];
2070  }
2071  }
2072 
2073  /* as we didn't add the fixed (lb = ub) variables to sdpa, we have to add their contributions to the objective by hand */
2074  *objval += sdpisolver->fixedvarsobjcontr;
2075  }
2076 
2077  if ( *dualsollength > 0 )
2078  {
2079  assert( dualsol != NULL );
2080  if ( *dualsollength < sdpisolver->nvars )
2081  {
2082  SCIPdebugMessage("The given array in SCIPsdpiSolverGetSol only had length %d, but %d was needed", *dualsollength, sdpisolver->nvars);
2083  *dualsollength = sdpisolver->nvars;
2084 
2085  return SCIP_OKAY;
2086  }
2087 
2088  /* get the solution from sdpa */
2089  assert( (sdpisolver->penalty && sdpisolver->nactivevars + 1 == sdpisolver->sdpa->getConstraintNumber()) || /*lint !e776*/
2090  sdpisolver->nactivevars == sdpisolver->sdpa->getConstraintNumber() ); /* in the second case we have r as an additional variable */
2091  sdpasol = sdpisolver->sdpa->getResultXVec();
2092  /* insert the entries into dualsol, for non-fixed vars we copy those from sdpa, the rest are the saved entries from inserting (they equal lb=ub) */
2093  for (v = 0; v < sdpisolver->nvars; v++)
2094  {
2095  if ( sdpisolver->inputtosdpamapper[v] > 0 )
2096  {
2097  /* minus one because the inputtosdpamapper gives the sdpa indices which start at one, but the array starts at 0 */
2098  dualsol[v] = sdpasol[sdpisolver->inputtosdpamapper[v] - 1];
2099  }
2100  else
2101  {
2102  /* this is the value that was saved when inserting, as this variable has lb=ub */
2103  assert( -sdpisolver->inputtosdpamapper[v] <= sdpisolver->nvars - sdpisolver->nactivevars );
2104  dualsol[v] = sdpisolver->fixedvarsval[(-1 * sdpisolver->inputtosdpamapper[v]) - 1]; /*lint !e679*/
2105  }
2106  }
2107  }
2108  return SCIP_OKAY;
2109 }
2110 
2119  SCIP_SDPISOLVER* sdpisolver,
2120  SCIP_Real* lbvars,
2121  SCIP_Real* ubvars,
2122  int* arraylength
2124  )
2125 {/*lint !e1784*/
2126  int i;
2127  SCIP_Real* X; /* block of primal solution matrix corresponding to the LP-part */
2128  int lpblockind;
2129  int nlpcons;
2130 
2131  assert( sdpisolver != NULL );
2132  assert( sdpisolver->sdpa != NULL );
2133  assert( lbvars != NULL );
2134  assert( ubvars != NULL );
2135  assert( arraylength != NULL );
2136  assert( *arraylength >= 0 );
2137  CHECK_IF_SOLVED( sdpisolver );
2138 
2139  /* check if the arrays are long enough */
2140  if ( *arraylength < sdpisolver->nvars )
2141  {
2142  *arraylength = sdpisolver->nvars;
2143  SCIPdebugMessage("Insufficient length of array in SCIPsdpiSolverGetPrimalBoundVars (gave %d, needed %d)\n", *arraylength, sdpisolver->nvars);
2144  return SCIP_OKAY;
2145  }
2146 
2147  /* initialize the return-arrays with zero */
2148  for (i = 0; i < sdpisolver->nvars; i++)
2149  {
2150  lbvars[i] = 0.0;
2151  ubvars[i] = 0.0;
2152  }
2153 
2154  /* if no variable bounds were added, we return the zero vector (we do this separately, because in this case there might be no LP-block) */
2155  if ( sdpisolver->nvarbounds == 0 )
2156  {
2157  SCIPdebugMessage("Asked for PrimalBoundVars, but there were no variable bounds in sdpa, returning zero vector !");
2158  return SCIP_OKAY;
2159  }
2160 
2161  /* get the block of primal solution matrix corresponding to the LP-part from sdpa */
2162  lpblockind = (int) sdpisolver->sdpa->getBlockNumber(); /* the LP block is the last one and sdpa counts from one */
2163  assert( sdpisolver->sdpa->getBlockType((long long) lpblockind) == SDPA::LP );/*lint !e747*/
2164  nlpcons = (int) sdpisolver->sdpa->getBlockSize((long long) lpblockind);/*lint !e747*/
2165  assert( nlpcons >= 0 );
2166 
2167  X = sdpisolver->sdpa->getResultYMat((long long) lpblockind);/*lint !e747*/
2168 
2169  /* iterate over all variable bounds and insert the corresponding primal variables in the right positions of the return-arrays */
2170  assert( sdpisolver->nvarbounds <= 2 * sdpisolver->nvars || (sdpisolver->nvarbounds <= 2 * sdpisolver->nvars + 1 && sdpisolver->penalty ) );
2171  /* if we solved a penalty formulation, the last variable bound belongs to the penalty variable, which we aren't interested in here */
2172  for (i = 0; i < ((sdpisolver->penalty) ? sdpisolver->nvarbounds - 1 : sdpisolver->nvarbounds); i++)
2173  {
2174  if ( sdpisolver->varboundpos[i] < 0 )
2175  {
2176  /* this is a lower bound */
2177  /* the last nvarbounds entries correspond to the varbounds */
2178  lbvars[sdpisolver->sdpatoinputmapper[-1 * sdpisolver->varboundpos[i] -1]] = X[nlpcons - sdpisolver->nvarbounds + i]; /*lint !e679, !e834 */
2179  }
2180  else
2181  {
2182  /* this is an upper bound */
2183  /* the last nvarbounds entries correspond to the varbounds */
2184  ubvars[sdpisolver->sdpatoinputmapper[+1 * sdpisolver->varboundpos[i] - 1]] = X[nlpcons - sdpisolver->nvarbounds + i]; /*lint !e679, !e834 */
2185  }
2186  }
2187 
2188  return SCIP_OKAY;
2189 }
2190 
2192 SCIP_RETCODE SCIPsdpiSolverGetIterations(
2193  SCIP_SDPISOLVER* sdpisolver,
2194  int* iterations
2195  )
2196 {/*lint !e1784*/
2197  assert( sdpisolver != NULL );
2198  assert( sdpisolver->sdpa != NULL );
2199  assert( iterations != NULL );
2200 
2201  *iterations = sdpisolver->niterations;
2202 
2203  return SCIP_OKAY;
2204 }
2205 
2207 SCIP_RETCODE SCIPsdpiSolverGetSdpCalls(
2208  SCIP_SDPISOLVER* sdpisolver,
2209  int* calls
2210  )
2211 {/*lint !e1784*/
2212  assert( sdpisolver != NULL );
2213  assert( sdpisolver->sdpa != NULL );
2214  assert( calls != NULL );
2215 
2216  *calls = sdpisolver->nsdpcalls;
2217 
2218  return SCIP_OKAY;
2219 }
2220 
2222 SCIP_RETCODE SCIPsdpiSolverSettingsUsed(
2223  SCIP_SDPISOLVER* sdpisolver,
2224  SCIP_SDPSOLVERSETTING* usedsetting
2225  )
2226 {/*lint !e1784*/
2227  assert( sdpisolver != NULL );
2228  assert( usedsetting != NULL );
2229  CHECK_IF_SOLVED(sdpisolver);
2230 
2231  *usedsetting = sdpisolver->usedsetting;
2232 
2233  return SCIP_OKAY;
2234 }
2235 
2241 /*
2242  * Numerical Methods
2243  */
2244 
2249 SCIP_Real SCIPsdpiSolverInfinity(
2250  SCIP_SDPISOLVER* sdpisolver
2251  )
2252 {/*lint !e1784*/
2253  return 1E+20; /* default infinity from SCIP */
2254 }/*lint !e715*/
2255 
2257 SCIP_Bool SCIPsdpiSolverIsInfinity(
2258  SCIP_SDPISOLVER* sdpisolver,
2259  SCIP_Real val
2260  )
2261 {/*lint !e1784*/
2262  return ( val <= -SCIPsdpiSolverInfinity(sdpisolver) || val >= SCIPsdpiSolverInfinity(sdpisolver) );
2263 }
2264 
2266 SCIP_RETCODE SCIPsdpiSolverGetRealpar(
2267  SCIP_SDPISOLVER* sdpisolver,
2268  SCIP_SDPPARAM type,
2269  SCIP_Real* dval
2270  )
2271 {/*lint !e1784*/
2272  assert( sdpisolver != NULL );
2273  assert( dval != NULL );
2274 
2275  switch( type )/*lint --e{788}*/
2276  {
2277  case SCIP_SDPPAR_EPSILON:
2278  *dval = sdpisolver->epsilon;
2279  break;
2280  case SCIP_SDPPAR_GAPTOL:
2281  *dval = sdpisolver->gaptol;
2282  break;
2283  case SCIP_SDPPAR_FEASTOL:
2284  *dval = sdpisolver->feastol;
2285  break;
2287  *dval = sdpisolver->sdpsolverfeastol;
2288  break;
2290  *dval = 0.0;
2291  SCIPdebugMessage("Parameter SCIP_SDPPAR_PENALTYPARAM not used by SDPA"); /* this parameter is only used by DSDP */
2292  break;
2293  case SCIP_SDPPAR_OBJLIMIT:
2294  *dval = sdpisolver->objlimit;
2295  break;
2297  *dval = sdpisolver->lambdastar;
2298  break;
2299  default:
2300  return SCIP_PARAMETERUNKNOWN;
2301  }
2302 
2303  return SCIP_OKAY;
2304 }
2305 
2307 SCIP_RETCODE SCIPsdpiSolverSetRealpar(
2308  SCIP_SDPISOLVER* sdpisolver,
2309  SCIP_SDPPARAM type,
2310  SCIP_Real dval
2311  )
2312 {/*lint !e1784*/
2313  assert( sdpisolver != NULL );
2314 
2315  switch( type )/*lint --e{788}*/
2316  {
2317  case SCIP_SDPPAR_EPSILON:
2318  sdpisolver->epsilon = dval;
2319  SCIPdebugMessage("Setting sdpisolver epsilon to %f.\n", dval);
2320  break;
2321  case SCIP_SDPPAR_GAPTOL:
2322  sdpisolver->gaptol = dval;
2323  SCIPdebugMessage("Setting sdpisolver gaptol to %f.\n", dval);
2324  break;
2325  case SCIP_SDPPAR_FEASTOL:
2326  sdpisolver->feastol = dval;
2327  SCIPdebugMessage("Setting sdpisolver feastol to %f.\n", dval);
2328  break;
2330  sdpisolver->sdpsolverfeastol = dval;
2331  SCIPdebugMessage("Setting sdpisolver sdpsolverfeastol to %f.\n", dval);
2332  break;
2334  SCIPdebugMessage("Parameter SCIP_SDPPAR_PENALTYPARAM not used by SDPA"); /* this parameter is only used by DSDP */
2335  break;
2336  case SCIP_SDPPAR_OBJLIMIT:
2337  SCIPdebugMessage("Setting sdpisolver objlimit to %f.\n", dval);
2338  sdpisolver->objlimit = dval;
2339  break;
2341  SCIPdebugMessage("Setting sdpisolver lambdastar parameter to %f.\n", dval);
2342  sdpisolver->lambdastar = dval;
2343  break;
2344  default:
2345  return SCIP_PARAMETERUNKNOWN;
2346  }
2347 
2348  return SCIP_OKAY;
2349 }
2350 
2352 SCIP_RETCODE SCIPsdpiSolverGetIntpar(
2353  SCIP_SDPISOLVER* sdpisolver,
2354  SCIP_SDPPARAM type,
2355  int* ival
2356  )
2357 {/*lint !e1784*/
2358  assert( sdpisolver != NULL );
2359 
2360  switch( type )/*lint --e{788}*/
2361  {
2362  case SCIP_SDPPAR_SDPINFO:
2363  *ival = (int) sdpisolver->sdpinfo;
2364  SCIPdebugMessage("Getting sdpisolver information output (%d).\n", *ival);
2365  break;
2366  default:
2367  return SCIP_PARAMETERUNKNOWN;
2368  }
2369 
2370  return SCIP_OKAY;
2371 }
2372 
2374 SCIP_RETCODE SCIPsdpiSolverSetIntpar(
2375  SCIP_SDPISOLVER* sdpisolver,
2376  SCIP_SDPPARAM type,
2377  int ival
2378  )
2379 {/*lint !e1784*/
2380  assert( sdpisolver != NULL );
2381 
2382  switch( type )/*lint --e{788}*/
2383  {
2384  case SCIP_SDPPAR_SDPINFO:
2385  sdpisolver->sdpinfo = (SCIP_Bool) ival;
2386  SCIPdebugMessage("Setting sdpisolver information output (%d).\n", ival);
2387  break;
2388  default:
2389  return SCIP_PARAMETERUNKNOWN;
2390  }
2391 
2392  return SCIP_OKAY;
2393 }
2394 
2396 SCIP_RETCODE SCIPsdpiSolverComputeLambdastar(
2397  SCIP_SDPISOLVER* sdpisolver,
2398  SCIP_Real maxguess
2399  )
2400 {/*lint !e1784*/
2401  SCIP_Real compval;
2402 
2403  assert( sdpisolver != NULL );
2404 
2405  /* we set the value to min{max{MIN_LAMBDASTAR, LAMBDASTAR_FACTOR * MAX_GUESS}, MAX_LAMBDASTAR}, where MAX_GUESS is the maximum of the guesses
2406  * of the SDP-Blocks, if the define LAMBDASTAR_TWOPOINTS is set, we instead choose either LAMBDASTAR_LOW or HIGH depending on LAMBASTAR_THRESHOLD */
2407 
2408 #ifdef LAMBDASTAR_TWOPOINTS
2409  if ( maxguess < LAMBDASTAR_THRESHOLD )
2410  compval = LAMBDASTAR_LOW;
2411  else
2412  compval = LAMBDASTAR_HIGH;
2413 #else
2414  compval = LAMBDASTAR_FACTOR * maxguess;
2415 #endif
2416 
2417  if ( compval < MIN_LAMBDASTAR )
2418  {
2419  sdpisolver->lambdastar = MIN_LAMBDASTAR;
2420  SCIPdebugMessage("Setting lambdastar to %f.\n", MIN_LAMBDASTAR);
2421  }
2422  else if ( compval > MAX_LAMBDASTAR )
2423  {
2424  sdpisolver->lambdastar = MAX_LAMBDASTAR;
2425  SCIPdebugMessage("Setting lambdastar to %f.\n", MAX_LAMBDASTAR);
2426  }
2427  else
2428  {
2429  sdpisolver->lambdastar = compval;
2430  SCIPdebugMessage("Setting lambdastar to %f.\n", compval);
2431  }
2432 
2433  return SCIP_OKAY;
2434 }
2435 
2438  SCIP_SDPISOLVER* sdpisolver,
2439  SCIP_Real maxcoeff,
2440  SCIP_Real* penaltyparam
2441  )
2442 {/*lint !e1784*/
2443  SCIP_Real compval;
2444 
2445  assert( sdpisolver != NULL );
2446  assert( penaltyparam != NULL );
2447 
2448  compval = PENALTYPARAM_FACTOR * maxcoeff;
2449 
2450  if ( compval < MIN_PENALTYPARAM )
2451  {
2452  SCIPdebugMessage("Setting penaltyparameter to %f.\n", MIN_PENALTYPARAM);
2453  *penaltyparam = MIN_PENALTYPARAM;
2454  }
2455  else if ( compval > MAX_PENALTYPARAM )
2456  {
2457  SCIPdebugMessage("Setting penaltyparameter to %f.\n", MAX_PENALTYPARAM);
2458  *penaltyparam = MAX_PENALTYPARAM;
2459  }
2460  else
2461  {
2462  SCIPdebugMessage("Setting penaltyparameter to %f.\n", compval);
2463  *penaltyparam = compval;
2464  }
2465  return SCIP_OKAY;
2466 }
2467 
2470  SCIP_SDPISOLVER* sdpisolver,
2471  SCIP_Real penaltyparam,
2472  SCIP_Real* maxpenaltyparam
2473  )
2474 {/*lint !e1784*/
2475  SCIP_Real compval;
2476 
2477  assert( sdpisolver != NULL );
2478  assert( maxpenaltyparam != NULL );
2479 
2480  compval = penaltyparam * MAXPENALTYPARAM_FACTOR;
2481 
2482  if ( compval < MAX_MAXPENALTYPARAM )
2483  {
2484  *maxpenaltyparam = compval;
2485  SCIPdebugMessage("Setting maximum penaltyparameter to %f.\n", compval);
2486  }
2487  else
2488  {
2489  *maxpenaltyparam = MAX_MAXPENALTYPARAM;
2490  SCIPdebugMessage("Setting penaltyparameter to %f.\n", MAX_MAXPENALTYPARAM);
2491  }
2492 
2493  return SCIP_OKAY;
2494 }
2495 
2501 /*
2502  * File Interface Methods
2503  */
2504 
2509 SCIP_RETCODE SCIPsdpiSolverReadSDP(
2510  SCIP_SDPISOLVER* sdpisolver,
2511  const char* fname
2512  )
2513 {/*lint !e1784*/
2514  SCIPdebugMessage("Not implemented yet\n");
2515  return SCIP_LPERROR;
2516 }/*lint !e715*/
2517 
2519 SCIP_RETCODE SCIPsdpiSolverWriteSDP(
2520  SCIP_SDPISOLVER* sdpisolver,
2521  const char* fname
2522  )
2523 {/*lint !e1784*/
2524  assert( fname != NULL );
2525 
2526  sdpisolver->sdpa->writeInputSparse(const_cast<char*>(fname), const_cast<char*>("%8.3f"));
2527 
2528  return SCIP_OKAY;
2529 }
2530 
const char * SCIPsdpiSolverGetSolverName(void)
#define MIN_PENALTYPARAM
#define FEASTOLCHANGE
static SCIP_RETCODE checkFeastolAndResolve(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, 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 *feastol)
SCIP_RETCODE SCIPsdpiSolverSetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real dval)
SCIP_RETCODE SCIPsdpiSolverFree(SCIP_SDPISOLVER **sdpisolver)
SCIP_Real SCIPsdpiSolverInfinity(SCIP_SDPISOLVER *sdpisolver)
void * SCIPsdpiSolverGetSolverPointer(SCIP_SDPISOLVER *sdpisolver)
#define LAMBDASTAR_LOW
#define LAMBDASTAR_HIGH
#define INFEASFEASTOLCHANGE
SCIP_RETCODE SCIPsdpiSolverIgnoreInstability(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *success)
enum SCIP_SDPSolverSetting SCIP_SDPSOLVERSETTING
Definition: type_sdpi.h:78
SCIP_Bool SCIPsdpiSolverIsPrimalUnbounded(SCIP_SDPISOLVER *sdpisolver)
#define MAX_LAMBDASTAR
SCIP_RETCODE SCIPsdpiSolverGetObjval(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval)
#define PENALTYPARAM_FACTOR
const char * SCIPsdpiSolverGetSolverDesc(void)
SCIP_Bool SCIPsdpiSolverIsInfinity(SCIP_SDPISOLVER *sdpisolver, SCIP_Real val)
interface methods for specific SDP-solvers
SCIP_RETCODE SCIPsdpiSolverResetCounter(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real *dval)
SCIP_Bool SCIPsdpiSolverIsObjlimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
#define MAXPENALTYPARAM_FACTOR
SCIP_Bool SCIPsdpiSolverFeasibilityKnown(SCIP_SDPISOLVER *sdpisolver)
#define MAX_MAXPENALTYPARAM
SCIP_RETCODE SCIPsdpiSolverComputeLambdastar(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxguess)
SCIP_Real SCIPsdpiSolverGetDefaultSdpiSolverFeastol(void)
SCIP_Bool SCIPsdpiSolverIsPrimalFeasible(SCIP_SDPISOLVER *sdpisolver)
#define LAMBDASTAR_THRESHOLD
SCIP_RETCODE SCIPsdpiSolverSettingsUsed(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPSOLVERSETTING *usedsetting)
SCIP_RETCODE SCIPsdpiSolverGetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int *ival)
SCIP_Bool SCIPsdpiSolverWasSolved(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)
Definition: sdpsolchecker.c:57
SCIP_RETCODE SCIPsdpiSolverCreate(SCIP_SDPISOLVER **sdpisolver, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem)
#define LAMBDASTAR_FACTOR
#define CHECK_IF_SOLVED_BOOL(sdpisolver)
checks a given SDP solution for feasibility
static SCIP_Bool isFixed(SCIP_SDPISOLVER *sdpisolver, SCIP_Real lb, SCIP_Real ub)
#define GAPTOLCHANGE
int SCIPsdpiSolverGetDefaultSdpiSolverNpenaltyIncreases(void)
#define MIN_LAMBDASTAR
SCIP_RETCODE SCIPsdpiSolverIncreaseCounter(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetSolFeasibility(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
#define PENALTYBOUNDTOL
SCIP_RETCODE SCIPsdpiSolverWriteSDP(SCIP_SDPISOLVER *sdpisolver, const char *fname)
SCIP_Bool SCIPsdpiSolverIsAcceptable(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiSolverIsOptimal(SCIP_SDPISOLVER *sdpisolver)
#define CHECK_IF_SOLVED(sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetSdpCalls(SCIP_SDPISOLVER *sdpisolver, int *calls)
SCIP_RETCODE SCIPsdpiSolverComputeMaxPenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Real *maxpenaltyparam)
SCIP_RETCODE SCIPsdpiSolverGetPrimalBoundVars(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
SCIP_Bool SCIPsdpiSolverIsDualInfeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverSetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int ival)
SCIP_Bool SCIPsdpiSolverIsPrimalInfeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverReadSDP(SCIP_SDPISOLVER *sdpisolver, const char *fname)
struct SCIP_SDPiSolver SCIP_SDPISOLVER
Definition: sdpisolver.h:70
SCIP_RETCODE SCIPsdpiSolverComputePenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxcoeff, SCIP_Real *penaltyparam)
SCIP_Bool SCIPsdpiSolverIsIterlimExc(SCIP_SDPISOLVER *sdpisolver)
int SCIPsdpiSolverGetInternalStatus(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 *start, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit, SCIP_Bool *feasorig, SCIP_Bool *penaltybound)
enum SCIP_SDPParam SCIP_SDPPARAM
Definition: type_sdpi.h:67
SCIP_Bool SCIPsdpiSolverIsDualUnbounded(SCIP_SDPISOLVER *sdpisolver)
#define INFEASMINFEASTOL
SCIP_Bool SCIPsdpiSolverIsTimelimExc(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 *lprownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *start, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit)
#define BMS_CALL(x)
SCIP_Bool SCIPsdpiSolverIsDualFeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetIterations(SCIP_SDPISOLVER *sdpisolver, int *iterations)
SCIP_Bool SCIPsdpiSolverIsConverged(SCIP_SDPISOLVER *sdpisolver)
#define MAX_PENALTYPARAM