SCIP-SDP  3.2.0
sdpi.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 programs based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2020 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-2020 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 
40 #include <assert.h>
41 #include <time.h>
42 
43 #include "sdpi/sdpisolver.h"
44 #include "sdpi/sdpi.h"
45 #include "scipsdp/SdpVarfixer.h"
46 #include "sdpi/lapack_interface.h" /* to check feasibility if all variables are fixed during preprocessing */
47 
48 #include "blockmemshell/memory.h" /* for memory allocation */
49 #include "scip/def.h" /* for SCIP_Real, _Bool, ... */
50 #include "scip/pub_misc.h" /* for sorting */
51 #include "scip/pub_message.h" /* for debug and error message */
52 
53 /* turn off lint warnings for whole file: */
54 /*lint --e{788,818}*/
55 
56 
58 #define BMS_CALL(x) do \
59  { \
60  if( NULL == (x) ) \
61  { \
62  SCIPerrorMessage("No memory in function call\n"); \
63  return SCIP_NOMEMORY; \
64  } \
65  } \
66  while( FALSE )
67 
69 #define CHECK_IF_SOLVED(sdpi) do \
70  { \
71  if ( ! (sdpi->solved) ) \
72  { \
73  SCIPerrorMessage("Tried to access solution information ahead of solving! \n"); \
74  return SCIP_LPERROR; \
75  } \
76  } \
77  while( FALSE )
78 
80 #define CHECK_IF_SOLVED_BOOL(sdpi) do \
81  { \
82  if ( ! (sdpi->solved) ) \
83  { \
84  SCIPerrorMessage("Tried to access solution information ahead of solving! \n"); \
85  return FALSE; \
86  } \
87  } \
88  while( FALSE )
89 
91 #define DUPLICATE_ARRAY_NULL(blkmem, target, source, size) do \
92  { \
93  if (size > 0) \
94  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, target, source, size) ); \
95  else \
96  *target = NULL; \
97  } \
98  while( FALSE )
99 
101 #define SCIP_CALL_PARAM(x) do \
102  { \
103  SCIP_RETCODE _restat_; \
104  if ( (_restat_ = (x)) != SCIP_OKAY ) \
105  { \
106  if ( _restat_ != SCIP_PARAMETERUNKNOWN ) \
107  { \
108  SCIPerrorMessage("Error <%d> in function call\n", _restat_); \
109  SCIPABORT(); \
110  } \
111  return _restat_; \
112  } \
113  } \
114  while( FALSE )
115 
117 #define SCIP_CALL_PARAM_IGNORE_UNKNOWN(x) do \
118  { \
119  SCIP_RETCODE _restat_; \
120  if ( (_restat_ = (x)) != SCIP_OKAY ) \
121  { \
122  if ( _restat_ != SCIP_PARAMETERUNKNOWN ) \
123  { \
124  SCIPerrorMessage("Error <%d> in function call\n", _restat_); \
125  SCIPABORT(); \
126  } \
127  } \
128  } \
129  while( FALSE )
130 
131 /* #define PRINTSLATER */
132 #define MIN_GAPTOL 1e-10
134 #define DEFAULT_SDPSOLVERGAPTOL 1e-4
135 #define DEFAULT_FEASTOL 1e-6
136 #define DEFAULT_EPSILON 1e-9
137 #define DEFAULT_PENALTYPARAM 1e+5
138 #define DEFAULT_MAXPENALTYPARAM 1e+10
139 #define DEFAULT_NPENALTYINCR 8
142 struct SCIP_SDPi
143 {
144  SCIP_SDPISOLVER* sdpisolver;
145  SCIP_MESSAGEHDLR* messagehdlr;
146  BMS_BLKMEM* blkmem;
147  BMS_BUFMEM* bufmem;
148  int nvars;
149  SCIP_Real* obj;
150  SCIP_Real* lb;
151  SCIP_Real* ub;
152  int nsdpblocks;
153  int* sdpblocksizes;
154  int* sdpnblockvars;
156  /* constant SDP data: */
157  int sdpconstnnonz;
158  int* sdpconstnblocknonz;
160  int** sdpconstrow;
161  int** sdpconstcol;
162  SCIP_Real** sdpconstval;
164  /* non-constant SDP data: */
165  int sdpnnonz;
166  int** sdpnblockvarnonz;
168  int** sdpvar;
170  int*** sdprow;
172  int*** sdpcol;
173  SCIP_Real*** sdpval;
175  /* lp data: */
176  int nlpcons;
177  SCIP_Real* lplhs;
178  SCIP_Real* lprhs;
179  int lpnnonz;
180  int* lprow;
181  int* lpcol;
182  SCIP_Real* lpval;
184  /* other data */
185  int slatercheck;
186  int sdpid;
187  int niterations;
188  int nsdpcalls;
189  SCIP_Bool solved;
190  SCIP_Bool penalty;
191  SCIP_Bool infeasible;
192  SCIP_Bool allfixed;
193  SCIP_Real epsilon;
194  SCIP_Real gaptol;
195  SCIP_Real feastol;
196  SCIP_Real penaltyparam;
197  SCIP_Real maxpenaltyparam;
198  int npenaltyincr;
199  SCIP_Real peninfeasadjust;
200  SCIP_Real bestbound;
201  SCIP_SDPSLATER primalslater;
202  SCIP_SDPSLATER dualslater;
203 };
204 
205 
206 /*
207  * Local Functions
208  */
209 
214 static
216  int* i,
217  int* j
218  )
219 {
220  if ( *i < *j )
221  {
222  int temp;
223  temp = *i;
224  *i = *j;
225  *j = temp;
226  }
227 }
228 
229 #ifndef NDEBUG
230 
231 static
232 SCIP_Bool isFixed(
233  SCIP_SDPI* sdpi,
234  int v
235  )
236 {
237  SCIP_Real lb;
238  SCIP_Real ub;
239 
240  assert ( sdpi != NULL );
241  assert ( v < sdpi->nvars );
242  assert ( sdpi->lb != NULL );
243  assert ( sdpi->ub != NULL );
244 
245  lb = sdpi->lb[v];
246  ub = sdpi->ub[v];
247 
248  assert( lb < ub + sdpi->feastol || sdpi->infeasible );
249 
250  return ( ub-lb <= sdpi->epsilon );
251 }
252 #else
253 #define isFixed(sdpi, v) (sdpi->ub[v] - sdpi->lb[v] <= sdpi->epsilon)
254 #endif
255 
263 static
265  SCIP_SDPI* sdpi,
266  int* sdpconstnnonz,
267  int* sdpconstnblocknonz,
269  int** sdpconstrow,
270  int** sdpconstcol,
271  SCIP_Real** sdpconstval
272  )
273 {
274  int i;
275  int v;
276  int block;
277  int* nfixednonz;
278  int** fixedrows;
279  int** fixedcols;
280  SCIP_Real** fixedvals;
281 
282  assert ( sdpi != NULL );
283  assert ( sdpconstnnonz != NULL );
284  assert ( sdpconstnblocknonz != NULL );
285  assert ( sdpconstrow != NULL );
286  assert ( sdpconstcol != NULL );
287  assert ( sdpconstval != NULL );
288 #ifndef NDEBUG
289  for (block = 0; block < sdpi->nsdpblocks; block++)
290  {
291  assert ( sdpconstrow[block] != NULL );
292  assert ( sdpconstcol[block] != NULL );
293  assert ( sdpconstval[block] != NULL );
294  }
295 #endif
296 
297  fixedrows = NULL;
298  fixedcols = NULL;
299  fixedvals = NULL;
300 
301  /* allocate memory for the nonzeros that need to be fixed, as this is only temporarly needed, we allocate as much as theoretically possible */
302  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &nfixednonz, sdpi->nsdpblocks) );
303  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &fixedrows, sdpi->nsdpblocks) );
304  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &fixedcols, sdpi->nsdpblocks) );
305  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &fixedvals, sdpi->nsdpblocks) );
306 
307  for (block = 0; block < sdpi->nsdpblocks; block++)
308  {
309  /* compute the number of fixed nonzeros in this block */
310  nfixednonz[block] = 0;
311  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
312  {
313  if (isFixed(sdpi, sdpi->sdpvar[block][v]))
314  nfixednonz[block] += sdpi->sdpnblockvarnonz[block][v];
315  }
316 
317  fixedrows[block] = NULL;
318  fixedcols[block] = NULL;
319  fixedvals[block] = NULL;
320 
321  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(fixedrows[block]), nfixednonz[block]) );
322  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(fixedcols[block]), nfixednonz[block]) );
323  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(fixedvals[block]), nfixednonz[block]) );
324 
325  /* set nfixednonz to 0 to use it for indexing later (at the end of the next for-block it will again have the same value) */
326  nfixednonz[block] = 0;
327  }
328 
329  /* iterate over all variables, saving the nonzeros of the fixed ones */
330  for (block = 0; block < sdpi->nsdpblocks; block++)
331  {
332  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
333  {
334  if (isFixed(sdpi, sdpi->sdpvar[block][v]))
335  {
336  for (i = 0; i < sdpi->sdpnblockvarnonz[block][v]; i++)
337  {
338  fixedrows[block][nfixednonz[block]] = sdpi->sdprow[block][v][i];
339  fixedcols[block][nfixednonz[block]] = sdpi->sdpcol[block][v][i];
340  /* this is the final value to add, so we no longer have to remember, from which variable this nonzero comes,
341  * the -1 comes from +y_iA_i but -A_0 */
342  fixedvals[block][nfixednonz[block]] = - sdpi->sdpval[block][v][i] * sdpi->lb[sdpi->sdpvar[block][v]];
343  nfixednonz[block]++;
344  }
345  }
346  }
347  }
348 
349  /* compute the constant matrix */
350  *sdpconstnnonz = 0;
351  for (block = 0; block < sdpi->nsdpblocks; block++)
352  {
353  SCIP_CALL( SCIPsdpVarfixerMergeArraysIntoNew(sdpi->blkmem, sdpi->epsilon, sdpi->sdpconstrow[block], sdpi->sdpconstcol[block], sdpi->sdpconstval[block],
354  sdpi->sdpconstnblocknonz[block], fixedrows[block], fixedcols[block], fixedvals[block], nfixednonz[block],
355  sdpconstrow[block], sdpconstcol[block], sdpconstval[block], &sdpconstnblocknonz[block]) );
356  *sdpconstnnonz += sdpconstnblocknonz[block];
357  }
358 
359  /* free all memory */
360  for (block = 0; block < sdpi->nsdpblocks; block++)
361  {
362  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(fixedvals[block]), nfixednonz[block]);
363  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(fixedcols[block]), nfixednonz[block]);
364  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(fixedrows[block]), nfixednonz[block]);
365  }
366  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &fixedvals, sdpi->nsdpblocks);
367  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &fixedcols, sdpi->nsdpblocks);
368  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &fixedrows, sdpi->nsdpblocks);
369  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &nfixednonz, sdpi->nsdpblocks);
370 
371  return SCIP_OKAY;
372 }
373 
377 static
378 SCIP_RETCODE findEmptyRowColsSDP(
379  SCIP_SDPI* sdpi,
380  int* sdpconstnblocknonz,
382  int** sdpconstrow,
383  int** sdpconstcol,
384  SCIP_Real** sdpconstval,
385  int** indchanges,
389  int* nremovedinds,
390  int* blockindchanges,
391  int* nremovedblocks
392  )
393 {
394  int block;
395  int v;
396  int i;
397  int nfoundinds;
398 
399  assert( sdpi != NULL );
400  assert( sdpconstnblocknonz != NULL );
401  assert( sdpconstrow != NULL );
402  assert( sdpconstcol != NULL );
403  assert( sdpconstval != NULL );
404  assert( indchanges != NULL );
405  assert( nremovedinds != NULL );
406  assert( blockindchanges != NULL );
407  assert( nremovedblocks != NULL );
408 
409  /* initialize indchanges with -1 */
410  for (block = 0; block < sdpi->nsdpblocks; block++)
411  {
412  for (i = 0; i < sdpi->sdpblocksizes[block]; i++)
413  indchanges[block][i] = -1;
414  }
415  *nremovedblocks = 0;
416 
417  /* iterate over all active nonzeros, setting the values of indchange for their row and col to 1 (this is an intermediate value to save that the
418  * index is still needed, it will later be set to the number of rows/cols deleted earlier) */
419  for (block = 0; block < sdpi->nsdpblocks; block++)
420  {
421  /* the number of indices already found in this block, saved for prematurely stopping the loops */
422  nfoundinds = 0;
423  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
424  {
425  if ( ! (isFixed(sdpi, sdpi->sdpvar[block][v])) )
426  {
427  for (i = 0; i < sdpi->sdpnblockvarnonz[block][v]; i++)
428  {
429  assert ( REALABS(sdpi->sdpval[block][v][i]) > sdpi->epsilon); /* this should really be a nonzero */
430  if ( indchanges[block][sdpi->sdprow[block][v][i]] == -1 )
431  {
432  indchanges[block][sdpi->sdprow[block][v][i]] = 1;
433  nfoundinds++;
434  }
435  if ( indchanges[block][sdpi->sdpcol[block][v][i]] == -1 )
436  {
437  indchanges[block][sdpi->sdpcol[block][v][i]] = 1;
438  nfoundinds++;
439  }
440  if ( nfoundinds == sdpi->sdpblocksizes[block] )
441  break; /* we're done for this block */
442  }
443  }
444  if (nfoundinds == sdpi->sdpblocksizes[block])
445  break; /* we're done for this block */
446  }
447 
448  if ( nfoundinds < sdpi->sdpblocksizes[block] )
449  {
450  /* if some indices haven't been found yet, look in the constant part for them */
451  for (i = 0; i < sdpconstnblocknonz[block]; i++)
452  {
453  assert ( REALABS(sdpconstval[block][i]) > sdpi->epsilon); /* this should really be a nonzero */
454  if ( indchanges[block][sdpconstrow[block][i]] == -1 )
455  {
456  indchanges[block][sdpconstrow[block][i]] = 1;
457  nfoundinds++;
458  }
459  if ( indchanges[block][sdpconstcol[block][i]] == -1 )
460  {
461  indchanges[block][sdpconstcol[block][i]] = 1;
462  nfoundinds++;
463  }
464  if ( nfoundinds == sdpi->sdpblocksizes[block] )
465  break; /* we're done for this block */
466  }
467  }
468 
469  /* now iterate over all indices to compute the final values of indchanges, all 0 are set to -1, all 1 are changed to the number of -1 before it */
470  nremovedinds[block] = 0;
471  for (i = 0; i < sdpi->sdpblocksizes[block]; i++)
472  {
473  if ( indchanges[block][i] == -1 )
474  {
475  SCIPdebugMessage("empty row and col %d were removed from block %d of SDP %d\n", i, block, sdpi->sdpid);
476  /* this index wasn't found (indchanges was initialized with 0), so it can be removed */
477  nremovedinds[block]++;
478  }
479  else
480  {
481  /* this index has been found, so set the value to the number of removed inds before it */
482  indchanges[block][i] = nremovedinds[block];
483  }
484  }
485 
486  /* check if the block became empty */
487  if ( nremovedinds[block] == sdpi->sdpblocksizes[block] )
488  {
489  SCIPdebugMessage("empty block %d detected in SDP %d, this will be removed", block, sdpi->sdpid);
490  blockindchanges[block] = -1;
491  (*nremovedblocks)++;
492  }
493  else
494  blockindchanges[block] = *nremovedblocks;
495  }
496 
497  return SCIP_OKAY;
498 }
499 
504 static
506  SCIP_SDPI* sdpi,
507  int* nactivelpcons,
508  SCIP_Real* lplhsafterfix,
512  SCIP_Real* lprhsafterfix,
516  int* rownactivevars,
517  SCIP_Bool* fixingsfound
518  )
519 {
520  int i;
521  int c;
522  int lastrow = -1;
523  int nonzind = -1;
524  int nonzcol = -1;
525  SCIP_Real nonzval;
526 
527  assert( sdpi != NULL );
528  assert( nactivelpcons != NULL );
529  assert( sdpi->nlpcons == 0 || lplhsafterfix != NULL );
530  assert( sdpi->nlpcons == 0 || lprhsafterfix != NULL );
531  assert( sdpi->nlpcons == 0 || rownactivevars != NULL );
532  assert( sdpi->nlpcons == 0 || fixingsfound != NULL );
533 
534  /* if there is no LP-part, there is nothing to do */
535  if ( sdpi->nlpcons == 0 || sdpi->lpnnonz == 0 )
536  {
537  *nactivelpcons = 0;
538  return SCIP_OKAY;
539  }
540 
541  /* initialize rownactivevars */
542  for (c = 0; c < sdpi->nlpcons; c++)
543  rownactivevars[c] = 0;
544  *nactivelpcons = 0;
545 
546  for (i = 0; i < sdpi->lpnnonz; i++)
547  {
548  assert( i == 0 || sdpi->lprow[i-1] <= sdpi->lprow[i] );
549 
550  /* we reached a new row */
551  if ( sdpi->lprow[i] > lastrow )
552  {
553  /* if the last row had at least two active variables, we keep the lhs- and rhs-value */
554  if ( lastrow >= 0 && rownactivevars[lastrow] > 1 )
555  (*nactivelpcons)++;
556  else if ( lastrow >= 0 && rownactivevars[lastrow] == 1 )
557  {
558  assert( 0 <= nonzind && nonzind < sdpi->lpnnonz );
559 
560  nonzcol = sdpi->lpcol[nonzind];
561  assert( 0 <= nonzcol && nonzcol < sdpi->nvars );
562 
563  nonzval = sdpi->lpval[nonzind];
564  assert( REALABS(nonzval) > sdpi->epsilon );
565 
566  /* we have to check if this is an improvement of the current bound */
567  if ( nonzval < 0.0 ) /* we have to compare with the upper bound for lhs and lower bound for rhs */
568  {
569  /* check for the left-hand-side */
570  if ( (lplhsafterfix[*nactivelpcons] > - SCIPsdpiInfinity(sdpi)) &&
571  ( (lplhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->epsilon) )
572  {
573  /* this bound is sharper than the original one */
574  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
575  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
576  sdpi->ub[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
577 
578  /* check if this leads to a fixing of this variable */
579  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
580  {
581  *fixingsfound = TRUE;
582  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
583  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
584  }
585  /* check if this makes the problem infeasible */
586  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
587  {
588  sdpi->infeasible = TRUE;
589  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
590  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
591  return SCIP_OKAY;
592  }
593  }
594  /* check for the right-hand-side */
595  if ( (lprhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
596  ( (lprhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] + sdpi->epsilon) )
597  {
598  /* this bound is sharper than the original one */
599  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
600  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
601  sdpi->lb[nonzcol] = lprhsafterfix[*nactivelpcons] / nonzval;
602 
603  /* check if this leads to a fixing of this variable */
604  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
605  {
606  *fixingsfound = TRUE;
607  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
608  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
609  }
610 
611  /* check if this makes the problem infeasible */
612  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
613  {
614  sdpi->infeasible = TRUE;
615  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
616  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
617  return SCIP_OKAY;
618  }
619  }
620  }
621  else /* we compare with the lower bound for lhs and upper bound for rhs */
622  {
623  /* check for the left-hand-side */
624  if ( (lplhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
625  ( (lplhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] + sdpi->epsilon) )
626  {
627  /* this bound is sharper than the original one */
628  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
629  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
630  sdpi->lb[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
631 
632  /* check if this leads to a fixing of this variable */
633  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
634  {
635  *fixingsfound = TRUE;
636  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
637  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
638  }
639 
640  /* check if this makes the problem infeasible */
641  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
642  {
643  sdpi->infeasible = TRUE;
644  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
645  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
646  return SCIP_OKAY;
647  }
648  }
649  /* check for the right-hand-side */
650  if ( (lprhsafterfix[*nactivelpcons] > - SCIPsdpiInfinity(sdpi)) &&
651  ( (lprhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->epsilon) )
652  {
653  /* this bound is sharper than the original one */
654  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
655  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
656  sdpi->ub[nonzcol] = lprhsafterfix[*nactivelpcons] / nonzval;
657 
658  /* check if this leads to a fixing of this variable */
659  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
660  {
661  *fixingsfound = TRUE;
662  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
663  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
664  }
665 
666  /* check if this makes the problem infeasible */
667  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
668  {
669  sdpi->infeasible = TRUE;
670  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
671  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
672  return SCIP_OKAY;
673  }
674  }
675  }
676  }
677  else if ( lastrow >= 0 ) /* because of earlier ifs we have rownactivevars = 0 */
678  {
679  assert( lastrow == -1 || rownactivevars[lastrow] == 0 );
680  /* we have a constraint lhs <= 0 <= rhs, so lhs should be non-positive and rhs non-negative, otherwise the problem is infeasible */
681  if ( lplhsafterfix[*nactivelpcons] > sdpi->feastol || lprhsafterfix[*nactivelpcons] < -sdpi->feastol )
682  {
683  sdpi->infeasible = TRUE;
684  SCIPdebugMessage("We found a constraint which with given fixings reads %f <= 0 <= %f, so the current problem is infeasible !\n",
685  lplhsafterfix[*nactivelpcons], lprhsafterfix[*nactivelpcons] );
686  return SCIP_OKAY;
687  }
688  }
689 
690  /* update lastrow for new row */
691  lastrow = sdpi->lprow[i];
692 
693  /* start the next lhr & rhs with the original value */
694  lplhsafterfix[*nactivelpcons] = sdpi->lplhs[lastrow];
695  lprhsafterfix[*nactivelpcons] = sdpi->lprhs[lastrow];
696  }
697 
698  /* if the variable is active, we increase rownactivevars */
699  if ( ! isFixed(sdpi, sdpi->lpcol[i]) )
700  {
701  rownactivevars[lastrow]++;
702  nonzind = i;
703  }
704  else
705  {
706  /* otherwise we add the value (coefficient * value of fixed variable) to the lhs and rhs, the minus comes from +A_i but -A_0 */
707  lplhsafterfix[*nactivelpcons] -= sdpi->lpval[i] * sdpi->lb[sdpi->lpcol[i]];
708  lprhsafterfix[*nactivelpcons] -= sdpi->lpval[i] * sdpi->lb[sdpi->lpcol[i]];
709  }
710  }
711 
712  /* for the last row of the lp we have to check if it is active, as in the above for-queue we only do so when the next row start */
713  if ( rownactivevars[lastrow] > 1 )
714  (*nactivelpcons)++;
715  else if ( rownactivevars[lastrow] == 1 )
716  {
717  assert( 0 <= nonzind && nonzind < sdpi->lpnnonz );
718 
719  nonzcol = sdpi->lpcol[nonzind];
720  assert( 0 <= nonzcol && nonzcol < sdpi->nvars );
721 
722  nonzval = sdpi->lpval[nonzind];
723  assert( REALABS(nonzval) > sdpi->epsilon );
724 
725  /* we have to check if this is an improvement of the current bound */
726  if ( nonzval < 0.0 ) /* we have to compare with the upper bound for lhs and lower bound for rhs */
727  {
728  /* check for the left-hand-side */
729  if ( (lplhsafterfix[*nactivelpcons] > SCIPsdpiInfinity(sdpi)) &&
730  ( (lplhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->epsilon) )
731  {
732  /* this bound is sharper than the original one */
733  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
734  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
735  sdpi->ub[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
736 
737  /* check if this leads to a fixing of this variable */
738  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
739  {
740  *fixingsfound = TRUE;
741  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
742  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
743  }
744 
745  /* check if this makes the problem infeasible */
746  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
747  {
748  sdpi->infeasible = TRUE;
749  SCIPdebugMessage("We found an upper bound that is lower than the lower bound, so the problem is infeasible !\n");
750  return SCIP_OKAY;
751  }
752  }
753  /* check for the right-hand-side */
754  if ( (lprhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
755  ( (lprhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] - sdpi->epsilon) )
756  {
757  /* this bound is sharper than the original one */
758  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
759  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
760  sdpi->lb[nonzcol] = lprhsafterfix[*nactivelpcons] / nonzval;
761 
762  /* check if this leads to a fixing of this variable */
763  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
764  {
765  *fixingsfound = TRUE;
766  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
767  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
768  }
769 
770  /* check if this makes the problem infeasible */
771  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
772  {
773  sdpi->infeasible = TRUE;
774  SCIPdebugMessage("We found an upper bound that is lower than the lower bound, so the problem is infeasible !\n");
775  return SCIP_OKAY;
776  }
777  }
778  }
779  else /* we compare with the lower bound for lhs and upper bound for rhs */
780  {
781  /* check for the left-hand-side */
782  if ( (lplhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
783  ( (lplhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] + sdpi->epsilon) )
784  {
785  /* this bound is sharper than the original one */
786  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
787  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
788  sdpi->lb[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
789 
790  /* check if this leads to a fixing of this variable */
791  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
792  {
793  *fixingsfound = TRUE;
794  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
795  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
796  }
797 
798  /* check if this makes the problem infeasible */
799  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
800  {
801  sdpi->infeasible = TRUE;
802  SCIPdebugMessage("We found a lower bound that is bigger than the upper bound, so the problem is infeasible !\n");
803  return SCIP_OKAY;
804  }
805  }
806  /* check for the right-hand-side */
807  if ( (lprhsafterfix[*nactivelpcons] > SCIPsdpiInfinity(sdpi)) &&
808  ( (lprhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->epsilon) )
809  {
810  /* this bound is sharper than the original one */
811  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
812  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
813  sdpi->ub[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
814 
815  /* check if this leads to a fixing of this variable */
816  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
817  {
818  *fixingsfound = TRUE;
819  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
820  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
821  }
822 
823  /* check if this makes the problem infeasible */
824  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
825  {
826  sdpi->infeasible = TRUE;
827  SCIPdebugMessage("We found an upper bound that is lower than the lower bound, so the problem is infeasible !\n");
828  return SCIP_OKAY;
829  }
830  }
831  }
832  }
833  else
834  {
835  assert( lastrow == -1 || rownactivevars[lastrow] == 0 );
836  /* we have a constraint lhs <= 0 <= rhs, so lhs should be non-positive and rhs non-negative, otherwise the problem is infeasible */
837  if ( lplhsafterfix[*nactivelpcons] > sdpi->feastol || lprhsafterfix[*nactivelpcons] < -sdpi->feastol )
838  {
839  sdpi->infeasible = TRUE;
840  SCIPdebugMessage("We found a constraint which with given fixings reads %f <= 0 <= %f, so the current problem is infeasible !\n",
841  lplhsafterfix[*nactivelpcons], lprhsafterfix[*nactivelpcons] );
842  return SCIP_OKAY;
843  }
844  }
845 
846  return SCIP_OKAY;
847 }
848 
850 static
851 SCIP_RETCODE checkAllFixed(
852  SCIP_SDPI* sdpi
853  )
854 {
855  int v;
856 
857  /* check all variables until we find an unfixed one */
858  for (v = 0; v < sdpi->nvars; v++)
859  {
860  if ( ! isFixed(sdpi, v) )
861  {
862  sdpi->allfixed = FALSE;
863 
864  return SCIP_OKAY;
865  }
866  }
867 
868  /* we did not find an unfixed variable, so all are fixed */
869  SCIPdebugMessage("Detected that all variables in SDP %d are fixed.\n", sdpi->sdpid);
870  sdpi->allfixed = TRUE;
871 
872  return SCIP_OKAY;
873 }
874 
878 static
880  SCIP_SDPI* sdpi,
881  int* sdpconstnblocknonz,
883  int** sdpconstrow,
884  int** sdpconstcol,
885  SCIP_Real** sdpconstval,
886  int** indchanges,
890  int* nremovedinds,
891  int* blockindchanges
892  )
893 {
894  SCIP_Real* fullmatrix; /* we need to give the full matrix to LAPACK */
895  int maxsize; /* as we don't want to allocate memory newly for every SDP-block, we allocate memory according to the size of the largest block */
896  SCIP_Real fixedval;
897  SCIP_Real eigenvalue;
898  int size;
899  int b;
900  int i;
901  int v;
902 
903  assert( sdpi->allfixed );
904 
905  /* compute the maximum blocksize */
906  maxsize = -1;
907 
908  for (b = 0; b < sdpi->nsdpblocks; b++)
909  {
910  if ( sdpi->sdpblocksizes[b] - nremovedinds[b] > maxsize )
911  maxsize = sdpi->sdpblocksizes[b] - nremovedinds[b];
912  }
913 
914  /* allocate memory */
915  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &fullmatrix, maxsize * maxsize) ); /*lint !e647*/
916 
917  /* iterate over all SDP-blocks and check if the smallest eigenvalue is non-negative */
918  for (b = 0; b < sdpi->nsdpblocks; b++)
919  {
920  /* if the block is removed, we don't need to do anything, otherwise build the full matrix */
921  if ( blockindchanges[b] == -1 )
922  continue;
923 
924  size = sdpi->sdpblocksizes[b] - nremovedinds[b];
925 
926  /* initialize the matrix with zero */
927  for (i = 0; i < size * size; i++)
928  fullmatrix[i] = 0.0;
929 
930  /* add the constant part (with negative sign) */
931  for (i = 0; i < sdpconstnblocknonz[b]; i++)
932  {
933  assert( 0 <= sdpconstrow[b][i] - indchanges[b][sdpconstrow[b][i]] && sdpconstrow[b][i] - indchanges[b][sdpconstrow[b][i]] < size );
934  assert( 0 <= sdpconstcol[b][i] - indchanges[b][sdpconstcol[b][i]] && sdpconstcol[b][i] - indchanges[b][sdpconstcol[b][i]] < size );
935  fullmatrix[(sdpconstrow[b][i] - indchanges[b][sdpconstrow[b][i]]) * size
936  + sdpconstcol[b][i] - indchanges[b][sdpconstcol[b][i]]] = -1 * sdpconstval[b][i]; /*lint !e679*/
937  }
938 
939  /* add the contributions of the fixed variables */
940  for (v = 0; v < sdpi->sdpnblockvars[b]; v++)
941  {
942  fixedval = sdpi->lb[sdpi->sdpvar[b][v]];
943 
944  /* if the variable is fixed to zero, we can ignore its contributions */
945  if ( REALABS(fixedval) < sdpi->epsilon )
946  continue;
947 
948  /* iterate over all nonzeros */
949  for (i = 0; i < sdpi->sdpnblockvarnonz[b][v]; i++)
950  {
951  assert( 0 <= sdpi->sdprow[b][v][i] - indchanges[b][sdpi->sdprow[b][v][i]] &&
952  sdpi->sdprow[b][v][i] - indchanges[b][sdpi->sdprow[b][v][i]] < size );
953  assert( 0 <= sdpi->sdpcol[b][v][i] - indchanges[b][sdpi->sdpcol[b][v][i]] &&
954  sdpi->sdpcol[b][v][i] - indchanges[b][sdpi->sdpcol[b][v][i]] < size );
955  fullmatrix[(sdpi->sdprow[b][v][i] - indchanges[b][sdpi->sdprow[b][v][i]]) * size
956  + sdpi->sdpcol[b][v][i] - indchanges[b][sdpi->sdpcol[b][v][i]]] += fixedval * sdpi->sdpval[b][v][i]; /*lint !e679*/
957  }
958  }
959 
960  /* compute the smallest eigenvalue */
961  SCIP_CALL( SCIPlapackComputeIthEigenvalue(sdpi->bufmem, FALSE, size, fullmatrix, 1, &eigenvalue, NULL) );
962 
963  /* check if the eigenvalue is negative */
964  if ( eigenvalue < -1 * sdpi->feastol )
965  {
966  sdpi->infeasible = TRUE;
967  SCIPdebugMessage("Detected infeasibility for SDP %d with all fixed variables!\n", sdpi->sdpid);
968  break;
969  }
970  }
971 
972  /* free memory */
973  BMSfreeBlockMemoryArray(sdpi->blkmem, &fullmatrix, maxsize * maxsize);/*lint !e737*//*lint !e647*/
974 
975  /* if we didn't find an SDP-block with negative eigenvalue, the solution is feasible */
976  sdpi->infeasible = FALSE;
977  SCIPdebugMessage("Unique solution for SDP %d with all fixed variables is feasible!\n", sdpi->sdpid);
978 
979  return SCIP_OKAY;
980 }
981 
985 static
986 SCIP_RETCODE checkSlaterCondition(
987  SCIP_SDPI* sdpi,
988  SCIP_Real timelimit,
989  clock_t starttime,
990  int* sdpconstnblocknonz,
992  int** sdpconstrow,
993  int** sdpconstcol,
994  SCIP_Real** sdpconstval,
995  int** indchanges,
997  int* nremovedinds,
998  SCIP_Real* lplhsafterfix,
999  SCIP_Real* lprhsafterfix,
1000  int* rowsnactivevars,
1001  int* blockindchanges,
1003  int sdpconstnnonz,
1004  int nactivelpcons,
1005  int nremovedblocks,
1006  SCIP_Bool rootnodefailed
1008  )
1009 {
1010  SCIP_Real objval;
1011  SCIP_Bool origfeas = FALSE;
1012  SCIP_Bool penaltybound = FALSE;
1013  int* slaterlprow;
1014  int* slaterlpcol;
1015  SCIP_Real* slaterlpval;
1016  SCIP_Real* slaterlplhs;
1017  SCIP_Real* slaterlprhs;
1018  int* slaterrowsnactivevars;
1019  int nremovedslaterlpinds;
1020  int i;
1021  int v;
1022  int b;
1023  int slaternactivelpcons;
1024  SCIP_Real* slaterlb;
1025  SCIP_Real* slaterub;
1026  int slaternremovedvarbounds;
1027  SCIP_Real solvertimelimit;
1028  clock_t currenttime;
1029 
1030  assert( sdpi != NULL );
1031  assert( sdpconstnnonz == 0 || sdpconstnblocknonz != NULL );
1032  assert( sdpconstnnonz == 0 || sdpconstrow != NULL );
1033  assert( sdpconstnnonz == 0 || sdpconstcol != NULL );
1034  assert( sdpconstnnonz == 0 || sdpconstval != NULL );
1035  assert( sdpi->nsdpblocks == 0 || indchanges != NULL );
1036  assert( sdpi->nsdpblocks == 0 || nremovedinds != NULL );
1037  assert( nactivelpcons == 0 || lplhsafterfix != NULL );
1038  assert( nactivelpcons == 0 || lprhsafterfix != NULL );
1039  assert( sdpi->nlpcons == 0 || rowsnactivevars != NULL );
1040  assert( sdpi->nsdpblocks == 0 || blockindchanges != NULL );
1041 
1042  /* first check the Slater condition for the dual problem */
1043 
1044  /* compute the timit limit to set for the solver */
1045  solvertimelimit = timelimit;
1046  if ( ! SCIPsdpiIsInfinity(sdpi, solvertimelimit) )
1047  {
1048  currenttime = clock();
1049  solvertimelimit -= (SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC;/*lint !e620*/
1050  }
1051 
1052  /* we solve the problem with a slack variable times identity added to the constraints and trying to minimize this slack variable r, if we are
1053  * still feasible for r > feastol, then we have an interior point with smallest eigenvalue > feastol, otherwise the Slater condition is harmed */
1054  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, 1.0, FALSE, FALSE, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
1055  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
1056  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
1057  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
1058  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
1059  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1060  SCIP_SDPSOLVERSETTING_UNSOLVED, solvertimelimit, &origfeas, &penaltybound) );
1061 
1062  if ( ! SCIPsdpiSolverIsOptimal(sdpi->sdpisolver) && ! SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver) && ! SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver) )
1063  {
1064  if ( rootnodefailed )
1065  {
1066  SCIPmessagePrintInfo(sdpi->messagehdlr, "Aborting due to failing to solve the root node relaxation, Slater condition for the dual problem could "
1067  "not be checked, ");
1068  }
1069  else if ( sdpi->slatercheck == 2 )
1070  SCIPmessagePrintInfo(sdpi->messagehdlr, "Unable to check Slater condition for dual problem.\n");
1071  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
1072  }
1073  else
1074  {
1075  if ( SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver) )
1076  {
1077  if ( rootnodefailed )
1078  SCIPmessagePrintInfo(sdpi->messagehdlr, "Aborting due to failing to solve the root node relaxation, Slater condition for the dual problem holds "
1079  "as smallest eigenvalue maximization problem is unbounded, ");
1080  else
1081  {
1082  SCIPdebugMessage("Slater condition for dual problem for SDP %d fullfilled, smallest eigenvalue maximization problem unbounded.\n", sdpi->sdpid);/*lint !e687*/
1083  }
1084  sdpi->dualslater = SCIP_SDPSLATER_HOLDS;
1085  }
1086  else if ( SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver) )
1087  {
1088  if ( rootnodefailed )
1089  {
1090  SCIPmessagePrintInfo(sdpi->messagehdlr, "Aborting due to failing to solve the root node relaxation, Slater condition for the dual problem "
1091  "not fullfilled as problem is infeasible, ");
1092  }
1093  else if ( sdpi->slatercheck == 2 )
1094  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for dual problem for SDP %d not fullfilled, problem infeasible.\n", sdpi->sdpid);
1095  sdpi->dualslater = SCIP_SDPSLATER_NOT;
1096  }
1097  else
1098  {
1099  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) );
1100 
1101  if ( objval < - sdpi->feastol )
1102  {
1103  if ( rootnodefailed )
1104  {
1105  SCIPmessagePrintInfo(sdpi->messagehdlr, "Aborting due to failing to solve the root node relaxation, Slater condition for the dual problem holds"
1106  "with smallest eigenvalue %f, ", -1.0 * objval);
1107  }
1108  else
1109  SCIPdebugMessage("Slater condition for SDP %d is fullfilled for dual problem with smallest eigenvalue %f.\n", sdpi->sdpid, -1.0 * objval);/*lint !e687*/
1110  sdpi->dualslater = SCIP_SDPSLATER_HOLDS;
1111  }
1112  else if ( objval < sdpi->feastol )
1113  {
1114  if ( rootnodefailed )
1115  {
1116  SCIPmessagePrintInfo(sdpi->messagehdlr, "Aborting due to failing to solve the root node relaxation, Slater condition for the dual problem "
1117  "not fullfilled with smallest eigenvalue %f, ", -1.0 * objval);
1118  }
1119  else if ( sdpi->slatercheck == 2 )
1120  {
1121  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for SDP %d not fullfilled for dual problem as smallest eigenvalue was %f, expect numerical trouble.\n",
1122  sdpi->sdpid, -1.0 * objval);
1123  }
1124  sdpi->dualslater = SCIP_SDPSLATER_NOT;
1125  }
1126  else
1127  {
1128  if ( sdpi->slatercheck == 2 )
1129  {
1130  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for SDP %d not fullfilled for dual problem as smallest eigenvalue was %f, problem is infeasible.\n",
1131  sdpi->sdpid, -1.0 * objval);
1132  }
1133  sdpi->dualslater = SCIP_SDPSLATER_INF;
1134  }
1135  }
1136  }
1137 
1138  /* check the Slater condition also for the primal problem */
1139 
1140  /* As we do not want to give equality constraints to the solver by reformulating the primal problem as a dual problem, we instead
1141  * solve the primal dual pair
1142  *
1143  * (P) max (0 0) * Y' s.t. (A_i 0 ) * Y' = c_i forall i, Y' psd
1144  * (0 1) ( 0 sum_j [(A_i)_jj])
1145  *
1146  * (D) min sum_i [c_i x_i] s.t. sum_i [A_i x_i] psd, sum_i[(sum_j [(A_i)_jj]) x_i] >= 1
1147  *
1148  * where we also set all finite lhs/rhs of all lp-constraints and varbounds to zero.
1149  * If the objective is strictly positive, than we now that there exists some r > 0 such that
1150  * Y is psd and Y+rI is feasible for the equality constraints in our original primal problem,
1151  * so Y+rI is also feasible for the original primal problem and is strictly positive definite
1152  * so the primal Slater condition holds
1153  */
1154 
1155  /* allocate the LP-arrays, as we have to add the additional LP-constraint, because we want to add extra entries, we cannot use BMSduplicate... */
1156  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterlprow, sdpi->lpnnonz + sdpi->nvars) );/*lint !e776*/
1157  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterlpcol, sdpi->lpnnonz + sdpi->nvars) );/*lint !e776*/
1158  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterlpval, sdpi->lpnnonz + sdpi->nvars) );/*lint !e776*/
1159 
1160  /* copy all old LP-entries */
1161  for (i = 0; i < sdpi->lpnnonz; i++)
1162  {
1163  slaterlprow[i] = sdpi->lprow[i];
1164  slaterlpcol[i] = sdpi->lpcol[i];
1165  slaterlpval[i] = sdpi->lpval[i];
1166  }
1167 
1168  /* add the new entries sum_j [(A_i)_jj], for this we have to iterate over the whole sdp-matrices (for all blocks), adding all diagonal entries */
1169  for (v = 0; v < sdpi->nvars; v++)
1170  {
1171  slaterlprow[sdpi->lpnnonz + v] = sdpi->nlpcons;/*lint !e679*/
1172  slaterlpcol[sdpi->lpnnonz + v] = v;/*lint !e679*/
1173  slaterlpval[sdpi->lpnnonz + v] = 0.0;/*lint !e679*/
1174  }
1175  for (b = 0; b < sdpi->nsdpblocks; b++)
1176  {
1177  for (v = 0; v < sdpi->sdpnblockvars[b]; v++)
1178  {
1179  for (i = 0; i < sdpi->sdpnblockvarnonz[b][v]; i++)
1180  {
1181  if ( sdpi->sdprow[b][v][i] == sdpi->sdpcol[b][v][i] ) /* it is a diagonal entry */
1182  slaterlpval[sdpi->lpnnonz + sdpi->sdpvar[b][v]] += sdpi->sdpval[b][v][i];/*lint !e679*/
1183  }
1184  }
1185  }
1186 
1187  /* iterate over all added LP-entries and remove all zeros (by shifting further variables) */
1188  nremovedslaterlpinds = 0;
1189  for (v = 0; v < sdpi->nvars; v++)
1190  {
1191  if ( REALABS(slaterlpval[sdpi->lpnnonz + v]) <= sdpi->epsilon )/*lint !e679*/
1192  nremovedslaterlpinds++;
1193  else
1194  {
1195  /* shift the entries */
1196  slaterlprow[sdpi->lpnnonz + v - nremovedslaterlpinds] = slaterlprow[sdpi->lpnnonz + v];/*lint !e679*/
1197  slaterlpcol[sdpi->lpnnonz + v - nremovedslaterlpinds] = slaterlpcol[sdpi->lpnnonz + v];/*lint !e679*/
1198  slaterlpval[sdpi->lpnnonz + v - nremovedslaterlpinds] = slaterlpval[sdpi->lpnnonz + v];/*lint !e679*/
1199  }
1200  }
1201 
1202  /* allocate memory for l/r-hs */
1203  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterlplhs, nactivelpcons + 1) );/*lint !e776*/
1204  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterlprhs, nactivelpcons + 1) );/*lint !e776*/
1205 
1206  /* set the old entries to zero (if existing), as A_0 (including the LP-part) is removed because of the changed primal objective */
1207  for (i = 0; i < nactivelpcons; i++)
1208  {
1209  if ( SCIPsdpiSolverIsInfinity(sdpi->sdpisolver, lplhsafterfix[i]) )
1210  slaterlplhs[i] = lplhsafterfix[i];
1211  else
1212  slaterlplhs[i] = 0.0;
1213 
1214  if ( SCIPsdpiSolverIsInfinity(sdpi->sdpisolver, lprhsafterfix[i]) )
1215  slaterlprhs[i] = lprhsafterfix[i];
1216  else
1217  slaterlprhs[i] = 0.0;
1218  }
1219 
1220  /* add the new ones */
1221  slaterlplhs[nactivelpcons] = 1.0;
1222  slaterlprhs[nactivelpcons] = SCIPsdpiSolverInfinity(sdpi->sdpisolver);
1223 
1224  /* allocate memory for rowsnactivevars to update it for the added row */
1225  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterrowsnactivevars, sdpi->nlpcons + 1) );/*lint !e776*/
1226 
1227  /* copy the old entries */
1228  for (i = 0; i < sdpi->nlpcons; i++)
1229  slaterrowsnactivevars[i] = rowsnactivevars[i];
1230 
1231  /* add the new entry (this equals the number of active variables) */
1232  slaterrowsnactivevars[sdpi->nlpcons] = 0;
1233  for (v = 0; v < sdpi->nvars; v++)
1234  {
1235  if ( ! (isFixed(sdpi, v)) )
1236  slaterrowsnactivevars[sdpi->nlpcons]++;
1237  }
1238 
1239  slaternactivelpcons = (slaterrowsnactivevars[sdpi->nlpcons] > 1) ? nactivelpcons + 1 : nactivelpcons;
1240 
1241  /* copy the varbound arrays to change all finite varbounds to zero */
1242  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &slaterlb, sdpi->lb, sdpi->nvars);
1243  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &slaterub, sdpi->ub, sdpi->nvars);
1244 
1245  /* set all finite varbounds to zero */
1246  slaternremovedvarbounds = 0;
1247  for (v = 0; v < sdpi->nvars; v++)
1248  {
1249  if ( slaterlb[v] > -1 * SCIPsdpiSolverInfinity(sdpi->sdpisolver) )
1250  {
1251  slaterlb[v] = 0.0;
1252  slaternremovedvarbounds++;
1253  }
1254  if ( slaterub[v] < SCIPsdpiSolverInfinity(sdpi->sdpisolver) )
1255  {
1256  slaterub[v] = 0.0;
1257  slaternremovedvarbounds++;
1258  }
1259  }
1260 
1261  /* if all variables have finite upper and lower bounds these add variables to every constraint of the
1262  * primal problem that allow us to make the problem feasible for every primal matrix X, so the primal
1263  * Slater condition holds */
1264  if ( slaternremovedvarbounds == 2 * sdpi->nvars )
1265  {
1266  if ( rootnodefailed )
1267  {
1268  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problem holds since all variables have finite upper and lower bounds \n");
1269  }
1270  else
1271  SCIPdebugMessage("Slater condition for primal problem for SDP %d fullfilled as all variables have finite upper and lower bounds \n", sdpi->sdpid);/*lint !e687*/
1272  sdpi->primalslater = SCIP_SDPSLATER_HOLDS;
1273  }
1274  else
1275  {
1276  /* compute the timit limit to set for the solver */
1277  currenttime = clock();
1278  solvertimelimit = timelimit - ((SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC); /*lint !e620*/
1279 
1280  /* solve the problem to check Slater condition for primal of original problem */
1281  SCIP_CALL( SCIPsdpiSolverLoadAndSolve(sdpi->sdpisolver, sdpi->nvars, sdpi->obj, slaterlb, slaterub,
1282  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, 0, NULL, NULL, NULL, NULL,
1283  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
1284  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, slaternactivelpcons, sdpi->nlpcons + 1, slaterlplhs, slaterlprhs,
1285  slaterrowsnactivevars, sdpi->lpnnonz + sdpi->nvars - nremovedslaterlpinds, slaterlprow, slaterlpcol, slaterlpval, NULL, NULL, NULL, NULL,
1286  NULL, NULL, NULL, NULL, NULL, SCIP_SDPSOLVERSETTING_UNSOLVED, solvertimelimit) );
1287 
1288  if ( ! SCIPsdpiSolverIsOptimal(sdpi->sdpisolver) && ! SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver) && ! SCIPsdpiSolverIsPrimalUnbounded(sdpi->sdpisolver) )
1289  {
1290  if ( rootnodefailed )
1291  {
1292  SCIPmessagePrintInfo(sdpi->messagehdlr, "unable to check Slater condition for primal problem \n");
1293  }
1294  else if ( sdpi->slatercheck == 2 )
1295  SCIPmessagePrintInfo(sdpi->messagehdlr, "Unable to check Slater condition for primal problem, could not solve auxilliary problem.\n");
1296  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
1297  }
1298  else if ( SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver) )
1299  {
1300  if ( rootnodefailed )
1301  {
1302  SCIPmessagePrintInfo(sdpi->messagehdlr, " primal Slater condition shows infeasibility \n");
1303  }
1304  else if ( sdpi->slatercheck == 2 )
1305  {
1306  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problem for SDP %d not fullfilled "
1307  "smallest eigenvalue has to be negative, so primal problem is infeasible (if the dual slater condition holds,"
1308  "this means, that the original (dual) problem is unbounded.\n",sdpi->sdpid);
1309  }
1310  sdpi->primalslater = SCIP_SDPSLATER_NOT;
1311  }
1312  else if ( SCIPsdpiSolverIsPrimalUnbounded(sdpi->sdpisolver) )
1313  {
1314  if ( rootnodefailed )
1315  {
1316  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problems holds sunce smallest eigenvalue maximization problem"
1317  "is unbounded \n");
1318  }
1319  else
1320  SCIPdebugMessage("Slater condition for primal problem for SDP %d fullfilled, smallest eigenvalue maximization problem unbounded \n", sdpi->sdpid);/*lint !e687*/
1321  sdpi->primalslater = SCIP_SDPSLATER_HOLDS;
1322  }
1323  else
1324  {
1325  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) );
1326 
1327  if ( objval > - sdpi->feastol)
1328  {
1329  if ( rootnodefailed )
1330  {
1331  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problem not fullfilled with smallest eigenvalue %f \n", -1.0 * objval);
1332  }
1333  else if ( sdpi->slatercheck == 2 )
1334  {
1335  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problem for SDP %d not fullfilled "
1336  "as smallest eigenvalue was %f, expect numerical trouble or infeasible problem.\n",sdpi->sdpid, -1.0 * objval);
1337  }
1338  sdpi->primalslater = SCIP_SDPSLATER_NOT;
1339  }
1340  else
1341  {
1342  if ( rootnodefailed )
1343  {
1344  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problem fullfilled with smallest eigenvalue %f \n", -1.0 * objval);
1345  }
1346  else
1347  SCIPdebugMessage("Slater condition for primal problem of SDP %d is fullfilled with smallest eigenvalue %f.\n", sdpi->sdpid, -1.0 * objval);/*lint !e687*/
1348  sdpi->primalslater = SCIP_SDPSLATER_HOLDS;
1349  }
1350  }
1351  }
1352 
1353  /* free all memory */
1354  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterub, sdpi->nvars);/*lint !e737*/
1355  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlb, sdpi->nvars);/*lint !e737*/
1356  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterrowsnactivevars, sdpi->nlpcons + 1);/*lint !e737*//*lint !e776*/
1357  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlprhs, nactivelpcons + 1);/*lint !e737*//*lint !e776*/
1358  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlplhs, nactivelpcons + 1);/*lint !e737*//*lint !e776*/
1359  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlpval, sdpi->lpnnonz + sdpi->nvars);/*lint !e737*//*lint !e776*/
1360  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlpcol, sdpi->lpnnonz + sdpi->nvars);/*lint !e737*//*lint !e776*/
1361  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlprow, sdpi->lpnnonz + sdpi->nvars);/*lint !e737*//*lint !e776*/
1362 
1363  return SCIP_OKAY;
1364 }
1365 
1366 /*
1367  * Miscellaneous Methods
1368  */
1369 
1376  void
1377  )
1378 {
1379  return SCIPsdpiSolverGetSolverName();
1380 }
1381 
1384  void
1385  )
1386 {
1387  return SCIPsdpiSolverGetSolverDesc();
1388 }
1389 
1397  SCIP_SDPI* sdpi
1398  )
1399 {
1400  return SCIPsdpiSolverGetSolverPointer(sdpi->sdpisolver);
1401 }
1402 
1405  void
1406  )
1407 {
1409 }
1410 
1413  void
1414  )
1415 {
1417 }
1418 
1421  void
1422  )
1423 {
1425 }
1426 
1429  void
1430  )
1431 {
1433 }
1434 
1438 /*
1439  * SDPI Creation and Destruction Methods
1440  */
1441 
1446 SCIP_RETCODE SCIPsdpiCreate(
1447  SCIP_SDPI** sdpi,
1448  SCIP_MESSAGEHDLR* messagehdlr,
1449  BMS_BLKMEM* blkmem,
1450  BMS_BUFMEM* bufmem
1451  )
1452 {
1453  assert ( sdpi != NULL );
1454  assert ( blkmem != NULL );
1455 
1456  SCIPdebugMessage("Calling SCIPsdpiCreate\n");
1457 
1458  BMS_CALL( BMSallocBlockMemory(blkmem, sdpi) );
1459 
1460  SCIP_CALL( SCIPsdpiSolverCreate(&((*sdpi)->sdpisolver), messagehdlr, blkmem, bufmem) );
1461 
1462  (*sdpi)->messagehdlr = messagehdlr;
1463  (*sdpi)->blkmem = blkmem;
1464  (*sdpi)->bufmem = bufmem;
1465  (*sdpi)->sdpid = 1;
1466  (*sdpi)->niterations = 0;
1467  (*sdpi)->nsdpcalls = 0;
1468  (*sdpi)->nvars = 0;
1469  (*sdpi)->nsdpblocks = 0;
1470  (*sdpi)->sdpconstnnonz = 0;
1471  (*sdpi)->sdpnnonz = 0;
1472  (*sdpi)->nlpcons = 0;
1473  (*sdpi)->lpnnonz = 0;
1474  (*sdpi)->slatercheck = 0;
1475  (*sdpi)->solved = FALSE;
1476  (*sdpi)->penalty = FALSE;
1477  (*sdpi)->infeasible = FALSE;
1478  (*sdpi)->allfixed = FALSE;
1479 
1480  (*sdpi)->obj = NULL;
1481  (*sdpi)->lb = NULL;
1482  (*sdpi)->ub = NULL;
1483  (*sdpi)->sdpblocksizes = NULL;
1484  (*sdpi)->sdpnblockvars = NULL;
1485  (*sdpi)->sdpconstnblocknonz = NULL;
1486  (*sdpi)->sdpconstrow = NULL;
1487  (*sdpi)->sdpconstcol = NULL;
1488  (*sdpi)->sdpconstval = NULL;
1489  (*sdpi)->sdpnblockvarnonz = NULL;
1490  (*sdpi)->sdpvar = NULL;
1491  (*sdpi)->sdprow = NULL;
1492  (*sdpi)->sdpcol = NULL;
1493  (*sdpi)->sdpval = NULL;
1494  (*sdpi)->lplhs = NULL;
1495  (*sdpi)->lprhs = NULL;
1496  (*sdpi)->lprow = NULL;
1497  (*sdpi)->lpcol = NULL;
1498  (*sdpi)->lpval = NULL;
1499 
1500  (*sdpi)->epsilon = DEFAULT_EPSILON;
1501  (*sdpi)->gaptol = DEFAULT_SDPSOLVERGAPTOL;
1502  (*sdpi)->feastol = DEFAULT_FEASTOL;
1503  (*sdpi)->penaltyparam = DEFAULT_PENALTYPARAM;
1504  (*sdpi)->maxpenaltyparam = DEFAULT_MAXPENALTYPARAM;
1505  (*sdpi)->npenaltyincr = DEFAULT_NPENALTYINCR;
1506  (*sdpi)->bestbound = -SCIPsdpiSolverInfinity((*sdpi)->sdpisolver);
1507  (*sdpi)->primalslater = SCIP_SDPSLATER_NOINFO;
1508  (*sdpi)->dualslater = SCIP_SDPSLATER_NOINFO;
1509 
1510  return SCIP_OKAY;
1511 }
1512 
1514 SCIP_RETCODE SCIPsdpiFree(
1515  SCIP_SDPI** sdpi
1516  )
1517 {
1518  int i;
1519  int j;
1520 
1521  SCIPdebugMessage("Calling SCIPsdpiFree \n");
1522  assert ( sdpi != NULL );
1523  assert ( *sdpi != NULL );
1524 
1525  /* free the LP part */
1526  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lpval), (*sdpi)->lpnnonz);
1527  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lpcol), (*sdpi)->lpnnonz);
1528  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lprow), (*sdpi)->lpnnonz);
1529  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lprhs), (*sdpi)->nlpcons);
1530  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lplhs), (*sdpi)->nlpcons);
1531 
1532  /* free the individual nonzeros */
1533  for (i = 0; i < (*sdpi)->nsdpblocks; i++)
1534  {
1535  for (j = 0; j < (*sdpi)->sdpnblockvars[i]; j++)
1536  {
1537  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval[i][j]), (*sdpi)->sdpnblockvarnonz[i][j]);
1538  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow[i][j]), (*sdpi)->sdpnblockvarnonz[i][j]);
1539  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol[i][j]), (*sdpi)->sdpnblockvarnonz[i][j]);
1540  }
1541  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval[i]), (*sdpi)->sdpnblockvars[i]);
1542  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow[i]), (*sdpi)->sdpnblockvars[i]);
1543  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol[i]), (*sdpi)->sdpnblockvars[i]);
1544  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpvar[i]), (*sdpi)->sdpnblockvars[i]);
1545  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvarnonz[i]), (*sdpi)->sdpnblockvars[i]);
1546  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstval[i]), (*sdpi)->sdpconstnblocknonz[i]);
1547  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstrow[i]), (*sdpi)->sdpconstnblocknonz[i]);
1548  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstcol[i]), (*sdpi)->sdpconstnblocknonz[i]);
1549  }
1550 
1551  /* free the rest */
1552  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvarnonz), (*sdpi)->nsdpblocks);
1553  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstnblocknonz), (*sdpi)->nsdpblocks);
1554  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval), (*sdpi)->nsdpblocks);
1555  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol), (*sdpi)->nsdpblocks);
1556  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow), (*sdpi)->nsdpblocks);
1557  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpvar), (*sdpi)->nsdpblocks);
1558  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstval), (*sdpi)->nsdpblocks);
1559  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstcol), (*sdpi)->nsdpblocks);
1560  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstrow), (*sdpi)->nsdpblocks);
1561  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvars), (*sdpi)->nsdpblocks);
1562  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpblocksizes), (*sdpi)->nsdpblocks);
1563  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->ub), (*sdpi)->nvars);/*lint !e737*/
1564  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lb), (*sdpi)->nvars);/*lint !e737*/
1565  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->obj), (*sdpi)->nvars);/*lint !e737*/
1566 
1567  /* free the solver */
1568  SCIP_CALL( SCIPsdpiSolverFree(&((*sdpi)->sdpisolver)) );
1569 
1570  BMSfreeBlockMemory((*sdpi)->blkmem, sdpi);
1571 
1572  return SCIP_OKAY;
1573 }
1574 
1579 SCIP_RETCODE SCIPsdpiClone(
1580  SCIP_SDPI* oldsdpi,
1581  SCIP_SDPI* newsdpi
1582  )
1583 {
1584  BMS_BLKMEM* blkmem;
1585  int nvars;
1586  int nsdpblocks;
1587  int lpnnonz;
1588  int b;
1589  int v;
1590 
1591  assert( oldsdpi != NULL );
1592 
1593  SCIPdebugMessage("Cloning SDPI %d\n", oldsdpi->sdpid);
1594 
1595  /* general data */
1596  blkmem = oldsdpi->blkmem;
1597  nvars = oldsdpi->nvars;
1598  nsdpblocks = oldsdpi->nsdpblocks;
1599  lpnnonz = oldsdpi->lpnnonz;
1600 
1601  BMS_CALL( BMSallocBlockMemory(blkmem, &newsdpi) );
1602 
1603  SCIP_CALL( SCIPsdpiSolverCreate(&(newsdpi->sdpisolver), oldsdpi->messagehdlr, oldsdpi->blkmem, oldsdpi->bufmem) ); /* create new SDP-Solver Interface */
1604 
1605  newsdpi->messagehdlr = oldsdpi->messagehdlr;
1606  newsdpi->blkmem = blkmem;
1607  newsdpi->nvars = nvars;
1608 
1609  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->obj), oldsdpi->obj, nvars) );
1610  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lb), oldsdpi->lb, nvars) );
1611  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->ub), oldsdpi->ub, nvars) );
1612 
1613  newsdpi->nsdpblocks = nsdpblocks;
1614 
1615  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpblocksizes), oldsdpi->sdpblocksizes, nsdpblocks) );
1616  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvars), oldsdpi->sdpnblockvars, nsdpblocks) );
1617 
1618  /* constant SDP data */
1619  newsdpi->sdpconstnnonz = oldsdpi->sdpconstnnonz;
1620 
1621  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstnblocknonz), oldsdpi->sdpconstnblocknonz, nsdpblocks) );
1622  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstrow), nsdpblocks) );
1623  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstcol), nsdpblocks) );
1624  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstval), nsdpblocks) );
1625 
1626  for (b = 0; b < nsdpblocks; b++)
1627  {
1628  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstrow[b]), oldsdpi->sdpconstrow[b], oldsdpi->sdpconstnblocknonz[b]) );
1629  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstcol[b]), oldsdpi->sdpconstcol[b], oldsdpi->sdpconstnblocknonz[b]) );
1630  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstval[b]), oldsdpi->sdpconstval[b], oldsdpi->sdpconstnblocknonz[b]) );
1631  }
1632 
1633  /* SDP data */
1634  newsdpi->sdpnnonz = oldsdpi->sdpnnonz;
1635 
1636  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvarnonz), nsdpblocks) );
1637  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpvar), nsdpblocks) );
1638  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdprow), nsdpblocks) );
1639  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpcol), nsdpblocks) );
1640  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpval), nsdpblocks) );
1641 
1642  for (b = 0; b < nsdpblocks; b++)
1643  {
1644  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvarnonz[b]), oldsdpi->sdpnblockvarnonz[b], oldsdpi->sdpnblockvars[b]) );
1645  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpvar[b]), oldsdpi->sdpvar[b], oldsdpi->sdpnblockvars[b]) );
1646 
1647  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdprow[b]), oldsdpi->sdpnblockvars[b]) );
1648  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpcol[b]), oldsdpi->sdpnblockvars[b]) );
1649  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpval[b]), oldsdpi->sdpnblockvars[b]) );
1650 
1651  for (v = 0; v < oldsdpi->sdpnblockvars[b]; v++)
1652  {
1653  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdprow[b][v]), oldsdpi->sdprow[b][v], oldsdpi->sdpnblockvarnonz[b][v]) );
1654  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpcol[b][v]), oldsdpi->sdpcol[b][v], oldsdpi->sdpnblockvarnonz[b][v]) );
1655  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpval[b][v]), oldsdpi->sdpval[b][v], oldsdpi->sdpnblockvarnonz[b][v]) );
1656  }
1657  }
1658 
1659  /* LP data */
1660  newsdpi->nlpcons = oldsdpi->nlpcons;
1661 
1662  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lplhs), oldsdpi->lplhs, oldsdpi->nlpcons) );
1663  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lprhs), oldsdpi->lprhs, oldsdpi->nlpcons) );
1664 
1665  newsdpi->lpnnonz = lpnnonz;
1666 
1667  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lprow), oldsdpi->lprow, lpnnonz) );
1668  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lpcol), oldsdpi->lpcol, lpnnonz) );
1669  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lpval), oldsdpi->lpval, lpnnonz) );
1670 
1671  /* other data */
1672  newsdpi->solved = FALSE; /* as we don't copy the sdpisolver, this needs to be set to false */
1673  newsdpi->penalty = FALSE; /* all things about SDP-solutions are set to false as well, as we didn't solve the problem */
1674  newsdpi->infeasible = FALSE;
1675  newsdpi->allfixed = FALSE;
1676  newsdpi->sdpid = 1000000 + oldsdpi->sdpid; /* this is only used for debug output, setting it to this value should make it clear, that it is a new sdpi */
1677  newsdpi->epsilon = oldsdpi->epsilon;
1678  newsdpi->gaptol = oldsdpi->gaptol;
1679  newsdpi->feastol = oldsdpi->feastol;
1680 
1681  return SCIP_OKAY;
1682 }
1683 
1687 /*
1688  * Modification Methods
1689  */
1690 
1699 SCIP_RETCODE SCIPsdpiLoadSDP(
1700  SCIP_SDPI* sdpi,
1701  int nvars,
1702  SCIP_Real* obj,
1703  SCIP_Real* lb,
1704  SCIP_Real* ub,
1705  int nsdpblocks,
1706  int* sdpblocksizes,
1707  int* sdpnblockvars,
1708  int sdpconstnnonz,
1709  int* sdpconstnblocknonz,
1711  int** sdpconstrow,
1712  int** sdpconstcol,
1713  SCIP_Real** sdpconstval,
1714  int sdpnnonz,
1715  int** sdpnblockvarnonz,
1717  int** sdpvar,
1719  int*** sdprow,
1722  int*** sdpcol,
1723  SCIP_Real*** sdpval,
1725  int nlpcons,
1726  SCIP_Real* lplhs,
1727  SCIP_Real* lprhs,
1728  int lpnnonz,
1729  int* lprow,
1730  int* lpcol,
1731  SCIP_Real* lpval
1732  )
1733 {
1734  int i;
1735  int v;
1736  int block;
1737 
1738  SCIPdebugMessage("Calling SCIPsdpiLoadSDP (%d)\n",sdpi->sdpid);
1739 
1740  assert ( sdpi != NULL );
1741  assert ( nvars > 0 );
1742  assert ( obj != NULL );
1743  assert ( lb != NULL );
1744  assert ( ub != NULL );
1745 
1746 #ifdef SCIP_DEBUG
1747  if (sdpconstnnonz > 0 || sdpnnonz > 0 || nsdpblocks > 0)
1748  {
1749  assert ( sdpblocksizes != NULL );
1750  assert ( sdpnblockvars != NULL );
1751  assert ( nsdpblocks > 0 );
1752  assert ( sdpconstnblocknonz != NULL );
1753  assert ( sdpnblockvarnonz != NULL );
1754 
1755  if (sdpconstnnonz > 0)
1756  {
1757  assert ( sdpconstrow != NULL );
1758  assert ( sdpconstcol != NULL );
1759  assert ( sdpconstval != NULL );
1760 
1761  for (i = 0; i < nsdpblocks; i++)
1762  {
1763  if (sdpconstnblocknonz[i] > 0)
1764  {
1765  assert ( sdpconstrow[i] != NULL );
1766  assert ( sdpconstcol[i] != NULL );
1767  assert ( sdpconstval[i] != NULL );
1768  }
1769  }
1770  }
1771 
1772  if (sdpnnonz > 0)
1773  {
1774  assert ( sdprow != NULL );
1775  assert ( sdpcol != NULL );
1776  assert ( sdpval != NULL );
1777 
1778  for ( i = 0; i < nsdpblocks; i++ )
1779  {
1780  assert ( sdpcol[i] != NULL );
1781  assert ( sdprow[i] != NULL );
1782  assert ( sdpval[i] != NULL );
1783 
1784  for ( v = 0; v < sdpnblockvars[i]; v++)
1785  {
1786  if (sdpnblockvarnonz[i][v] > 0)
1787  {
1788  assert ( sdpcol[i][v] != NULL );
1789  assert ( sdprow[i][v] != NULL );
1790  assert ( sdpval[i][v] != NULL );
1791  }
1792  }
1793  }
1794  }
1795  }
1796 #endif
1797 
1798  assert ( nlpcons == 0 || lplhs != NULL );
1799  assert ( nlpcons == 0 || lprhs != NULL );
1800  assert ( lpnnonz == 0 || lprow != NULL );
1801  assert ( lpnnonz == 0 || lpcol != NULL );
1802  assert ( lpnnonz == 0 || lpval != NULL );
1803 
1804  /* memory allocation */
1805 
1806  /* first free the old arrays */
1807  for (block = sdpi->nsdpblocks - 1; block >= 0; block--)
1808  {
1809  for (v = sdpi->sdpnblockvars[block] - 1; v >= 0; v--)
1810  {
1811  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpval[block][v]), sdpi->sdpnblockvarnonz[block][v]);
1812  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdprow[block][v]), sdpi->sdpnblockvarnonz[block][v]);
1813  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpcol[block][v]), sdpi->sdpnblockvarnonz[block][v]);
1814  }
1815 
1816  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpval[block]), sdpi->sdpnblockvars[block]);
1817  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdprow[block]), sdpi->sdpnblockvars[block]);
1818  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpcol[block]), sdpi->sdpnblockvars[block]);
1819  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstval[block]), sdpi->sdpconstnblocknonz[block]);
1820  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstrow[block]), sdpi->sdpconstnblocknonz[block]);
1821  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstcol[block]), sdpi->sdpconstnblocknonz[block]);
1822  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpnblockvarnonz[block]), sdpi->sdpnblockvars[block]);
1823  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpvar[block]), sdpi->sdpnblockvars[block]);
1824  }
1825 
1826  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->ub), sdpi->nvars);
1827  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lb), sdpi->nvars);
1828  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->obj), sdpi->nvars);
1829 
1830  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpblocksizes), sdpi->nsdpblocks);
1831  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpnblockvars), sdpi->nsdpblocks);
1832  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstnblocknonz), sdpi->nsdpblocks);
1833 
1834  /* duplicate some arrays */
1835  BMS_CALL( BMSduplicateBlockMemoryArray(sdpi->blkmem, &(sdpi->obj), obj, nvars) );
1836  BMS_CALL( BMSduplicateBlockMemoryArray(sdpi->blkmem, &(sdpi->lb), lb, nvars) );
1837  BMS_CALL( BMSduplicateBlockMemoryArray(sdpi->blkmem, &(sdpi->ub), ub, nvars) );
1838  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpblocksizes), sdpblocksizes, nsdpblocks);
1839  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpnblockvars), sdpnblockvars, nsdpblocks);
1840  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstnblocknonz), sdpconstnblocknonz, nsdpblocks);
1841 
1842  /* allocate memory for the sdp arrays & duplicate them */
1843  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpnblockvarnonz), sdpi->nsdpblocks, nsdpblocks) );
1844  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstcol), sdpi->nsdpblocks, nsdpblocks) );
1845  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstrow), sdpi->nsdpblocks, nsdpblocks) );
1846  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstval), sdpi->nsdpblocks, nsdpblocks) );
1847  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpvar), sdpi->nsdpblocks, nsdpblocks) );
1848  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpcol), sdpi->nsdpblocks, nsdpblocks) );
1849  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdprow), sdpi->nsdpblocks, nsdpblocks) );
1850  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpval), sdpi->nsdpblocks, nsdpblocks) );
1851 
1852  for (block = 0; block < nsdpblocks; block++)
1853  {
1854  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpnblockvarnonz[block]), sdpnblockvarnonz[block], sdpnblockvars[block]);
1855 
1856  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstcol[block]), sdpconstcol[block], sdpconstnblocknonz[block]);
1857  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstrow[block]), sdpconstrow[block], sdpconstnblocknonz[block]);
1858  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstval[block]), sdpconstval[block], sdpconstnblocknonz[block]);
1859 
1860  /* make sure that we have a lower triangular matrix */
1861  for (i = 0; i < sdpi->sdpconstnblocknonz[block]; ++i)
1862  ensureLowerTriangular(&(sdpconstrow[block][i]), &(sdpconstcol[block][i]));
1863 
1864  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpvar[block]), sdpvar[block], sdpnblockvars[block]);
1865 
1866  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpcol[block]), sdpnblockvars[block]) );
1867  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdprow[block]), sdpnblockvars[block]) );
1868  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpval[block]), sdpnblockvars[block]) );
1869 
1870  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
1871  {
1872  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpcol[block][v]), sdpcol[block][v], sdpnblockvarnonz[block][v]);
1873  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdprow[block][v]), sdprow[block][v], sdpnblockvarnonz[block][v]);
1874  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpval[block][v]), sdpval[block][v], sdpnblockvarnonz[block][v]);
1875 
1876  /* make sure that we have a lower triangular matrix */
1877  for (i = 0; i < sdpi->sdpnblockvarnonz[block][v]; ++i)
1878  ensureLowerTriangular(&(sdprow[block][v][i]), &(sdpcol[block][v][i]));
1879  }
1880  }
1881 
1882  /* free old and duplicate new arrays for the LP part */
1883  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz);
1884  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz);
1885  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz);
1886  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons);
1887  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons);
1888 
1889  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lplhs), lplhs, nlpcons);
1890  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lprhs), lprhs, nlpcons);
1891  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lprow), lprow, lpnnonz);
1892  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lpcol), lpcol, lpnnonz);
1893  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lpval), lpval, lpnnonz);
1894 
1895  /* set the general information */
1896  sdpi->nvars = nvars;
1897  sdpi->nsdpblocks = nsdpblocks;
1898 
1899  sdpi->sdpconstnnonz = sdpconstnnonz;
1900  sdpi->sdpnnonz = sdpnnonz;
1901 
1902  /* LP part */
1903  sdpi->lpnnonz = lpnnonz;
1904  sdpi->nlpcons = nlpcons;
1905 
1906  sdpi->solved = FALSE;
1907  sdpi->infeasible = FALSE;
1908  sdpi->allfixed = FALSE;
1909  sdpi->nsdpcalls = 0;
1910  sdpi->niterations = 0;
1911 
1912  return SCIP_OKAY;
1913 }
1914 
1919 SCIP_RETCODE SCIPsdpiAddLPRows(
1920  SCIP_SDPI* sdpi,
1921  int nrows,
1922  const SCIP_Real* lhs,
1923  const SCIP_Real* rhs,
1924  int nnonz,
1925  const int* row,
1927  const int* col,
1928  const SCIP_Real* val
1929  )
1930 {
1931  int i;
1932 
1933  SCIPdebugMessage("Adding %d LP-Constraints to SDP %d.\n", nrows, sdpi->sdpid);
1934 
1935  assert ( sdpi != NULL );
1936 
1937  if ( nrows == 0 )
1938  return SCIP_OKAY; /* nothing to do in this case */
1939 
1940  assert ( lhs != NULL );
1941  assert ( rhs != NULL );
1942  assert ( nnonz >= 0 );
1943  assert ( row != NULL );
1944  assert ( col != NULL );
1945  assert ( val != NULL );
1946 
1947  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons, sdpi->nlpcons + nrows) ); /*lint !e776*/
1948  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons, sdpi->nlpcons + nrows) ); /*lint !e776*/
1949 
1950  for (i = 0; i < nrows; i++)
1951  {
1952  sdpi->lplhs[sdpi->nlpcons + i] = lhs[i]; /*lint !e679*/
1953  sdpi->lprhs[sdpi->nlpcons + i] = rhs[i]; /*lint !e679*/
1954  }
1955 
1956  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz, sdpi->lpnnonz + nnonz) ); /*lint !e776*/
1957  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz, sdpi->lpnnonz + nnonz) ); /*lint !e776*/
1958  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz, sdpi->lpnnonz + nnonz) ); /*lint !e776*/
1959 
1960  for (i = 0; i < nnonz; i++)
1961  {
1962  assert ( 0 <= row[i] && row[i] < nrows );
1963  /* the new rows are added at the end, so the row indices are increased by the old number of LP-constraints */
1964  sdpi->lprow[sdpi->lpnnonz + i] = row[i] + sdpi->nlpcons; /*lint !e679*/
1965 
1966  assert ( 0 <= col[i] && col[i] < sdpi->nvars ); /* only existing vars should be added to the LP-constraints */
1967  sdpi->lpcol[sdpi->lpnnonz + i] = col[i]; /*lint !e679*/
1968 
1969  sdpi->lpval[sdpi->lpnnonz + i] = val[i]; /*lint !e679*/
1970  }
1971 
1972  sdpi->nlpcons = sdpi->nlpcons + nrows;
1973  sdpi->lpnnonz = sdpi->lpnnonz + nnonz;
1974 
1975  sdpi->solved = FALSE;
1976  sdpi->infeasible = FALSE;
1977  sdpi->nsdpcalls = 0;
1978  sdpi->niterations = 0;
1979 
1980  return SCIP_OKAY;
1981 }
1982 
1984 SCIP_RETCODE SCIPsdpiDelLPRows(
1985  SCIP_SDPI* sdpi,
1986  int firstrow,
1987  int lastrow
1988  )
1989 {
1990  int i;
1991  int deletedrows;
1992  int firstrowind;
1993  int lastrowind;
1994  int deletednonz;
1995 
1996  SCIPdebugMessage("Deleting rows %d to %d from SDP %d.\n", firstrow, lastrow, sdpi->sdpid);
1997 
1998  assert ( sdpi != NULL );
1999  assert ( firstrow >= 0 );
2000  assert ( firstrow <= lastrow );
2001  assert ( lastrow < sdpi->nlpcons );
2002 
2003  /* shorten the procedure if the whole LP-part is to be deleted */
2004  if (firstrow == 0 && lastrow == sdpi->nlpcons - 1)
2005  {
2006  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz);/*lint !e737*/
2007  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz);/*lint !e737*/
2008  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz);/*lint !e737*/
2009  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons);/*lint !e737*/
2010  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons);/*lint !e737*/
2011 
2012  sdpi->lplhs = NULL;
2013  sdpi->lprhs = NULL;
2014  sdpi->lpcol = NULL;
2015  sdpi->lprow = NULL;
2016  sdpi->lpval = NULL;
2017 
2018  sdpi->nlpcons = 0;
2019  sdpi->lpnnonz = 0;
2020 
2021  sdpi->solved = FALSE;
2022  sdpi->infeasible = FALSE;
2023  sdpi->allfixed = FALSE;
2024  sdpi->nsdpcalls = 0;
2025  sdpi->niterations = 0;
2026 
2027  return SCIP_OKAY;
2028  }
2029 
2030  deletedrows = lastrow - firstrow + 1; /*lint !e834*/
2031  deletednonz = 0;
2032 
2033  /* first delete the left- and right-hand-sides */
2034  for (i = lastrow + 1; i < sdpi->nlpcons; i++) /* shift all rhs after the deleted rows */
2035  {
2036  sdpi->lplhs[i - deletedrows] = sdpi->lplhs[i]; /*lint !e679*/
2037  sdpi->lprhs[i - deletedrows] = sdpi->lprhs[i]; /*lint !e679*/
2038  }
2039  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons, sdpi->nlpcons - deletedrows) ); /*lint !e776*/
2040  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons, sdpi->nlpcons - deletedrows) ); /*lint !e776*/
2041 
2042  /* for deleting and reordering the lpnonzeroes, the arrays first have to be sorted to have the rows to be deleted together */
2043  SCIPsortIntIntReal(sdpi->lprow, sdpi->lpcol, sdpi->lpval, sdpi->lpnnonz); /* sort all arrays by non-decreasing row indices */
2044 
2045  firstrowind = -1;
2046  /*iterate over the lprowind array to find the first index belonging to a row that should be deleted */
2047  for (i = 0; i < sdpi->lpnnonz; i++)
2048  {
2049  if (sdpi->lprow[i] >= firstrow && sdpi->lprow[i] <= lastrow) /* the and part makes sure that there actually were some nonzeroes in these rows */
2050  {
2051  firstrowind = i;
2052  lastrowind = i;
2053  i++;
2054  break;
2055  }
2056  }
2057 
2058  if (firstrowind > -1) /* if this is still 0 there are no nonzeroes for the given rows */
2059  {
2060  /* now find the last occurence of one of the rows (as these are sorted all in between also belong to deleted rows and will be removed) */
2061  while (i < sdpi->lpnnonz && sdpi->lprow[i] <= lastrow)
2062  {
2063  lastrowind++; /*lint !e644*/
2064  i++;
2065  }
2066  deletednonz = lastrowind - firstrowind + 1; /*lint !e834*/
2067 
2068  /* finally shift all LP-array-entries after the deleted rows */
2069  for (i = lastrowind + 1; i < sdpi->lpnnonz; i++)
2070  {
2071  sdpi->lpcol[i - deletednonz] = sdpi->lpcol[i]; /*lint !e679*/
2072  /* all rowindices after the deleted ones have to be lowered to still have ongoing indices from 0 to nlpcons-1 */
2073  sdpi->lprow[i - deletednonz] = sdpi->lprow[i] - deletedrows; /*lint !e679*/
2074  sdpi->lpval[i - deletednonz] = sdpi->lpval[i]; /*lint !e679*/
2075  }
2076  }
2077 
2078  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz, sdpi->lpnnonz - deletednonz) ); /*lint !e776*/
2079  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz, sdpi->lpnnonz - deletednonz) ); /*lint !e776*/
2080  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz, sdpi->lpnnonz - deletednonz) ); /*lint !e776*/
2081  sdpi->nlpcons = sdpi->nlpcons - deletedrows;
2082  sdpi->lpnnonz = sdpi->lpnnonz - deletednonz;
2083 
2084  sdpi->solved = FALSE;
2085  sdpi->infeasible = FALSE;
2086  sdpi->allfixed = FALSE;
2087  sdpi->nsdpcalls = 0;
2088  sdpi->niterations = 0;
2089 
2090  return SCIP_OKAY;
2091 }
2092 
2094 SCIP_RETCODE SCIPsdpiDelLPRowset(
2095  SCIP_SDPI* sdpi,
2096  int* dstat
2099  )
2100 {
2101  int i;
2102  int oldnlpcons;
2103  int deletedrows;
2104 
2105  SCIPdebugMessage("Calling SCIPsdpiDelLPRowset for SDP %d.\n", sdpi->sdpid);
2106 
2107  assert ( sdpi != NULL );
2108  assert ( dstat != NULL );
2109 
2110  oldnlpcons = sdpi->nlpcons;
2111  deletedrows = 0;
2112 
2113  for (i = 0; i < oldnlpcons; i++)
2114  {
2115  if (dstat[i] == 1)
2116  {
2117  /* delete this row, it is shifted by - deletedrows, because in this problem the earlier rows have already been deleted */
2118  SCIP_CALL( SCIPsdpiDelLPRows(sdpi, i - deletedrows, i - deletedrows) );
2119  dstat[i] = -1;
2120  deletedrows++;
2121  }
2122  else
2123  dstat[i] = i - deletedrows;
2124  }
2125 
2126  sdpi->solved = FALSE;
2127  sdpi->infeasible = FALSE;
2128  sdpi->allfixed = FALSE;
2129  sdpi->nsdpcalls = 0;
2130  sdpi->niterations = 0;
2131 
2132  return SCIP_OKAY;
2133 }
2134 
2136 SCIP_RETCODE SCIPsdpiClear(
2137  SCIP_SDPI* sdpi
2138  )
2139 {
2140  assert( sdpi != NULL );
2141 
2142  SCIPdebugMessage("Called SCIPsdpiClear in SDP %d.\n", sdpi->sdpid);
2143 
2144  /* we reset all counters */
2145  sdpi->sdpid = 1;
2146  SCIP_CALL( SCIPsdpiSolverResetCounter(sdpi->sdpisolver) );
2147 
2148  return SCIP_OKAY;
2149 }
2150 
2152 SCIP_RETCODE SCIPsdpiChgObj(
2153  SCIP_SDPI* sdpi,
2154  int nvars,
2155  const int* ind,
2156  const SCIP_Real* obj
2157  )
2158 {
2159  int i;
2160 
2161  SCIPdebugMessage("Changing %d objective coefficients in SDP %d\n", nvars, sdpi->sdpid);
2162 
2163  assert( sdpi != NULL );
2164  assert( ind != NULL );
2165  assert( obj != NULL );
2166 
2167  for (i = 0; i < nvars; i++)
2168  {
2169  assert( 0 <= ind[i] && ind[i] < sdpi->nvars );
2170  sdpi->obj[ind[i]] = obj[i];
2171  }
2172 
2173  sdpi->solved = FALSE;
2174  sdpi->nsdpcalls = 0;
2175  sdpi->niterations = 0;
2176 
2177  return SCIP_OKAY;
2178 }
2179 
2181 SCIP_RETCODE SCIPsdpiChgBounds(
2182  SCIP_SDPI* sdpi,
2183  int nvars,
2184  const int* ind,
2185  const SCIP_Real* lb,
2186  const SCIP_Real* ub
2187  )
2188 {
2189  int i;
2190 
2191  SCIPdebugMessage("Changing %d variable bounds in SDP %d\n", nvars, sdpi->sdpid);
2192 
2193  assert( sdpi != NULL );
2194  assert( ind != NULL );
2195  assert( lb != NULL );
2196  assert( ub != NULL );
2197 
2198  for (i = 0; i < nvars; i++)
2199  {
2200  assert( 0 <= ind[i] && ind[i] < sdpi->nvars );
2201  sdpi->lb[ind[i]] = lb[i];
2202  sdpi->ub[ind[i]] = ub[i];
2203  }
2204 
2205  sdpi->solved = FALSE;
2206  sdpi->infeasible = FALSE;
2207  sdpi->allfixed = FALSE;
2208  sdpi->nsdpcalls = 0;
2209  sdpi->niterations = 0;
2210 
2211  return SCIP_OKAY;
2212 }
2213 
2216  SCIP_SDPI* sdpi,
2217  int nrows,
2218  const int* ind,
2219  const SCIP_Real* lhs,
2220  const SCIP_Real* rhs
2221  )
2222 {
2223  int i;
2224 
2225  SCIPdebugMessage("Changing %d left and right hand sides of SDP %d\n", nrows, sdpi->sdpid);
2226 
2227  assert( sdpi != NULL );
2228  assert( 0 <= nrows && nrows <= sdpi->nlpcons );
2229  assert( ind != NULL );
2230  assert( lhs != NULL );
2231  assert( rhs != NULL );
2232 
2233  for (i = 0; i < nrows; i++)
2234  {
2235  assert ( ind[i] >= 0 );
2236  assert ( ind[i] < sdpi->nlpcons );
2237  sdpi->lplhs[ind[i]] = lhs[i];
2238  sdpi->lprhs[ind[i]] = rhs[i];
2239  }
2240 
2241  sdpi->solved = FALSE;
2242  sdpi->infeasible = FALSE;
2243  sdpi->allfixed = FALSE;
2244  sdpi->nsdpcalls = 0;
2245  sdpi->niterations = 0;
2246 
2247  return SCIP_OKAY;
2248 }
2249 
2250 
2251 /*
2252  * Data Accessing Methods
2253  */
2254 
2259 SCIP_RETCODE SCIPsdpiGetNLPRows(
2260  SCIP_SDPI* sdpi,
2261  int* nlprows
2262  )
2263 {
2264  assert( sdpi != NULL );
2265  assert( nlprows != NULL );
2266 
2267  *nlprows = sdpi->nlpcons;
2268 
2269  return SCIP_OKAY;
2270 }
2271 
2274  SCIP_SDPI* sdpi,
2275  int* nsdpblocks
2276  )
2277 {
2278  assert( sdpi != NULL );
2279  assert( nsdpblocks != NULL );
2280 
2281  *nsdpblocks = sdpi->nsdpblocks;
2282 
2283  return SCIP_OKAY;
2284 }
2285 
2287 SCIP_RETCODE SCIPsdpiGetNVars(
2288  SCIP_SDPI* sdpi,
2289  int* nvars
2290  )
2291 {
2292  assert( sdpi != NULL );
2293  assert( nvars != NULL );
2294 
2295  *nvars = sdpi->nvars;
2296 
2297  return SCIP_OKAY;
2298 }
2299 
2301 SCIP_RETCODE SCIPsdpiGetSDPNNonz(
2302  SCIP_SDPI* sdpi,
2303  int* nnonz
2304  )
2305 {
2306  assert( sdpi != NULL );
2307  assert( nnonz != NULL );
2308 
2309  *nnonz = sdpi->sdpnnonz;
2310 
2311  return SCIP_OKAY;
2312 }
2313 
2316  SCIP_SDPI* sdpi,
2317  int* nnonz
2318  )
2319 {
2320  assert( sdpi != NULL );
2321  assert( nnonz != NULL );
2322 
2323  *nnonz = sdpi->sdpconstnnonz;
2324 
2325  return SCIP_OKAY;
2326 }
2327 
2329 SCIP_RETCODE SCIPsdpiGetLPNNonz(
2330  SCIP_SDPI* sdpi,
2331  int* nnonz
2332  )
2333 {
2334  assert( sdpi != NULL );
2335  assert( nnonz != NULL );
2336 
2337  *nnonz = sdpi->lpnnonz;
2338 
2339  return SCIP_OKAY;
2340 }
2341 
2343 SCIP_RETCODE SCIPsdpiGetObj(
2344  SCIP_SDPI* sdpi,
2345  int firstvar,
2346  int lastvar,
2347  SCIP_Real* vals
2348  )
2349 {
2350  int i;
2351 
2352  assert( sdpi != NULL );
2353  assert( firstvar >= 0 );
2354  assert( firstvar <= lastvar );
2355  assert( lastvar < sdpi->nvars);
2356  assert( vals != NULL );
2357 
2358  for (i = 0; i < lastvar - firstvar + 1; i++) /*lint !e834*/
2359  vals[i] = sdpi->obj[firstvar + i]; /*lint !e679*/
2360 
2361  return SCIP_OKAY;
2362 }
2363 
2365 SCIP_RETCODE SCIPsdpiGetBounds(
2366  SCIP_SDPI* sdpi,
2367  int firstvar,
2368  int lastvar,
2369  SCIP_Real* lbs,
2370  SCIP_Real* ubs
2371  )
2372 {
2373  int i;
2374 
2375  assert( sdpi != NULL );
2376  assert( firstvar >= 0 );
2377  assert( firstvar <= lastvar );
2378  assert( lastvar < sdpi->nvars);
2379  assert( lbs != NULL );
2380  assert( ubs != NULL );
2381 
2382  for (i = 0; i < lastvar - firstvar + 1; i++) /*lint !e834*/
2383  {
2384  if (lbs != NULL)
2385  lbs[i] = sdpi->lb[firstvar + i]; /*lint !e679*/
2386  if (ubs != NULL)
2387  ubs[i] = sdpi->ub[firstvar + i]; /*lint !e679*/
2388  }
2389  return SCIP_OKAY;
2390 }
2391 
2393 SCIP_RETCODE SCIPsdpiGetLhSides(
2394  SCIP_SDPI* sdpi,
2395  int firstrow,
2396  int lastrow,
2397  SCIP_Real* lhss
2398  )
2399 {
2400  int i;
2401 
2402  assert( sdpi != NULL );
2403  assert( firstrow >= 0 );
2404  assert( firstrow <= lastrow );
2405  assert( lastrow < sdpi->nlpcons);
2406  assert( lhss != NULL );
2407 
2408  for (i = 0; i < lastrow - firstrow + 1; i++) /*lint !e834*/
2409  lhss[firstrow + i] = sdpi->lplhs[i]; /*lint !e679*/
2410 
2411  return SCIP_OKAY;
2412 }
2413 
2415 SCIP_RETCODE SCIPsdpiGetRhSides(
2416  SCIP_SDPI* sdpi,
2417  int firstrow,
2418  int lastrow,
2419  SCIP_Real* rhss
2420  )
2421 {
2422  int i;
2423 
2424  assert( sdpi != NULL );
2425  assert( firstrow >= 0 );
2426  assert( firstrow <= lastrow );
2427  assert( lastrow < sdpi->nlpcons);
2428  assert( rhss != NULL );
2429 
2430  for (i = 0; i < lastrow - firstrow + 1; i++) /*lint !e834*/
2431  rhss[firstrow + i] = sdpi->lprhs[i]; /*lint !e679*/
2432 
2433  return SCIP_OKAY;
2434 }
2435 
2436 
2441 /*
2442  * Solving Methods
2443  */
2444 
2454 SCIP_RETCODE SCIPsdpiSolve(
2455  SCIP_SDPI* sdpi,
2456  SCIP_Real* starty,
2457  int* startZnblocknonz,
2459  int** startZrow,
2461  int** startZcol,
2463  SCIP_Real** startZval,
2465  int* startXnblocknonz,
2467  int** startXrow,
2469  int** startXcol,
2471  SCIP_Real** startXval,
2473  SCIP_SDPSOLVERSETTING startsettings,
2475  SCIP_Bool enforceslatercheck,
2477  SCIP_Real timelimit
2478  )
2479 {
2480  int* sdpconstnblocknonz = NULL;
2481  int** sdpconstrow = NULL;
2482  int** sdpconstcol = NULL;
2483  SCIP_Real** sdpconstval = NULL;
2484  int** indchanges = NULL;
2485  int* nremovedinds = NULL;
2486  SCIP_Real* lplhsafterfix;
2487  SCIP_Real* lprhsafterfix;
2488  SCIP_Real solvertimelimit;
2489  SCIP_Bool fixingfound;
2490  clock_t starttime;
2491  clock_t currenttime;
2492  int* rowsnactivevars;
2493  int* blockindchanges;
2494  int sdpconstnnonz;
2495  int nactivelpcons;
2496  int nremovedblocks = 0;
2497  int block;
2498  int naddediterations;
2499  int naddedsdpcalls;
2500 
2501  assert( sdpi != NULL );
2502 
2503  starttime = clock();
2504 
2505  SCIPdebugMessage("Forwarding SDP %d to solver!\n", sdpi->sdpid);
2506 
2507  sdpi->penalty = FALSE;
2508  sdpi->bestbound = -SCIPsdpiSolverInfinity(sdpi->sdpisolver);
2509  sdpi->solved = FALSE;
2510  sdpi->nsdpcalls = 0;
2511  sdpi->niterations = 0;
2512 
2513  /* allocate memory for computing the constant matrix after fixings and finding empty rows and columns, this is as much as might possibly be
2514  * needed, this will be shrinked again before solving */
2515  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstnblocknonz, sdpi->nsdpblocks) );
2516  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstrow, sdpi->nsdpblocks) );
2517  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstcol, sdpi->nsdpblocks) );
2518  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstval, sdpi->nsdpblocks) );
2519  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &indchanges, sdpi->nsdpblocks) );
2520  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &nremovedinds, sdpi->nsdpblocks) );
2521  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &blockindchanges, sdpi->nsdpblocks) );
2522  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &lplhsafterfix, sdpi->nlpcons) );
2523  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &lprhsafterfix, sdpi->nlpcons) );
2524  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &rowsnactivevars, sdpi->nlpcons) );
2525 
2526  for (block = 0; block < sdpi->nsdpblocks; block++)
2527  {
2528  sdpconstrow[block] = NULL;
2529  sdpconstcol[block] = NULL;
2530  sdpconstval[block] = NULL;
2531  indchanges[block] = NULL;
2532  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(indchanges[block]), sdpi->sdpblocksizes[block]) );
2533  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
2534  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
2535  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
2536  }
2537 
2538  /* compute the lplphss and lprhss, detect empty rows and check for additional variable fixings caused by boundchanges from
2539  * lp rows with a single active variable */
2540  do
2541  {
2542  fixingfound = FALSE;
2543  SCIP_CALL( computeLpLhsRhsAfterFixings(sdpi, &nactivelpcons, lplhsafterfix, lprhsafterfix, rowsnactivevars, &fixingfound) );
2544  }
2545  while ( fixingfound );
2546 
2547  /* initialize sdpconstnblocknonz */
2548  for (block = 0; block < sdpi->nsdpblocks; block++)
2549  sdpconstnblocknonz[block] = sdpi->sdpnnonz + sdpi->sdpconstnnonz;
2550 
2551  SCIP_CALL( compConstMatAfterFixings(sdpi, &sdpconstnnonz, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval) );
2552 
2553  /* shrink the constant arrays after the number of fixed nonzeros is known */
2554  for (block = 0; block < sdpi->nsdpblocks; block++)
2555  {
2556  assert ( sdpconstnblocknonz[block] <= sdpi->sdpnnonz + sdpi->sdpconstnnonz ); /* otherwise the memory wasn't sufficient,
2557  * but we allocated more than enough */
2558  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
2559  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
2560  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
2561  }
2562 
2563  SCIP_CALL( findEmptyRowColsSDP(sdpi, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges, nremovedinds, blockindchanges, &nremovedblocks) );
2564 
2565  /* check if all variables are fixed, if this is the case, check if the remaining solution if feasible (we only need to check the SDP-constraint,
2566  * the linear constraints were already checked in computeLpLhsRhsAfterFixings) */
2567  SCIP_CALL( checkAllFixed(sdpi) );
2568  if ( sdpi->allfixed && ! sdpi->infeasible )
2569  {
2570  SCIP_CALL( checkFixedFeasibilitySdp(sdpi, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges, nremovedinds, blockindchanges) );
2571  }
2572 
2573  if ( sdpi->infeasible )
2574  {
2575  SCIPdebugMessage("SDP %d not given to solver, as infeasibility was detected during presolving!\n", sdpi->sdpid++);
2576  SCIP_CALL( SCIPsdpiSolverIncreaseCounter(sdpi->sdpisolver) );
2577 
2578  sdpi->solved = TRUE;
2579  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2580  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2581  }
2582  else if ( sdpi->allfixed )
2583  {
2584  SCIPdebugMessage("SDP %d not given to solver, as all variables were fixed during presolving (the solution was feasible)!\n", sdpi->sdpid++);
2585  SCIP_CALL( SCIPsdpiSolverIncreaseCounter(sdpi->sdpisolver) );
2586 
2587  sdpi->solved = TRUE;
2588  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2589  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2590  }
2591  else
2592  {
2593  if ( sdpi->slatercheck )
2594  {
2595  SCIP_CALL( checkSlaterCondition(sdpi, timelimit, starttime, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges,
2596  nremovedinds, lplhsafterfix, lprhsafterfix, rowsnactivevars, blockindchanges, sdpconstnnonz, nactivelpcons, nremovedblocks, FALSE) );
2597  }
2598 
2599  /* compute the timit limit to set for the solver */
2600  solvertimelimit = timelimit;
2601  if ( ! SCIPsdpiIsInfinity(sdpi, solvertimelimit) )
2602  {
2603  currenttime = clock();
2604  solvertimelimit -= (SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC;/*lint !e620*/
2605  }
2606 
2607  /* try to solve the problem */
2608  SCIP_CALL( SCIPsdpiSolverLoadAndSolve(sdpi->sdpisolver, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
2609  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2610  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2611  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2612  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
2613  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2614  startXnblocknonz, startXrow, startXcol, startXval, startsettings, solvertimelimit) );
2615 
2616  sdpi->solved = TRUE;
2617 
2618  /* add iterations and sdpcalls */
2619  naddediterations = 0;
2620  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2621  sdpi->niterations += naddediterations;
2622  naddedsdpcalls = 0;
2623  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2624  sdpi->nsdpcalls += naddedsdpcalls;
2625 
2626  /* if the solver didn't produce a satisfactory result, we have to try with a penalty formulation */
2627  if ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && ! SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver) )
2628  {
2629  SCIP_Real penaltyparam;
2630  SCIP_Real penaltyparamfact;
2631  SCIP_Real gaptol;
2632  SCIP_Real gaptolfact;
2633  SCIP_Bool feasorig;
2634  SCIP_Bool penaltybound;
2635  SCIP_Real objbound;
2636  SCIP_Real objval;
2637 
2638  feasorig = FALSE;
2639  penaltybound = TRUE;
2640 
2641  /* first check feasibility using the penalty approach */
2642 
2643  /* compute the timit limit to set for the solver */
2644  solvertimelimit = timelimit;
2645  if ( ! SCIPsdpiIsInfinity(sdpi, solvertimelimit) )
2646  {
2647  currenttime = clock();
2648  solvertimelimit -= (SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC;/*lint !e620*/
2649  }
2650 
2651  SCIPdebugMessage("SDP %d returned inacceptable result, trying penalty formulation.\n", sdpi->sdpid);
2652 
2653  /* we solve the problem with a slack variable times identity added to the constraints and trying to minimize this slack variable r, if
2654  * the optimal objective is bigger than feastol, then we know that the problem is infeasible */
2655  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, 1.0, FALSE, FALSE, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
2656  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2657  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2658  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2659  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
2660  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2661  startXnblocknonz, startXrow, startXcol, startXval, SCIP_SDPSOLVERSETTING_UNSOLVED, solvertimelimit, &feasorig, &penaltybound) );
2662 
2663  /* add iterations and sdpcalls */
2664  naddediterations = 0;
2665  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2666  sdpi->niterations += naddediterations;
2667  naddedsdpcalls = 0;
2668  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2669  sdpi->nsdpcalls += naddedsdpcalls;
2670 
2671  /* get objective value */
2672  if ( SCIPsdpiSolverWasSolved(sdpi->sdpisolver) )
2673  {
2674  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) );
2675  }
2676  else
2677  objval = -SCIPsdpiInfinity(sdpi);
2678 
2679  /* If the penalty formulation was successfully solved and has a strictly positive objective value, we know that
2680  * the problem is infeasible. Note that we need to check against the maximum of feastol and gaptol, since this
2681  * is the objective of an SDP which is only exact up to gaptol, and cutting a feasible node off is an error
2682  * while continueing with an infeasible problem only takes additional time until we found out again later.
2683  */
2684  if ( (SCIPsdpiSolverIsOptimal(sdpi->sdpisolver) && (objval > (sdpi->feastol > sdpi->gaptol ?
2685  sdpi->peninfeasadjust * sdpi->feastol : sdpi->peninfeasadjust * sdpi->gaptol))) ||
2686  (SCIPsdpiSolverWasSolved(sdpi->sdpisolver) && SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver)) )
2687  {
2688  SCIPdebugMessage("SDP %d found infeasible using penalty formulation, maximum of smallest eigenvalue is %f.\n", sdpi->sdpid, -1.0 * objval);
2689  sdpi->penalty = TRUE;
2690  sdpi->infeasible = TRUE;
2691  }
2692  else
2693  {
2694  feasorig = FALSE;
2695  penaltybound = TRUE;
2696 
2697  penaltyparam = sdpi->penaltyparam;
2698 
2699  SCIPdebugMessage("SDP %d not found infeasible using penalty formulation, maximum of smallest eigenvalue is %f.\n", sdpi->sdpid, -1.0 * objval);
2700 
2701  /* we compute the factor to increase with as n-th root of the total increase until the maximum, where n is the number of iterations
2702  * (for npenaltyincr = 0 we make sure that the parameter is too large after the first change)
2703  */
2704  penaltyparamfact = sdpi->npenaltyincr > 0 ? pow((sdpi->maxpenaltyparam / sdpi->penaltyparam), 1.0/sdpi->npenaltyincr) :
2705  2*sdpi->maxpenaltyparam / sdpi->penaltyparam;
2706  gaptol = sdpi->gaptol;
2707  gaptolfact = sdpi->npenaltyincr > 0 ? pow((MIN_GAPTOL / sdpi->gaptol), 1.0/sdpi->npenaltyincr) : 0.5 * MIN_GAPTOL / sdpi->gaptol;
2708 
2709  /* increase penalty-param and decrease feasibility tolerance until we find a feasible solution or reach the final bound for either one of them */
2710  while ( ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) || ! feasorig ) &&
2711  ( penaltyparam < sdpi->maxpenaltyparam + sdpi->epsilon ) && ( gaptol > 0.99 * MIN_GAPTOL ) && ( ! SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver) ))
2712  {
2713  SCIPdebugMessage("Solver did not produce an acceptable result, trying SDP %d again with penaltyparameter %f\n", sdpi->sdpid, penaltyparam);
2714 
2715  /* compute the timit limit to set for the solver */
2716  solvertimelimit = timelimit;
2717  if ( ! SCIPsdpiIsInfinity(sdpi, solvertimelimit) )
2718  {
2719  currenttime = clock();
2720  solvertimelimit -= (SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC;/*lint !e620*/
2721 
2722  if ( solvertimelimit <= 0 )
2723  break;
2724  }
2725 
2726  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, penaltyparam, TRUE, TRUE, sdpi->nvars, sdpi->obj,
2727  sdpi->lb, sdpi->ub, sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2728  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2729  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2730  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
2731  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2732  startXnblocknonz, startXrow, startXcol, startXval, startsettings, solvertimelimit, &feasorig, &penaltybound) );
2733 
2734  /* add iterations and sdpcalls */
2735  naddediterations = 0;
2736  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2737  sdpi->niterations += naddediterations;
2738  naddedsdpcalls = 0;
2739  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2740  sdpi->nsdpcalls += naddedsdpcalls;
2741 
2742  /* If the solver did not converge, we increase the penalty parameter */
2743  if ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) )
2744  {
2745  penaltyparam *= penaltyparamfact;
2746  SCIPdebugMessage("Solver did not converge even with penalty formulation, increasing penaltyparameter.\n");
2747  continue;
2748  }
2749 
2750  /* if we succeeded to solve the problem, update the bound */
2751  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objbound) );
2752  if ( objbound > sdpi->bestbound + sdpi->gaptol )
2753  sdpi->bestbound = objbound;
2754 
2755  /* If we don't get a feasible solution to our original problem we have to update either Gamma (if the penalty bound was active
2756  * in the primal problem) or gaptol (otherwise) */
2757  if ( ! feasorig )
2758  {
2759  if ( penaltybound )
2760  {
2761  penaltyparam *= penaltyparamfact;
2762  SCIPdebugMessage("Penalty formulation produced a result which is infeasible for the original problem, increasing penaltyparameter\n");
2763  }
2764  else
2765  {
2766  gaptol *= gaptolfact;
2767  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, SCIP_SDPPAR_GAPTOL, gaptol) );
2768  SCIPdebugMessage("Penalty formulation produced a result which is infeasible for the original problem, even though primal penalty "
2769  "bound was not reached, decreasing tolerance for duality gap in SDP-solver\n");
2770  }
2771  }
2772  }
2773 
2774  /* reset the tolerance in the SDP-solver */
2775  if ( gaptol > sdpi->gaptol )
2776  {
2777  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, SCIP_SDPPAR_GAPTOL, sdpi->gaptol) );
2778  }
2779 
2780  /* check if we were able to solve the problem in the end */
2781  if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && feasorig )
2782  {
2783  sdpi->penalty = TRUE;
2784  sdpi->solved = TRUE;
2785  }
2786 #if 0 /* we don't really know if it is infeasible or just ill-posed (no KKT-point) */
2787  else if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && ! feasorig )
2788  {
2789  SCIPdebugMessage("Problem was found to be infeasible using a penalty formulation \n");
2790  sdpi->infeasible = TRUE;
2791  sdpi->penalty = TRUE;
2792  sdpi->solved = TRUE;
2793  }
2794 #endif
2795  else
2796  {
2797  SCIPdebugMessage("SDP-Solver could not solve the problem even after using a penalty formulation \n");
2798  sdpi->solved = FALSE;
2799  sdpi->penalty = TRUE;
2800  }
2801 
2802  /* if we still didn't succeed and enforceslatercheck was set, we finally test for the Slater condition to give a reason for failure */
2803  if ( sdpi->solved == FALSE && enforceslatercheck)
2804  {
2805  SCIP_CALL( checkSlaterCondition(sdpi, timelimit, starttime, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges,
2806  nremovedinds, lplhsafterfix, lprhsafterfix, rowsnactivevars, blockindchanges, sdpconstnnonz, nactivelpcons, nremovedblocks, TRUE) );
2807  }
2808  else if ( sdpi->solved == FALSE )
2809  {
2810 #if 0
2811  SCIPmessagePrintInfo(sdpi->messagehdlr, "Numerical trouble\n");
2812 #else
2813  SCIPdebugMessage("SDP-Interface was unable to solve SDP %d\n", sdpi->sdpid);/*lint !e687*/
2814 #endif
2815  }
2816  }
2817  }
2818  }
2819 
2820  /* empty the memory allocated here */
2821  for (block = 0; block < sdpi->nsdpblocks; block++)
2822  {
2823  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpconstnblocknonz[block]);/*lint !e737*/
2824  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpconstnblocknonz[block]);/*lint !e737*/
2825  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpconstnblocknonz[block]);/*lint !e737*/
2826  BMSfreeBlockMemoryArray(sdpi->blkmem, &(indchanges[block]), sdpi->sdpblocksizes[block]);/*lint !e737*/
2827  }
2828  BMSfreeBlockMemoryArray(sdpi->blkmem, &rowsnactivevars, sdpi->nlpcons);/*lint !e737*/
2829  BMSfreeBlockMemoryArray(sdpi->blkmem, &lprhsafterfix, sdpi->nlpcons);/*lint !e737*/
2830  BMSfreeBlockMemoryArray(sdpi->blkmem, &lplhsafterfix, sdpi->nlpcons);/*lint !e737*/
2831  BMSfreeBlockMemoryArray(sdpi->blkmem, &blockindchanges, sdpi->nsdpblocks);/*lint !e737*/
2832  BMSfreeBlockMemoryArray(sdpi->blkmem, &nremovedinds, sdpi->nsdpblocks);/*lint !e737*/
2833  BMSfreeBlockMemoryArray(sdpi->blkmem, &indchanges, sdpi->nsdpblocks);/*lint !e737*/
2834  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstval, sdpi->nsdpblocks);/*lint !e737*/
2835  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstcol, sdpi->nsdpblocks);/*lint !e737*/
2836  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstrow, sdpi->nsdpblocks);/*lint !e737*/
2837  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstnblocknonz, sdpi->nsdpblocks);/*lint !e737*/
2838 
2839  sdpi->sdpid++;
2840 
2841  return SCIP_OKAY;
2842 }
2843 
2844 
2845 
2846 
2847 /*
2848  * Solution Information Methods
2849  */
2850 
2856  SCIP_SDPI* sdpi
2857  )
2858 {
2859  assert( sdpi != NULL );
2860 
2861  return ( sdpi->solved && SCIPsdpiSolverWasSolved(sdpi->sdpisolver) );
2862 }
2863 
2866  SCIP_SDPI* sdpi
2867  )
2868 {
2869  assert( sdpi != NULL );
2870 
2871  return ( SCIPsdpiWasSolved(sdpi) && (! sdpi->penalty) );
2872 }
2873 
2879  SCIP_SDPI* sdpi
2880  )
2881 {
2882  assert( sdpi != NULL );
2883  CHECK_IF_SOLVED_BOOL(sdpi);
2884 
2885  if ( sdpi->infeasible || sdpi->allfixed )
2886  return TRUE;
2887 
2888  return SCIPsdpiSolverFeasibilityKnown(sdpi->sdpisolver);
2889 }
2890 
2893  SCIP_SDPI* sdpi,
2894  SCIP_Bool* primalfeasible,
2895  SCIP_Bool* dualfeasible
2896  )
2897 {
2898  assert( sdpi != NULL );
2899  CHECK_IF_SOLVED(sdpi);
2900 
2901  if ( sdpi->infeasible )
2902  {
2903  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2904  *dualfeasible = FALSE;
2905  return SCIP_OKAY;
2906  }
2907  else if ( sdpi->allfixed )
2908  {
2909  SCIPdebugMessage("All variables were fixed during preprocessing, dual problem is feasible, primal feasibility not available\n");
2910  *dualfeasible = TRUE;
2911  return SCIP_OKAY;
2912  }
2913 
2914  SCIP_CALL( SCIPsdpiSolverGetSolFeasibility(sdpi->sdpisolver, primalfeasible, dualfeasible) );
2915 
2916  return SCIP_OKAY;
2917 }
2918 
2923  SCIP_SDPI* sdpi
2924  )
2925 {
2926  assert( sdpi != NULL );
2927  CHECK_IF_SOLVED_BOOL(sdpi);
2928 
2929  if ( sdpi->infeasible )
2930  {
2931  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal unboundedness not available\n");
2932  return FALSE;
2933  }
2934  else if ( sdpi->allfixed )
2935  {
2936  SCIPdebugMessage("All variables were fixed during preprocessing, primal unboundedness not available\n");
2937  return FALSE;
2938  }
2939 
2940  return SCIPsdpiSolverIsPrimalUnbounded(sdpi->sdpisolver);
2941 }
2942 
2947  SCIP_SDPI* sdpi
2948  )
2949 {
2950  assert( sdpi != NULL );
2951  CHECK_IF_SOLVED_BOOL(sdpi);
2952 
2953  if ( sdpi->infeasible )
2954  {
2955  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2956  return FALSE;
2957  }
2958  else if ( sdpi->allfixed )
2959  {
2960  SCIPdebugMessage("All variables were fixed during preprocessing, primal feasibility not available\n");
2961  return FALSE;
2962  }
2963 
2964  return SCIPsdpiSolverIsPrimalInfeasible(sdpi->sdpisolver);
2965 }
2966 
2971  SCIP_SDPI* sdpi
2972  )
2973 {
2974  assert(sdpi != NULL );
2975  CHECK_IF_SOLVED_BOOL(sdpi);
2976 
2977  if ( sdpi->infeasible )
2978  {
2979  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2980  return FALSE;
2981  }
2982  else if ( sdpi->allfixed )
2983  {
2984  SCIPdebugMessage("All variables fixed during preprocessing, primal feasibility not available\n");
2985  return FALSE;
2986  }
2987 
2988  return SCIPsdpiSolverIsPrimalFeasible(sdpi->sdpisolver);
2989 }
2990 
2995  SCIP_SDPI* sdpi
2996  )
2997 {
2998  assert( sdpi != NULL );
2999  CHECK_IF_SOLVED_BOOL(sdpi);
3000 
3001  if ( sdpi->infeasible )
3002  {
3003  SCIPdebugMessage("Problem was found infeasible during preprocessing, therefore is not unbounded\n");
3004  return FALSE;
3005  }
3006  else if ( sdpi->allfixed )
3007  {
3008  SCIPdebugMessage("All variables were fixed during preprocessing, therefore the problem is not unbounded\n");
3009  return FALSE;
3010  }
3011 
3012  return SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver);
3013 }
3014 
3019  SCIP_SDPI* sdpi
3020  )
3021 {
3022  assert( sdpi != NULL );
3023  CHECK_IF_SOLVED_BOOL(sdpi);
3024 
3025  if ( sdpi->infeasible )
3026  {
3027  SCIPdebugMessage("Problem was found infeasible during preprocessing\n");
3028  return TRUE;
3029  }
3030  else if ( sdpi->allfixed )
3031  {
3032  SCIPdebugMessage("All variables were fixed during preprocessing, solution is feasible\n");
3033  return FALSE;
3034  }
3035 
3036  return SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver);
3037 }
3038 
3043  SCIP_SDPI* sdpi
3044  )
3045 {
3046  assert( sdpi != NULL );
3047  CHECK_IF_SOLVED_BOOL(sdpi);
3048 
3049  if ( sdpi->infeasible )
3050  {
3051  SCIPdebugMessage("Problem was found infeasible during preprocessing\n");
3052  return FALSE;
3053  }
3054  else if ( sdpi->allfixed )
3055  {
3056  SCIPdebugMessage("All variables fixed during preprocessing, solution is feasible\n");
3057  return TRUE;
3058  }
3059 
3060  return SCIPsdpiSolverIsDualFeasible(sdpi->sdpisolver);
3061 }
3062 
3065  SCIP_SDPI* sdpi
3066  )
3067 {
3068  assert( sdpi != NULL );
3069  CHECK_IF_SOLVED_BOOL(sdpi);
3070 
3071  if ( sdpi->infeasible )
3072  {
3073  SCIPdebugMessage("Problem was found infeasible during preprocessing, this counts as converged.\n");
3074  return TRUE;
3075  }
3076  else if ( sdpi->allfixed )
3077  {
3078  SCIPdebugMessage("All variables were fixed during preprocessing, this counts as converged.\n");
3079  return TRUE;
3080  }
3081 
3082  return SCIPsdpiSolverIsConverged(sdpi->sdpisolver);
3083 }
3084 
3087  SCIP_SDPI* sdpi
3088  )
3089 {
3090  assert( sdpi != NULL );
3091  CHECK_IF_SOLVED_BOOL(sdpi);
3092 
3093  if ( sdpi->infeasible )
3094  {
3095  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective limit available.\n");
3096  return FALSE;
3097  }
3098  else if ( sdpi->allfixed )
3099  {
3100  SCIPdebugMessage("All variables were fixed during preprocessing, no objective limit available.\n");
3101  return FALSE;
3102  }
3103 
3104  return SCIPsdpiSolverIsObjlimExc(sdpi->sdpisolver);
3105 }
3106 
3109  SCIP_SDPI* sdpi
3110  )
3111 {
3112  assert( sdpi != NULL );
3113  CHECK_IF_SOLVED_BOOL(sdpi);
3114 
3115  if ( sdpi->infeasible )
3116  {
3117  SCIPdebugMessage("Problem was found infeasible during preprocessing, no iteration limit available.\n");
3118  return FALSE;
3119  }
3120  else if ( sdpi->allfixed )
3121  {
3122  SCIPdebugMessage("All variables were fixed during preprocessing, no iteration limit available.\n");
3123  return FALSE;
3124  }
3125 
3126  return SCIPsdpiSolverIsIterlimExc(sdpi->sdpisolver);
3127 }
3128 
3131  SCIP_SDPI* sdpi
3132  )
3133 {
3134  assert( sdpi != NULL );
3135 
3136  if ( sdpi->infeasible )
3137  {
3138  SCIPdebugMessage("Problem was found infeasible during preprocessing, no time limit available.\n");
3139  return FALSE;
3140  }
3141  else if ( sdpi->allfixed )
3142  {
3143  SCIPdebugMessage("All variables were fixed during preprocessing, no time limit available.\n");
3144  return FALSE;
3145  }
3146  else if ( ! sdpi->solved )
3147  {
3148  SCIPdebugMessage("Problem was not solved, time limit not exceeded.\n");
3149  return FALSE;
3150  }
3151 
3152  return SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver);
3153 }
3154 
3167  SCIP_SDPI* sdpi
3168  )
3169 {
3170  assert( sdpi != NULL );
3171 
3172  if ( ! sdpi->solved )
3173  {
3174  SCIPdebugMessage("Problem wasn't solved yet.\n");
3175  return -1;
3176  }
3177  else if ( sdpi->infeasible )
3178  {
3179  SCIPdebugMessage("Problem was found infeasible during preprocessing, no internal status available.\n");
3180  return 0;
3181  }
3182  else if ( sdpi->allfixed )
3183  {
3184  SCIPdebugMessage("All variables were fixed during preprocessing, no internal status available.\n");
3185  return 0;
3186  }
3187 
3188  return SCIPsdpiSolverGetInternalStatus(sdpi->sdpisolver);
3189 }
3190 
3193  SCIP_SDPI* sdpi
3194  )
3195 {
3196  assert( sdpi != NULL );
3197  CHECK_IF_SOLVED_BOOL(sdpi);
3198 
3199  if ( sdpi->infeasible )
3200  {
3201  SCIPdebugMessage("Problem was found infeasible during preprocessing, therefore there is no optimal solution.\n");
3202  return FALSE;
3203  }
3204  else if ( sdpi->allfixed )
3205  {
3206  SCIPdebugMessage("All variables were fixed during preprocessing, therefore there is no optimal solution.\n");
3207  return FALSE;
3208  }
3209 
3210  return SCIPsdpiSolverIsOptimal(sdpi->sdpisolver);
3211 }
3212 
3217  SCIP_SDPI* sdpi
3218  )
3219 {
3220  assert( sdpi != NULL );
3221 
3222  if ( sdpi->infeasible )
3223  {
3224  SCIPdebugMessage("Problem was found infeasible during preprocessing, this is acceptable in a B&B context.\n");
3225  return TRUE;
3226  }
3227  else if ( sdpi->allfixed )
3228  {
3229  SCIPdebugMessage("All variables fixed during preprocessing, this is acceptable in a B&B context.\n");
3230  return TRUE;
3231  }
3232  else if ( ! sdpi->solved )
3233  {
3234  SCIPdebugMessage("Problem not solved succesfully, this is not acceptable in a B&B context.\n");
3235  return FALSE;
3236  }
3237 
3238  return SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver);
3239 }
3240 
3242 SCIP_RETCODE SCIPsdpiGetObjval(
3243  SCIP_SDPI* sdpi,
3244  SCIP_Real* objval
3245  )
3246 {
3247  assert( sdpi != NULL );
3248  assert( objval != NULL );
3249  CHECK_IF_SOLVED(sdpi);
3250 
3251  if ( sdpi->infeasible )
3252  {
3253  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective value available.\n");
3254  return SCIP_OKAY;
3255  }
3256 
3257  if ( sdpi->allfixed )
3258  {
3259  int v;
3260 
3261  /* As all variables were fixed during preprocessing, we have to compute it ourselves here */
3262  *objval = 0;
3263 
3264  for (v = 0; v < sdpi->nvars; v++)
3265  *objval += sdpi->lb[v] * sdpi->obj[v];
3266 
3267  return SCIP_OKAY;
3268  }
3269 
3270  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, objval) );
3271 
3272  return SCIP_OKAY;
3273 }
3274 
3279  SCIP_SDPI* sdpi,
3280  SCIP_Real* objlb
3281  )
3282 {
3283  assert( sdpi != NULL );
3284  assert( objlb != NULL );
3285 
3286  /* if we could successfully solve the problem, the best bound is the optimal objective */
3287  if ( sdpi->solved )
3288  {
3289  if ( sdpi->infeasible )
3290  {
3291  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective value available.\n");
3292  return SCIP_OKAY;
3293  }
3294 
3295  if ( sdpi->allfixed )
3296  {
3297  int v;
3298 
3299  /* As all variables were fixed during preprocessing, we have to compute it ourselves here */
3300  *objlb = 0;
3301 
3302  for (v = 0; v < sdpi->nvars; v++)
3303  *objlb += sdpi->lb[v] * sdpi->obj[v];
3304 
3305  return SCIP_OKAY;
3306  }
3307 
3308  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, objlb) );
3309  return SCIP_OKAY;
3310  }
3311 
3312  /* if we could not solve it, but tried the penalty formulation, we take the best bound computed by the penalty approach */
3313  if ( sdpi->penalty )
3314  {
3315  *objlb = sdpi->bestbound;
3316  return SCIP_OKAY;
3317  }
3318 
3319  /* if we could not solve it and did not use the penalty formulation (e.g. because the time limit was reached), we have no information */
3320 
3321  *objlb = -SCIPsdpiInfinity(sdpi);
3322  return SCIP_OKAY;
3323 }
3324 
3328 SCIP_RETCODE SCIPsdpiGetSol(
3329  SCIP_SDPI* sdpi,
3330  SCIP_Real* objval,
3331  SCIP_Real* dualsol,
3332  int* dualsollength
3334  )
3335 {
3336  assert( sdpi != NULL );
3337  assert( dualsollength != NULL );
3338  assert( *dualsollength == 0 || dualsol != NULL );
3339  CHECK_IF_SOLVED(sdpi);
3340 
3341  if ( sdpi->infeasible )
3342  {
3343  SCIPdebugMessage("Problem was found infeasible during preprocessing, no solution available.\n");
3344  return SCIP_OKAY;
3345  }
3346  else if ( sdpi->allfixed )
3347  {
3348  if ( objval != NULL )
3349  {
3350  SCIP_CALL( SCIPsdpiGetObjval(sdpi, objval) );
3351  }
3352  if ( *dualsollength > 0 )
3353  {
3354  int v;
3355 
3356  assert( dualsol != NULL );
3357  if ( *dualsollength < sdpi->nvars )
3358  {
3359  SCIPdebugMessage("The given array in SCIPsdpiGetSol only had length %d, but %d was needed", *dualsollength, sdpi->nvars);
3360  *dualsollength = sdpi->nvars;
3361 
3362  return SCIP_OKAY;
3363  }
3364 
3365  /* we give the fixed values as the solution */
3366  for (v = 0; v < sdpi->nvars; v++)
3367  dualsol[v] = sdpi->lb[v];
3368 
3369  return SCIP_OKAY;
3370  }
3371  }
3372 
3373  SCIP_CALL( SCIPsdpiSolverGetSol(sdpi->sdpisolver, objval, dualsol, dualsollength) );
3374 
3375  return SCIP_OKAY;
3376 }
3377 
3380  SCIP_SDPI* sdpi,
3381  int nblocks,
3382  int* startXnblocknonz
3384  )
3385 {
3386  assert( sdpi != NULL );
3387  assert( nblocks >= 0 );
3388  assert( startXnblocknonz != NULL );
3389 
3390  if ( sdpi->infeasible )
3391  {
3392  SCIPdebugMessage("Problem was found infeasible during preprocessing, no preoptimal solution available.\n");
3393  startXnblocknonz[0] = -1;
3394 
3395  return SCIP_OKAY;
3396  }
3397  else if ( sdpi->allfixed )
3398  {
3399  SCIPdebugMessage("No primal solution available, as problem was solved during preprocessing\n");
3400  startXnblocknonz[0] = -1;
3401 
3402  return SCIP_OKAY;
3403  }
3404 
3405  SCIP_CALL( SCIPsdpiSolverGetPreoptimalPrimalNonzeros(sdpi->sdpisolver, nblocks, startXnblocknonz) );
3406 
3407  return SCIP_OKAY;
3408 }
3409 
3418  SCIP_SDPI* sdpi,
3419  SCIP_Bool* success,
3420  SCIP_Real* dualsol,
3421  int* dualsollength,
3423  int nblocks,
3424  int* startXnblocknonz,
3426  int** startXrow,
3427  int** startXcol,
3428  SCIP_Real** startXval
3429  )
3430 {
3431  assert( sdpi != NULL );
3432  assert( success != NULL );
3433  assert( dualsol != NULL );
3434  assert( dualsollength != NULL );
3435  assert( *dualsollength >= 0 );
3436  assert( startXnblocknonz != NULL || nblocks == -1 );
3437  assert( startXrow != NULL || nblocks == -1 );
3438  assert( startXcol != NULL || nblocks == -1 );
3439  assert( startXval != NULL || nblocks == -1 );
3440 
3441  if ( sdpi->infeasible )
3442  {
3443  *success = FALSE;
3444  SCIPdebugMessage("Problem was found infeasible during preprocessing, no preoptimal solution available.\n");
3445  assert( startXnblocknonz != NULL );
3446  startXnblocknonz[0] = -1;
3447 
3448  return SCIP_OKAY;
3449  }
3450  else if ( sdpi->allfixed )
3451  {
3452  int v;
3453 
3454  assert( dualsol != NULL );
3455 
3456  *success = FALSE;
3457 
3458  if ( *dualsollength < sdpi->nvars )
3459  {
3460  SCIPdebugMessage("The given array in SCIPsdpiGetPreoptimalSol only had length %d, but %d was needed", *dualsollength, sdpi->nvars);
3461  *dualsollength = sdpi->nvars;
3462 
3463  return SCIP_OKAY;
3464  }
3465 
3466  /* we give the fixed values as the solution */
3467  for (v = 0; v < sdpi->nvars; v++)
3468  dualsol[v] = sdpi->lb[v];
3469 
3470  if ( nblocks > -1 )
3471  {
3472  SCIPdebugMessage("No primal solution available, as problem was solved during preprocessing\n");
3473  assert( startXnblocknonz != NULL );
3474  startXnblocknonz[0] = -1;
3475  }
3476 
3477  return SCIP_OKAY;
3478  }
3479 
3480  SCIP_CALL( SCIPsdpiSolverGetPreoptimalSol(sdpi->sdpisolver, success, dualsol, dualsollength, nblocks, startXnblocknonz,
3481  startXrow, startXcol, startXval) );
3482 
3483  return SCIP_OKAY;
3484 }
3485 
3492  SCIP_SDPI* sdpi,
3493  SCIP_Real* lbvars,
3494  SCIP_Real* ubvars,
3495  int* arraylength
3497  )
3498 {
3499  assert( sdpi != NULL );
3500  assert( lbvars != NULL );
3501  assert( ubvars != NULL );
3502  assert( arraylength != NULL );
3503  assert( *arraylength >= 0 );
3504  CHECK_IF_SOLVED(sdpi);
3505 
3506  if ( sdpi->infeasible )
3507  {
3508  SCIPdebugMessage("Problem was found infeasible during preprocessing, no primal variables available.\n");
3509  return SCIP_OKAY;
3510  }
3511  else if ( sdpi->allfixed )
3512  {
3513  SCIPdebugMessage("All variables fixed during preprocessing, no primal variables available.\n");
3514  return SCIP_OKAY;
3515  }
3516 
3517  SCIP_CALL( SCIPsdpiSolverGetPrimalBoundVars(sdpi->sdpisolver, lbvars, ubvars, arraylength) );
3518 
3519  return SCIP_OKAY;
3520 }
3521 
3524  SCIP_SDPI* sdpi,
3525  int nblocks,
3526  int* startXnblocknonz
3527  )
3528 {
3529  assert( sdpi != NULL );
3530 
3531  if ( sdpi->infeasible )
3532  {
3533  SCIPdebugMessage("Problem was found infeasible during preprocessing, no primal solution available.\n");
3534  return SCIP_OKAY;
3535  }
3536  else if ( sdpi->allfixed )
3537  {
3538  SCIPdebugMessage("All variables fixed during preprocessing, no primal solution available.\n");
3539  return SCIP_OKAY;
3540  }
3541 
3542  SCIP_CALL( SCIPsdpiSolverGetPrimalNonzeros(sdpi->sdpisolver, nblocks, startXnblocknonz) );
3543 
3544  return SCIP_OKAY;
3545 }
3546 
3554  SCIP_SDPI* sdpi,
3555  int nblocks,
3556  int* startXnblocknonz,
3558  int** startXrow,
3559  int** startXcol,
3560  SCIP_Real** startXval
3561  )
3562 {/* TODO: should also set startXnblocknonz[0] = -1 in case the problem was solved in presolving */
3563  assert( sdpi != NULL );
3564 
3565  if ( sdpi->infeasible )
3566  {
3567  SCIPdebugMessage("Problem was found infeasible during preprocessing, no primal solution available.\n");
3568  return SCIP_OKAY;
3569  }
3570  else if ( sdpi->allfixed )
3571  {
3572  SCIPdebugMessage("All variables fixed during preprocessing, no primal solution available.\n");
3573  return SCIP_OKAY;
3574  }
3575 
3576  SCIP_CALL( SCIPsdpiSolverGetPrimalMatrix(sdpi->sdpisolver, nblocks, startXnblocknonz, startXrow, startXcol, startXval) );
3577 
3578  return SCIP_OKAY;
3579 }
3580 
3583  SCIP_SDPI* sdpi
3584  )
3585 {
3586  assert( sdpi != NULL );
3587 
3588  return SCIPsdpiSolverGetMaxPrimalEntry( sdpi->sdpisolver );
3589 }
3590 
3593  SCIP_SDPI* sdpi,
3594  int* iterations
3595  )
3596 {
3597  assert( sdpi != NULL );
3598  assert( iterations != NULL );
3599 
3600  *iterations = sdpi->niterations;
3601 
3602  return SCIP_OKAY;
3603 }
3604 
3606 SCIP_RETCODE SCIPsdpiGetSdpCalls(
3607  SCIP_SDPI* sdpi,
3608  int* calls
3609  )
3610 {
3611  assert( sdpi != NULL );
3612  assert( calls != NULL );
3613 
3614  *calls = sdpi->nsdpcalls;
3615 
3616  return SCIP_OKAY;
3617 }
3618 
3621  SCIP_SDPI* sdpi,
3622  SCIP_SDPSOLVERSETTING* usedsetting
3623  )
3624 {
3625  assert( sdpi != NULL );
3626  assert( usedsetting != NULL );
3627 
3628  if ( ! sdpi->solved )
3629  {
3630  SCIPdebugMessage("Problem was not solved successfully.\n");
3631  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3632  return SCIP_OKAY;
3633  }
3634  else if ( sdpi->infeasible && ! sdpi->penalty ) /* if we solved the penalty formulation, we may also set infeasible if it is infeasible for the original problem */
3635  {
3636  SCIPdebugMessage("Problem was found infeasible during preprocessing, no settings used.\n");
3637  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3638  return SCIP_OKAY;
3639  }
3640  else if ( sdpi->allfixed )
3641  {
3642  SCIPdebugMessage("All varialbes fixed during preprocessing, no settings used.\n");
3643  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3644  return SCIP_OKAY;
3645  }
3646  else if ( sdpi->penalty )
3647  {
3648  *usedsetting = SCIP_SDPSOLVERSETTING_PENALTY;
3649  return SCIP_OKAY;
3650  }
3651 
3652  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, usedsetting) );
3653  return SCIP_OKAY;
3654 }
3655 
3658  SCIP_SDPI* sdpi,
3659  SCIP_SDPSLATERSETTING* slatersetting
3660  )
3661 {
3662  SCIP_SDPSOLVERSETTING usedsetting;
3663 
3664  assert( sdpi != NULL );
3665  assert( slatersetting != NULL );
3666 
3667  if ( ! sdpi->solved )
3668  {
3669  SCIPdebugMessage("Problem was not solved successfully");
3670  if ( sdpi->bestbound > -SCIPsdpiSolverInfinity(sdpi->sdpisolver) )
3671  {
3672  SCIPdebugMessage(", but we could at least compute a lower bound. \n");
3673  if ( sdpi->dualslater == SCIP_SDPSLATER_INF)
3674  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDINFEASIBLE;
3675  else
3676  {
3677  switch( sdpi->primalslater )/*lint --e{788}*/
3678  {
3679  case SCIP_SDPSLATER_NOINFO:
3680  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3681  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
3682  else
3683  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3684  break;
3685  case SCIP_SDPSLATER_NOT:
3686  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
3687  break;
3688  case SCIP_SDPSLATER_HOLDS:
3689  switch( sdpi->dualslater )/*lint --e{788}*/
3690  {
3691  case SCIP_SDPSLATER_NOINFO:
3692  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3693  break;
3694  case SCIP_SDPSLATER_NOT:
3695  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
3696  break;
3697  case SCIP_SDPSLATER_HOLDS:
3698  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDWSLATER;
3699  break;
3700  default:
3701  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3702  break;
3703  }
3704  break;
3705  default:
3706  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3707  break;
3708  }
3709  }
3710  }
3711  else
3712  {
3713  SCIPdebugMessage(".\n");
3714  if ( sdpi->dualslater == SCIP_SDPSLATER_INF)
3716  else
3717  {
3718  switch( sdpi->primalslater )/*lint --e{788}*/
3719  {
3720  case SCIP_SDPSLATER_NOINFO:
3721  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3722  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
3723  else
3724  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3725  break;
3726  case SCIP_SDPSLATER_NOT:
3727  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
3728  break;
3729  case SCIP_SDPSLATER_HOLDS:
3730  switch( sdpi->dualslater )/*lint --e{788}*/
3731  {
3732  case SCIP_SDPSLATER_NOINFO:
3733  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3734  break;
3735  case SCIP_SDPSLATER_NOT:
3736  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
3737  break;
3738  case SCIP_SDPSLATER_HOLDS:
3739  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDWSLATER;
3740  break;
3741  default:
3742  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3743  break;
3744  }
3745  break;
3746  default:
3747  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3748  break;
3749  }
3750  }
3751  }
3752  return SCIP_OKAY;
3753  }
3754  else if ( sdpi->infeasible && ( ! sdpi->penalty ) ) /* if we solved the penalty formulation, we may also set infeasible if it is infeasible for the original problem */
3755  {
3756  SCIPdebugMessage("Problem was found infeasible during preprocessing, no settings used.\n");
3757  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3758  return SCIP_OKAY;
3759  }
3760  else if ( sdpi->allfixed )
3761  {
3762  SCIPdebugMessage("All varialbes fixed during preprocessing, no settings used.\n");
3763  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3764  return SCIP_OKAY;
3765  }
3766  else if ( sdpi->penalty )
3767  {
3768  switch( sdpi->primalslater )/*lint --e{788}*/
3769  {
3770  case SCIP_SDPSLATER_NOINFO:
3771  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3772  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
3773  else if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3774  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
3775  else
3776  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3777  break;
3778  case SCIP_SDPSLATER_NOT:
3779  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3780  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
3781  else
3782  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
3783  break;
3784  case SCIP_SDPSLATER_HOLDS:
3785  switch( sdpi->dualslater )/*lint --e{788}*/
3786  {
3787  case SCIP_SDPSLATER_NOINFO:
3788  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3789  break;
3790  case SCIP_SDPSLATER_NOT:
3791  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
3792  break;
3793  case SCIP_SDPSLATER_HOLDS:
3794  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYWSLATER;
3795  break;
3796  case SCIP_SDPSLATER_INF:
3797  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
3798  break;
3799  default:
3800  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3801  break;
3802  }
3803  break;
3804  default:
3805  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3806  break;
3807  }
3808  return SCIP_OKAY;
3809  }
3810 
3811  switch( sdpi->primalslater )/*lint --e{788}*/
3812  {
3813  case SCIP_SDPSLATER_NOINFO:
3814  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3815  {
3816  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3817  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3818  switch( usedsetting )/*lint --e{788}*/
3819  {
3821  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
3822  break;
3825  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
3826  break;
3827  default:
3828  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3829  break;
3830  }
3831  }
3832  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3833  {
3834  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3835  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3836  switch( usedsetting )/*lint --e{788}*/
3837  {
3839  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
3840  break;
3844  break;
3845  default:
3846  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3847  break;
3848  }
3849  }
3850  else
3851  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3852  break;
3853  case SCIP_SDPSLATER_NOT:
3854  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3855  {
3856  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3857  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3858  switch( usedsetting )/*lint --e{788}*/
3859  {
3861  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
3862  break;
3866  break;
3867  default:
3868  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3869  break;
3870  }
3871  }
3872  else
3873  {
3874  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3875  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3876  switch( usedsetting )/*lint --e{788}*/
3877  {
3879  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
3880  break;
3883  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
3884  break;
3885  default:
3886  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3887  break;
3888  }
3889  }
3890  break;
3891  case SCIP_SDPSLATER_HOLDS:
3892  switch( sdpi->dualslater )/*lint --e{788}*/
3893  {
3894  case SCIP_SDPSLATER_NOINFO:
3895  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3896  break;
3897  case SCIP_SDPSLATER_NOT:
3898  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3899  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3900  switch( usedsetting )/*lint --e{788}*/
3901  {
3903  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
3904  break;
3907  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
3908  break;
3909  default:
3910  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3911  break;
3912  }
3913  break;
3914  case SCIP_SDPSLATER_INF:
3915  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3916  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3917  switch( usedsetting )/*lint --e{788}*/
3918  {
3920  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
3921  break;
3925  break;
3926  default:
3927  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3928  break;
3929  }
3930  break;
3931  case SCIP_SDPSLATER_HOLDS:
3932  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3933  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3934  switch( usedsetting )/*lint --e{788}*/
3935  {
3937  *slatersetting = SCIP_SDPSLATERSETTING_STABLEWSLATER;
3938  break;
3941  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLEWSLATER;
3942  break;
3943  default:
3944  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3945  break;
3946  }
3947  break;
3948  default:
3949  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3950  break;
3951  }
3952  break;
3953  default:
3954  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3955  break;
3956  }
3957 
3958  return SCIP_OKAY;
3959 }
3960 
3962 SCIP_RETCODE SCIPsdpiSlater(
3963  SCIP_SDPI* sdpi,
3964  SCIP_SDPSLATER* primalslater,
3965  SCIP_SDPSLATER* dualslater
3966  )
3967 {
3968  assert( sdpi != NULL );
3969  assert( primalslater != NULL );
3970  assert( dualslater != NULL );
3971 
3972  if ( sdpi->infeasible )
3973  {
3974  *primalslater = SCIP_SDPSLATER_NOINFO;
3975  *dualslater = sdpi->dualslater;
3976  return SCIP_OKAY;
3977  }
3978 
3979  if (sdpi->allfixed )
3980  {
3981  *primalslater = SCIP_SDPSLATER_NOINFO;
3982  *dualslater = SCIP_SDPSLATER_NOINFO;
3983  return SCIP_OKAY;
3984  }
3985 
3986  *primalslater = sdpi->primalslater;
3987  *dualslater = sdpi->dualslater;
3988 
3989  return SCIP_OKAY;
3990 }
3991 
3997 /*
3998  * Numerical Methods
3999  */
4000 
4006  SCIP_SDPI* sdpi
4007  )
4008 {
4009  assert( sdpi != NULL );
4010 
4011  return SCIPsdpiSolverInfinity(sdpi->sdpisolver);
4012 }
4013 
4016  SCIP_SDPI* sdpi,
4017  SCIP_Real val
4018  )
4019 {
4020  assert( sdpi != NULL );
4021 
4022  return ((val <= -SCIPsdpiInfinity(sdpi)) || (val >= SCIPsdpiInfinity(sdpi)));
4023 }
4024 
4026 SCIP_RETCODE SCIPsdpiGetRealpar(
4027  SCIP_SDPI* sdpi,
4028  SCIP_SDPPARAM type,
4029  SCIP_Real* dval
4030  )
4031 {
4032  assert( sdpi != NULL );
4033  assert( sdpi->sdpisolver != NULL );
4034  assert( dval != NULL );
4035 
4036  switch( type )/*lint --e{788}*/
4037  {
4038  case SCIP_SDPPAR_EPSILON:
4039  *dval = sdpi->epsilon;
4040  break;
4041  case SCIP_SDPPAR_GAPTOL:
4042  *dval = sdpi->gaptol;
4043  break;
4044  case SCIP_SDPPAR_FEASTOL:
4045  *dval = sdpi->feastol;
4046  break;
4048  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4049  break;
4050  case SCIP_SDPPAR_OBJLIMIT:
4051  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4052  break;
4054  *dval = sdpi->penaltyparam;
4055  break;
4057  *dval = sdpi->maxpenaltyparam;
4058  break;
4060  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4061  break;
4063  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4064  break;
4066  *dval = sdpi->peninfeasadjust;
4067  break;
4068  default:
4069  return SCIP_PARAMETERUNKNOWN;
4070  }
4071 
4072  return SCIP_OKAY;
4073 }
4074 
4076 SCIP_RETCODE SCIPsdpiSetRealpar(
4077  SCIP_SDPI* sdpi,
4078  SCIP_SDPPARAM type,
4079  SCIP_Real dval
4080  )
4081 {
4082  assert( sdpi != NULL );
4083 
4084  switch( type )/*lint --e{788}*/
4085  {
4086  case SCIP_SDPPAR_EPSILON:
4087  sdpi->epsilon = dval;
4088  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4089  break;
4090  case SCIP_SDPPAR_GAPTOL:
4091  sdpi->gaptol = dval;
4092  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4093  break;
4094  case SCIP_SDPPAR_FEASTOL:
4095  sdpi->feastol = dval;
4096  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4097  break;
4099  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4100  break;
4101  case SCIP_SDPPAR_OBJLIMIT:
4102  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4103  break;
4105  sdpi->penaltyparam = dval;
4106  SCIP_CALL_PARAM_IGNORE_UNKNOWN( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4107  break;
4109  sdpi->maxpenaltyparam = dval;
4110  break;
4112  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4113  break;
4115  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4116  break;
4118  sdpi->peninfeasadjust = dval;
4119  break;
4120  default:
4121  return SCIP_PARAMETERUNKNOWN;
4122  }
4123 
4124  return SCIP_OKAY;
4125 }
4126 
4128 SCIP_RETCODE SCIPsdpiGetIntpar(
4129  SCIP_SDPI* sdpi,
4130  SCIP_SDPPARAM type,
4131  int* ival
4132  )
4133 {
4134  assert( sdpi != NULL );
4135  assert( sdpi->sdpisolver != NULL );
4136  assert( ival != NULL );
4137 
4138  switch( type )/*lint --e{788}*/
4139  {
4140  case SCIP_SDPPAR_SDPINFO:
4141  case SCIP_SDPPAR_NTHREADS:
4142  SCIP_CALL_PARAM( SCIPsdpiSolverGetIntpar(sdpi->sdpisolver, type, ival) );
4143  break;
4145  *ival = sdpi->slatercheck;
4146  break;
4148  *ival = sdpi->npenaltyincr;
4149  break;
4150  default:
4151  return SCIP_PARAMETERUNKNOWN;
4152  }
4153 
4154  return SCIP_OKAY;
4155 }
4156 
4158 SCIP_RETCODE SCIPsdpiSetIntpar(
4159  SCIP_SDPI* sdpi,
4160  SCIP_SDPPARAM type,
4161  int ival
4162  )
4163 {
4164  assert( sdpi != NULL );
4165  assert( sdpi->sdpisolver != NULL );
4166 
4167  switch( type )/*lint --e{788}*/
4168  {
4169  case SCIP_SDPPAR_SDPINFO:
4170  assert( ival == 0 || ival == 1 ); /* this is a boolean parameter */
4171  SCIP_CALL_PARAM( SCIPsdpiSolverSetIntpar(sdpi->sdpisolver, type, ival) );
4172  break;
4173  case SCIP_SDPPAR_NTHREADS:
4174  SCIP_CALL_PARAM( SCIPsdpiSolverSetIntpar(sdpi->sdpisolver, type, ival) );
4175  break;
4177  sdpi->slatercheck = ival;
4178  break;
4180  sdpi->npenaltyincr = ival;
4181  break;
4182  default:
4183  return SCIP_PARAMETERUNKNOWN;
4184  }
4185 
4186  return SCIP_OKAY;
4187 }
4188 
4191  SCIP_SDPI* sdpi,
4192  SCIP_Real maxguess
4193  )
4194 {
4195  return SCIPsdpiSolverComputeLambdastar(sdpi->sdpisolver, maxguess);
4196 }
4197 
4200  SCIP_SDPI* sdpi,
4201  SCIP_Real maxcoeff,
4202  SCIP_Real* penaltyparam
4203  )
4204 {
4205  SCIP_CALL( SCIPsdpiSolverComputePenaltyparam(sdpi->sdpisolver, maxcoeff, penaltyparam) );
4206 
4207  sdpi->penaltyparam = *penaltyparam;
4208 
4209  return SCIP_OKAY;
4210 }
4211 
4214  SCIP_SDPI* sdpi,
4215  SCIP_Real penaltyparam,
4216  SCIP_Real* maxpenaltyparam
4217  )
4218 {
4219  SCIP_CALL( SCIPsdpiSolverComputeMaxPenaltyparam(sdpi->sdpisolver, penaltyparam, maxpenaltyparam) );
4220 
4221  sdpi->maxpenaltyparam = *maxpenaltyparam;
4222 
4223  /* if the initial penalty parameter is smaller than the maximum one, we decrease the initial correspondingly */
4224  /* if the maximum penalty parameter is smaller than the initial penalty paramater, we decrease the initial one correspondingly */
4225  if ( sdpi->penaltyparam > *maxpenaltyparam )
4226  {
4227  SCIPdebugMessage("Decreasing penaltyparameter of %f to maximum penalty paramater of %f.\n", sdpi->penaltyparam, *maxpenaltyparam);
4228  sdpi->penaltyparam = *maxpenaltyparam;
4229  }
4230 
4231  return SCIP_OKAY;
4232 }
4233 
4239 /*
4240  * File Interface Methods
4241  */
4242 
4247 SCIP_RETCODE SCIPsdpiReadSDP(
4248  SCIP_SDPI* sdpi,
4249  const char* fname
4250  )
4251 {
4252  assert( sdpi != NULL );
4253  assert( fname != NULL );
4254 
4255  SCIPdebugMessage("Not implemented yet\n");
4256  return SCIP_LPERROR;
4257 }
4258 
4260 SCIP_RETCODE SCIPsdpiWriteSDP(
4261  SCIP_SDPI* sdpi,
4262  const char* fname
4263  )
4264 {
4265  assert( sdpi != NULL );
4266  assert( fname != NULL );
4267 
4268  SCIPdebugMessage("Not implemented yet\n");
4269  return SCIP_LPERROR;
4270 }
4271 
SCIP_RETCODE SCIPsdpiFree(SCIP_SDPI **sdpi)
Definition: sdpi.c:1514
SCIP_Bool SCIPsdpiIsDualUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:2994
#define DEFAULT_SDPSOLVERGAPTOL
Definition: sdpi.c:134
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetPrimalBoundVars(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
SCIP_RETCODE SCIPsdpiDelLPRows(SCIP_SDPI *sdpi, int firstrow, int lastrow)
Definition: sdpi.c:1984
SCIP_EXPORT SCIP_Real SCIPsdpiSolverInfinity(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT int SCIPsdpiSolverGetInternalStatus(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiChgLPLhRhSides(SCIP_SDPI *sdpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: sdpi.c:2215
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int *ival)
SCIP_RETCODE SCIPsdpiGetSdpCalls(SCIP_SDPI *sdpi, int *calls)
Definition: sdpi.c:3606
SCIP_Bool SCIPsdpiDoesWarmstartNeedPrimal(void)
Definition: sdpi.c:1428
#define BMS_CALL(x)
Definition: sdpi.c:58
SCIP_EXPORT SCIP_Real SCIPsdpiSolverGetMaxPrimalEntry(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetSolFeasibility(SCIP_SDPI *sdpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: sdpi.c:2892
SCIP_RETCODE SCIPsdpiWriteSDP(SCIP_SDPI *sdpi, const char *fname)
Definition: sdpi.c:4260
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real *dval)
static SCIP_RETCODE checkAllFixed(SCIP_SDPI *sdpi)
Definition: sdpi.c:851
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverResetCounter(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverSettingsUsed(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPSOLVERSETTING *usedsetting)
SCIP_RETCODE SCIPsdpiGetLPNNonz(SCIP_SDPI *sdpi, int *nnonz)
Definition: sdpi.c:2329
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetPreoptimalSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *success, SCIP_Real *dualsol, int *dualsollength, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
SCIP_RETCODE SCIPsdpiGetPrimalMatrix(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
Definition: sdpi.c:3553
enum SCIP_SDPSolverSetting SCIP_SDPSOLVERSETTING
Definition: type_sdpi.h:80
SCIP_Bool SCIPsdpiIsOptimal(SCIP_SDPI *sdpi)
Definition: sdpi.c:3192
SCIP_RETCODE SCIPsdpiGetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int *ival)
Definition: sdpi.c:4128
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsObjlimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetSDPNNonz(SCIP_SDPI *sdpi, int *nnonz)
Definition: sdpi.c:2301
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsConverged(SCIP_SDPISOLVER *sdpisolver)
#define MIN_GAPTOL
Definition: sdpi.c:132
SCIP_Bool SCIPsdpiIsInfinity(SCIP_SDPI *sdpi, SCIP_Real val)
Definition: sdpi.c:4015
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverSetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real dval)
const char * SCIPsdpiGetSolverName(void)
Definition: sdpi.c:1375
SCIP_RETCODE SCIPsdpiGetNSDPBlocks(SCIP_SDPI *sdpi, int *nsdpblocks)
Definition: sdpi.c:2273
SCIP_RETCODE SCIPsdpiGetSol(SCIP_SDPI *sdpi, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
Definition: sdpi.c:3328
interface methods for specific SDP-solvers
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsTimelimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_Real SCIPsdpiSolverGetDefaultSdpiSolverGaptol(void)
SCIP_Bool SCIPsdpiIsPrimalInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2946
#define DEFAULT_FEASTOL
Definition: sdpi.c:135
SCIP_RETCODE SCIPsdpiSolve(SCIP_SDPI *sdpi, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Bool enforceslatercheck, SCIP_Real timelimit)
Definition: sdpi.c:2454
SCIP_Bool SCIPsdpiFeasibilityKnown(SCIP_SDPI *sdpi)
Definition: sdpi.c:2878
SCIP_RETCODE SCIPsdpiLoadSDP(SCIP_SDPI *sdpi, 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 nlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval)
Definition: sdpi.c:1699
SCIP_RETCODE SCIPsdpiComputeLambdastar(SCIP_SDPI *sdpi, SCIP_Real maxguess)
Definition: sdpi.c:4190
SCIP_RETCODE SCIPsdpiGetPrimalNonzeros(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz)
Definition: sdpi.c:3523
SCIP_RETCODE SCIPsdpiGetIterations(SCIP_SDPI *sdpi, int *iterations)
Definition: sdpi.c:3592
SCIP_RETCODE SCIPsdpiSettingsUsed(SCIP_SDPI *sdpi, SCIP_SDPSOLVERSETTING *usedsetting)
Definition: sdpi.c:3620
SCIP_RETCODE SCIPsdpiSlaterSettings(SCIP_SDPI *sdpi, SCIP_SDPSLATERSETTING *slatersetting)
Definition: sdpi.c:3657
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetSolFeasibility(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsPrimalInfeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
SCIP_EXPORT SCIP_Real SCIPsdpiSolverGetDefaultSdpiSolverFeastol(void)
static SCIP_RETCODE findEmptyRowColsSDP(SCIP_SDPI *sdpi, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int **indchanges, int *nremovedinds, int *blockindchanges, int *nremovedblocks)
Definition: sdpi.c:378
SCIP_Bool SCIPsdpiIsAcceptable(SCIP_SDPI *sdpi)
Definition: sdpi.c:3216
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsDualFeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiIsIterlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3108
SCIP_Bool SCIPsdpiIsTimelimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3130
SCIP_Bool SCIPsdpiIsDualInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:3018
General interface methods for SDP-preprocessing (mainly fixing variables and removing empty rows/cols...
SCIP_RETCODE SCIPsdpiGetConstNNonz(SCIP_SDPI *sdpi, int *nnonz)
Definition: sdpi.c:2315
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetSdpCalls(SCIP_SDPISOLVER *sdpisolver, int *calls)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverCreate(SCIP_SDPISOLVER **sdpisolver, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem)
enum SCIP_SDPSlaterSetting SCIP_SDPSLATERSETTING
Definition: type_sdpi.h:102
SCIP_RETCODE SCIPsdpiClone(SCIP_SDPI *oldsdpi, SCIP_SDPI *newsdpi)
Definition: sdpi.c:1579
SCIP_RETCODE SCIPsdpiChgBounds(SCIP_SDPI *sdpi, int nvars, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: sdpi.c:2181
SCIP_RETCODE SCIPsdpiDelLPRowset(SCIP_SDPI *sdpi, int *dstat)
Definition: sdpi.c:2094
SCIP_RETCODE SCIPsdpiGetLowerObjbound(SCIP_SDPI *sdpi, SCIP_Real *objlb)
Definition: sdpi.c:3278
SCIP_Bool SCIPsdpiIsObjlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3086
#define SCIP_CALL_PARAM_IGNORE_UNKNOWN(x)
Definition: sdpi.c:117
SCIP_RETCODE SCIPsdpiGetObj(SCIP_SDPI *sdpi, int firstvar, int lastvar, SCIP_Real *vals)
Definition: sdpi.c:2343
SCIP_EXPORT int SCIPsdpiSolverGetDefaultSdpiSolverNpenaltyIncreases(void)
void * SCIPsdpiGetSolverPointer(SCIP_SDPI *sdpi)
Definition: sdpi.c:1396
int SCIPsdpiGetInternalStatus(SCIP_SDPI *sdpi)
Definition: sdpi.c:3166
static SCIP_RETCODE checkFixedFeasibilitySdp(SCIP_SDPI *sdpi, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int **indchanges, int *nremovedinds, int *blockindchanges)
Definition: sdpi.c:879
SCIP_Real SCIPsdpiGetDefaultSdpiSolverFeastol(void)
Definition: sdpi.c:1404
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverSetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int ival)
SCIP_EXPORT SCIP_RETCODE SCIPlapackComputeIthEigenvalue(BMS_BUFMEM *bufmem, SCIP_Bool geteigenvectors, int n, SCIP_Real *A, int i, SCIP_Real *eigenvalue, SCIP_Real *eigenvector)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverFeasibilityKnown(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiAddLPRows(SCIP_SDPI *sdpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, int nnonz, const int *row, const int *col, const SCIP_Real *val)
Definition: sdpi.c:1919
SCIP_EXPORT const char * SCIPsdpiSolverGetSolverName(void)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetPrimalMatrix(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
SCIP_RETCODE SCIPsdpiGetNVars(SCIP_SDPI *sdpi, int *nvars)
Definition: sdpi.c:2287
const char * SCIPsdpiGetSolverDesc(void)
Definition: sdpi.c:1383
SCIP_RETCODE SCIPsdpiComputePenaltyparam(SCIP_SDPI *sdpi, SCIP_Real maxcoeff, SCIP_Real *penaltyparam)
Definition: sdpi.c:4199
SCIP_RETCODE SCIPsdpiSetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int ival)
Definition: sdpi.c:4158
SCIP_Bool SCIPsdpiIsPrimalUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:2922
SCIP_Real SCIPsdpiInfinity(SCIP_SDPI *sdpi)
Definition: sdpi.c:4005
#define CHECK_IF_SOLVED_BOOL(sdpi)
Definition: sdpi.c:80
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverLoadAndSolve(SCIP_SDPISOLVER *sdpisolver, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, int noldlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int *rownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit)
SCIP_RETCODE SCIPsdpiGetRhSides(SCIP_SDPI *sdpi, int firstrow, int lastrow, SCIP_Real *rhss)
Definition: sdpi.c:2415
SCIP_RETCODE SCIPsdpiCreate(SCIP_SDPI **sdpi, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem)
Definition: sdpi.c:1446
#define DUPLICATE_ARRAY_NULL(blkmem, target, source, size)
Definition: sdpi.c:91
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsDualInfeasible(SCIP_SDPISOLVER *sdpisolver)
adds the main functionality to fix/unfix/(multi-)aggregate variables by merging two three-tuple-array...
SCIP_EXPORT const char * SCIPsdpiSolverGetSolverDesc(void)
static void ensureLowerTriangular(int *i, int *j)
Definition: sdpi.c:215
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverComputeMaxPenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Real *maxpenaltyparam)
SCIP_RETCODE SCIPsdpiGetObjval(SCIP_SDPI *sdpi, SCIP_Real *objval)
Definition: sdpi.c:3242
SCIP_EXPORT void * SCIPsdpiSolverGetSolverPointer(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsAcceptable(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverIncreaseCounter(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsOptimal(SCIP_SDPISOLVER *sdpisolver)
int SCIPsdpiGetDefaultSdpiSolverNpenaltyIncreases(void)
Definition: sdpi.c:1420
SCIP_Bool SCIPsdpiIsConverged(SCIP_SDPI *sdpi)
Definition: sdpi.c:3064
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverWasSolved(SCIP_SDPISOLVER *sdpisolver)
static SCIP_Bool isFixed(SCIP_SDPI *sdpi, int v)
Definition: sdpi.c:232
#define DEFAULT_MAXPENALTYPARAM
Definition: sdpi.c:138
SCIP_Bool SCIPsdpiWasSolved(SCIP_SDPI *sdpi)
Definition: sdpi.c:2855
SCIP_RETCODE SCIPsdpiReadSDP(SCIP_SDPI *sdpi, const char *fname)
Definition: sdpi.c:4247
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverDoesWarmstartNeedPrimal(void)
SCIP_RETCODE SCIPsdpiComputeMaxPenaltyparam(SCIP_SDPI *sdpi, SCIP_Real penaltyparam, SCIP_Real *maxpenaltyparam)
Definition: sdpi.c:4213
SCIP_RETCODE SCIPsdpiClear(SCIP_SDPI *sdpi)
Definition: sdpi.c:2136
SCIP_RETCODE SCIPsdpiGetBounds(SCIP_SDPI *sdpi, int firstvar, int lastvar, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: sdpi.c:2365
SCIP_RETCODE SCIPsdpiChgObj(SCIP_SDPI *sdpi, int nvars, const int *ind, const SCIP_Real *obj)
Definition: sdpi.c:2152
SCIP_RETCODE SCIPsdpiGetPreoptimalSol(SCIP_SDPI *sdpi, SCIP_Bool *success, SCIP_Real *dualsol, int *dualsollength, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
Definition: sdpi.c:3417
#define DEFAULT_NPENALTYINCR
Definition: sdpi.c:139
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetObjval(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval)
#define DEFAULT_PENALTYPARAM
Definition: sdpi.c:137
SCIP_Bool SCIPsdpiIsDualFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:3042
struct SCIP_SDPi SCIP_SDPI
Definition: type_sdpi.h:114
SCIP_Bool SCIPsdpiIsPrimalFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2970
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverComputePenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxcoeff, SCIP_Real *penaltyparam)
SCIP_RETCODE SCIPsdpiSetRealpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, SCIP_Real dval)
Definition: sdpi.c:4076
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetPrimalNonzeros(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverLoadAndSolveWithPenalty(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Bool withobj, SCIP_Bool rbound, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, int noldlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int *rownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit, SCIP_Bool *feasorig, SCIP_Bool *penaltybound)
enum SCIP_SDPSlater SCIP_SDPSLATER
Definition: type_sdpi.h:112
SCIP_Real SCIPsdpiGetMaxPrimalEntry(SCIP_SDPI *sdpi)
Definition: sdpi.c:3582
SCIP_RETCODE SCIPsdpVarfixerMergeArraysIntoNew(BMS_BLKMEM *blkmem, SCIP_Real epsilon, int *firstrow, int *firstcol, SCIP_Real *firstval, int firstlength, int *secondrow, int *secondcol, SCIP_Real *secondval, int secondlength, int *targetrow, int *targetcol, SCIP_Real *targetval, int *targetlength)
Definition: SdpVarfixer.c:253
interface methods for eigenvector computation and matrix multiplication using openblas ...
static SCIP_RETCODE checkSlaterCondition(SCIP_SDPI *sdpi, SCIP_Real timelimit, clock_t starttime, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int **indchanges, int *nremovedinds, SCIP_Real *lplhsafterfix, SCIP_Real *lprhsafterfix, int *rowsnactivevars, int *blockindchanges, int sdpconstnnonz, int nactivelpcons, int nremovedblocks, SCIP_Bool rootnodefailed)
Definition: sdpi.c:986
struct SCIP_SDPiSolver SCIP_SDPISOLVER
Definition: sdpisolver.h:70
SCIP_RETCODE SCIPsdpiGetRealpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, SCIP_Real *dval)
Definition: sdpi.c:4026
static SCIP_RETCODE compConstMatAfterFixings(SCIP_SDPI *sdpi, int *sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval)
Definition: sdpi.c:264
SCIP_Real SCIPsdpiGetDefaultSdpiSolverGaptol(void)
Definition: sdpi.c:1412
SCIP_RETCODE SCIPsdpiGetPreoptimalPrimalNonzeros(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz)
Definition: sdpi.c:3379
#define CHECK_IF_SOLVED(sdpi)
Definition: sdpi.c:69
#define DEFAULT_EPSILON
Definition: sdpi.c:136
enum SCIP_SDPParam SCIP_SDPPARAM
Definition: type_sdpi.h:69
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverFree(SCIP_SDPISOLVER **sdpisolver)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetPreoptimalPrimalNonzeros(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz)
SCIP_RETCODE SCIPsdpiGetNLPRows(SCIP_SDPI *sdpi, int *nlprows)
Definition: sdpi.c:2259
SCIP_RETCODE SCIPsdpiGetLhSides(SCIP_SDPI *sdpi, int firstrow, int lastrow, SCIP_Real *lhss)
Definition: sdpi.c:2393
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetIterations(SCIP_SDPISOLVER *sdpisolver, int *iterations)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsInfinity(SCIP_SDPISOLVER *sdpisolver, SCIP_Real val)
SCIP_RETCODE SCIPsdpiGetPrimalBoundVars(SCIP_SDPI *sdpi, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
Definition: sdpi.c:3491
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsPrimalFeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverComputeLambdastar(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxguess)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsDualUnbounded(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiSolvedOrig(SCIP_SDPI *sdpi)
Definition: sdpi.c:2865
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsPrimalUnbounded(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSlater(SCIP_SDPI *sdpi, SCIP_SDPSLATER *primalslater, SCIP_SDPSLATER *dualslater)
Definition: sdpi.c:3962
#define SCIP_CALL_PARAM(x)
Definition: sdpi.c:101
static SCIP_RETCODE computeLpLhsRhsAfterFixings(SCIP_SDPI *sdpi, int *nactivelpcons, SCIP_Real *lplhsafterfix, SCIP_Real *lprhsafterfix, int *rownactivevars, SCIP_Bool *fixingsfound)
Definition: sdpi.c:505
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsIterlimExc(SCIP_SDPISOLVER *sdpisolver)