SCIP-SDP  2.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sdpisolver_dsdp.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of SCIPSDP - a solving framework for mixed-integer */
4 /* semidefinite programms based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2016 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-2016 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*/
35 
41 #include <assert.h>
42 #include <sys/time.h>
43 
44 #include "sdpi/sdpisolver.h"
45 
46 /* turn off warning for DSDSP */
47 #pragma GCC diagnostic ignored "-Wstrict-prototypes"
48 #include "dsdp5.h" /* for DSDPUsePenalty, etc */
49 #pragma GCC diagnostic warning "-Wstrict-prototypes"
50 
51 
52 #include "blockmemshell/memory.h" /* for memory allocation */
53 #include "scip/def.h" /* for SCIP_Real, _Bool, ... */
54 #include "scip/pub_misc.h" /* for sorting */
55 
56 /* turn off lint warnings for whole file: */
57 /*lint --e{788,818}*/
58 
59 #define PENALTYBOUNDTOL 1E-3
62 #define MIN_PENALTYPARAM 1e5
63 #define MAX_PENALTYPARAM 1e12
64 #define PENALTYPARAM_FACTOR 1e4
65 #define MAX_MAXPENALTYPARAM 1e15
66 #define MAXPENALTYPARAM_FACTOR 1e6
69 #define DSDP_CALL(x) do \
70  { \
71  int _dsdperrorcode_; \
72  if ( (_dsdperrorcode_ = (x)) != 0 ) \
73  { \
74  SCIPerrorMessage("DSDP-Error <%d> in function call.\n", _dsdperrorcode_); \
75  return SCIP_LPERROR; \
76  } \
77  } \
78  while( FALSE )
79 
81 #define DSDP_CALL_BOOL(x) do \
82  { \
83  int _dsdperrorcode_; \
84  if ( (_dsdperrorcode_ = (x)) != 0 ) \
85  { \
86  SCIPerrorMessage("DSDP-Error <%d> in function call.\n", _dsdperrorcode_); \
87  return FALSE; \
88  } \
89  } \
90  while( FALSE )
91 
93 #define DSDP_CALLM(x) do \
94  { \
95  int _dsdperrorcode_; \
96  if ( (_dsdperrorcode_ = (x)) != 0 ) \
97  { \
98  SCIPerrorMessage("DSDP-Error <%d> in function call.\n", _dsdperrorcode_); \
99  return SCIP_NOMEMORY; \
100  } \
101  } \
102  while( FALSE )
103 
105 #define BMS_CALL(x) do \
106  { \
107  if( NULL == (x) ) \
108  { \
109  SCIPerrorMessage("No memory in function call.\n"); \
110  return SCIP_NOMEMORY; \
111  } \
112  } \
113  while( FALSE )
114 
116 #define TIMEOFDAY_CALL(x) do \
117  { \
118  int _errorcode_; \
119  if ( (_errorcode_ = (x)) != 0 ) \
120  { \
121  SCIPerrorMessage("Error in gettimeofday! \n"); \
122  return SCIP_ERROR; \
123  } \
124  } \
125  while( FALSE )
126 
128 #define CHECK_IF_SOLVED(sdpisolver) do \
129  { \
130  if (!(sdpisolver->solved)) \
131  { \
132  SCIPerrorMessage("Tried to access solution information for SDP %d ahead of solving!\n", sdpisolver->sdpcounter); \
133  return SCIP_LPERROR; \
134  } \
135  } \
136  while( FALSE )
137 
139 #define CHECK_IF_SOLVED_BOOL(sdpisolver) do \
140  { \
141  if (!(sdpisolver->solved)) \
142  { \
143  SCIPerrorMessage("Tried to access solution information for SDP %d ahead of solving!\n", sdpisolver->sdpcounter); \
144  return FALSE; \
145  } \
146  } \
147  while( FALSE )
148 
149 
151 struct SCIP_SDPiSolver
152 {
153  SCIP_MESSAGEHDLR* messagehdlr;
154  BMS_BLKMEM* blkmem;
155  DSDP dsdp;
156  SDPCone sdpcone;
157  LPCone lpcone;
158  BCone bcone;
159  int nvars;
160  int nactivevars;
161  int* inputtodsdpmapper;
164  int* dsdptoinputmapper;
165  SCIP_Real* fixedvarsval;
166  SCIP_Real fixedvarsobjcontr;
167  SCIP_Bool solved;
168  int sdpcounter;
169  SCIP_Real epsilon;
170  SCIP_Real feastol;
171  SCIP_Real penaltyparam;
172  SCIP_Real objlimit;
173  SCIP_Bool sdpinfo;
174  SCIP_Bool penaltyworbound;
175  SCIP_SDPSOLVERSETTING usedsetting;
176  SCIP_Bool timelimit;
177  SCIP_Bool timelimitinitial;
178 };
179 
180 typedef struct Timings
181 {
182  struct timeval starttime;
183  SCIP_Real timelimit;
184  SCIP_Bool stopped;
185 } Timings;
186 
187 
188 /*
189  * Local Functions
190  */
191 
195 static
197  int i,
198  int j
199  )
200 {
201  assert( j >= 0 );
202  assert( i >= j );
203 
204  return i*(i+1)/2 + j;
205 }
206 
207 #ifndef NDEBUG
208 
209 static
210 SCIP_Bool isFixed(
211  SCIP_SDPISOLVER* sdpisolver,
212  SCIP_Real lb,
213  SCIP_Real ub
214  )
215 {
216  assert( lb < ub + sdpisolver->feastol );
217 
218  return (REALABS(ub-lb) <= sdpisolver->feastol);
219 }
220 #else
221 #define isFixed(sdpisolver,lb,ub) (REALABS(ub-lb) <= sdpisolver->feastol)
222 #endif
223 
225 static
226 void sortColRow(
227  int* row,
228  int* col,
229  SCIP_Real* val,
230  int length
231  )
232 {
233  int firstentry;
234  int nextentry = 0;
235 
236  /* first sort by col indices */
237  SCIPsortIntIntReal(col, row, val, length);
238 
239  /* for those with identical col-indices now sort by non-decreasing row-index, first find all entries with the same col-index */
240  while (nextentry < length)
241  {
242  firstentry = nextentry; /* the next col starts where the last one ended */
243 
244  while (nextentry < length && col[nextentry] == col[firstentry]) /* as long as the row still matches, increase nextentry */
245  ++nextentry;
246 
247  /* now sort all entries between firstentry and nextentry-1 by their row-indices */
248  SCIPsortIntReal(row + firstentry, val + firstentry, nextentry - firstentry);
249  }
250 }
251 
253 static
255  DSDP dsdp,
256  void* ctx
257  )
258 {
259  Timings* timings;
260  struct timeval currenttime;
261  SCIP_Real startseconds;
262  SCIP_Real currentseconds;
263  SCIP_Real elapsedtime;
264 
265  assert( dsdp != NULL );
266  assert( ctx != NULL );
267 
268  timings = (Timings*) ctx;
269 
270  startseconds = (SCIP_Real) (timings->starttime).tv_sec + (SCIP_Real) (timings->starttime).tv_usec / 1e6;
271 
272  TIMEOFDAY_CALL( gettimeofday(&currenttime, NULL) );/*lint !e438, !e550, !e641 */
273  currentseconds = (SCIP_Real) currenttime.tv_sec + (SCIP_Real) currenttime.tv_usec / 1e6;
274 
275  elapsedtime = currentseconds - startseconds;
276 
277  if ( elapsedtime > timings->timelimit )
278  {
279  DSDP_CALL( DSDPSetConvergenceFlag(dsdp, DSDP_USER_TERMINATION) );/*lint !e641 */
280  timings->stopped = TRUE;
281  SCIPdebugMessage("Time limit reached! Stopping DSDP.\n");
282  }
283 
284  return 0;
285 }
286 
287 
288 /*
289  * Miscellaneous Methods
290  */
291 
297 const char* SCIPsdpiSolverGetSolverName(
298  void
299  )
300 {
301  return "DSDP"; /* getting the version is not supported in DSDP */
302 }
303 
305 const char* SCIPsdpiSolverGetSolverDesc(
306  void
307  )
308 {
309  return "Dual-Scaling Interior Point SDP-Solver by S. Benson, Y. Ye, and X. Zhang (http://www.mcs.anl.gov/hs/software/DSDP/)";
310 }
311 
319  SCIP_SDPISOLVER* sdpisolver
320  )
321 {
322  assert( sdpisolver != NULL );
323  return (void*) sdpisolver->dsdp;
324 }
325 
329 /*
330  * SDPI Creation and Destruction Methods
331  */
332 
337 SCIP_RETCODE SCIPsdpiSolverCreate(
338  SCIP_SDPISOLVER** sdpisolver,
339  SCIP_MESSAGEHDLR* messagehdlr,
340  BMS_BLKMEM* blkmem
341  )
342 {
343  assert( sdpisolver != NULL );
344  assert( blkmem != NULL );
345 
346  SCIPdebugMessage("Calling SCIPsdpiCreate \n");
347 
348  BMS_CALL( BMSallocBlockMemory(blkmem, sdpisolver) );
349 
350  (*sdpisolver)->messagehdlr = messagehdlr;
351  (*sdpisolver)->blkmem = blkmem;
352 
353  /* the following four variables will be properly initialized only immediatly prior to solving because DSDP and the
354  * SDPCone need information about the number of variables and sdpblocks during creation */
355  (*sdpisolver)->dsdp = NULL;
356  (*sdpisolver)->sdpcone = NULL;
357  (*sdpisolver)->lpcone = NULL;
358  (*sdpisolver)->bcone = NULL;
359 
360  (*sdpisolver)->nvars = 0;
361  (*sdpisolver)->nactivevars = 0;
362  (*sdpisolver)->inputtodsdpmapper = NULL;
363  (*sdpisolver)->dsdptoinputmapper = NULL;
364  (*sdpisolver)->fixedvarsval = NULL;
365  (*sdpisolver)->fixedvarsobjcontr = 0.0;
366  (*sdpisolver)->solved = FALSE;
367  (*sdpisolver)->timelimit = FALSE;
368  (*sdpisolver)->timelimitinitial = FALSE;
369  (*sdpisolver)->sdpcounter = 0;
370 
371  (*sdpisolver)->epsilon = 1e-4;
372  (*sdpisolver)->feastol = 1e-6;
373  (*sdpisolver)->penaltyparam = 1e5;
374  (*sdpisolver)->objlimit = SCIPsdpiSolverInfinity(*sdpisolver);
375  (*sdpisolver)->sdpinfo = FALSE;
376  (*sdpisolver)->usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
377 
378  return SCIP_OKAY;
379 }
380 
382 SCIP_RETCODE SCIPsdpiSolverFree(
383  SCIP_SDPISOLVER** sdpisolver
384  )
385 {
386  assert( sdpisolver != NULL );
387  assert( *sdpisolver != NULL );
388 
389  SCIPdebugMessage("Freeing SDPISolver\n");
390 
391  if ( (*sdpisolver)->dsdp != NULL )
392  {
393  DSDP_CALL( DSDPDestroy((*sdpisolver)->dsdp) );
394  }
395 
396  if ( (*sdpisolver)->nvars > 0 )
397  BMSfreeBlockMemoryArray((*sdpisolver)->blkmem, &(*sdpisolver)->inputtodsdpmapper, (*sdpisolver)->nvars);/*lint !e737 */
398 
399  if ( (*sdpisolver)->nactivevars > 0 )
400  BMSfreeBlockMemoryArray((*sdpisolver)->blkmem, &(*sdpisolver)->dsdptoinputmapper, (*sdpisolver)->nactivevars);/*lint !e737 */
401 
402  if ( (*sdpisolver)->nvars >= (*sdpisolver)->nactivevars )
403  BMSfreeBlockMemoryArrayNull((*sdpisolver)->blkmem, &(*sdpisolver)->fixedvarsval, (*sdpisolver)->nvars - (*sdpisolver)->nactivevars); /*lint !e776*/
404 
405  BMSfreeBlockMemory((*sdpisolver)->blkmem, sdpisolver);
406 
407  return SCIP_OKAY;
408 }
409 
411 SCIP_RETCODE SCIPsdpiSolverIncreaseCounter(
412  SCIP_SDPISOLVER* sdpisolver
413  )
414 {
415  assert( sdpisolver != NULL );
416 
417  sdpisolver->sdpcounter++;
418 
419  return SCIP_OKAY;
420 }
421 
423 SCIP_RETCODE SCIPsdpiSolverResetCounter(
424  SCIP_SDPISOLVER* sdpisolver
425  )
426 {
427  assert( sdpisolver != NULL );
428 
429  SCIPdebugMessage("Resetting counter of SDP-Interface from %d to 0.\n", sdpisolver->sdpcounter);
430  sdpisolver->sdpcounter = 0;
431 
432  return SCIP_OKAY;
433 }
434 
438 /*
439  * Solving Methods
440  */
441 
457 SCIP_RETCODE SCIPsdpiSolverLoadAndSolve(
458  SCIP_SDPISOLVER* sdpisolver,
459  int nvars,
460  SCIP_Real* obj,
461  SCIP_Real* lb,
462  SCIP_Real* ub,
463  int nsdpblocks,
464  int* sdpblocksizes,
465  int* sdpnblockvars,
466  int sdpconstnnonz,
467  int* sdpconstnblocknonz,
469  int** sdpconstrow,
470  int** sdpconstcol,
471  SCIP_Real** sdpconstval,
472  int sdpnnonz,
473  int** sdpnblockvarnonz,
475  int** sdpvar,
477  int*** sdprow,
478  int*** sdpcol,
479  SCIP_Real*** sdpval,
480  int** indchanges,
482  int* nremovedinds,
483  int* blockindchanges,
484  int nremovedblocks,
485  int nlpcons,
486  int noldlpcons,
487  SCIP_Real* lplhs,
488  SCIP_Real* lprhs,
489  int* rownactivevars,
490  int lpnnonz,
491  int* lprow,
492  int* lpcol,
493  SCIP_Real* lpval,
494  SCIP_Real* start,
495  SCIP_SDPSOLVERSETTING startsettings,
497  SCIP_Real timelimit
498  )
499 {
500  return SCIPsdpiSolverLoadAndSolveWithPenalty(sdpisolver, 0.0, TRUE, TRUE, nvars, obj, lb, ub, nsdpblocks, sdpblocksizes, sdpnblockvars,
501  sdpconstnnonz, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, sdpnnonz, sdpnblockvarnonz, sdpvar, sdprow, sdpcol, sdpval,
502  indchanges, nremovedinds, blockindchanges, nremovedblocks, nlpcons, noldlpcons, lplhs, lprhs, rownactivevars, lpnnonz, lprow, lpcol,
503  lpval, start, startsettings, timelimit, NULL, NULL);
504 }
505 
526  SCIP_SDPISOLVER* sdpisolver,
527  SCIP_Real penaltyparam,
528  SCIP_Bool withobj,
529  SCIP_Bool rbound,
530  int nvars,
531  SCIP_Real* obj,
532  SCIP_Real* lb,
533  SCIP_Real* ub,
534  int nsdpblocks,
535  int* sdpblocksizes,
536  int* sdpnblockvars,
537  int sdpconstnnonz,
538  int* sdpconstnblocknonz,
540  int** sdpconstrow,
541  int** sdpconstcol,
542  SCIP_Real** sdpconstval,
543  int sdpnnonz,
544  int** sdpnblockvarnonz,
546  int** sdpvar,
548  int*** sdprow,
549  int*** sdpcol,
550  SCIP_Real*** sdpval,
551  int** indchanges,
553  int* nremovedinds,
554  int* blockindchanges,
555  int nremovedblocks,
556  int nlpcons,
557  int noldlpcons,
558  SCIP_Real* lplhs,
559  SCIP_Real* lprhs,
560  int* rownactivevars,
561  int lpnnonz,
562  int* lprow,
563  int* lpcol,
564  SCIP_Real* lpval,
565  SCIP_Real* start,
566  SCIP_SDPSOLVERSETTING startsettings,
568  SCIP_Real timelimit,
569  SCIP_Bool* feasorig,
571  SCIP_Bool* penaltybound
573  )
574 {/*lint --e{413}*/
575  int* dsdpconstind = NULL; /* indices for constant SDP-constraint-matrices, needs to be stored for DSDP during solving and be freed only afterwards */
576  SCIP_Real* dsdpconstval = NULL; /* non-zero values for constant SDP-constraint-matrices, needs to be stored for DSDP during solving and be freed only afterwards */
577  int* dsdpind = NULL; /* indices for SDP-constraint-matrices, needs to be stored for DSDP during solving and be freed only afterwards */
578  SCIP_Real* dsdpval = NULL; /* non-zero values for SDP-constraint-matrices, needs to be stored for DSDP during solving and be freed only afterwards */
579  int* dsdplpbegcol = NULL; /* starting-indices for all columns in LP, needs to be stored for DSDP during solving and be freed only afterwards */
580  int* dsdplprow = NULL; /* row indices in LP, needs to be stored for DSDP during solving and be freed only afterwards */
581  SCIP_Real* dsdplpval = NULL; /* nonzeroes in LP, needs to be stored for DSDP during solving and be freed only afterwards */
582  int i;
583  int j;
584  int ind;
585  int block;
586  int startind;
587  int nfixedvars;
588  int dsdpnlpnonz = 0;
589  int nrnonz = 0;
590  Timings timings;
591 
592 #ifdef SCIP_DEBUG
593  DSDPTerminationReason reason; /* this will later be used to check if DSDP converged */
594 #endif
595 
596  assert( sdpisolver != NULL );
597  assert( penaltyparam > -1 * sdpisolver->epsilon );
598  assert( penaltyparam < sdpisolver->epsilon || ( feasorig != NULL ) );
599  assert( nvars > 0 );
600  assert( obj != NULL );
601  assert( lb != NULL );
602  assert( ub != NULL );
603  assert( nsdpblocks >= 0 );
604  assert( nsdpblocks == 0 || sdpblocksizes != NULL );
605  assert( nsdpblocks == 0 || sdpnblockvars != NULL );
606  assert( sdpconstnnonz >= 0 );
607  assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstnblocknonz != NULL );
608  assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstrow != NULL );
609  assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstcol != NULL );
610  assert( nsdpblocks == 0 || sdpconstnnonz == 0 || sdpconstval != NULL );
611  assert( sdpnnonz >= 0 );
612  assert( nsdpblocks == 0 || sdpnblockvarnonz != NULL );
613  assert( nsdpblocks == 0 || sdpvar != NULL );
614  assert( nsdpblocks == 0 || sdprow != NULL );
615  assert( nsdpblocks == 0 || sdpcol != NULL );
616  assert( nsdpblocks == 0 || sdpval != NULL );
617  assert( nsdpblocks == 0 || indchanges != NULL );
618  assert( nsdpblocks == 0 || nremovedinds != NULL );
619  assert( nsdpblocks == 0 || blockindchanges != NULL );
620  assert( 0 <= nremovedblocks && nremovedblocks <= nsdpblocks );
621  assert( nlpcons >= 0 );
622  assert( noldlpcons >= nlpcons );
623  assert( nlpcons == 0 || lplhs != NULL );
624  assert( nlpcons == 0 || lprhs != NULL );
625  assert( nlpcons == 0 || rownactivevars != NULL );
626  assert( lpnnonz >= 0 );
627  assert( nlpcons == 0 || lprow != NULL );
628  assert( nlpcons == 0 || lpcol != NULL );
629  assert( nlpcons == 0 || lpval != NULL );
630 
631  if ( timelimit <= 0.0 )
632  {
633  sdpisolver->timelimit = TRUE;
634  sdpisolver->timelimitinitial = TRUE;
635  sdpisolver->solved = FALSE;
636  return SCIP_OKAY;
637  }
638  else
639  sdpisolver->timelimitinitial = FALSE;
640 
641  /* start the timing */
642  TIMEOFDAY_CALL( gettimeofday(&(timings.starttime), NULL) );/*lint !e438, !e550, !e641 */
643  timings.timelimit = timelimit;
644  timings.stopped = FALSE;
645 
646  /* 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
647  * same SDP), also remember settings for statistics */
648  if ( penaltyparam < sdpisolver->epsilon )
649  {
650  SCIPdebugMessage("Inserting Data into DSDP for SDP (%d) \n", ++sdpisolver->sdpcounter);
651  sdpisolver->usedsetting = SCIP_SDPSOLVERSETTING_FAST;
652  }
653  else
654  {
655  SCIPdebugMessage("Inserting Data again into DSDP for SDP (%d) \n", sdpisolver->sdpcounter);
656  sdpisolver->usedsetting = SCIP_SDPSOLVERSETTING_PENALTY;
657  }
658 
659  /* allocate memory for inputtodsdpmapper, dsdptoinputmapper and the fixed variable information, for the latter this will
660  * later be shrinked if the needed size is known */
661  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->inputtodsdpmapper), sdpisolver->nvars, nvars) );
662  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->dsdptoinputmapper), sdpisolver->nactivevars, nvars) );
663  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->fixedvarsval), sdpisolver->nvars - sdpisolver->nactivevars, nvars) ); /*lint !e776*/
664 
665  sdpisolver->nvars = nvars;
666  sdpisolver->nactivevars = 0;
667  nfixedvars = 0;
668 
669  /* find the fixed variables */
670  sdpisolver->fixedvarsobjcontr = 0.0;
671  for (i = 0; i < nvars; i++)
672  {
673  if ( isFixed(sdpisolver, lb[i], ub[i]) )
674  {
675  nfixedvars++;
676  sdpisolver->inputtodsdpmapper[i] = -nfixedvars;
677  sdpisolver->fixedvarsobjcontr += obj[i] * lb[i]; /* this is the value this variable contributes to the objective */
678  sdpisolver->fixedvarsval[nfixedvars - 1] = lb[i]; /* if lb=ub, than this is the value the variable will have in every solution */
679  SCIPdebugMessage("Fixing variable %d locally to %f for SDP %d in DSDP\n", i, lb[i], sdpisolver->sdpcounter);
680  }
681  else
682  {
683  sdpisolver->dsdptoinputmapper[sdpisolver->nactivevars] = i;
684  sdpisolver->nactivevars++;
685  sdpisolver->inputtodsdpmapper[i] = sdpisolver->nactivevars; /* dsdp starts counting at 1, so we do this after increasing nactivevars */
686  SCIPdebugMessage("Variable %d becomes variable %d for SDP %d in DSDP\n", i, sdpisolver->inputtodsdpmapper[i], sdpisolver->sdpcounter);
687  }
688  }
689  assert( sdpisolver->nactivevars + nfixedvars == sdpisolver->nvars );
690  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
691  {
692  SCIPdebugMessage("Variable %d is the slack variable for the explicit penalty formulation\n", sdpisolver->nactivevars + 1);
693  }
694 
695  /* if we want to solve without objective, we reset fixedvarsobjcontr */
696  if ( ! withobj )
697  sdpisolver->fixedvarsobjcontr = 0.0;
698 
699  /* shrink the fixedvars and dsdptoinputmapper arrays to the right size */
700  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->fixedvarsval), nvars, nfixedvars) );
701  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &(sdpisolver->dsdptoinputmapper), nvars, sdpisolver->nactivevars) );
702 
703  /* insert data */
704 
705  if ( sdpisolver->dsdp != NULL )
706  {
707  DSDP_CALL( DSDPDestroy(sdpisolver->dsdp) ); /* if there already exists a DSDP-instance, destroy the old one */
708  }
709 
710  /* in case we don't want to bound r, we can't use the penalty formulation in DSDP and have to give r explicitly */
711  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
712  {
713  DSDP_CALLM( DSDPCreate(sdpisolver->nactivevars + 1, &(sdpisolver->dsdp)) );
714  sdpisolver->penaltyworbound = TRUE;
715  }
716  else
717  {
718  DSDP_CALLM( DSDPCreate(sdpisolver->nactivevars, &(sdpisolver->dsdp)) );
719  sdpisolver->penaltyworbound = FALSE;
720  }
721  DSDP_CALLM( DSDPCreateSDPCone(sdpisolver->dsdp, nsdpblocks - nremovedblocks, &(sdpisolver->sdpcone)) );
722  DSDP_CALLM( DSDPCreateLPCone(sdpisolver->dsdp, &(sdpisolver->lpcone)) );
723  DSDP_CALLM( DSDPCreateBCone(sdpisolver->dsdp, &(sdpisolver->bcone)) );
724 
725 #ifdef SCIP_MORE_DEBUG
726  SCIPmessagePrintInfo(sdpi->messagehdlr, "setting objective values for SDP %d:\n", sdpisolver->sdpcounter);
727 #endif
728 
729  for (i = 0; i < sdpisolver->nactivevars; i++)
730  {
731  if ( withobj )
732  {
733  /* insert objective value, DSDP counts from 1 to n instead of 0 to n-1, *(-1) because DSDP maximizes instead of minimizing */
734  DSDP_CALL( DSDPSetDualObjective(sdpisolver->dsdp, i+1, -1.0 * obj[sdpisolver->dsdptoinputmapper[i]]) );
735 #ifdef SCIP_MORE_DEBUG
736  SCIPmessagePrintInfo(sdpi->messagehdlr, "var %d (was var %d): %f, ", i+1, sdpisolver->dsdptoinputmapper[i], obj[sdpisolver->dsdptoinputmapper[i]]);
737 #endif
738  }
739  else
740  {
741  DSDP_CALL( DSDPSetDualObjective(sdpisolver->dsdp, i+1, 0.0) );
742  }
743 
744  if ( ! SCIPsdpiSolverIsInfinity(sdpisolver, lb[sdpisolver->dsdptoinputmapper[i]]) )
745  {
746  /* insert lower bound, DSDP counts from 1 to n instead of 0 to n-1 */
747  DSDP_CALL( BConeSetLowerBound(sdpisolver->bcone, i+1, lb[sdpisolver->dsdptoinputmapper[i]]) );
748  }
749 
750  if ( ! SCIPsdpiSolverIsInfinity(sdpisolver, ub[sdpisolver->dsdptoinputmapper[i]]) )
751  {
752  /* insert upper bound, DSDP counts from 1 to n instead of 0 to n-1 */
753  DSDP_CALL(BConeSetUpperBound(sdpisolver->bcone, i+1, ub[sdpisolver->dsdptoinputmapper[i]]));
754  }
755  }
756 
757  /* insert the objective value for r if solving without rbound, it is variable nactivevars + 1 and the objective is multiplied by -1 as we maximize */
758  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
759  {
760  DSDP_CALL( DSDPSetDualObjective(sdpisolver->dsdp, sdpisolver->nactivevars + 1, -1.0 * penaltyparam) );
761 #ifdef SCIP_MORE_DEBUG
762  SCIPmessagePrintInfo(sdpi->messagehdlr, "slack variable r: %f, ", penaltyparam);
763 #endif
764  }
765 
766 #ifdef SCIP_MORE_DEBUG
767  SCIPmessagePrintInfo(sdpi->messagehdlr, "\n");
768  SCIPdebugMessage("ATTENTION: BConeView shows the WRONG sign for the lower bound!\n");
769  BConeView(sdpisolver->bcone);
770 #endif
771 
772  /* set blocksizes */
773  for (block = 0; block < nsdpblocks; ++block)
774  {
775  /* only insert blocksizes for the blocks we didn't remove */
776  if ( blockindchanges[block] > -1 )
777  {
778  /* (blocks are counted from 0 to m-1) */
779  DSDP_CALL( SDPConeSetBlockSize(sdpisolver->sdpcone, block- blockindchanges[block], sdpblocksizes[block] - nremovedinds[block]) );
780  }
781  }
782 
783  /* start inserting the non-constant SDP-Constraint-Matrices */
784  if ( sdpnnonz > 0 )
785  {
786  int v;
787  int k;
788  int blockvar;
789 
790  nrnonz = 0;
791 
792  /* allocate memory */
793  /* This needs to be one long array, because DSDP uses it for solving so all nonzeros have to be in it and it may not be freed before the
794  * problem is solved. The distinct blocks/variables (for the i,j-parts) are then given by dsdpind + startind, which gives a pointer to the
795  * first array-element belonging to this block and then the number of elements in this block is given to DSDP for iterating over it. */
796 
797  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
798  {
799  /* we need to compute the total number of nonzeros for the slack variable r, which equals the total number of diagonal entries */
800  for (block = 0; block < nsdpblocks; block++)
801  nrnonz += sdpblocksizes[block] - nremovedinds[block];
802  assert( nrnonz >= 0 );
803 
804  /* indices given to DSDP, for this the elements in the lower triangular part of the matrix are labeled from 0 to n*(n+1)/2 -1 */
805  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdpind, sdpnnonz + nrnonz) ); /*lint !e776*/
806  /* values given to DSDP, these will be multiplied by -1 because in DSDP -1* (sum A_i^j y_i - A_0) should be positive semidefinite */
807  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdpval, sdpnnonz + nrnonz) ); /*lint !e776*/
808  }
809  else
810  {
811  /* indices given to DSDP, for this the elements in the lower triangular part of the matrix are labeled from 0 to n*(n+1)/2 -1 */
812  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdpind, sdpnnonz) );
813  /* values given to DSDP, these will be multiplied by -1 because in DSDP -1* (sum A_i^j y_i - A_0) should be positive semidefinite */
814  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdpval, sdpnnonz) );
815  }
816 
817  ind = 0; /* this will be used for iterating over the nonzeroes */
818 
819  for (block = 0; block < nsdpblocks; block++)
820  {
821  for (i = 0; i < sdpisolver->nactivevars; i++)
822  {
823  /* we iterate over all non-fixed variables, so add them to the dsdp arrays for this block/var combination */
824  v = sdpisolver->dsdptoinputmapper[i];
825 
826  /* find the position of variable v in this block */
827  blockvar = -1;
828  for (k = 0; k < sdpnblockvars[block]; k++)
829  {
830  if ( v == sdpvar[block][k] )
831  {
832  blockvar = k;
833  break;
834  }
835  }
836 
837  startind = ind;
838 
839  if ( blockvar > -1 ) /* the variable exists in this block */
840  {
841  for (k = 0; k < sdpnblockvarnonz[block][blockvar]; k++)
842  {
843  /* rows and cols with active nonzeros should not be removed */
844  assert( indchanges[block][sdprow[block][blockvar][k]] > -1 && indchanges[block][sdpcol[block][blockvar][k]] > -1 );
845 
846  /* substract the number of removed indices before the row and col to get the indices after fixings */
847  dsdpind[ind] = compLowerTriangPos(sdprow[block][blockvar][k] - indchanges[block][sdprow[block][blockvar][k]],
848  sdpcol[block][blockvar][k] - indchanges[block][sdpcol[block][blockvar][k]]);
849  dsdpval[ind] = -1.0 * sdpval[block][blockvar][k]; /* *(-1) because in DSDP -1* (sum A_i^j y_i - A_0) should be positive semidefinite */
850  ind++;
851  }
852 
853  /* sort the arrays for this matrix (by non decreasing indices) as this might help the solving time of DSDP */
854  SCIPsortIntReal(dsdpind + startind, dsdpval + startind, sdpnblockvarnonz[block][blockvar]);
855 
856  assert( blockindchanges[block] > -1 ); /* we shouldn't insert into blocks we removed */
857 
858  /* i + 1 because DSDP starts counting the variables at 1, adding startind shifts the arrays to the first
859  * nonzero belonging to this block and this variable */
860  DSDP_CALL( SDPConeSetASparseVecMat(sdpisolver->sdpcone, block - blockindchanges[block], i + 1, sdpblocksizes[block] - nremovedinds[block],
861  1.0, 0, dsdpind + startind,dsdpval + startind, sdpnblockvarnonz[block][blockvar]));
862  }
863  }
864  }
865 
866  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
867  {
868  startind = ind;
869  /* add r * Identity for each block */
870  for (block = 0; block < nsdpblocks; block++)
871  {
872  if ( blockindchanges[block] > -1 )
873  {
874  for (i = 0; i < sdpblocksizes[block] - nremovedinds[block]; i++)
875  {
876  dsdpind[ind] = compLowerTriangPos(i, i);
877  dsdpval[ind] = -1.0; /* *(-1) because in DSDP -1* (sum A_i^j y_i - A_0 + r*I) should be positive semidefinite */
878  ind++;
879  }
880  DSDP_CALL( SDPConeSetASparseVecMat(sdpisolver->sdpcone, block - blockindchanges[block], sdpisolver->nactivevars + 1,
881  sdpblocksizes[block] - nremovedinds[block], 1.0, 0, dsdpind + ind - (sdpblocksizes[block] - nremovedinds[block]) ,
882  dsdpval + ind - (sdpblocksizes[block] - nremovedinds[block]), sdpblocksizes[block] - nremovedinds[block]) ); /*lint !e679*/
883  }
884  }
885  assert( ind - startind == nrnonz );
886  }
887  }
888 
889  /* start inserting the constant matrix */
890  if ( sdpconstnnonz > 0 )
891  {
892  assert( nsdpblocks > 0 );
893  assert( sdpconstnblocknonz!= NULL );
894  assert( sdpconstcol != NULL );
895  assert( sdpconstrow != NULL );
896  assert( sdpconstval != NULL );
897 
898  /* allocate memory */
899 
900  /* DSDP uses these for solving, so they may not be freed before the problem is solved. */
901 
902  /* indices given to DSDP, for this the elements in the lower triangular part of the matrix are labeled from 0 to n*(n+1)/2 -1 */
903  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdpconstind, sdpconstnnonz) );
904  /* values given to DSDP, for this the original values are mutliplied by -1 because in DSDP -1* (sum A_i^j y_i - A_0) should be positive semidefinite */
905  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdpconstval, sdpconstnnonz) );
906 
907  ind = 0;
908 
909  for (block = 0; block < nsdpblocks; block++)
910  {
911  startind = ind; /* starting index of this block in the dsdpconst arrays */
912 
913  if ( sdpconstnblocknonz[block] > 0 )
914  {
915  /* insert the constant-nonzeros */
916  for (i = 0; i < sdpconstnblocknonz[block]; i++)
917  {
918  /* rows and cols with nonzeros should not be removed */
919  assert( indchanges[block][sdpconstrow[block][i]] > -1 && indchanges[block][sdpconstcol[block][i]] > -1 );
920 
921  /* substract the number of deleted indices before this to get the index after variable fixings */
922  dsdpconstind[ind] = compLowerTriangPos(sdpconstrow[block][i] - indchanges[block][sdpconstrow[block][i]],
923  sdpconstcol[block][i] - indchanges[block][sdpconstcol[block][i]]);
924  dsdpconstval[ind] = -1 * sdpconstval[block][i]; /* *(-1) because in DSDP -1* (sum A_i^j y_i - A_0^j) should be positive semidefinite */
925  ind++;
926  }
927 
928  /* sort the arrays for this Matrix (by non decreasing indices) as this might help the solving time of DSDP */
929  SCIPsortIntReal(dsdpconstind + startind, dsdpconstval + startind, sdpconstnblocknonz[block]);
930 
931  assert( blockindchanges[block] > -1 ); /* we shouldn't insert into a block we removed */
932 
933  /* constant matrix is given as variable 0, the arrays are shifted to the first element of this block by adding
934  * startind, ind - startind gives the number of elements for this block */
935  DSDP_CALL( SDPConeSetASparseVecMat(sdpisolver->sdpcone, block - blockindchanges[block], 0, sdpblocksizes[block] - nremovedinds[block],
936  1.0, 0, dsdpconstind + startind, dsdpconstval + startind, ind - startind));
937  }
938  }
939  }
940 
941 #ifdef SCIP_MORE_DEBUG
942  SDPConeView2(sdpisolver->sdpcone);
943 #endif
944 
945  /* start inserting the LP constraints */
946  if ( nlpcons > 0 || lpnnonz > 0 || ! SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit) )
947  {
948  int nextcol;
949  int* rowmapper; /* maps the lhs- and rhs-inequalities of the old LP-cons to their constraint numbers in DSDP */
950  int pos;
951  int newpos;
952  int nlpineqs;
953 
954  assert( noldlpcons > 0 );
955  assert( lprhs != NULL );
956  assert( lpcol != NULL );
957  assert( lprow != NULL );
958  assert( lpval != NULL );
959 
960  /* 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 */
961  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &rowmapper, 2*noldlpcons) ); /*lint !e647*/
962 
963  /* compute the rowmapper and the number of inequalities we have to add to DSDP (as we have to split the ranged rows) */
964  pos = 0;
965  newpos = 0; /* the position in the lhs and rhs arrays */
966  for (i = 0; i < noldlpcons; i++)
967  {
968  if ( rownactivevars[i] >= 2 )
969  {
970  if ( lplhs[newpos] > - SCIPsdpiSolverInfinity(sdpisolver) )
971  {
972  rowmapper[2*i] = pos; /*lint !e679*/
973  pos++;
974  }
975  else
976  rowmapper[2*i] = -1; /*lint !e679*/
977 
978  if ( lprhs[newpos] < SCIPsdpiSolverInfinity(sdpisolver) )
979  {
980  rowmapper[2*i + 1] = pos; /*lint !e679*/
981  pos++;
982  }
983  else
984  rowmapper[2*i + 1] = -1; /*lint !e679*/
985 
986  newpos++;
987  }
988  else
989  {
990  rowmapper[2*i] = -1; /*lint !e679*/
991  rowmapper[2*i + 1] = -1; /*lint !e679*/
992  }
993  }
994  nlpineqs = pos;
995  assert( nlpineqs <= 2*nlpcons ); /* *2 comes from left- and right-hand-sides */
996 
997  /* memory allocation */
998 
999  /* these arrays are needed in DSDP during solving, so they may only be freed afterwards */
1000  /* dsdplpbegcol[i] gives the number of nonzeros in column 0 (right hand side) till i-1 (i going from 1 till m, with extra entries 0 (always 0)
1001  * and m+1 (always lpcons + lpnnonz)) */
1002  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
1003  {
1004  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdplpbegcol, sdpisolver->nactivevars + 3) ); /* extra entry for r */ /*lint !e776*/
1005  }
1006  else
1007  {
1008  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdplpbegcol, sdpisolver->nactivevars + 2) ); /*lint !e776*/
1009  }
1010 
1011  /* dsdplprow saves the row indices of the LP for DSDP */
1012  /* worst-case length is 2*lpnnonz + nlpineqs, because left- and right-hand-sides are also included in the vectorand we might have to duplicate the
1013  * non-zeros when splitting the ranged rows, this will be shortened after the exact length after fixings is known, in case we have an objective limit,
1014  * this is increased by one entry for the right-hand-side and at most nvars entries for the nonzeros, in case of rbound = FALSE, where we have to add
1015  * the entries for r ourselves, we have to add another nlpineqs for one entry for r for each active lp-constraint */
1016  if ( SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit) )
1017  {
1018  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
1019  {
1020  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdplprow, 2 * nlpineqs + 2*lpnnonz) ); /*lint !e647*/
1021  }
1022  else
1023  {
1024  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdplprow, nlpineqs + 2*lpnnonz) ); /*lint !e647*/
1025  }
1026  }
1027  else
1028  {
1029  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
1030  {
1031  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdplprow, (nlpineqs + 1) + 2*lpnnonz + nvars + nlpineqs) ); /*lint !e647*/
1032  }
1033  else
1034  {
1035  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdplprow, (nlpineqs + 1) + 2*lpnnonz + nvars) ); /*lint !e647*/
1036  }
1037  }
1038 
1039  /* values given to DSDP */
1040  /* dsdplprow saves the row indices of the LP for DSDP */
1041  /* worst-case length is 2*lpnnonz + nlpineqs, because left- and right-hand-sides are also included in the vectorand we might have to duplicate the
1042  * non-zeros when splitting the ranged rows, this will be shortened after the exact length after fixings is known, in case we have an objective limit,
1043  * this is increased by one entry for the right-hand-side and at most nvars entries for the nonzeros, in case of rbound = FALSE, where we have to add
1044  * the entries for r ourselves, we have to add another nlpineqs for one entry for r for each active lp-constraint */
1045  if ( SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit) )
1046  {
1047  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
1048  {
1049  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdplpval, 2 * nlpineqs + 2*lpnnonz) ); /*lint !e647*/
1050  }
1051  else
1052  {
1053  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdplpval, nlpineqs + 2*lpnnonz) ); /*lint !e647*/
1054  }
1055  }
1056  else
1057  {
1058  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
1059  {
1060  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdplpval, (nlpineqs + 1) + 2*lpnnonz + nvars + nlpineqs) ); /*lint !e647*/
1061  }
1062  else
1063  {
1064  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdplpval, (nlpineqs + 1) + 2*lpnnonz + nvars) ); /*lint !e647*/
1065  }
1066  }
1067 
1068  /* add all left- and right-hand-sides that are greater than zero (if their corresponding inequalities exist), the pos counter is increased for every
1069  * active row, to get the correct row numbers, the nonz-counter only if the lhs/rhs is unequal to zero and added to DSDP */
1070  dsdpnlpnonz = 0;
1071  pos = 0;
1072  for (i = 0; i < nlpcons; i++)
1073  {
1074  if ( lplhs[i] > - SCIPsdpiSolverInfinity(sdpisolver) )
1075  {
1076  if ( REALABS(lplhs[i]) > sdpisolver->epsilon )
1077  {
1078  dsdplprow[dsdpnlpnonz] = pos;
1079  dsdplpval[dsdpnlpnonz] = -lplhs[i]; /* we multiply by -1 because DSDP wants <= instead of >= */
1080  dsdpnlpnonz++;
1081  }
1082  pos++;
1083  }
1084  if ( lprhs[i] < SCIPsdpiSolverInfinity(sdpisolver) )
1085  {
1086  if ( REALABS(lprhs[i]) > sdpisolver->epsilon )
1087  {
1088  dsdplprow[dsdpnlpnonz] = pos;
1089  dsdplpval[dsdpnlpnonz] = lprhs[i];
1090  dsdpnlpnonz++;
1091  }
1092  pos++;
1093  }
1094  }
1095  assert( pos == nlpineqs );
1096 
1097  /* add the right-hand-side for the objective bound */
1098  if ( ! SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit) )
1099  {
1100  if ( REALABS(sdpisolver->objlimit) > sdpisolver->epsilon )
1101  {
1102  dsdplprow[dsdpnlpnonz] = nlpcons; /* this is the last lp-constraint, as DSDP counts from 0 to nlpcons-1, this is number nlpcons */
1103  dsdplpval[dsdpnlpnonz] = sdpisolver->objlimit; /* as we want <= upper bound, this is the correct type of inequality for DSDP */
1104  dsdpnlpnonz++;
1105  }
1106  }
1107 
1108  /* now add the nonzeros */
1109 
1110  /* for this we have to sort the nonzeros by col first and then by row, as this is the sorting DSDP wants */
1111  sortColRow(lprow, lpcol, lpval, lpnnonz);
1112 
1113  /* iterate over all nonzeros to add the active ones to the dsdp arrays and compute dsdplpbegcol */
1114  nextcol = 0;
1115  dsdplpbegcol[0] = 0;
1116  for (i = 0; i < lpnnonz; i++)
1117  {
1118  /* if a new variable starts, set the corresponding dsdplpbegcol-entry */
1119  if ( lpcol[i] >= nextcol )
1120  {
1121  /* set the dsdplpbegcol entries, as there might be active variables which appear only in the sdp but not the lp-part, we also have to set
1122  * the starting values for all variables in between to the same value (as we also set the entry for the found variable, this for-queue
1123  * will always have at least one index in the index set) */
1124  for (j = nextcol; j <= lpcol[i]; j++)
1125  {
1126  if ( sdpisolver->inputtodsdpmapper[j] >= 0 )
1127  {
1128  assert( ! (isFixed(sdpisolver, lb[j], ub[j])) );
1129  dsdplpbegcol[sdpisolver->inputtodsdpmapper[j]] = dsdpnlpnonz;
1130 
1131  /* add the entry to the objlimit-lp-constraint for the last variables */
1132  if ( (! SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit)) && (REALABS( obj[j] ) > sdpisolver->epsilon))
1133  {
1134  dsdplprow[dsdpnlpnonz] = nlpcons;
1135  dsdplpval[dsdpnlpnonz] = obj[j];
1136  dsdpnlpnonz++;
1137  }
1138  }
1139  }
1140  nextcol = j;
1141  }
1142 
1143  /* add the nonzero, if it isn't fixed and the row isn't to be deleted (because it is only a variable bound) */
1144  if ( ! isFixed(sdpisolver, lb[lpcol[i]], ub[lpcol[i]]) )
1145  {
1146  /* add it to the inequality for the lhs of the ranged row, if it exists */
1147  if ( rowmapper[2*lprow[i]] > -1 ) /*lint !e679*/
1148  {
1149  /* the index is adjusted for deleted lp rows, also rows are numbered 0,...,nlpcons-1 in DSDP, as they are
1150  * here, nlpcons is added to the index as the first nlpcons entries correspond to the right hand sides */
1151  dsdplprow[dsdpnlpnonz] = rowmapper[2*lprow[i]]; /*lint !e679*/
1152  dsdplpval[dsdpnlpnonz] = -lpval[i]; /* - because dsdp wants <= instead of >= constraints */
1153  dsdpnlpnonz++;
1154  }
1155  /* add it to the inequality for the rhs of the ranged row, if it exists */
1156  if ( rowmapper[2*lprow[i] + 1] > -1 ) /*lint !e679*/
1157  {
1158  /* the index is adjusted for deleted lp rows, also rows are numbered 0,...,nlpcons-1 in DSDP, as they are
1159  * here, nlpcons is added to the index as the first nlpcons entries correspond to the right hand sides */
1160  dsdplprow[dsdpnlpnonz] = rowmapper[2*lprow[i] + 1]; /*lint !e679*/
1161  dsdplpval[dsdpnlpnonz] = lpval[i];
1162  dsdpnlpnonz++;
1163  }
1164  }
1165 #ifndef SCIP_NDEBUG
1166  /* if this is an active nonzero for the row, it should have at least one active var */
1167  else
1168  assert( isFixed(sdpisolver, lb[lpcol[i]], ub[lpcol[i]]) || rownactivevars[lprow[i]] == 1 );
1169 #endif
1170  }
1171 
1172  /* set the begcol array for all remaining variables (that aren't part of the LP-part), and also set the objlimit-constraint-entries */
1173  for (j = nextcol; j < nvars; j++)
1174  {
1175  if ( sdpisolver->inputtodsdpmapper[j] >= 0 )
1176  {
1177  assert( ! (isFixed(sdpisolver, lb[j], ub[j])) );
1178  dsdplpbegcol[sdpisolver->inputtodsdpmapper[j]] = dsdpnlpnonz;
1179  /* add the entry to the objlimit-lp-constraint for the last variables */
1180  if ( (! SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit)) && (REALABS( obj[j] ) > sdpisolver->epsilon))
1181  {
1182  dsdplprow[dsdpnlpnonz] = nlpcons;
1183  dsdplpval[dsdpnlpnonz] = obj[j];
1184  dsdpnlpnonz++;
1185  }
1186  }
1187  }
1188 
1189  dsdplpbegcol[sdpisolver->nactivevars + 1] = dsdpnlpnonz; /*lint !e679*/
1190 
1191  /* add r * Identity if using a penalty formulation without a bound on r */
1192  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
1193  {
1194  for (i = 0; i < nlpineqs; i++)
1195  {
1196  dsdplprow[dsdpnlpnonz] = i;
1197  dsdplpval[dsdpnlpnonz] = -1.0; /* for >=-inequalities we would add a +1, but then we have to multiply these with -1 for DSDP */
1198  dsdpnlpnonz++;
1199  }
1200  dsdplpbegcol[sdpisolver->nactivevars + 2] = dsdpnlpnonz; /*lint !e679*/
1201  }
1202 
1203  /* free the memory for the rowshifts-array */
1204  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &rowmapper, 2*noldlpcons); /*lint !e647, !e737*/
1205 
1206  /* shrink the dsdplp-arrays */
1207  if ( SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit) )
1208  {
1209  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
1210  {
1211  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &dsdplprow, 2*nlpineqs + 2*lpnnonz, dsdpnlpnonz) ); /*lint !e647*/
1212  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &dsdplpval, 2*nlpineqs + 2*lpnnonz, dsdpnlpnonz) ); /*lint !e647*/
1213  }
1214  else
1215  {
1216  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &dsdplprow, nlpineqs + 2*lpnnonz, dsdpnlpnonz) ); /*lint !e647*/
1217  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &dsdplpval, nlpineqs + 2*lpnnonz, dsdpnlpnonz) ); /*lint !e647*/
1218  }
1219  }
1220  else
1221  {
1222  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
1223  {
1224  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &dsdplprow, (nlpineqs + 1) + 2*lpnnonz + nvars + nlpineqs, dsdpnlpnonz) ); /*lint !e647*/
1225  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &dsdplpval, (nlpineqs + 1) + 2*lpnnonz + nvars + nlpineqs, dsdpnlpnonz) ); /*lint !e647*/
1226  }
1227  else
1228  {
1229  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &dsdplprow, (nlpineqs + 1) + 2*lpnnonz + nvars, dsdpnlpnonz) ); /*lint !e647*/
1230  BMS_CALL( BMSreallocBlockMemoryArray(sdpisolver->blkmem, &dsdplpval, (nlpineqs + 1) + 2*lpnnonz + nvars, dsdpnlpnonz) ); /*lint !e647*/
1231  }
1232  }
1233  /* add the arrays to dsdp (in this case we need no additional if for the penalty version without bounds, as we already added the extra var,
1234  * so DSDP knows, that there is an additional entry in dsdplpbegcol which then gives the higher number of nonzeros) */
1235  if ( SCIPsdpiSolverIsInfinity(sdpisolver, sdpisolver->objlimit) )
1236  {
1237  DSDP_CALL( LPConeSetData(sdpisolver->lpcone, nlpineqs, dsdplpbegcol, dsdplprow, dsdplpval) );
1238  }
1239  else
1240  {
1241  DSDP_CALL( LPConeSetData(sdpisolver->lpcone, nlpineqs + 1, dsdplpbegcol, dsdplprow, dsdplpval) );
1242  }
1243 #ifdef SCIP_MORE_DEBUG
1244  LPConeView(sdpisolver->lpcone);
1245 #endif
1246  }
1247 
1248  SCIPdebugMessage("Calling DSDP-Solve for SDP (%d) \n", sdpisolver->sdpcounter);
1249 
1250  DSDP_CALL( DSDPSetGapTolerance(sdpisolver->dsdp, sdpisolver->epsilon) ); /* set DSDP's tolerance for duality gap */
1251  DSDP_CALL( DSDPSetRTolerance(sdpisolver->dsdp, sdpisolver->feastol) ); /* set DSDP's tolerance for the SDP-constraints */
1252  if ( sdpisolver-> sdpinfo )
1253  {
1254  DSDP_CALL( DSDPSetStandardMonitor(sdpisolver->dsdp, 1) ); /* output DSDP information after every 1 iteration */
1255  }
1256 
1257  /* set the penalty parameter (only if rbound = TRUE, otherwise we had to add everything ourselves) */
1258  if ( penaltyparam >= sdpisolver->epsilon && rbound ) /* in sdpisolverSolve this is called with an exact 0 */
1259  {
1260  DSDP_CALL( DSDPSetPenaltyParameter(sdpisolver->dsdp, penaltyparam) );
1261  DSDP_CALL( DSDPUsePenalty(sdpisolver->dsdp, 1) );
1262  }
1263  else
1264  {
1265  /* set the penalty parameter to the default value */
1266  DSDP_CALL( DSDPSetPenaltyParameter(sdpisolver->dsdp, sdpisolver->penaltyparam) );
1267  }
1268 
1269  /* set the starting solution */
1270  if ( start != NULL )
1271  {
1272  for (i = 1; i <= sdpisolver->nactivevars; i++) /* we iterate over the variables in DSDP */
1273  {
1274  DSDP_CALL( DSDPSetY0(sdpisolver->dsdp, i, start[sdpisolver->dsdptoinputmapper[i]]) );
1275  }
1276  }
1277 
1278  /* start the solving process */
1279  DSDP_CALLM( DSDPSetup(sdpisolver->dsdp) );
1280  if ( ! SCIPsdpiSolverIsInfinity(sdpisolver, timelimit) )
1281  {
1282  DSDP_CALLM( DSDPSetMonitor(sdpisolver->dsdp, checkTimeLimitDSDP, (void*) &timings) );
1283  }
1284  DSDP_CALL( DSDPSolve(sdpisolver->dsdp) );
1285 
1286  /* check if solving was stopped because of the time limit */
1287  if ( timings.stopped )
1288  {
1289  sdpisolver->timelimit = TRUE;
1290  sdpisolver->solved = FALSE;
1291  }
1292  else
1293  {
1294  sdpisolver->timelimit = FALSE;
1295  DSDP_CALL( DSDPComputeX(sdpisolver->dsdp) ); /* computes X and determines feasibility and unboundedness of the solution */
1296  sdpisolver->solved = TRUE;
1297  }
1298 
1299  /*these arrays were used to give information to DSDP and were needed during solving and for computing X, so they may only be freed now*/
1300  if ( sdpconstnnonz > 0 )
1301  {
1302  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdpconstval, sdpconstnnonz);/*lint !e737 */
1303  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdpconstind, sdpconstnnonz);/*lint !e737 */
1304  }
1305 
1306  if ( sdpnnonz > 0 )
1307  {
1308  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
1309  {
1310  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdpval, sdpnnonz + nrnonz); /*lint !e737, !e776*/
1311  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdpind, sdpnnonz + nrnonz); /*lint !e737, !e776*/
1312  }
1313  else
1314  {
1315  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdpval, sdpnnonz);/*lint !e737 */
1316  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdpind, sdpnnonz);/*lint !e737 */
1317  }
1318  }
1319 
1320  if ( nlpcons > 0 || lpnnonz > 0 )
1321  {
1322  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdplpval, dsdpnlpnonz);/*lint !e644, !e737*/
1323  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdplprow, dsdpnlpnonz);/*lint !e737 */
1324  if ( penaltyparam > sdpisolver->epsilon && (! rbound) )
1325  {
1326  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdplpbegcol, sdpisolver->nactivevars + 3); /*lint !e737, !e776*/
1327  }
1328  else
1329  {
1330  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdplpbegcol, sdpisolver->nactivevars + 2); /*lint !e737, !e776*/
1331  }
1332  }
1333 
1334 #ifdef SCIP_DEBUG
1335  DSDP_CALL( DSDPStopReason(sdpisolver->dsdp, &reason) );
1336 
1337  switch ( reason )
1338  {
1339  case DSDP_CONVERGED:
1340  SCIPdebugMessage("DSDP converged!\n");
1341  break;
1342 
1343  case DSDP_INFEASIBLE_START:
1344  SCIPdebugMessage("DSDP started with an infeasible point!\n");
1345  break;
1346 
1347  case DSDP_SMALL_STEPS:
1348  SCIPdebugMessage("Short step lengths created by numerical difficulties prevented progress in DSDP!\n");
1349  break;
1350 
1351  case DSDP_INDEFINITE_SCHUR_MATRIX:
1352  SCIPdebugMessage("Schur Matrix in DSDP was indefinite but should have been positive semidefinite!\n");
1353  break;
1354 
1355  case DSDP_MAX_IT:
1356  SCIPdebugMessage("DSDP reached maximum number of iterations!\n");
1357  break;
1358 
1359  case DSDP_NUMERICAL_ERROR:
1360  SCIPdebugMessage("A numerical error occured in DSDP!\n");
1361  break;
1362 
1363  case DSDP_UPPERBOUND:
1364  SCIPdebugMessage("Dual objective value in DSDP reached upper bound.\n");
1365  break;
1366 
1367  case DSDP_USER_TERMINATION:
1368  SCIPdebugMessage("DSDP didn't stop solving, did you?\n");
1369  break;
1370 
1371  case CONTINUE_ITERATING:
1372  SCIPdebugMessage("DSDP wants to continue iterating but somehow was stopped!\n");
1373  break;
1374 
1375  default:
1376  SCIPdebugMessage("Unknown stopping reason in DSDP!\n");
1377  break;
1378  }
1379 #endif
1380 
1381  if ( penaltyparam >= sdpisolver->epsilon && sdpisolver->solved )
1382  {
1383  if ( rbound )
1384  {
1385  /* in this case we used the penalty-formulation of DSDP, so we can check their value of r */
1386  SCIP_Real rval;
1387  SCIP_Real trace;
1388 
1389  DSDP_CALL( DSDPGetR(sdpisolver->dsdp, &rval) );
1390 
1391  *feasorig = (rval < sdpisolver->feastol );
1392 
1393  /* if r > 0 or we are in debug mode, also check the primal bound */
1394 #ifdef NDEBUG
1395  if ( ! *feasorig )
1396  {
1397 #endif
1398  if ( penaltybound != NULL )
1399  {
1400  SCIPdebugMessage("Solution not feasible in original problem, r = %f\n", rval);
1401 
1402  /* get the trace of X to compare it with the penalty parameter */
1403  DSDP_CALL( DSDPGetTraceX(sdpisolver->dsdp, &trace) );
1404 
1405 #if 0 /* DSDP doesn't seem to adhere to its own feasiblity tolerance */
1406  assert( trace < penaltyparam + sdpisolver->feastol ); /* solution should be primal feasible */
1407 #endif
1408 
1409  /* if the relative gap is smaller than the tolerance, we return equality */
1410  if ( (penaltyparam - trace) / penaltyparam < PENALTYBOUNDTOL )
1411  {
1412  *penaltybound = TRUE;
1413  SCIPdebugMessage("Tr(X) = %f == %f = Gamma, penalty formulation not exact, Gamma should be increased or problem is infeasible\n",
1414  trace, penaltyparam);
1415  }
1416  else
1417  *penaltybound = FALSE;
1418  }
1419 #ifdef NDEBUG
1420  }
1421 #endif
1422  }
1423  else
1424  {
1425  SCIP_Real* dsdpsol;
1426  SCIP_Real trace;
1427 
1428  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdpsol, sdpisolver->nactivevars + 1) ); /*lint !e776*/
1429  /* last entry of DSDPGetY needs to be the number of variables, will return an error otherwise */
1430  DSDP_CALL( DSDPGetY(sdpisolver->dsdp, dsdpsol, sdpisolver->nactivevars + 1) );
1431 
1432  *feasorig = (dsdpsol[sdpisolver->nactivevars] < sdpisolver->feastol); /* r is the last variable in DSDP, so the last entry gives us the value */
1433 #ifdef NDEBUG
1434  if ( ! *feasorig )
1435  {
1436 #endif
1437  if ( penaltybound != NULL )
1438  {
1439  SCIPdebugMessage("Solution not feasible in original problem, r = %f\n", dsdpsol[sdpisolver->nactivevars]);
1440 
1441  /* get the trace of X to compare it with the penalty parameter */
1442  DSDP_CALL( DSDPGetTraceX(sdpisolver->dsdp, &trace) );
1443 
1444 #if 0 /* DSDP doesn't seem to adhere to its own feasiblity tolerance */
1445  assert( trace < penaltyparam + sdpisolver->feastol ); /* solution should be primal feasible */
1446 #endif
1447 
1448  /* if the relative gap is smaller than the tolerance, we return equality */
1449  if ( (penaltyparam - trace) / penaltyparam < PENALTYBOUNDTOL )
1450  {
1451  *penaltybound = TRUE;
1452  SCIPdebugMessage("Tr(X) = %f == %f = Gamma, penalty formulation not exact, Gamma should be increased or problem is infeasible\n",
1453  trace, penaltyparam);
1454  }
1455  else
1456  *penaltybound = FALSE;
1457  }
1458 #ifdef NDEBUG
1459  }
1460 #endif
1461  }
1462  }
1463 
1464  return SCIP_OKAY;
1465 }/*lint !e715 */
1471 /*
1472  * Solution Information Methods
1473  */
1474 
1479 SCIP_Bool SCIPsdpiSolverWasSolved(
1480  SCIP_SDPISOLVER* sdpisolver
1481  )
1482 {
1483  assert( sdpisolver != NULL );
1484  return sdpisolver->solved;
1485 }
1486 
1494  SCIP_SDPISOLVER* sdpisolver
1495  )
1496 {
1497  DSDPSolutionType pdfeasible;
1498 
1499  assert( sdpisolver != NULL );
1500  CHECK_IF_SOLVED_BOOL( sdpisolver );
1501 
1502  DSDP_CALL_BOOL( DSDPGetSolutionType(sdpisolver->dsdp, &pdfeasible) );
1503 
1504  if ( pdfeasible == DSDP_PDUNKNOWN )
1505  return FALSE;
1506 
1507  return TRUE;
1508 }
1509 
1511 SCIP_RETCODE SCIPsdpiSolverGetSolFeasibility(
1512  SCIP_SDPISOLVER* sdpisolver,
1513  SCIP_Bool* primalfeasible,
1514  SCIP_Bool* dualfeasible
1515  )
1516 {
1517  DSDPSolutionType pdfeasible;
1518 
1519  assert( sdpisolver != NULL );
1520  assert( primalfeasible != NULL );
1521  assert( dualfeasible != NULL );
1522  CHECK_IF_SOLVED( sdpisolver );
1523 
1524  DSDP_CALL( DSDPGetSolutionType(sdpisolver->dsdp, &pdfeasible) );
1525 
1526  switch ( pdfeasible )
1527  {
1528  case DSDP_PDFEASIBLE:
1529  *primalfeasible = TRUE;
1530  *dualfeasible = TRUE;
1531  break;
1532 
1533  case DSDP_UNBOUNDED:
1534  *primalfeasible = FALSE;
1535  *dualfeasible = TRUE;
1536  break;
1537 
1538  case DSDP_INFEASIBLE:
1539  *primalfeasible = TRUE;
1540  *dualfeasible = FALSE;
1541  break;
1542 
1543  default: /* should only include DSDP_PDUNKNOWN */
1544  SCIPerrorMessage("DSDP doesn't know if primal and dual solutions are feasible\n");
1545  return SCIP_LPERROR;
1546  }
1547 
1548  return SCIP_OKAY;
1549 }
1550 
1554  SCIP_SDPISOLVER* sdpisolver
1555  )
1556 {
1557  DSDPSolutionType pdfeasible;
1558 
1559  assert( sdpisolver != NULL );
1560  CHECK_IF_SOLVED_BOOL( sdpisolver );
1561 
1562  DSDP_CALL_BOOL( DSDPGetSolutionType(sdpisolver->dsdp, &pdfeasible) );
1563  if ( pdfeasible == DSDP_PDUNKNOWN )
1564  {
1565 /* SCIPerrorMessage("DSDP doesn't know if primal and dual solutions are feasible");
1566  SCIPABORT();
1567  return SCIP_LPERROR;*/
1568  SCIPdebugMessage("DSDP doesn't know if primal and dual solutions are feasible.");
1569  return FALSE;
1570  }
1571  else if ( pdfeasible == DSDP_INFEASIBLE )
1572  return TRUE;
1573 
1574  return FALSE;
1575 }
1576 
1580  SCIP_SDPISOLVER* sdpisolver
1581  )
1582 {
1583  DSDPSolutionType pdfeasible;
1584 
1585  assert( sdpisolver != NULL );
1586  CHECK_IF_SOLVED_BOOL( sdpisolver );
1587 
1588  DSDP_CALL_BOOL( DSDPGetSolutionType(sdpisolver->dsdp, &pdfeasible) );
1589  if ( pdfeasible == DSDP_PDUNKNOWN )
1590  {
1591 /* SCIPerrorMessage("DSDP doesn't know if primal and dual solutions are feasible");
1592  SCIPABORT();
1593  return SCIP_LPERROR;*/
1594  SCIPdebugMessage("DSDP doesn't know if primal and dual solutions are feasible");
1595  return FALSE;
1596  }
1597  else if ( pdfeasible == DSDP_UNBOUNDED )
1598  return TRUE;
1599 
1600  return FALSE;
1601 }
1602 
1606  SCIP_SDPISOLVER* sdpisolver
1607  )
1608 {
1609  DSDPSolutionType pdfeasible;
1610 
1611  assert( sdpisolver != NULL );
1612  CHECK_IF_SOLVED_BOOL( sdpisolver );
1613 
1614  DSDP_CALL_BOOL( DSDPGetSolutionType(sdpisolver->dsdp, &pdfeasible) );
1615  if ( pdfeasible == DSDP_PDUNKNOWN )
1616  {
1617  SCIPdebugMessage("DSDP doesn't know if primal and dual solutions are feasible");
1618  return FALSE;
1619  }
1620  else if ( pdfeasible == DSDP_UNBOUNDED )
1621  return FALSE;
1622 
1623  return TRUE;
1624 }
1625 
1629  SCIP_SDPISOLVER* sdpisolver
1630  )
1631 {
1632  DSDPSolutionType pdfeasible;
1633 
1634  assert( sdpisolver != NULL );
1635  CHECK_IF_SOLVED_BOOL( sdpisolver );
1636 
1637  DSDP_CALL_BOOL( DSDPGetSolutionType(sdpisolver->dsdp, &pdfeasible) );
1638  if ( pdfeasible == DSDP_PDUNKNOWN )
1639  {
1640  SCIPdebugMessage("DSDP doesn't know if primal and dual solutions are feasible");
1641  return FALSE;
1642  }
1643  else if ( pdfeasible == DSDP_UNBOUNDED )
1644  return TRUE;
1645 
1646  return FALSE;
1647 }
1648 
1652  SCIP_SDPISOLVER* sdpisolver
1653  )
1654 {
1655  DSDPSolutionType pdfeasible;
1656 
1657  assert( sdpisolver != NULL );
1658  CHECK_IF_SOLVED_BOOL( sdpisolver );
1659 
1660  DSDP_CALL_BOOL(DSDPGetSolutionType(sdpisolver->dsdp, &pdfeasible));
1661 
1662  if ( pdfeasible == DSDP_PDUNKNOWN )
1663  {
1664  SCIPdebugMessage("DSDP doesn't know if primal and dual solutions are feasible");
1665  return FALSE;
1666  }
1667  else if ( pdfeasible == DSDP_INFEASIBLE )
1668  return TRUE;
1669 
1670  return FALSE;
1671 }
1672 
1676  SCIP_SDPISOLVER* sdpisolver
1677  )
1678 {
1679  DSDPSolutionType pdfeasible;
1680 
1681  assert( sdpisolver != NULL );
1682  CHECK_IF_SOLVED_BOOL( sdpisolver );
1683 
1684  DSDP_CALL_BOOL( DSDPGetSolutionType(sdpisolver->dsdp, &pdfeasible) );
1685 
1686  if ( pdfeasible == DSDP_PDUNKNOWN )
1687  {
1688  SCIPdebugMessage("DSDP doesn't know if primal and dual solutions are feasible");
1689  return FALSE;
1690  }
1691  else if ( pdfeasible == DSDP_INFEASIBLE )
1692  return FALSE;
1693 
1694  return TRUE;
1695 }
1696 
1698 SCIP_Bool SCIPsdpiSolverIsConverged(
1699  SCIP_SDPISOLVER* sdpisolver
1700  )
1701 {
1702  DSDPTerminationReason reason;
1703 
1704  assert( sdpisolver != NULL );
1705 
1706  if ( sdpisolver->timelimit )
1707  return FALSE;
1708 
1709  CHECK_IF_SOLVED_BOOL( sdpisolver );
1710 
1711  DSDP_CALL_BOOL( DSDPStopReason(sdpisolver->dsdp, &reason) );
1712 
1713  if ( reason == DSDP_CONVERGED )
1714  return TRUE;
1715 
1716  return FALSE;
1717 }
1718 
1720 SCIP_Bool SCIPsdpiSolverIsObjlimExc(
1721  SCIP_SDPISOLVER* sdpisolver
1722  )
1723 {/*lint --e{715}*/
1724  SCIPdebugMessage("Method not implemented for DSDP, as objective limit is given as an ordinary LP-constraint, so in case the objective limit was "
1725  "exceeded, the problem will be reported as infeasible ! \n");
1726 
1727  return FALSE;
1728 }
1729 
1731 SCIP_Bool SCIPsdpiSolverIsIterlimExc(
1732  SCIP_SDPISOLVER* sdpisolver
1733  )
1734 {
1735  DSDPTerminationReason reason;
1736 
1737  assert( sdpisolver != NULL );
1738  CHECK_IF_SOLVED_BOOL( sdpisolver );
1739 
1740  DSDP_CALL_BOOL( DSDPStopReason(sdpisolver->dsdp, &reason) );
1741 
1742  if ( reason == DSDP_MAX_IT )
1743  return TRUE;
1744 
1745  return FALSE;
1746 }
1747 
1749 SCIP_Bool SCIPsdpiSolverIsTimelimExc(
1750  SCIP_SDPISOLVER* sdpisolver
1751  )
1752 {
1753  assert( sdpisolver != NULL );
1754 
1755  return sdpisolver->timelimit;
1756 }
1757 
1769  SCIP_SDPISOLVER* sdpisolver
1770  )
1771 {
1772  DSDPTerminationReason reason;
1773  int dsdpreturn;
1774 
1775  assert( sdpisolver != NULL );
1776 
1777  if ( sdpisolver->dsdp == NULL || (! sdpisolver->solved) )
1778  return -1;
1779 
1780  if ( sdpisolver->timelimit )
1781  return 5;
1782 
1783  dsdpreturn = DSDPStopReason(sdpisolver->dsdp, &reason);
1784 
1785  if (dsdpreturn != 0)
1786  {
1787  SCIPerrorMessage("DSDP-Error <%d> in function call.\n", dsdpreturn);
1788  return 7;
1789  }
1790 
1791  switch ( reason )/*lint --e{788}*/
1792  {
1793  case DSDP_CONVERGED:
1794  return 0;
1795 
1796  case DSDP_INFEASIBLE_START:
1797  return 1;
1798 
1799  case DSDP_SMALL_STEPS:
1800  return 2;
1801 
1802  case DSDP_INDEFINITE_SCHUR_MATRIX:
1803  return 2;
1804 
1805  case DSDP_MAX_IT:
1806  return 4;
1807 
1808  case DSDP_NUMERICAL_ERROR:
1809  return 2;
1810 
1811  case DSDP_UPPERBOUND:
1812  return 3;
1813 
1814  case DSDP_USER_TERMINATION:
1815  return 5;
1816 
1817  default:
1818  return 7;
1819  }
1820 }
1821 
1823 SCIP_Bool SCIPsdpiSolverIsOptimal(
1824  SCIP_SDPISOLVER* sdpisolver
1825  )
1826 {
1827  assert( sdpisolver != NULL );
1828  return (SCIPsdpiSolverIsConverged(sdpisolver) && SCIPsdpiSolverIsPrimalFeasible(sdpisolver) && SCIPsdpiSolverIsDualFeasible(sdpisolver));
1829 }
1830 
1833 SCIP_Bool SCIPsdpiSolverIsAcceptable(
1834  SCIP_SDPISOLVER* sdpisolver
1835  )
1836 {
1837  assert( sdpisolver != NULL );
1838 
1839  return SCIPsdpiSolverIsConverged(sdpisolver);
1840 }
1841 
1843 SCIP_RETCODE SCIPsdpiSolverIgnoreInstability(
1844  SCIP_SDPISOLVER* sdpisolver,
1845  SCIP_Bool* success
1846  )
1847 {/*lint --e{715}*/
1848  SCIPdebugMessage("Not implemented yet\n");
1849  return SCIP_LPERROR;
1850 }
1851 
1853 SCIP_RETCODE SCIPsdpiSolverGetObjval(
1854  SCIP_SDPISOLVER* sdpisolver,
1855  SCIP_Real* objval
1856  )
1857 {
1858  assert( sdpisolver != NULL );
1859  assert( objval != NULL );
1860  CHECK_IF_SOLVED( sdpisolver );
1861 
1862  DSDP_CALL( DSDPGetDObjective(sdpisolver->dsdp, objval) );
1863  *objval = -1*(*objval); /*DSDP maximizes instead of minimizing, so the objective values were multiplied by -1 when inserted */
1864 
1865  /* as we didn't add the fixed (lb = ub) variables to dsdp, we have to add their contributions to the objective by hand */
1866  *objval += sdpisolver->fixedvarsobjcontr;
1867 
1868  return SCIP_OKAY;
1869 }
1870 
1875 SCIP_RETCODE SCIPsdpiSolverGetSol(
1876  SCIP_SDPISOLVER* sdpisolver,
1877  SCIP_Real* objval,
1878  SCIP_Real* dualsol,
1879  int* dualsollength
1881  )
1882 {
1883  SCIP_Real* dsdpsol;
1884  int v;
1885  int dsdpnvars;
1886 
1887  assert( sdpisolver != NULL );
1888  assert( dualsollength != NULL );
1889  CHECK_IF_SOLVED( sdpisolver );
1890 
1891  dsdpnvars = sdpisolver->penaltyworbound ? sdpisolver->nactivevars + 1 : sdpisolver->nactivevars; /* in the first case we added r as an explicit var */
1892 
1893  if ( objval != NULL )
1894  {
1895  DSDP_CALL( DSDPGetDObjective(sdpisolver->dsdp, objval) );
1896  *objval *= -1; /* DSDP maximizes instead of minimizing, so the objective values were multiplied by -1 when inserted */
1897 
1898  /* as we didn't add the fixed (lb = ub) variables to dsdp, we have to add their contributions to the objective by hand */
1899  *objval += sdpisolver->fixedvarsobjcontr;
1900  }
1901 
1902  if ( *dualsollength > 0 )
1903  {
1904  assert( dualsol != NULL );
1905  if ( *dualsollength < sdpisolver->nvars )
1906  {
1907  SCIPdebugMessage("The given array in SCIPsdpiSolverGetSol only had length %d, but %d was needed", *dualsollength, sdpisolver->nvars);
1908  *dualsollength = sdpisolver->nvars;
1909 
1910  return SCIP_OKAY;
1911  }
1912 
1913  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &dsdpsol, dsdpnvars) );
1914  DSDP_CALL( DSDPGetY(sdpisolver->dsdp, dsdpsol, dsdpnvars) ); /* last entry needs to be the number of variables, will return an error otherwise */
1915 
1916  /* insert the entries into dualsol, for non-fixed vars we copy those from dsdp, the rest are the saved entries from inserting (they equal lb=ub) */
1917  for (v = 0; v < sdpisolver->nvars; v++)
1918  {
1919  if (sdpisolver->inputtodsdpmapper[v] > -1)
1920  {
1921  /* minus one because the inputtodsdpmapper gives the dsdp indices which start at one, but the array starts at 0 */
1922  dualsol[v] = dsdpsol[sdpisolver->inputtodsdpmapper[v] - 1];
1923  }
1924  else
1925  {
1926  /* this is the value that was saved when inserting, as this variable has lb=ub */
1927  dualsol[v] = sdpisolver->fixedvarsval[(-1 * sdpisolver->inputtodsdpmapper[v]) - 1]; /*lint !e679*/
1928  }
1929  }
1930  BMSfreeBlockMemoryArray(sdpisolver->blkmem, &dsdpsol, dsdpnvars);/*lint !e737 */
1931  }
1932  return SCIP_OKAY;
1933 }
1934 
1943  SCIP_SDPISOLVER* sdpisolver,
1944  SCIP_Real* lbvars,
1945  SCIP_Real* ubvars,
1946  int* arraylength
1948  )
1949 {
1950  SCIP_Real* lbvarsdsdp;
1951  SCIP_Real* ubvarsdsdp;
1952  int i;
1953 
1954  assert( sdpisolver != NULL );
1955  assert( lbvars != NULL );
1956  assert( ubvars != NULL );
1957  assert( arraylength != NULL );
1958  assert( *arraylength >= 0 );
1959  CHECK_IF_SOLVED( sdpisolver );
1960 
1961  /* check if the arrays are long enough */
1962  if ( *arraylength < sdpisolver->nvars )
1963  {
1964  *arraylength = sdpisolver->nvars;
1965  SCIPdebugMessage("Insufficient length of array in SCIPsdpiSolverGetPrimalBoundVars (gave %d, needed %d)\n", *arraylength, sdpisolver->nvars);
1966  return SCIP_OKAY;
1967  }
1968 
1969  /* allocate memory for the arrays given to DSDP */
1970  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &lbvarsdsdp, sdpisolver->nactivevars) );
1971  BMS_CALL( BMSallocBlockMemoryArray(sdpisolver->blkmem, &ubvarsdsdp, sdpisolver->nactivevars) );
1972 
1973  /* get the values for the active variables from DSDP */
1974  DSDP_CALL( BConeCopyX(sdpisolver->bcone, lbvarsdsdp, ubvarsdsdp, sdpisolver->nactivevars) );
1975 
1976  /* copy them to the right spots of lbvars & ubvars */
1977  for (i = 0; i < sdpisolver->nvars; i++)
1978  {
1979  if ( sdpisolver->inputtodsdpmapper[i] < 0 )
1980  {
1981  /* if the variable was fixed, it didn't exist in the relaxation, so we set the value to 0
1982  * (as DSDP already uses this value for unbounded vars) */
1983  lbvars[i] = 0;
1984  ubvars[i] = 0;
1985  }
1986  else
1987  {
1988  lbvars[i] = lbvarsdsdp[sdpisolver->inputtodsdpmapper[i] - 1];
1989  ubvars[i] = ubvarsdsdp[sdpisolver->inputtodsdpmapper[i] - 1];
1990  }
1991  }
1992 
1993  /* free allocated memory */
1994  BMSfreeBlockMemoryArrayNull(sdpisolver->blkmem, &ubvarsdsdp, sdpisolver->nactivevars);
1995  BMSfreeBlockMemoryArrayNull(sdpisolver->blkmem, &lbvarsdsdp, sdpisolver->nactivevars);
1996 
1997  return SCIP_OKAY;
1998 }
1999 
2001 SCIP_RETCODE SCIPsdpiSolverGetIterations(
2002  SCIP_SDPISOLVER* sdpisolver,
2003  int* iterations
2004  )
2005 {
2006  assert( sdpisolver != NULL );
2007  assert( iterations != NULL );
2008 
2009  if ( sdpisolver->timelimitinitial )
2010  *iterations = 0;
2011  else
2012  DSDP_CALL( DSDPGetIts(sdpisolver->dsdp, iterations) );
2013 
2014  return SCIP_OKAY;
2015 }
2016 
2018 SCIP_RETCODE SCIPsdpiSolverGetSdpCalls(
2019  SCIP_SDPISOLVER* sdpisolver,
2020  int* calls
2021  )
2022 {
2023  assert( sdpisolver != NULL );
2024  assert( calls != NULL );
2025 
2026  if ( sdpisolver->timelimitinitial )
2027  *calls = 0;
2028  else
2029  *calls = 1;
2030 
2031  return SCIP_OKAY;
2032 }
2033 
2035 SCIP_RETCODE SCIPsdpiSolverSettingsUsed(
2036  SCIP_SDPISOLVER* sdpisolver,
2037  SCIP_SDPSOLVERSETTING* usedsetting
2038  )
2039 {
2040  assert( sdpisolver != NULL );
2041  assert( usedsetting != NULL );
2042 
2043  if ( ! SCIPsdpiSolverIsAcceptable(sdpisolver) )
2044  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
2045  else
2046  *usedsetting = sdpisolver->usedsetting;
2047 
2048  return SCIP_OKAY;
2049 }
2050 
2056 /*
2057  * Numerical Methods
2058  */
2059 
2064 SCIP_Real SCIPsdpiSolverInfinity(
2065  SCIP_SDPISOLVER* sdpisolver
2066  )
2067 {
2068  return 1E+20; /* default infinity from SCIP */
2069 }/*lint !e715 */
2070 
2072 SCIP_Bool SCIPsdpiSolverIsInfinity(
2073  SCIP_SDPISOLVER* sdpisolver,
2074  SCIP_Real val
2075  )
2076 {
2077  return ((val <= -SCIPsdpiSolverInfinity(sdpisolver)) || (val >= SCIPsdpiSolverInfinity(sdpisolver)));
2078 }
2079 
2081 SCIP_RETCODE SCIPsdpiSolverGetRealpar(
2082  SCIP_SDPISOLVER* sdpisolver,
2083  SCIP_SDPPARAM type,
2084  SCIP_Real* dval
2085  )
2086 {
2087  assert( sdpisolver != NULL );
2088  assert( dval != NULL );
2089 
2090  switch( type )/*lint --e{788}*/
2091  {
2092  case SCIP_SDPPAR_EPSILON:
2093  *dval = sdpisolver->epsilon;
2094  break;
2095  case SCIP_SDPPAR_FEASTOL:
2096  *dval = sdpisolver->feastol;
2097  break;
2099  *dval = sdpisolver->penaltyparam;
2100  break;
2101  case SCIP_SDPPAR_OBJLIMIT:
2102  *dval = sdpisolver->objlimit;
2103  break;
2104  default:
2105  return SCIP_PARAMETERUNKNOWN;
2106  }
2107 
2108  return SCIP_OKAY;
2109 }
2110 
2112 SCIP_RETCODE SCIPsdpiSolverSetRealpar(
2113  SCIP_SDPISOLVER* sdpisolver,
2114  SCIP_SDPPARAM type,
2115  SCIP_Real dval
2116  )
2117 {
2118  assert( sdpisolver != NULL );
2119 
2120  switch( type )/*lint --e{788}*/
2121  {
2122  case SCIP_SDPPAR_EPSILON:
2123  sdpisolver->epsilon = dval;
2124  SCIPdebugMessage("Setting sdpisolver epsilon to %f.\n", dval);
2125  break;
2126  case SCIP_SDPPAR_FEASTOL:
2127  sdpisolver->feastol = dval;
2128  SCIPdebugMessage("Setting sdpisolver feastol to %f.\n", dval);
2129  break;
2131  sdpisolver->penaltyparam = dval;
2132  SCIPdebugMessage("Setting sdpisolver penaltyparameter to %f.\n", dval);
2133  break;
2134  case SCIP_SDPPAR_OBJLIMIT:
2135  SCIPdebugMessage("Setting sdpisolver objlimit to %f.\n", dval);
2136  sdpisolver->objlimit = dval;
2137  break;
2139  SCIPdebugMessage("Parameter SCIP_SDPPAR_LAMBDASTAR not used by DSDP"); /* this parameter is only used by SDPA */
2140  break;
2141  default:
2142  return SCIP_PARAMETERUNKNOWN;
2143  }
2144 
2145  return SCIP_OKAY;
2146 }
2147 
2149 SCIP_RETCODE SCIPsdpiSolverGetIntpar(
2150  SCIP_SDPISOLVER* sdpisolver,
2151  SCIP_SDPPARAM type,
2152  int* ival
2153  )
2154 {
2155  assert( sdpisolver != NULL );
2156 
2157  switch( type )/*lint --e{788}*/
2158  {
2159  case SCIP_SDPPAR_SDPINFO:
2160  *ival = (int) sdpisolver->sdpinfo;
2161  SCIPdebugMessage("Getting sdpisolver information output (%d).\n", *ival);
2162  break;
2163  default:
2164  return SCIP_PARAMETERUNKNOWN;
2165  }
2166 
2167  return SCIP_OKAY;
2168 }
2169 
2171 SCIP_RETCODE SCIPsdpiSolverSetIntpar(
2172  SCIP_SDPISOLVER* sdpisolver,
2173  SCIP_SDPPARAM type,
2174  int ival
2175  )
2176 {
2177  assert( sdpisolver != NULL );
2178 
2179  switch( type )/*lint --e{788}*/
2180  {
2181  case SCIP_SDPPAR_SDPINFO:
2182  sdpisolver->sdpinfo = (SCIP_Bool) ival;
2183  SCIPdebugMessage("Setting sdpisolver information output (%d).\n", ival);
2184  break;
2185  default:
2186  return SCIP_PARAMETERUNKNOWN;
2187  }
2188 
2189  return SCIP_OKAY;
2190 }
2191 
2193 SCIP_RETCODE SCIPsdpiSolverComputeLambdastar(
2194  SCIP_SDPISOLVER* sdpisolver,
2195  SCIP_Real maxguess
2196  )
2197 {
2198  SCIPdebugMessage("Lambdastar parameter not used by DSDP"); /* this parameter is only used by SDPA */
2199 
2200  return SCIP_OKAY;
2201 }/*lint !e715 */
2202 
2205  SCIP_SDPISOLVER* sdpisolver,
2206  SCIP_Real maxcoeff,
2207  SCIP_Real* penaltyparam
2208  )
2209 {
2210  SCIP_Real compval;
2211 
2212  assert( sdpisolver != NULL );
2213  assert( penaltyparam != NULL );
2214 
2215  compval = PENALTYPARAM_FACTOR * maxcoeff;
2216 
2217  if ( compval < MIN_PENALTYPARAM )
2218  {
2219  SCIPdebugMessage("Setting penaltyparameter to %f.\n", MIN_PENALTYPARAM);
2220  sdpisolver->penaltyparam = MIN_PENALTYPARAM;
2221  *penaltyparam = MIN_PENALTYPARAM;
2222  }
2223  else if ( compval > MAX_PENALTYPARAM )
2224  {
2225  SCIPdebugMessage("Setting penaltyparameter to %f.\n", MAX_PENALTYPARAM);
2226  sdpisolver->penaltyparam = MAX_PENALTYPARAM;
2227  *penaltyparam = MAX_PENALTYPARAM;
2228  }
2229  else
2230  {
2231  SCIPdebugMessage("Setting penaltyparameter to %f.\n", compval);
2232  sdpisolver->penaltyparam = compval;
2233  *penaltyparam = compval;
2234  }
2235  return SCIP_OKAY;
2236 }
2237 
2240  SCIP_SDPISOLVER* sdpisolver,
2241  SCIP_Real penaltyparam,
2242  SCIP_Real* maxpenaltyparam
2243  )
2244 {
2245  SCIP_Real compval;
2246 
2247  assert( sdpisolver != NULL );
2248  assert( maxpenaltyparam != NULL );
2249 
2250  compval = penaltyparam * MAXPENALTYPARAM_FACTOR;
2251 
2252  if ( compval < MAX_MAXPENALTYPARAM )
2253  {
2254  *maxpenaltyparam = compval;
2255  SCIPdebugMessage("Setting maximum penaltyparameter to %f.\n", compval);
2256  }
2257  else
2258  {
2259  *maxpenaltyparam = MAX_MAXPENALTYPARAM;
2260  SCIPdebugMessage("Setting penaltyparameter to %f.\n", MAX_MAXPENALTYPARAM);
2261  }
2262 
2263  /* if the maximum penalty parameter is smaller than the initial penalty paramater, we decrease the initial one correspondingly */
2264  if ( sdpisolver->penaltyparam > *maxpenaltyparam )
2265  {
2266  SCIPdebugMessage("Decreasing penaltyparameter of %f to maximum penalty paramater of %f.\n", sdpisolver->penaltyparam, *maxpenaltyparam);
2267  sdpisolver->penaltyparam = *maxpenaltyparam;
2268  }
2269  return SCIP_OKAY;
2270 }
2271 
2277 /*
2278  * File Interface Methods
2279  */
2280 
2285 SCIP_RETCODE SCIPsdpiSolverReadSDP(
2286  SCIP_SDPISOLVER* sdpisolver,
2287  const char* fname
2288  )
2289 {/*lint --e{715}*/
2290  SCIPdebugMessage("Not implemented yet\n");
2291  return SCIP_LPERROR;
2292 }
2293 
2295 SCIP_RETCODE SCIPsdpiSolverWriteSDP(
2296  SCIP_SDPISOLVER* sdpisolver,
2297  const char* fname
2298  )
2299 {/*lint --e{715}*/
2300  SCIPdebugMessage("Not implemented yet\n");
2301  return SCIP_LPERROR;
2302 }
2303 
SCIP_Bool SCIPsdpiSolverIsConverged(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)
int SCIPsdpiSolverGetInternalStatus(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiSolverIsPrimalFeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiSolverIsPrimalUnbounded(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiSolverIsObjlimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiSolverIsDualFeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
SCIP_Real SCIPsdpiSolverInfinity(SCIP_SDPISOLVER *sdpisolver)
static SCIP_Bool isFixed(SCIP_SDPISOLVER *sdpisolver, SCIP_Real lb, SCIP_Real ub)
const char * SCIPsdpiSolverGetSolverDesc(void)
#define CHECK_IF_SOLVED_BOOL(sdpisolver)
enum SCIP_SDPSolverSetting SCIP_SDPSOLVERSETTING
Definition: type_sdpi.h:74
SCIP_RETCODE SCIPsdpiSolverGetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int *ival)
#define DSDP_CALL_BOOL(x)
SCIP_RETCODE SCIPsdpiSolverSettingsUsed(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPSOLVERSETTING *usedsetting)
interface methods for specific SDP-solvers
#define MIN_PENALTYPARAM
SCIP_RETCODE SCIPsdpiSolverResetCounter(SCIP_SDPISOLVER *sdpisolver)
void * SCIPsdpiSolverGetSolverPointer(SCIP_SDPISOLVER *sdpisolver)
#define TIMEOFDAY_CALL(x)
SCIP_RETCODE SCIPsdpiSolverGetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real *dval)
SCIP_Bool SCIPsdpiSolverIsInfinity(SCIP_SDPISOLVER *sdpisolver, SCIP_Real val)
#define PENALTYPARAM_FACTOR
SCIP_RETCODE SCIPsdpiSolverSetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real dval)
SCIP_Bool SCIPsdpiSolverIsPrimalInfeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetSolFeasibility(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
SCIP_RETCODE SCIPsdpiSolverFree(SCIP_SDPISOLVER **sdpisolver)
#define DSDP_CALLM(x)
#define CHECK_IF_SOLVED(sdpisolver)
static void sortColRow(int *row, int *col, SCIP_Real *val, int length)
SCIP_Bool SCIPsdpiSolverIsDualUnbounded(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiSolverFeasibilityKnown(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetObjval(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval)
#define MAX_PENALTYPARAM
struct Timings Timings
#define BMS_CALL(x)
const char * SCIPsdpiSolverGetSolverName(void)
SCIP_RETCODE SCIPsdpiSolverComputeMaxPenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Real *maxpenaltyparam)
SCIP_RETCODE SCIPsdpiSolverSetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int ival)
SCIP_Bool SCIPsdpiSolverIsIterlimExc(SCIP_SDPISOLVER *sdpisolver)
#define MAXPENALTYPARAM_FACTOR
SCIP_RETCODE SCIPsdpiSolverGetPrimalBoundVars(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
SCIP_RETCODE SCIPsdpiSolverLoadAndSolve(SCIP_SDPISOLVER *sdpisolver, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, int noldlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int *rownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *start, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit)
static int checkTimeLimitDSDP(DSDP dsdp, void *ctx)
SCIP_RETCODE SCIPsdpiSolverIncreaseCounter(SCIP_SDPISOLVER *sdpisolver)
static int compLowerTriangPos(int i, int j)
SCIP_Bool SCIPsdpiSolverIsTimelimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverComputeLambdastar(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxguess)
SCIP_Bool SCIPsdpiSolverWasSolved(SCIP_SDPISOLVER *sdpisolver)
#define MAX_MAXPENALTYPARAM
SCIP_RETCODE SCIPsdpiSolverCreate(SCIP_SDPISOLVER **sdpisolver, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem)
SCIP_RETCODE SCIPsdpiSolverIgnoreInstability(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *success)
struct SCIP_SDPiSolver SCIP_SDPISOLVER
Definition: sdpisolver.h:70
SCIP_Bool SCIPsdpiSolverIsOptimal(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverGetSdpCalls(SCIP_SDPISOLVER *sdpisolver, int *calls)
SCIP_Bool SCIPsdpiSolverIsAcceptable(SCIP_SDPISOLVER *sdpisolver)
#define PENALTYBOUNDTOL
enum SCIP_SDPParam SCIP_SDPPARAM
Definition: type_sdpi.h:63
SCIP_RETCODE SCIPsdpiSolverComputePenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxcoeff, SCIP_Real *penaltyparam)
SCIP_Bool SCIPsdpiSolverIsDualInfeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSolverWriteSDP(SCIP_SDPISOLVER *sdpisolver, const char *fname)
SCIP_RETCODE SCIPsdpiSolverReadSDP(SCIP_SDPISOLVER *sdpisolver, const char *fname)
SCIP_RETCODE SCIPsdpiSolverGetIterations(SCIP_SDPISOLVER *sdpisolver, int *iterations)
#define DSDP_CALL(x)