SCIP-SDP  3.1.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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-2018 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-2018 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.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  * Local Functions
207  */
208 
213 static
215  int* i,
216  int* j
217  )
218 {
219  if ( *i < *j )
220  {
221  int temp;
222  temp = *i;
223  *i = *j;
224  *j = temp;
225  }
226 }
227 
228 #ifndef NDEBUG
229 
230 static
231 SCIP_Bool isFixed(
232  SCIP_SDPI* sdpi,
233  int v
234  )
235 {
236  SCIP_Real lb;
237  SCIP_Real ub;
238 
239  assert ( sdpi != NULL );
240  assert ( v < sdpi->nvars );
241  assert ( sdpi->lb != NULL );
242  assert ( sdpi->ub != NULL );
243 
244  lb = sdpi->lb[v];
245  ub = sdpi->ub[v];
246 
247  assert( lb < ub + sdpi->feastol || sdpi->infeasible );
248 
249  return ( ub-lb <= sdpi->epsilon );
250 }
251 #else
252 #define isFixed(sdpi, v) (sdpi->ub[v] - sdpi->lb[v] <= sdpi->epsilon)
253 #endif
254 
262 static
264  SCIP_SDPI* sdpi,
265  int* sdpconstnnonz,
266  int* sdpconstnblocknonz,
268  int** sdpconstrow,
269  int** sdpconstcol,
270  SCIP_Real** sdpconstval
271  )
272 {
273  int i;
274  int v;
275  int block;
276  int* nfixednonz;
277  int** fixedrows;
278  int** fixedcols;
279  SCIP_Real** fixedvals;
280 
281  assert ( sdpi != NULL );
282  assert ( sdpconstnnonz != NULL );
283  assert ( sdpconstnblocknonz != NULL );
284  assert ( sdpconstrow != NULL );
285  assert ( sdpconstcol != NULL );
286  assert ( sdpconstval != NULL );
287 #ifndef NDEBUG
288  for (block = 0; block < sdpi->nsdpblocks; block++)
289  {
290  assert ( sdpconstrow[block] != NULL );
291  assert ( sdpconstcol[block] != NULL );
292  assert ( sdpconstval[block] != NULL );
293  }
294 #endif
295 
296  fixedrows = NULL;
297  fixedcols = NULL;
298  fixedvals = NULL;
299 
300  /* allocate memory for the nonzeros that need to be fixed, as this is only temporarly needed, we allocate as much as theoretically possible */
301  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &nfixednonz, sdpi->nsdpblocks) );
302  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &fixedrows, sdpi->nsdpblocks) );
303  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &fixedcols, sdpi->nsdpblocks) );
304  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &fixedvals, sdpi->nsdpblocks) );
305 
306  for (block = 0; block < sdpi->nsdpblocks; block++)
307  {
308  /* compute the number of fixed nonzeros in this block */
309  nfixednonz[block] = 0;
310  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
311  {
312  if (isFixed(sdpi, sdpi->sdpvar[block][v]))
313  nfixednonz[block] += sdpi->sdpnblockvarnonz[block][v];
314  }
315 
316  fixedrows[block] = NULL;
317  fixedcols[block] = NULL;
318  fixedvals[block] = NULL;
319 
320  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(fixedrows[block]), nfixednonz[block]) );
321  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(fixedcols[block]), nfixednonz[block]) );
322  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(fixedvals[block]), nfixednonz[block]) );
323 
324  /* 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) */
325  nfixednonz[block] = 0;
326  }
327 
328  /* iterate over all variables, saving the nonzeros of the fixed ones */
329  for (block = 0; block < sdpi->nsdpblocks; block++)
330  {
331  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
332  {
333  if (isFixed(sdpi, sdpi->sdpvar[block][v]))
334  {
335  for (i = 0; i < sdpi->sdpnblockvarnonz[block][v]; i++)
336  {
337  fixedrows[block][nfixednonz[block]] = sdpi->sdprow[block][v][i];
338  fixedcols[block][nfixednonz[block]] = sdpi->sdpcol[block][v][i];
339  /* this is the final value to add, so we no longer have to remember, from which variable this nonzero comes,
340  * the -1 comes from +y_iA_i but -A_0 */
341  fixedvals[block][nfixednonz[block]] = - sdpi->sdpval[block][v][i] * sdpi->lb[sdpi->sdpvar[block][v]];
342  nfixednonz[block]++;
343  }
344  }
345  }
346  }
347 
348  /* compute the constant matrix */
349  *sdpconstnnonz = 0;
350  for (block = 0; block < sdpi->nsdpblocks; block++)
351  {
352  SCIP_CALL( SCIPsdpVarfixerMergeArraysIntoNew(sdpi->blkmem, sdpi->epsilon, sdpi->sdpconstrow[block], sdpi->sdpconstcol[block], sdpi->sdpconstval[block],
353  sdpi->sdpconstnblocknonz[block], fixedrows[block], fixedcols[block], fixedvals[block], nfixednonz[block],
354  sdpconstrow[block], sdpconstcol[block], sdpconstval[block], &sdpconstnblocknonz[block]) );
355  *sdpconstnnonz += sdpconstnblocknonz[block];
356  }
357 
358  /* free all memory */
359  for (block = 0; block < sdpi->nsdpblocks; block++)
360  {
361  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(fixedvals[block]), nfixednonz[block]);
362  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(fixedcols[block]), nfixednonz[block]);
363  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(fixedrows[block]), nfixednonz[block]);
364  }
365  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &fixedvals, sdpi->nsdpblocks);
366  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &fixedcols, sdpi->nsdpblocks);
367  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &fixedrows, sdpi->nsdpblocks);
368  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &nfixednonz, sdpi->nsdpblocks);
369 
370  return SCIP_OKAY;
371 }
372 
376 static
377 SCIP_RETCODE findEmptyRowColsSDP(
378  SCIP_SDPI* sdpi,
379  int* sdpconstnblocknonz,
381  int** sdpconstrow,
382  int** sdpconstcol,
383  SCIP_Real** sdpconstval,
384  int** indchanges,
388  int* nremovedinds,
389  int* blockindchanges,
390  int* nremovedblocks
391  )
392 {
393  int block;
394  int v;
395  int i;
396  int nfoundinds;
397 
398  assert( sdpi != NULL );
399  assert( sdpconstnblocknonz != NULL );
400  assert( sdpconstrow != NULL );
401  assert( sdpconstcol != NULL );
402  assert( sdpconstval != NULL );
403  assert( indchanges != NULL );
404  assert( nremovedinds != NULL );
405  assert( blockindchanges != NULL );
406  assert( nremovedblocks != NULL );
407 
408  /* initialize indchanges with -1 */
409  for (block = 0; block < sdpi->nsdpblocks; block++)
410  {
411  for (i = 0; i < sdpi->sdpblocksizes[block]; i++)
412  indchanges[block][i] = -1;
413  }
414  *nremovedblocks = 0;
415 
416  /* 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
417  * index is still needed, it will later be set to the number of rows/cols deleted earlier) */
418  for (block = 0; block < sdpi->nsdpblocks; block++)
419  {
420  /* the number of indices already found in this block, saved for prematurely stopping the loops */
421  nfoundinds = 0;
422  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
423  {
424  if ( ! (isFixed(sdpi, sdpi->sdpvar[block][v])) )
425  {
426  for (i = 0; i < sdpi->sdpnblockvarnonz[block][v]; i++)
427  {
428  assert ( REALABS(sdpi->sdpval[block][v][i]) > sdpi->epsilon); /* this should really be a nonzero */
429  if ( indchanges[block][sdpi->sdprow[block][v][i]] == -1 )
430  {
431  indchanges[block][sdpi->sdprow[block][v][i]] = 1;
432  nfoundinds++;
433  }
434  if ( indchanges[block][sdpi->sdpcol[block][v][i]] == -1 )
435  {
436  indchanges[block][sdpi->sdpcol[block][v][i]] = 1;
437  nfoundinds++;
438  }
439  if ( nfoundinds == sdpi->sdpblocksizes[block] )
440  break; /* we're done for this block */
441  }
442  }
443  if (nfoundinds == sdpi->sdpblocksizes[block])
444  break; /* we're done for this block */
445  }
446 
447  if ( nfoundinds < sdpi->sdpblocksizes[block] )
448  {
449  /* if some indices haven't been found yet, look in the constant part for them */
450  for (i = 0; i < sdpconstnblocknonz[block]; i++)
451  {
452  assert ( REALABS(sdpconstval[block][i]) > sdpi->epsilon); /* this should really be a nonzero */
453  if ( indchanges[block][sdpconstrow[block][i]] == -1 )
454  {
455  indchanges[block][sdpconstrow[block][i]] = 1;
456  nfoundinds++;
457  }
458  if ( indchanges[block][sdpconstcol[block][i]] == -1 )
459  {
460  indchanges[block][sdpconstcol[block][i]] = 1;
461  nfoundinds++;
462  }
463  if ( nfoundinds == sdpi->sdpblocksizes[block] )
464  break; /* we're done for this block */
465  }
466  }
467 
468  /* 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 */
469  nremovedinds[block] = 0;
470  for (i = 0; i < sdpi->sdpblocksizes[block]; i++)
471  {
472  if ( indchanges[block][i] == -1 )
473  {
474  SCIPdebugMessage("empty row and col %d were removed from block %d of SDP %d\n", i, block, sdpi->sdpid);
475  /* this index wasn't found (indchanges was initialized with 0), so it can be removed */
476  nremovedinds[block]++;
477  }
478  else
479  {
480  /* this index has been found, so set the value to the number of removed inds before it */
481  indchanges[block][i] = nremovedinds[block];
482  }
483  }
484 
485  /* check if the block became empty */
486  if ( nremovedinds[block] == sdpi->sdpblocksizes[block] )
487  {
488  SCIPdebugMessage("empty block %d detected in SDP %d, this will be removed", block, sdpi->sdpid);
489  blockindchanges[block] = -1;
490  (*nremovedblocks)++;
491  }
492  else
493  blockindchanges[block] = *nremovedblocks;
494  }
495 
496  return SCIP_OKAY;
497 }
498 
503 static
505  SCIP_SDPI* sdpi,
506  int* nactivelpcons,
507  SCIP_Real* lplhsafterfix,
511  SCIP_Real* lprhsafterfix,
515  int* rownactivevars,
516  SCIP_Bool* fixingsfound
517  )
518 {
519  int i;
520  int c;
521  int lastrow = -1;
522  int nonzind = -1;
523  int nonzcol = -1;
524  SCIP_Real nonzval;
525 
526  assert( sdpi != NULL );
527  assert( nactivelpcons != NULL );
528  assert( sdpi->nlpcons == 0 || lplhsafterfix != NULL );
529  assert( sdpi->nlpcons == 0 || lprhsafterfix != NULL );
530  assert( sdpi->nlpcons == 0 || rownactivevars != NULL );
531  assert( sdpi->nlpcons == 0 || fixingsfound != NULL );
532 
533  /* if there is no LP-part, there is nothing to do */
534  if ( sdpi->nlpcons == 0 || sdpi->lpnnonz == 0 )
535  {
536  *nactivelpcons = 0;
537  return SCIP_OKAY;
538  }
539 
540  /* initialize rownactivevars */
541  for (c = 0; c < sdpi->nlpcons; c++)
542  rownactivevars[c] = 0;
543  *nactivelpcons = 0;
544 
545  for (i = 0; i < sdpi->lpnnonz; i++)
546  {
547  assert( i == 0 || sdpi->lprow[i-1] <= sdpi->lprow[i] );
548 
549  /* we reached a new row */
550  if ( sdpi->lprow[i] > lastrow )
551  {
552  /* if the last row had at least two active variables, we keep the lhs- and rhs-value */
553  if ( lastrow >= 0 && rownactivevars[lastrow] > 1 )
554  (*nactivelpcons)++;
555  else if ( lastrow >= 0 && rownactivevars[lastrow] == 1 )
556  {
557  assert( 0 <= nonzind && nonzind < sdpi->lpnnonz );
558 
559  nonzcol = sdpi->lpcol[nonzind];
560  assert( 0 <= nonzcol && nonzcol < sdpi->nvars );
561 
562  nonzval = sdpi->lpval[nonzind];
563  assert( REALABS(nonzval) > sdpi->epsilon );
564 
565  /* we have to check if this is an improvement of the current bound */
566  if ( nonzval < 0.0 ) /* we have to compare with the upper bound for lhs and lower bound for rhs */
567  {
568  /* check for the left-hand-side */
569  if ( (lplhsafterfix[*nactivelpcons] > - SCIPsdpiInfinity(sdpi)) &&
570  ( (lplhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->epsilon) )
571  {
572  /* this bound is sharper than the original one */
573  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
574  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
575  sdpi->ub[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
576 
577  /* check if this leads to a fixing of this variable */
578  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
579  {
580  *fixingsfound = TRUE;
581  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
582  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
583  }
584  /* check if this makes the problem infeasible */
585  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
586  {
587  sdpi->infeasible = TRUE;
588  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
589  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
590  return SCIP_OKAY;
591  }
592  }
593  /* check for the right-hand-side */
594  if ( (lprhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
595  ( (lprhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] + sdpi->epsilon) )
596  {
597  /* this bound is sharper than the original one */
598  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
599  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
600  sdpi->lb[nonzcol] = lprhsafterfix[*nactivelpcons] / nonzval;
601 
602  /* check if this leads to a fixing of this variable */
603  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
604  {
605  *fixingsfound = TRUE;
606  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
607  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
608  }
609 
610  /* check if this makes the problem infeasible */
611  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
612  {
613  sdpi->infeasible = TRUE;
614  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
615  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
616  return SCIP_OKAY;
617  }
618  }
619  }
620  else /* we compare with the lower bound for lhs and upper bound for rhs */
621  {
622  /* check for the left-hand-side */
623  if ( (lplhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
624  ( (lplhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] + sdpi->epsilon) )
625  {
626  /* this bound is sharper than the original one */
627  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
628  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
629  sdpi->lb[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
630 
631  /* check if this leads to a fixing of this variable */
632  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
633  {
634  *fixingsfound = TRUE;
635  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
636  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
637  }
638 
639  /* check if this makes the problem infeasible */
640  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
641  {
642  sdpi->infeasible = TRUE;
643  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
644  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
645  return SCIP_OKAY;
646  }
647  }
648  /* check for the right-hand-side */
649  if ( (lprhsafterfix[*nactivelpcons] > - SCIPsdpiInfinity(sdpi)) &&
650  ( (lprhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->epsilon) )
651  {
652  /* this bound is sharper than the original one */
653  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
654  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
655  sdpi->ub[nonzcol] = lprhsafterfix[*nactivelpcons] / nonzval;
656 
657  /* check if this leads to a fixing of this variable */
658  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
659  {
660  *fixingsfound = TRUE;
661  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
662  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
663  }
664 
665  /* check if this makes the problem infeasible */
666  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
667  {
668  sdpi->infeasible = TRUE;
669  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
670  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
671  return SCIP_OKAY;
672  }
673  }
674  }
675  }
676  else if ( lastrow >= 0 ) /* because of earlier ifs we have rownactivevars = 0 */
677  {
678  assert( lastrow == -1 || rownactivevars[lastrow] == 0 );
679  /* we have a constraint lhs <= 0 <= rhs, so lhs should be non-positive and rhs non-negative, otherwise the problem is infeasible */
680  if ( lplhsafterfix[*nactivelpcons] > sdpi->feastol || lprhsafterfix[*nactivelpcons] < -sdpi->feastol )
681  {
682  sdpi->infeasible = TRUE;
683  SCIPdebugMessage("We found a constraint which with given fixings reads %f <= 0 <= %f, so the current problem is infeasible !\n",
684  lplhsafterfix[*nactivelpcons], lprhsafterfix[*nactivelpcons] );
685  return SCIP_OKAY;
686  }
687  }
688 
689  /* update lastrow for new row */
690  lastrow = sdpi->lprow[i];
691 
692  /* start the next lhr & rhs with the original value */
693  lplhsafterfix[*nactivelpcons] = sdpi->lplhs[lastrow];
694  lprhsafterfix[*nactivelpcons] = sdpi->lprhs[lastrow];
695  }
696 
697  /* if the variable is active, we increase rownactivevars */
698  if ( ! isFixed(sdpi, sdpi->lpcol[i]) )
699  {
700  rownactivevars[lastrow]++;
701  nonzind = i;
702  }
703  else
704  {
705  /* otherwise we add the value (coefficient * value of fixed variable) to the lhs and rhs, the minus comes from +A_i but -A_0 */
706  lplhsafterfix[*nactivelpcons] -= sdpi->lpval[i] * sdpi->lb[sdpi->lpcol[i]];
707  lprhsafterfix[*nactivelpcons] -= sdpi->lpval[i] * sdpi->lb[sdpi->lpcol[i]];
708  }
709  }
710 
711  /* 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 */
712  if ( rownactivevars[lastrow] > 1 )
713  (*nactivelpcons)++;
714  else if ( rownactivevars[lastrow] == 1 )
715  {
716  assert( 0 <= nonzind && nonzind < sdpi->lpnnonz );
717 
718  nonzcol = sdpi->lpcol[nonzind];
719  assert( 0 <= nonzcol && nonzcol < sdpi->nvars );
720 
721  nonzval = sdpi->lpval[nonzind];
722  assert( REALABS(nonzval) > sdpi->epsilon );
723 
724  /* we have to check if this is an improvement of the current bound */
725  if ( nonzval < 0.0 ) /* we have to compare with the upper bound for lhs and lower bound for rhs */
726  {
727  /* check for the left-hand-side */
728  if ( (lplhsafterfix[*nactivelpcons] > SCIPsdpiInfinity(sdpi)) &&
729  ( (lplhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->epsilon) )
730  {
731  /* this bound is sharper than the original one */
732  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
733  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
734  sdpi->ub[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
735 
736  /* check if this leads to a fixing of this variable */
737  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
738  {
739  *fixingsfound = TRUE;
740  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
741  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
742  }
743 
744  /* check if this makes the problem infeasible */
745  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
746  {
747  sdpi->infeasible = TRUE;
748  SCIPdebugMessage("We found an upper bound that is lower than the lower bound, so the problem is infeasible !\n");
749  return SCIP_OKAY;
750  }
751  }
752  /* check for the right-hand-side */
753  if ( (lprhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
754  ( (lprhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] - sdpi->epsilon) )
755  {
756  /* this bound is sharper than the original one */
757  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
758  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
759  sdpi->lb[nonzcol] = lprhsafterfix[*nactivelpcons] / nonzval;
760 
761  /* check if this leads to a fixing of this variable */
762  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
763  {
764  *fixingsfound = TRUE;
765  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
766  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
767  }
768 
769  /* check if this makes the problem infeasible */
770  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
771  {
772  sdpi->infeasible = TRUE;
773  SCIPdebugMessage("We found an upper bound that is lower than the lower bound, so the problem is infeasible !\n");
774  return SCIP_OKAY;
775  }
776  }
777  }
778  else /* we compare with the lower bound for lhs and upper bound for rhs */
779  {
780  /* check for the left-hand-side */
781  if ( (lplhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
782  ( (lplhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] + sdpi->epsilon) )
783  {
784  /* this bound is sharper than the original one */
785  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
786  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
787  sdpi->lb[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
788 
789  /* check if this leads to a fixing of this variable */
790  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
791  {
792  *fixingsfound = TRUE;
793  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
794  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
795  }
796 
797  /* check if this makes the problem infeasible */
798  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
799  {
800  sdpi->infeasible = TRUE;
801  SCIPdebugMessage("We found a lower bound that is bigger than the upper bound, so the problem is infeasible !\n");
802  return SCIP_OKAY;
803  }
804  }
805  /* check for the right-hand-side */
806  if ( (lprhsafterfix[*nactivelpcons] > SCIPsdpiInfinity(sdpi)) &&
807  ( (lprhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->epsilon) )
808  {
809  /* this bound is sharper than the original one */
810  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
811  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
812  sdpi->ub[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
813 
814  /* check if this leads to a fixing of this variable */
815  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->epsilon )
816  {
817  *fixingsfound = TRUE;
818  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
819  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
820  }
821 
822  /* check if this makes the problem infeasible */
823  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
824  {
825  sdpi->infeasible = TRUE;
826  SCIPdebugMessage("We found an upper bound that is lower than the lower bound, so the problem is infeasible !\n");
827  return SCIP_OKAY;
828  }
829  }
830  }
831  }
832  else
833  {
834  assert( lastrow == -1 || rownactivevars[lastrow] == 0 );
835  /* we have a constraint lhs <= 0 <= rhs, so lhs should be non-positive and rhs non-negative, otherwise the problem is infeasible */
836  if ( lplhsafterfix[*nactivelpcons] > sdpi->feastol || lprhsafterfix[*nactivelpcons] < -sdpi->feastol )
837  {
838  sdpi->infeasible = TRUE;
839  SCIPdebugMessage("We found a constraint which with given fixings reads %f <= 0 <= %f, so the current problem is infeasible !\n",
840  lplhsafterfix[*nactivelpcons], lprhsafterfix[*nactivelpcons] );
841  return SCIP_OKAY;
842  }
843  }
844 
845  return SCIP_OKAY;
846 }
847 
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 
2453 SCIP_RETCODE SCIPsdpiSolve(
2454  SCIP_SDPI* sdpi,
2455  SCIP_Real* starty,
2456  int* startZnblocknonz,
2458  int** startZrow,
2460  int** startZcol,
2462  SCIP_Real** startZval,
2464  int* startXnblocknonz,
2466  int** startXrow,
2468  int** startXcol,
2470  SCIP_Real** startXval,
2472  SCIP_SDPSOLVERSETTING startsettings,
2474  SCIP_Bool enforceslatercheck,
2476  SCIP_Real timelimit
2477  )
2478 {
2479  int* sdpconstnblocknonz = NULL;
2480  int** sdpconstrow = NULL;
2481  int** sdpconstcol = NULL;
2482  SCIP_Real** sdpconstval = NULL;
2483  int** indchanges = NULL;
2484  int* nremovedinds = NULL;
2485  SCIP_Real* lplhsafterfix;
2486  SCIP_Real* lprhsafterfix;
2487  SCIP_Real solvertimelimit;
2488  SCIP_Bool fixingfound;
2489  clock_t starttime;
2490  clock_t currenttime;
2491  int* rowsnactivevars;
2492  int* blockindchanges;
2493  int sdpconstnnonz;
2494  int nactivelpcons;
2495  int nremovedblocks = 0;
2496  int block;
2497  int naddediterations;
2498  int naddedsdpcalls;
2499 
2500  assert( sdpi != NULL );
2501 
2502  starttime = clock();
2503 
2504  SCIPdebugMessage("Forwarding SDP %d to solver!\n", sdpi->sdpid);
2505 
2506  sdpi->penalty = FALSE;
2507  sdpi->bestbound = -SCIPsdpiSolverInfinity(sdpi->sdpisolver);
2508  sdpi->solved = FALSE;
2509  sdpi->nsdpcalls = 0;
2510  sdpi->niterations = 0;
2511 
2512  /* allocate memory for computing the constant matrix after fixings and finding empty rows and columns, this is as much as might possibly be
2513  * needed, this will be shrinked again before solving */
2514  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstnblocknonz, sdpi->nsdpblocks) );
2515  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstrow, sdpi->nsdpblocks) );
2516  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstcol, sdpi->nsdpblocks) );
2517  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstval, sdpi->nsdpblocks) );
2518  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &indchanges, sdpi->nsdpblocks) );
2519  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &nremovedinds, sdpi->nsdpblocks) );
2520  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &blockindchanges, sdpi->nsdpblocks) );
2521  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &lplhsafterfix, sdpi->nlpcons) );
2522  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &lprhsafterfix, sdpi->nlpcons) );
2523  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &rowsnactivevars, sdpi->nlpcons) );
2524 
2525  for (block = 0; block < sdpi->nsdpblocks; block++)
2526  {
2527  sdpconstrow[block] = NULL;
2528  sdpconstcol[block] = NULL;
2529  sdpconstval[block] = NULL;
2530  indchanges[block] = NULL;
2531  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(indchanges[block]), sdpi->sdpblocksizes[block]) );
2532  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
2533  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
2534  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
2535  }
2536 
2537  /* compute the lplphss and lprhss, detect empty rows and check for additional variable fixings caused by boundchanges from
2538  * lp rows with a single active variable */
2539  do
2540  {
2541  fixingfound = FALSE;
2542  SCIP_CALL( computeLpLhsRhsAfterFixings(sdpi, &nactivelpcons, lplhsafterfix, lprhsafterfix, rowsnactivevars, &fixingfound) );
2543  }
2544  while ( fixingfound );
2545 
2546  /* initialize sdpconstnblocknonz */
2547  for (block = 0; block < sdpi->nsdpblocks; block++)
2548  sdpconstnblocknonz[block] = sdpi->sdpnnonz + sdpi->sdpconstnnonz;
2549 
2550  SCIP_CALL( compConstMatAfterFixings(sdpi, &sdpconstnnonz, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval) );
2551 
2552  /* shrink the constant arrays after the number of fixed nonzeros is known */
2553  for (block = 0; block < sdpi->nsdpblocks; block++)
2554  {
2555  assert ( sdpconstnblocknonz[block] <= sdpi->sdpnnonz + sdpi->sdpconstnnonz ); /* otherwise the memory wasn't sufficient,
2556  * but we allocated more than enough */
2557  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
2558  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
2559  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
2560  }
2561 
2562  SCIP_CALL( findEmptyRowColsSDP(sdpi, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges, nremovedinds, blockindchanges, &nremovedblocks) );
2563 
2564  /* 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,
2565  * the linear constraints were already checked in computeLpLhsRhsAfterFixings) */
2566  SCIP_CALL( checkAllFixed(sdpi) );
2567  if ( sdpi->allfixed && ! sdpi->infeasible )
2568  {
2569  SCIP_CALL( checkFixedFeasibilitySdp(sdpi, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges, nremovedinds, blockindchanges) );
2570  }
2571 
2572  if ( sdpi->infeasible )
2573  {
2574  SCIPdebugMessage("SDP %d not given to solver, as infeasibility was detected during presolving!\n", sdpi->sdpid++);
2575  SCIP_CALL( SCIPsdpiSolverIncreaseCounter(sdpi->sdpisolver) );
2576 
2577  sdpi->solved = TRUE;
2578  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2579  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2580  }
2581  else if ( sdpi->allfixed )
2582  {
2583  SCIPdebugMessage("SDP %d not given to solver, as all variables were fixed during presolving (the solution was feasible)!\n", sdpi->sdpid++);
2584  SCIP_CALL( SCIPsdpiSolverIncreaseCounter(sdpi->sdpisolver) );
2585 
2586  sdpi->solved = TRUE;
2587  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2588  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2589  }
2590  else
2591  {
2592  if ( sdpi->slatercheck )
2593  {
2594  SCIP_CALL( checkSlaterCondition(sdpi, timelimit, starttime, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges,
2595  nremovedinds, lplhsafterfix, lprhsafterfix, rowsnactivevars, blockindchanges, sdpconstnnonz, nactivelpcons, nremovedblocks, FALSE) );
2596  }
2597 
2598  /* compute the timit limit to set for the solver */
2599  solvertimelimit = timelimit;
2600  if ( ! SCIPsdpiIsInfinity(sdpi, solvertimelimit) )
2601  {
2602  currenttime = clock();
2603  solvertimelimit -= (SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC;/*lint !e620*/
2604  }
2605 
2606  /* try to solve the problem */
2607  SCIP_CALL( SCIPsdpiSolverLoadAndSolve(sdpi->sdpisolver, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
2608  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2609  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2610  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2611  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
2612  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2613  startXnblocknonz, startXrow, startXcol, startXval, startsettings, solvertimelimit) );
2614 
2615  sdpi->solved = TRUE;
2616 
2617  /* add iterations and sdpcalls */
2618  naddediterations = 0;
2619  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2620  sdpi->niterations += naddediterations;
2621  naddedsdpcalls = 0;
2622  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2623  sdpi->nsdpcalls += naddedsdpcalls;
2624 
2625  /* if the solver didn't produce a satisfactory result, we have to try with a penalty formulation */
2626  if ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && ! SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver) )
2627  {
2628  SCIP_Real penaltyparam;
2629  SCIP_Real penaltyparamfact;
2630  SCIP_Real gaptol;
2631  SCIP_Real gaptolfact;
2632  SCIP_Bool feasorig;
2633  SCIP_Bool penaltybound;
2634  SCIP_Real objbound;
2635  SCIP_Real objval;
2636 
2637  feasorig = FALSE;
2638  penaltybound = TRUE;
2639 
2640  /* first check feasibility using the penalty approach */
2641 
2642  /* compute the timit limit to set for the solver */
2643  solvertimelimit = timelimit;
2644  if ( ! SCIPsdpiIsInfinity(sdpi, solvertimelimit) )
2645  {
2646  currenttime = clock();
2647  solvertimelimit -= (SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC;/*lint !e620*/
2648  }
2649 
2650  /* we solve the problem with a slack variable times identity added to the constraints and trying to minimize this slack variable r, if
2651  * the optimal objective is bigger than feastol, then we know that the problem is infeasible */
2652  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, 1.0, FALSE, FALSE, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
2653  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2654  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2655  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2656  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
2657  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2658  startXnblocknonz, startXrow, startXcol, startXval, SCIP_SDPSOLVERSETTING_UNSOLVED, solvertimelimit, &feasorig, &penaltybound) );
2659 
2660  /* add iterations and sdpcalls */
2661  naddediterations = 0;
2662  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2663  sdpi->niterations += naddediterations;
2664  naddedsdpcalls = 0;
2665  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2666  sdpi->nsdpcalls += naddedsdpcalls;
2667 
2668  /* get objective value */
2669  if ( SCIPsdpiSolverWasSolved(sdpi->sdpisolver) )
2670  {
2671  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) );
2672  }
2673  else
2674  objval = -SCIPsdpiInfinity(sdpi);
2675 
2676  /* If the penalty formulation was successfully solved and has a strictly positive objective value, we know that
2677  * the problem is infeasible. Note that we need to check against the maximum of feastol and gaptol, since this
2678  * is the objective of an SDP which is only exact up to gaptol, and cutting a feasible node off is an error
2679  * while continueing with an infeasible problem only takes additional time until we found out again later.
2680  */
2681  if ( (SCIPsdpiSolverIsOptimal(sdpi->sdpisolver) && (objval > (sdpi->feastol > sdpi->gaptol ?
2682  sdpi->peninfeasadjust * sdpi->feastol : sdpi->peninfeasadjust * sdpi->gaptol))) ||
2683  (SCIPsdpiSolverWasSolved(sdpi->sdpisolver) && SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver)) )
2684  {
2685  SCIPdebugMessage("SDP %d found infeasible using penalty formulation, maximum of smallest eigenvalue is %f.\n", sdpi->sdpid, -1.0 * objval);
2686  sdpi->penalty = TRUE;
2687  sdpi->infeasible = TRUE;
2688  }
2689  else
2690  {
2691  feasorig = FALSE;
2692  penaltybound = TRUE;
2693 
2694  penaltyparam = sdpi->penaltyparam;
2695 
2696  /* 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
2697  * (for npenaltyincr = 0 we make sure that the parameter is too large after the first change)
2698  */
2699  penaltyparamfact = sdpi->npenaltyincr > 0 ? pow((sdpi->maxpenaltyparam / sdpi->penaltyparam), 1.0/sdpi->npenaltyincr) :
2700  2*sdpi->maxpenaltyparam / sdpi->penaltyparam;
2701  gaptol = sdpi->gaptol;
2702  gaptolfact = sdpi->npenaltyincr > 0 ? pow((MIN_GAPTOL / sdpi->gaptol), 1.0/sdpi->npenaltyincr) : 0.5 * MIN_GAPTOL / sdpi->gaptol;
2703 
2704  /* increase penalty-param and decrease feasibility tolerance until we find a feasible solution or reach the final bound for either one of them */
2705  while ( ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) || ! feasorig ) &&
2706  ( penaltyparam < sdpi->maxpenaltyparam + sdpi->epsilon ) && ( gaptol > 0.99 * MIN_GAPTOL ) && ( ! SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver) ))
2707  {
2708  SCIPdebugMessage("Solver did not produce an acceptable result, trying SDP %d again with penaltyparameter %f\n", sdpi->sdpid, penaltyparam);
2709 
2710  /* compute the timit limit to set for the solver */
2711  solvertimelimit = timelimit;
2712  if ( ! SCIPsdpiIsInfinity(sdpi, solvertimelimit) )
2713  {
2714  currenttime = clock();
2715  solvertimelimit -= (SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC;/*lint !e620*/
2716 
2717  if ( solvertimelimit <= 0 )
2718  break;
2719  }
2720 
2721  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, penaltyparam, TRUE, TRUE, sdpi->nvars, sdpi->obj,
2722  sdpi->lb, sdpi->ub, sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2723  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2724  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2725  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
2726  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2727  startXnblocknonz, startXrow, startXcol, startXval, startsettings, solvertimelimit, &feasorig, &penaltybound) );
2728 
2729  /* add iterations and sdpcalls */
2730  naddediterations = 0;
2731  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2732  sdpi->niterations += naddediterations;
2733  naddedsdpcalls = 0;
2734  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2735  sdpi->nsdpcalls += naddedsdpcalls;
2736 
2737  /* If the solver did not converge, we increase the penalty parameter */
2738  if ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) )
2739  {
2740  penaltyparam *= penaltyparamfact;
2741  SCIPdebugMessage("Solver did not converge even with penalty formulation, increasing penaltyparameter.\n");
2742  continue;
2743  }
2744 
2745  /* if we succeeded to solve the problem, update the bound */
2746  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objbound) );
2747  if ( objbound > sdpi->bestbound + sdpi->gaptol )
2748  sdpi->bestbound = objbound;
2749 
2750  /* If we don't get a feasible solution to our original problem we have to update either Gamma (if the penalty bound was active
2751  * in the primal problem) or gaptol (otherwise) */
2752  if ( ! feasorig )
2753  {
2754  if ( penaltybound )
2755  {
2756  penaltyparam *= penaltyparamfact;
2757  SCIPdebugMessage("Penalty formulation produced a result which is infeasible for the original problem, increasing penaltyparameter\n");
2758  }
2759  else
2760  {
2761  gaptol *= gaptolfact;
2762  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, SCIP_SDPPAR_GAPTOL, gaptol) );
2763  SCIPdebugMessage("Penalty formulation produced a result which is infeasible for the original problem, even though primal penalty "
2764  "bound was not reached, decreasing tolerance for duality gap in SDP-solver\n");
2765  }
2766  }
2767  }
2768 
2769  /* reset the tolerance in the SDP-solver */
2770  if ( gaptol > sdpi->gaptol )
2771  {
2772  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, SCIP_SDPPAR_GAPTOL, sdpi->gaptol) );
2773  }
2774 
2775  /* check if we were able to solve the problem in the end */
2776  if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && feasorig )
2777  {
2778  sdpi->penalty = TRUE;
2779  sdpi->solved = TRUE;
2780  }
2781 #if 0 /* we don't really know if it is infeasible or just ill-posed (no KKT-point) */
2782  else if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && ! feasorig )
2783  {
2784  SCIPdebugMessage("Problem was found to be infeasible using a penalty formulation \n");
2785  sdpi->infeasible = TRUE;
2786  sdpi->penalty = TRUE;
2787  sdpi->solved = TRUE;
2788  }
2789 #endif
2790  else
2791  {
2792  SCIPdebugMessage("SDP-Solver could not solve the problem even after using a penalty formulation \n");
2793  sdpi->solved = FALSE;
2794  sdpi->penalty = TRUE;
2795  }
2796 
2797  /* if we still didn't succeed and enforceslatercheck was set, we finally test for the Slater condition to give a reason for failure */
2798  if ( sdpi->solved == FALSE && enforceslatercheck)
2799  {
2800  SCIP_CALL( checkSlaterCondition(sdpi, timelimit, starttime, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges,
2801  nremovedinds, lplhsafterfix, lprhsafterfix, rowsnactivevars, blockindchanges, sdpconstnnonz, nactivelpcons, nremovedblocks, TRUE) );
2802  }
2803  else if ( sdpi->solved == FALSE )
2804  {
2805 #if 0
2806  SCIPmessagePrintInfo(sdpi->messagehdlr, "Numerical trouble\n");
2807 #else
2808  SCIPdebugMessage("SDP-Interface was unable to solve SDP %d\n", sdpi->sdpid);/*lint !e687*/
2809 #endif
2810  }
2811  }
2812  }
2813  }
2814 
2815  /* empty the memory allocated here */
2816  for (block = 0; block < sdpi->nsdpblocks; block++)
2817  {
2818  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpconstnblocknonz[block]);/*lint !e737*/
2819  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpconstnblocknonz[block]);/*lint !e737*/
2820  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpconstnblocknonz[block]);/*lint !e737*/
2821  BMSfreeBlockMemoryArray(sdpi->blkmem, &(indchanges[block]), sdpi->sdpblocksizes[block]);/*lint !e737*/
2822  }
2823  BMSfreeBlockMemoryArray(sdpi->blkmem, &rowsnactivevars, sdpi->nlpcons);/*lint !e737*/
2824  BMSfreeBlockMemoryArray(sdpi->blkmem, &lprhsafterfix, sdpi->nlpcons);/*lint !e737*/
2825  BMSfreeBlockMemoryArray(sdpi->blkmem, &lplhsafterfix, sdpi->nlpcons);/*lint !e737*/
2826  BMSfreeBlockMemoryArray(sdpi->blkmem, &blockindchanges, sdpi->nsdpblocks);/*lint !e737*/
2827  BMSfreeBlockMemoryArray(sdpi->blkmem, &nremovedinds, sdpi->nsdpblocks);/*lint !e737*/
2828  BMSfreeBlockMemoryArray(sdpi->blkmem, &indchanges, sdpi->nsdpblocks);/*lint !e737*/
2829  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstval, sdpi->nsdpblocks);/*lint !e737*/
2830  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstcol, sdpi->nsdpblocks);/*lint !e737*/
2831  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstrow, sdpi->nsdpblocks);/*lint !e737*/
2832  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstnblocknonz, sdpi->nsdpblocks);/*lint !e737*/
2833 
2834  sdpi->sdpid++;
2835 
2836  return SCIP_OKAY;
2837 }
2838 
2839 
2840 
2841 
2842 /*
2843  * Solution Information Methods
2844  */
2845 
2851  SCIP_SDPI* sdpi
2852  )
2853 {
2854  assert( sdpi != NULL );
2855 
2856  return ( sdpi->solved && SCIPsdpiSolverWasSolved(sdpi->sdpisolver) );
2857 }
2858 
2861  SCIP_SDPI* sdpi
2862  )
2863 {
2864  assert( sdpi != NULL );
2865 
2866  return ( SCIPsdpiWasSolved(sdpi) && (! sdpi->penalty) );
2867 }
2868 
2873  SCIP_SDPI* sdpi
2874  )
2875 {
2876  assert( sdpi != NULL );
2877  CHECK_IF_SOLVED_BOOL(sdpi);
2878 
2879  if ( sdpi->infeasible || sdpi->allfixed )
2880  return TRUE;
2881 
2882  return SCIPsdpiSolverFeasibilityKnown(sdpi->sdpisolver);
2883 }
2884 
2887  SCIP_SDPI* sdpi,
2888  SCIP_Bool* primalfeasible,
2889  SCIP_Bool* dualfeasible
2890  )
2891 {
2892  assert( sdpi != NULL );
2893  CHECK_IF_SOLVED(sdpi);
2894 
2895  if ( sdpi->infeasible )
2896  {
2897  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2898  *dualfeasible = FALSE;
2899  return SCIP_OKAY;
2900  }
2901  else if ( sdpi->allfixed )
2902  {
2903  SCIPdebugMessage("All variables were fixed during preprocessing, dual problem is feasible, primal feasibility not available\n");
2904  *dualfeasible = TRUE;
2905  return SCIP_OKAY;
2906  }
2907 
2908  SCIP_CALL( SCIPsdpiSolverGetSolFeasibility(sdpi->sdpisolver, primalfeasible, dualfeasible) );
2909 
2910  return SCIP_OKAY;
2911 }
2912 
2916  SCIP_SDPI* sdpi
2917  )
2918 {
2919  assert( sdpi != NULL );
2920  CHECK_IF_SOLVED_BOOL(sdpi);
2921 
2922  if ( sdpi->infeasible )
2923  {
2924  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal unboundedness not available\n");
2925  return FALSE;
2926  }
2927  else if ( sdpi->allfixed )
2928  {
2929  SCIPdebugMessage("All variables were fixed during preprocessing, primal unboundedness not available\n");
2930  return FALSE;
2931  }
2932 
2933  return SCIPsdpiSolverIsPrimalUnbounded(sdpi->sdpisolver);
2934 }
2935 
2939  SCIP_SDPI* sdpi
2940  )
2941 {
2942  assert( sdpi != NULL );
2943  CHECK_IF_SOLVED_BOOL(sdpi);
2944 
2945  if ( sdpi->infeasible )
2946  {
2947  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2948  return FALSE;
2949  }
2950  else if ( sdpi->allfixed )
2951  {
2952  SCIPdebugMessage("All variables were fixed during preprocessing, primal feasibility not available\n");
2953  return FALSE;
2954  }
2955 
2956  return SCIPsdpiSolverIsPrimalInfeasible(sdpi->sdpisolver);
2957 }
2958 
2962  SCIP_SDPI* sdpi
2963  )
2964 {
2965  assert(sdpi != NULL );
2966  CHECK_IF_SOLVED_BOOL(sdpi);
2967 
2968  if ( sdpi->infeasible )
2969  {
2970  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2971  return FALSE;
2972  }
2973  else if ( sdpi->allfixed )
2974  {
2975  SCIPdebugMessage("All variables fixed during preprocessing, primal feasibility not available\n");
2976  return FALSE;
2977  }
2978 
2979  return SCIPsdpiSolverIsPrimalFeasible(sdpi->sdpisolver);
2980 }
2981 
2985  SCIP_SDPI* sdpi
2986  )
2987 {
2988  assert( sdpi != NULL );
2989  CHECK_IF_SOLVED_BOOL(sdpi);
2990 
2991  if ( sdpi->infeasible )
2992  {
2993  SCIPdebugMessage("Problem was found infeasible during preprocessing, therefore is not unbounded\n");
2994  return FALSE;
2995  }
2996  else if ( sdpi->allfixed )
2997  {
2998  SCIPdebugMessage("All variables were fixed during preprocessing, therefore the problem is not unbounded\n");
2999  return FALSE;
3000  }
3001 
3002  return SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver);
3003 }
3004 
3008  SCIP_SDPI* sdpi
3009  )
3010 {
3011  assert( sdpi != NULL );
3012  CHECK_IF_SOLVED_BOOL(sdpi);
3013 
3014  if ( sdpi->infeasible )
3015  {
3016  SCIPdebugMessage("Problem was found infeasible during preprocessing\n");
3017  return TRUE;
3018  }
3019  else if ( sdpi->allfixed )
3020  {
3021  SCIPdebugMessage("All variables were fixed during preprocessing, solution is feasible\n");
3022  return FALSE;
3023  }
3024 
3025  return SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver);
3026 }
3027 
3031  SCIP_SDPI* sdpi
3032  )
3033 {
3034  assert( sdpi != NULL );
3035  CHECK_IF_SOLVED_BOOL(sdpi);
3036 
3037  if ( sdpi->infeasible )
3038  {
3039  SCIPdebugMessage("Problem was found infeasible during preprocessing\n");
3040  return FALSE;
3041  }
3042  else if ( sdpi->allfixed )
3043  {
3044  SCIPdebugMessage("All variables fixed during preprocessing, solution is feasible\n");
3045  return TRUE;
3046  }
3047 
3048  return SCIPsdpiSolverIsDualFeasible(sdpi->sdpisolver);
3049 }
3050 
3053  SCIP_SDPI* sdpi
3054  )
3055 {
3056  assert( sdpi != NULL );
3057  CHECK_IF_SOLVED_BOOL(sdpi);
3058 
3059  if ( sdpi->infeasible )
3060  {
3061  SCIPdebugMessage("Problem was found infeasible during preprocessing, this counts as converged.\n");
3062  return TRUE;
3063  }
3064  else if ( sdpi->allfixed )
3065  {
3066  SCIPdebugMessage("All variables were fixed during preprocessing, this counts as converged.\n");
3067  return TRUE;
3068  }
3069 
3070  return SCIPsdpiSolverIsConverged(sdpi->sdpisolver);
3071 }
3072 
3075  SCIP_SDPI* sdpi
3076  )
3077 {
3078  assert( sdpi != NULL );
3079  CHECK_IF_SOLVED_BOOL(sdpi);
3080 
3081  if ( sdpi->infeasible )
3082  {
3083  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective limit available.\n");
3084  return FALSE;
3085  }
3086  else if ( sdpi->allfixed )
3087  {
3088  SCIPdebugMessage("All variables were fixed during preprocessing, no objective limit available.\n");
3089  return FALSE;
3090  }
3091 
3092  return SCIPsdpiSolverIsObjlimExc(sdpi->sdpisolver);
3093 }
3094 
3097  SCIP_SDPI* sdpi
3098  )
3099 {
3100  assert( sdpi != NULL );
3101  CHECK_IF_SOLVED_BOOL(sdpi);
3102 
3103  if ( sdpi->infeasible )
3104  {
3105  SCIPdebugMessage("Problem was found infeasible during preprocessing, no iteration limit available.\n");
3106  return FALSE;
3107  }
3108  else if ( sdpi->allfixed )
3109  {
3110  SCIPdebugMessage("All variables were fixed during preprocessing, no iteration limit available.\n");
3111  return FALSE;
3112  }
3113 
3114  return SCIPsdpiSolverIsIterlimExc(sdpi->sdpisolver);
3115 }
3116 
3119  SCIP_SDPI* sdpi
3120  )
3121 {
3122  assert( sdpi != NULL );
3123 
3124  if ( sdpi->infeasible )
3125  {
3126  SCIPdebugMessage("Problem was found infeasible during preprocessing, no time limit available.\n");
3127  return FALSE;
3128  }
3129  else if ( sdpi->allfixed )
3130  {
3131  SCIPdebugMessage("All variables were fixed during preprocessing, no time limit available.\n");
3132  return FALSE;
3133  }
3134  else if ( ! sdpi->solved )
3135  {
3136  SCIPdebugMessage("Problem was not solved, time limit not exceeded.\n");
3137  return FALSE;
3138  }
3139 
3140  return SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver);
3141 }
3142 
3154  SCIP_SDPI* sdpi
3155  )
3156 {
3157  assert( sdpi != NULL );
3158 
3159  if ( ! sdpi->solved )
3160  {
3161  SCIPdebugMessage("Problem wasn't solved yet.\n");
3162  return -1;
3163  }
3164  else if ( sdpi->infeasible )
3165  {
3166  SCIPdebugMessage("Problem was found infeasible during preprocessing, no internal status available.\n");
3167  return 0;
3168  }
3169  else if ( sdpi->allfixed )
3170  {
3171  SCIPdebugMessage("All variables were fixed during preprocessing, no internal status available.\n");
3172  return 0;
3173  }
3174 
3175  return SCIPsdpiSolverGetInternalStatus(sdpi->sdpisolver);
3176 }
3177 
3180  SCIP_SDPI* sdpi
3181  )
3182 {
3183  assert( sdpi != NULL );
3184  CHECK_IF_SOLVED_BOOL(sdpi);
3185 
3186  if ( sdpi->infeasible )
3187  {
3188  SCIPdebugMessage("Problem was found infeasible during preprocessing, therefore there is no optimal solution.\n");
3189  return FALSE;
3190  }
3191  else if ( sdpi->allfixed )
3192  {
3193  SCIPdebugMessage("All variables were fixed during preprocessing, therefore there is no optimal solution.\n");
3194  return FALSE;
3195  }
3196 
3197  return SCIPsdpiSolverIsOptimal(sdpi->sdpisolver);
3198 }
3199 
3203  SCIP_SDPI* sdpi
3204  )
3205 {
3206  assert( sdpi != NULL );
3207 
3208  if ( sdpi->infeasible )
3209  {
3210  SCIPdebugMessage("Problem was found infeasible during preprocessing, this is acceptable in a B&B context.\n");
3211  return TRUE;
3212  }
3213  else if ( sdpi->allfixed )
3214  {
3215  SCIPdebugMessage("All variables fixed during preprocessing, this is acceptable in a B&B context.\n");
3216  return TRUE;
3217  }
3218  else if ( ! sdpi->solved )
3219  {
3220  SCIPdebugMessage("Problem not solved succesfully, this is not acceptable in a B&B context.\n");
3221  return FALSE;
3222  }
3223 
3224  return SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver);
3225 }
3226 
3228 SCIP_RETCODE SCIPsdpiGetObjval(
3229  SCIP_SDPI* sdpi,
3230  SCIP_Real* objval
3231  )
3232 {
3233  assert( sdpi != NULL );
3234  assert( objval != NULL );
3235  CHECK_IF_SOLVED(sdpi);
3236 
3237  if ( sdpi->infeasible )
3238  {
3239  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective value available.\n");
3240  return SCIP_OKAY;
3241  }
3242 
3243  if ( sdpi->allfixed )
3244  {
3245  int v;
3246 
3247  /* As all variables were fixed during preprocessing, we have to compute it ourselves here */
3248  *objval = 0;
3249 
3250  for (v = 0; v < sdpi->nvars; v++)
3251  *objval += sdpi->lb[v] * sdpi->obj[v];
3252 
3253  return SCIP_OKAY;
3254  }
3255 
3256  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, objval) );
3257 
3258  return SCIP_OKAY;
3259 }
3260 
3264  SCIP_SDPI* sdpi,
3265  SCIP_Real* objlb
3266  )
3267 {
3268  assert( sdpi != NULL );
3269  assert( objlb != NULL );
3270 
3271  /* if we could successfully solve the problem, the best bound is the optimal objective */
3272  if ( sdpi->solved )
3273  {
3274  if ( sdpi->infeasible )
3275  {
3276  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective value available.\n");
3277  return SCIP_OKAY;
3278  }
3279 
3280  if ( sdpi->allfixed )
3281  {
3282  int v;
3283 
3284  /* As all variables were fixed during preprocessing, we have to compute it ourselves here */
3285  *objlb = 0;
3286 
3287  for (v = 0; v < sdpi->nvars; v++)
3288  *objlb += sdpi->lb[v] * sdpi->obj[v];
3289 
3290  return SCIP_OKAY;
3291  }
3292 
3293  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, objlb) );
3294  return SCIP_OKAY;
3295  }
3296 
3297  /* if we could not solve it, but tried the penalty formulation, we take the best bound computed by the penalty approach */
3298  if ( sdpi->penalty )
3299  {
3300  *objlb = sdpi->bestbound;
3301  return SCIP_OKAY;
3302  }
3303 
3304  /* 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 */
3305 
3306  *objlb = -SCIPsdpiInfinity(sdpi);
3307  return SCIP_OKAY;
3308 }
3309 
3312 SCIP_RETCODE SCIPsdpiGetSol(
3313  SCIP_SDPI* sdpi,
3314  SCIP_Real* objval,
3315  SCIP_Real* dualsol,
3316  int* dualsollength
3318  )
3319 {
3320  assert( sdpi != NULL );
3321  assert( dualsollength != NULL );
3322  assert( *dualsollength == 0 || dualsol != NULL );
3323  CHECK_IF_SOLVED(sdpi);
3324 
3325  if ( sdpi->infeasible )
3326  {
3327  SCIPdebugMessage("Problem was found infeasible during preprocessing, no solution available.\n");
3328  return SCIP_OKAY;
3329  }
3330  else if ( sdpi->allfixed )
3331  {
3332  if ( objval != NULL )
3333  {
3334  SCIP_CALL( SCIPsdpiGetObjval(sdpi, objval) );
3335  }
3336  if ( *dualsollength > 0 )
3337  {
3338  int v;
3339 
3340  assert( dualsol != NULL );
3341  if ( *dualsollength < sdpi->nvars )
3342  {
3343  SCIPdebugMessage("The given array in SCIPsdpiGetSol only had length %d, but %d was needed", *dualsollength, sdpi->nvars);
3344  *dualsollength = sdpi->nvars;
3345 
3346  return SCIP_OKAY;
3347  }
3348 
3349  /* we give the fixed values as the solution */
3350  for (v = 0; v < sdpi->nvars; v++)
3351  dualsol[v] = sdpi->lb[v];
3352 
3353  return SCIP_OKAY;
3354  }
3355  }
3356 
3357  SCIP_CALL( SCIPsdpiSolverGetSol(sdpi->sdpisolver, objval, dualsol, dualsollength) );
3358 
3359  return SCIP_OKAY;
3360 }
3361 
3364  SCIP_SDPI* sdpi,
3365  int nblocks,
3366  int* startXnblocknonz
3368  )
3369 {
3370  assert( sdpi != NULL );
3371  assert( nblocks >= 0 );
3372  assert( startXnblocknonz != NULL );
3373 
3374  if ( sdpi->infeasible )
3375  {
3376  SCIPdebugMessage("Problem was found infeasible during preprocessing, no preoptimal solution available.\n");
3377  startXnblocknonz[0] = -1;
3378 
3379  return SCIP_OKAY;
3380  }
3381  else if ( sdpi->allfixed )
3382  {
3383  SCIPdebugMessage("No primal solution available, as problem was solved during preprocessing\n");
3384  startXnblocknonz[0] = -1;
3385 
3386  return SCIP_OKAY;
3387  }
3388 
3389  SCIP_CALL( SCIPsdpiSolverGetPreoptimalPrimalNonzeros(sdpi->sdpisolver, nblocks, startXnblocknonz) );
3390 
3391  return SCIP_OKAY;
3392 }
3393 
3402  SCIP_SDPI* sdpi,
3403  SCIP_Bool* success,
3404  SCIP_Real* dualsol,
3405  int* dualsollength,
3407  int nblocks,
3408  int* startXnblocknonz,
3410  int** startXrow,
3411  int** startXcol,
3412  SCIP_Real** startXval
3413  )
3414 {
3415  assert( sdpi != NULL );
3416  assert( success != NULL );
3417  assert( dualsol != NULL );
3418  assert( dualsollength != NULL );
3419  assert( *dualsollength >= 0 );
3420  assert( startXnblocknonz != NULL || nblocks == -1 );
3421  assert( startXrow != NULL || nblocks == -1 );
3422  assert( startXcol != NULL || nblocks == -1 );
3423  assert( startXval != NULL || nblocks == -1 );
3424 
3425  if ( sdpi->infeasible )
3426  {
3427  *success = FALSE;
3428  SCIPdebugMessage("Problem was found infeasible during preprocessing, no preoptimal solution available.\n");
3429  startXnblocknonz[0] = -1;
3430 
3431  return SCIP_OKAY;
3432  }
3433  else if ( sdpi->allfixed )
3434  {
3435  int v;
3436 
3437  assert( dualsol != NULL );
3438 
3439  *success = FALSE;
3440 
3441  if ( *dualsollength < sdpi->nvars )
3442  {
3443  SCIPdebugMessage("The given array in SCIPsdpiGetPreoptimalSol only had length %d, but %d was needed", *dualsollength, sdpi->nvars);
3444  *dualsollength = sdpi->nvars;
3445 
3446  return SCIP_OKAY;
3447  }
3448 
3449  /* we give the fixed values as the solution */
3450  for (v = 0; v < sdpi->nvars; v++)
3451  dualsol[v] = sdpi->lb[v];
3452 
3453  if ( nblocks > -1 )
3454  {
3455  SCIPdebugMessage("No primal solution available, as problem was solved during preprocessing\n");
3456  startXnblocknonz[0] = -1;
3457  }
3458 
3459  return SCIP_OKAY;
3460  }
3461 
3462  SCIP_CALL( SCIPsdpiSolverGetPreoptimalSol(sdpi->sdpisolver, success, dualsol, dualsollength, nblocks, startXnblocknonz,
3463  startXrow, startXcol, startXval) );
3464 
3465  return SCIP_OKAY;
3466 }
3467 
3473  SCIP_SDPI* sdpi,
3474  SCIP_Real* lbvars,
3475  SCIP_Real* ubvars,
3476  int* arraylength
3478  )
3479 {
3480  assert( sdpi != NULL );
3481  assert( lbvars != NULL );
3482  assert( ubvars != NULL );
3483  assert( arraylength != NULL );
3484  assert( *arraylength >= 0 );
3485  CHECK_IF_SOLVED(sdpi);
3486 
3487  if ( sdpi->infeasible )
3488  {
3489  SCIPdebugMessage("Problem was found infeasible during preprocessing, no primal variables available.\n");
3490  return SCIP_OKAY;
3491  }
3492  else if ( sdpi->allfixed )
3493  {
3494  SCIPdebugMessage("All variables fixed during preprocessing, no primal variables available.\n");
3495  return SCIP_OKAY;
3496  }
3497 
3498  SCIP_CALL( SCIPsdpiSolverGetPrimalBoundVars(sdpi->sdpisolver, lbvars, ubvars, arraylength) );
3499 
3500  return SCIP_OKAY;
3501 }
3502 
3505  SCIP_SDPI* sdpi,
3506  int nblocks,
3507  int* startXnblocknonz
3508  )
3509 {
3510  assert( sdpi != NULL );
3511 
3512  if ( sdpi->infeasible )
3513  {
3514  SCIPdebugMessage("Problem was found infeasible during preprocessing, no primal solution available.\n");
3515  return SCIP_OKAY;
3516  }
3517  else if ( sdpi->allfixed )
3518  {
3519  SCIPdebugMessage("All variables fixed during preprocessing, no primal solution available.\n");
3520  return SCIP_OKAY;
3521  }
3522 
3523  SCIP_CALL( SCIPsdpiSolverGetPrimalNonzeros(sdpi->sdpisolver, nblocks, startXnblocknonz) );
3524 
3525  return SCIP_OKAY;
3526 }
3527 
3533  SCIP_SDPI* sdpi,
3534  int nblocks,
3535  int* startXnblocknonz,
3537  int** startXrow,
3538  int** startXcol,
3539  SCIP_Real** startXval
3540  )
3541 {/* TODO: should also set startXnblocknonz[0] = -1 in case the problem was solved in presolving */
3542  assert( sdpi != NULL );
3543 
3544  if ( sdpi->infeasible )
3545  {
3546  SCIPdebugMessage("Problem was found infeasible during preprocessing, no primal solution available.\n");
3547  return SCIP_OKAY;
3548  }
3549  else if ( sdpi->allfixed )
3550  {
3551  SCIPdebugMessage("All variables fixed during preprocessing, no primal solution available.\n");
3552  return SCIP_OKAY;
3553  }
3554 
3555  SCIP_CALL( SCIPsdpiSolverGetPrimalMatrix(sdpi->sdpisolver, nblocks, startXnblocknonz, startXrow, startXcol, startXval) );
3556 
3557  return SCIP_OKAY;
3558 }
3559 
3562  SCIP_SDPI* sdpi
3563  )
3564 {
3565  assert( sdpi != NULL );
3566 
3567  return SCIPsdpiSolverGetMaxPrimalEntry( sdpi->sdpisolver );
3568 }
3569 
3572  SCIP_SDPI* sdpi,
3573  int* iterations
3574  )
3575 {
3576  assert( sdpi != NULL );
3577  assert( iterations != NULL );
3578 
3579  *iterations = sdpi->niterations;
3580 
3581  return SCIP_OKAY;
3582 }
3583 
3585 SCIP_RETCODE SCIPsdpiGetSdpCalls(
3586  SCIP_SDPI* sdpi,
3587  int* calls
3588  )
3589 {
3590  assert( sdpi != NULL );
3591  assert( calls != NULL );
3592 
3593  *calls = sdpi->nsdpcalls;
3594 
3595  return SCIP_OKAY;
3596 }
3597 
3600  SCIP_SDPI* sdpi,
3601  SCIP_SDPSOLVERSETTING* usedsetting
3602  )
3603 {
3604  assert( sdpi != NULL );
3605  assert( usedsetting != NULL );
3606 
3607  if ( ! sdpi->solved )
3608  {
3609  SCIPdebugMessage("Problem was not solved successfully.\n");
3610  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3611  return SCIP_OKAY;
3612  }
3613  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 */
3614  {
3615  SCIPdebugMessage("Problem was found infeasible during preprocessing, no settings used.\n");
3616  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3617  return SCIP_OKAY;
3618  }
3619  else if ( sdpi->allfixed )
3620  {
3621  SCIPdebugMessage("All varialbes fixed during preprocessing, no settings used.\n");
3622  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3623  return SCIP_OKAY;
3624  }
3625  else if ( sdpi->penalty )
3626  {
3627  *usedsetting = SCIP_SDPSOLVERSETTING_PENALTY;
3628  return SCIP_OKAY;
3629  }
3630 
3631  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, usedsetting) );
3632  return SCIP_OKAY;
3633 }
3634 
3637  SCIP_SDPI* sdpi,
3638  SCIP_SDPSLATERSETTING* slatersetting
3639  )
3640 {
3641  SCIP_SDPSOLVERSETTING usedsetting;
3642 
3643  assert( sdpi != NULL );
3644  assert( slatersetting != NULL );
3645 
3646  if ( ! sdpi->solved )
3647  {
3648  SCIPdebugMessage("Problem was not solved successfully");
3649  if ( sdpi->bestbound > -SCIPsdpiSolverInfinity(sdpi->sdpisolver) )
3650  {
3651  SCIPdebugMessage(", but we could at least compute a lower bound. \n");
3652  if ( sdpi->dualslater == SCIP_SDPSLATER_INF)
3653  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDINFEASIBLE;
3654  else
3655  {
3656  switch( sdpi->primalslater )/*lint --e{788}*/
3657  {
3658  case SCIP_SDPSLATER_NOINFO:
3659  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3660  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
3661  else
3662  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3663  break;
3664  case SCIP_SDPSLATER_NOT:
3665  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
3666  break;
3667  case SCIP_SDPSLATER_HOLDS:
3668  switch( sdpi->dualslater )/*lint --e{788}*/
3669  {
3670  case SCIP_SDPSLATER_NOINFO:
3671  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3672  break;
3673  case SCIP_SDPSLATER_NOT:
3674  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
3675  break;
3676  case SCIP_SDPSLATER_HOLDS:
3677  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDWSLATER;
3678  break;
3679  default:
3680  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3681  break;
3682  }
3683  break;
3684  default:
3685  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3686  break;
3687  }
3688  }
3689  }
3690  else
3691  {
3692  SCIPdebugMessage(".\n");
3693  if ( sdpi->dualslater == SCIP_SDPSLATER_INF)
3695  else
3696  {
3697  switch( sdpi->primalslater )/*lint --e{788}*/
3698  {
3699  case SCIP_SDPSLATER_NOINFO:
3700  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3701  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
3702  else
3703  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3704  break;
3705  case SCIP_SDPSLATER_NOT:
3706  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
3707  break;
3708  case SCIP_SDPSLATER_HOLDS:
3709  switch( sdpi->dualslater )/*lint --e{788}*/
3710  {
3711  case SCIP_SDPSLATER_NOINFO:
3712  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3713  break;
3714  case SCIP_SDPSLATER_NOT:
3715  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
3716  break;
3717  case SCIP_SDPSLATER_HOLDS:
3718  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDWSLATER;
3719  break;
3720  default:
3721  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3722  break;
3723  }
3724  break;
3725  default:
3726  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3727  break;
3728  }
3729  }
3730  }
3731  return SCIP_OKAY;
3732  }
3733  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 */
3734  {
3735  SCIPdebugMessage("Problem was found infeasible during preprocessing, no settings used.\n");
3736  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3737  return SCIP_OKAY;
3738  }
3739  else if ( sdpi->allfixed )
3740  {
3741  SCIPdebugMessage("All varialbes fixed during preprocessing, no settings used.\n");
3742  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3743  return SCIP_OKAY;
3744  }
3745  else if ( sdpi->penalty )
3746  {
3747  switch( sdpi->primalslater )/*lint --e{788}*/
3748  {
3749  case SCIP_SDPSLATER_NOINFO:
3750  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3751  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
3752  else if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3753  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
3754  else
3755  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3756  break;
3757  case SCIP_SDPSLATER_NOT:
3758  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3759  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
3760  else
3761  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
3762  break;
3763  case SCIP_SDPSLATER_HOLDS:
3764  switch( sdpi->dualslater )/*lint --e{788}*/
3765  {
3766  case SCIP_SDPSLATER_NOINFO:
3767  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3768  break;
3769  case SCIP_SDPSLATER_NOT:
3770  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
3771  break;
3772  case SCIP_SDPSLATER_HOLDS:
3773  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYWSLATER;
3774  break;
3775  case SCIP_SDPSLATER_INF:
3776  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
3777  break;
3778  default:
3779  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3780  break;
3781  }
3782  break;
3783  default:
3784  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3785  break;
3786  }
3787  return SCIP_OKAY;
3788  }
3789 
3790  switch( sdpi->primalslater )/*lint --e{788}*/
3791  {
3792  case SCIP_SDPSLATER_NOINFO:
3793  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3794  {
3795  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3796  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3797  switch( usedsetting )/*lint --e{788}*/
3798  {
3800  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
3801  break;
3804  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
3805  break;
3806  default:
3807  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3808  break;
3809  }
3810  }
3811  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3812  {
3813  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3814  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3815  switch( usedsetting )/*lint --e{788}*/
3816  {
3818  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
3819  break;
3823  break;
3824  default:
3825  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3826  break;
3827  }
3828  }
3829  else
3830  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3831  break;
3832  case SCIP_SDPSLATER_NOT:
3833  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3834  {
3835  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3836  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3837  switch( usedsetting )/*lint --e{788}*/
3838  {
3840  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
3841  break;
3845  break;
3846  default:
3847  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3848  break;
3849  }
3850  }
3851  else
3852  {
3853  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3854  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3855  switch( usedsetting )/*lint --e{788}*/
3856  {
3858  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
3859  break;
3862  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
3863  break;
3864  default:
3865  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3866  break;
3867  }
3868  }
3869  break;
3870  case SCIP_SDPSLATER_HOLDS:
3871  switch( sdpi->dualslater )/*lint --e{788}*/
3872  {
3873  case SCIP_SDPSLATER_NOINFO:
3874  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3875  break;
3876  case SCIP_SDPSLATER_NOT:
3877  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3878  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3879  switch( usedsetting )/*lint --e{788}*/
3880  {
3882  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
3883  break;
3886  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
3887  break;
3888  default:
3889  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3890  break;
3891  }
3892  break;
3893  case SCIP_SDPSLATER_INF:
3894  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3895  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3896  switch( usedsetting )/*lint --e{788}*/
3897  {
3899  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
3900  break;
3904  break;
3905  default:
3906  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3907  break;
3908  }
3909  break;
3910  case SCIP_SDPSLATER_HOLDS:
3911  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3912  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3913  switch( usedsetting )/*lint --e{788}*/
3914  {
3916  *slatersetting = SCIP_SDPSLATERSETTING_STABLEWSLATER;
3917  break;
3920  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLEWSLATER;
3921  break;
3922  default:
3923  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3924  break;
3925  }
3926  break;
3927  default:
3928  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3929  break;
3930  }
3931  break;
3932  default:
3933  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3934  break;
3935  }
3936 
3937  return SCIP_OKAY;
3938 }
3939 
3941 SCIP_RETCODE SCIPsdpiSlater(
3942  SCIP_SDPI* sdpi,
3943  SCIP_SDPSLATER* primalslater,
3944  SCIP_SDPSLATER* dualslater
3945  )
3946 {
3947  assert( sdpi != NULL );
3948  assert( primalslater != NULL );
3949  assert( dualslater != NULL );
3950 
3951 
3952  if ( sdpi->infeasible )
3953  {
3954  *primalslater = SCIP_SDPSLATER_NOINFO;
3955  *dualslater = sdpi->dualslater;
3956  return SCIP_OKAY;
3957  }
3958 
3959  if (sdpi->allfixed )
3960  {
3961  *primalslater = SCIP_SDPSLATER_NOINFO;
3962  *dualslater = SCIP_SDPSLATER_NOINFO;
3963  return SCIP_OKAY;
3964  }
3965 
3966  *primalslater = sdpi->primalslater;
3967  *dualslater = sdpi->dualslater;
3968 
3969  return SCIP_OKAY;
3970 }
3971 
3977 /*
3978  * Numerical Methods
3979  */
3980 
3986  SCIP_SDPI* sdpi
3987  )
3988 {
3989  assert( sdpi != NULL );
3990 
3991  return SCIPsdpiSolverInfinity(sdpi->sdpisolver);
3992 }
3993 
3996  SCIP_SDPI* sdpi,
3997  SCIP_Real val
3998  )
3999 {
4000  assert( sdpi != NULL );
4001 
4002  return ((val <= -SCIPsdpiInfinity(sdpi)) || (val >= SCIPsdpiInfinity(sdpi)));
4003 }
4004 
4006 SCIP_RETCODE SCIPsdpiGetRealpar(
4007  SCIP_SDPI* sdpi,
4008  SCIP_SDPPARAM type,
4009  SCIP_Real* dval
4010  )
4011 {
4012  assert( sdpi != NULL );
4013  assert( sdpi->sdpisolver != NULL );
4014  assert( dval != NULL );
4015 
4016  switch( type )/*lint --e{788}*/
4017  {
4018  case SCIP_SDPPAR_EPSILON:
4019  *dval = sdpi->epsilon;
4020  break;
4021  case SCIP_SDPPAR_GAPTOL:
4022  *dval = sdpi->gaptol;
4023  break;
4024  case SCIP_SDPPAR_FEASTOL:
4025  *dval = sdpi->feastol;
4026  break;
4028  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4029  break;
4030  case SCIP_SDPPAR_OBJLIMIT:
4031  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4032  break;
4034  *dval = sdpi->penaltyparam;
4035  break;
4037  *dval = sdpi->maxpenaltyparam;
4038  break;
4040  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4041  break;
4043  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4044  break;
4046  *dval = sdpi->peninfeasadjust;
4047  break;
4048  default:
4049  return SCIP_PARAMETERUNKNOWN;
4050  }
4051 
4052  return SCIP_OKAY;
4053 }
4054 
4056 SCIP_RETCODE SCIPsdpiSetRealpar(
4057  SCIP_SDPI* sdpi,
4058  SCIP_SDPPARAM type,
4059  SCIP_Real dval
4060  )
4061 {
4062  assert( sdpi != NULL );
4063 
4064  switch( type )/*lint --e{788}*/
4065  {
4066  case SCIP_SDPPAR_EPSILON:
4067  sdpi->epsilon = dval;
4068  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4069  break;
4070  case SCIP_SDPPAR_GAPTOL:
4071  sdpi->gaptol = dval;
4072  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4073  break;
4074  case SCIP_SDPPAR_FEASTOL:
4075  sdpi->feastol = dval;
4076  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4077  break;
4079  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4080  break;
4081  case SCIP_SDPPAR_OBJLIMIT:
4082  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4083  break;
4085  sdpi->penaltyparam = dval;
4086  SCIP_CALL_PARAM_IGNORE_UNKNOWN( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4087  break;
4089  sdpi->maxpenaltyparam = dval;
4090  break;
4092  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4093  break;
4095  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4096  break;
4098  sdpi->peninfeasadjust = dval;
4099  break;
4100  default:
4101  return SCIP_PARAMETERUNKNOWN;
4102  }
4103 
4104  return SCIP_OKAY;
4105 }
4106 
4108 SCIP_RETCODE SCIPsdpiGetIntpar(
4109  SCIP_SDPI* sdpi,
4110  SCIP_SDPPARAM type,
4111  int* ival
4112  )
4113 {
4114  assert( sdpi != NULL );
4115  assert( sdpi->sdpisolver != NULL );
4116  assert( ival != NULL );
4117 
4118  switch( type )/*lint --e{788}*/
4119  {
4120  case SCIP_SDPPAR_SDPINFO:
4121  case SCIP_SDPPAR_NTHREADS:
4122  SCIP_CALL_PARAM( SCIPsdpiSolverGetIntpar(sdpi->sdpisolver, type, ival) );
4123  break;
4125  *ival = sdpi->slatercheck;
4126  break;
4128  *ival = sdpi->npenaltyincr;
4129  break;
4130  default:
4131  return SCIP_PARAMETERUNKNOWN;
4132  }
4133 
4134  return SCIP_OKAY;
4135 }
4136 
4138 SCIP_RETCODE SCIPsdpiSetIntpar(
4139  SCIP_SDPI* sdpi,
4140  SCIP_SDPPARAM type,
4141  int ival
4142  )
4143 {
4144  assert( sdpi != NULL );
4145  assert( sdpi->sdpisolver != NULL );
4146 
4147  switch( type )/*lint --e{788}*/
4148  {
4149  case SCIP_SDPPAR_SDPINFO:
4150  assert( ival == 0 || ival == 1 ); /* this is a boolean parameter */
4151  SCIP_CALL_PARAM( SCIPsdpiSolverSetIntpar(sdpi->sdpisolver, type, ival) );
4152  break;
4153  case SCIP_SDPPAR_NTHREADS:
4154  SCIP_CALL_PARAM( SCIPsdpiSolverSetIntpar(sdpi->sdpisolver, type, ival) );
4155  break;
4157  sdpi->slatercheck = ival;
4158  break;
4160  sdpi->npenaltyincr = ival;
4161  break;
4162  default:
4163  return SCIP_PARAMETERUNKNOWN;
4164  }
4165 
4166  return SCIP_OKAY;
4167 }
4168 
4171  SCIP_SDPI* sdpi,
4172  SCIP_Real maxguess
4173  )
4174 {
4175  return SCIPsdpiSolverComputeLambdastar(sdpi->sdpisolver, maxguess);
4176 }
4177 
4180  SCIP_SDPI* sdpi,
4181  SCIP_Real maxcoeff,
4182  SCIP_Real* penaltyparam
4183  )
4184 {
4185  SCIP_CALL( SCIPsdpiSolverComputePenaltyparam(sdpi->sdpisolver, maxcoeff, penaltyparam) );
4186 
4187  sdpi->penaltyparam = *penaltyparam;
4188 
4189  return SCIP_OKAY;
4190 }
4191 
4194  SCIP_SDPI* sdpi,
4195  SCIP_Real penaltyparam,
4196  SCIP_Real* maxpenaltyparam
4197  )
4198 {
4199  SCIP_CALL( SCIPsdpiSolverComputeMaxPenaltyparam(sdpi->sdpisolver, penaltyparam, maxpenaltyparam) );
4200 
4201  sdpi->maxpenaltyparam = *maxpenaltyparam;
4202 
4203  /* if the initial penalty parameter is smaller than the maximum one, we decrease the initial correspondingly */
4204  /* if the maximum penalty parameter is smaller than the initial penalty paramater, we decrease the initial one correspondingly */
4205  if ( sdpi->penaltyparam > *maxpenaltyparam )
4206  {
4207  SCIPdebugMessage("Decreasing penaltyparameter of %f to maximum penalty paramater of %f.\n", sdpi->penaltyparam, *maxpenaltyparam);
4208  sdpi->penaltyparam = *maxpenaltyparam;
4209  }
4210 
4211  return SCIP_OKAY;
4212 }
4213 
4219 /*
4220  * File Interface Methods
4221  */
4222 
4227 SCIP_RETCODE SCIPsdpiReadSDP(
4228  SCIP_SDPI* sdpi,
4229  const char* fname
4230  )
4231 {/*lint --e{715}*/
4232  SCIPdebugMessage("Not implemented yet\n");
4233  return SCIP_LPERROR;
4234 }
4235 
4237 SCIP_RETCODE SCIPsdpiWriteSDP(
4238  SCIP_SDPI* sdpi,
4239  const char* fname
4240  )
4241 {/*lint --e{715}*/
4242  SCIPdebugMessage("Not implemented yet\n");
4243  return SCIP_LPERROR;
4244 }
4245 
SCIP_RETCODE SCIPsdpiFree(SCIP_SDPI **sdpi)
Definition: sdpi.c:1514
SCIP_Bool SCIPsdpiIsDualUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:2984
#define DEFAULT_SDPSOLVERGAPTOL
Definition: sdpi.c:134
EXTERN SCIP_RETCODE SCIPsdpiSolverIncreaseCounter(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_RETCODE SCIPsdpiSolverGetSdpCalls(SCIP_SDPISOLVER *sdpisolver, int *calls)
SCIP_RETCODE SCIPsdpiDelLPRows(SCIP_SDPI *sdpi, int firstrow, int lastrow)
Definition: sdpi.c:1984
EXTERN SCIP_RETCODE SCIPsdpiSolverGetSolFeasibility(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
SCIP_RETCODE SCIPsdpiChgLPLhRhSides(SCIP_SDPI *sdpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: sdpi.c:2215
EXTERN SCIP_RETCODE SCIPsdpiSolverSetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real dval)
SCIP_RETCODE SCIPsdpiGetSdpCalls(SCIP_SDPI *sdpi, int *calls)
Definition: sdpi.c:3585
EXTERN SCIP_RETCODE SCIPlapackComputeIthEigenvalue(BMS_BUFMEM *bufmem, SCIP_Bool geteigenvectors, int n, SCIP_Real *A, int i, SCIP_Real *eigenvalue, SCIP_Real *eigenvector)
EXTERN SCIP_Bool SCIPsdpiSolverIsObjlimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiDoesWarmstartNeedPrimal(void)
Definition: sdpi.c:1428
#define BMS_CALL(x)
Definition: sdpi.c:58
SCIP_RETCODE SCIPsdpiGetSolFeasibility(SCIP_SDPI *sdpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: sdpi.c:2886
SCIP_RETCODE SCIPsdpiWriteSDP(SCIP_SDPI *sdpi, const char *fname)
Definition: sdpi.c:4237
EXTERN SCIP_Bool SCIPsdpiSolverIsAcceptable(SCIP_SDPISOLVER *sdpisolver)
static SCIP_RETCODE checkAllFixed(SCIP_SDPI *sdpi)
Definition: sdpi.c:851
EXTERN SCIP_RETCODE SCIPsdpiSolverCreate(SCIP_SDPISOLVER **sdpisolver, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem)
SCIP_RETCODE SCIPsdpiGetLPNNonz(SCIP_SDPI *sdpi, int *nnonz)
Definition: sdpi.c:2329
EXTERN 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)
EXTERN SCIP_RETCODE SCIPsdpiSolverResetCounter(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Bool SCIPsdpiSolverFeasibilityKnown(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Bool SCIPsdpiSolverIsConverged(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetPrimalMatrix(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
Definition: sdpi.c:3532
EXTERN SCIP_RETCODE SCIPsdpiSolverGetPrimalBoundVars(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
enum SCIP_SDPSolverSetting SCIP_SDPSOLVERSETTING
Definition: type_sdpi.h:80
SCIP_Bool SCIPsdpiIsOptimal(SCIP_SDPI *sdpi)
Definition: sdpi.c:3179
SCIP_RETCODE SCIPsdpiGetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int *ival)
Definition: sdpi.c:4108
SCIP_RETCODE SCIPsdpiGetSDPNNonz(SCIP_SDPI *sdpi, int *nnonz)
Definition: sdpi.c:2301
#define MIN_GAPTOL
Definition: sdpi.c:132
SCIP_Bool SCIPsdpiIsInfinity(SCIP_SDPI *sdpi, SCIP_Real val)
Definition: sdpi.c:3995
const char * SCIPsdpiGetSolverName(void)
Definition: sdpi.c:1375
EXTERN SCIP_RETCODE SCIPsdpiSolverFree(SCIP_SDPISOLVER **sdpisolver)
EXTERN SCIP_RETCODE SCIPsdpiSolverComputeMaxPenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Real *maxpenaltyparam)
EXTERN SCIP_RETCODE SCIPsdpiSolverGetPreoptimalPrimalNonzeros(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz)
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:3312
interface methods for specific SDP-solvers
SCIP_Bool SCIPsdpiIsPrimalInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2938
#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:2453
SCIP_Bool SCIPsdpiFeasibilityKnown(SCIP_SDPI *sdpi)
Definition: sdpi.c:2872
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:4170
EXTERN int SCIPsdpiSolverGetDefaultSdpiSolverNpenaltyIncreases(void)
SCIP_RETCODE SCIPsdpiGetPrimalNonzeros(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz)
Definition: sdpi.c:3504
EXTERN SCIP_Bool SCIPsdpiSolverWasSolved(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Bool SCIPsdpiSolverDoesWarmstartNeedPrimal(void)
SCIP_RETCODE SCIPsdpiGetIterations(SCIP_SDPI *sdpi, int *iterations)
Definition: sdpi.c:3571
SCIP_RETCODE SCIPsdpiSettingsUsed(SCIP_SDPI *sdpi, SCIP_SDPSOLVERSETTING *usedsetting)
Definition: sdpi.c:3599
EXTERN SCIP_RETCODE SCIPsdpiSolverComputePenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxcoeff, SCIP_Real *penaltyparam)
EXTERN SCIP_Bool SCIPsdpiSolverIsDualFeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSlaterSettings(SCIP_SDPI *sdpi, SCIP_SDPSLATERSETTING *slatersetting)
Definition: sdpi.c:3636
EXTERN SCIP_Bool SCIPsdpiSolverIsOptimal(SCIP_SDPISOLVER *sdpisolver)
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:377
SCIP_Bool SCIPsdpiIsAcceptable(SCIP_SDPI *sdpi)
Definition: sdpi.c:3202
EXTERN 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)
EXTERN SCIP_Bool SCIPsdpiSolverIsPrimalUnbounded(SCIP_SDPISOLVER *sdpisolver)
EXTERN int SCIPsdpiSolverGetInternalStatus(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiIsIterlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3096
SCIP_Bool SCIPsdpiIsTimelimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3118
SCIP_Bool SCIPsdpiIsDualInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:3007
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
enum SCIP_SDPSlaterSetting SCIP_SDPSLATERSETTING
Definition: type_sdpi.h:102
SCIP_RETCODE SCIPsdpiClone(SCIP_SDPI *oldsdpi, SCIP_SDPI *newsdpi)
Definition: sdpi.c:1579
EXTERN SCIP_RETCODE SCIPsdpiSolverGetIterations(SCIP_SDPISOLVER *sdpisolver, int *iterations)
EXTERN SCIP_RETCODE SCIPsdpiSolverSetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int ival)
SCIP_RETCODE SCIPsdpiChgBounds(SCIP_SDPI *sdpi, int nvars, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: sdpi.c:2181
EXTERN const char * SCIPsdpiSolverGetSolverDesc(void)
EXTERN SCIP_RETCODE SCIPsdpiSolverGetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int *ival)
SCIP_RETCODE SCIPsdpiDelLPRowset(SCIP_SDPI *sdpi, int *dstat)
Definition: sdpi.c:2094
EXTERN SCIP_RETCODE SCIPsdpiSolverGetPrimalMatrix(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
EXTERN SCIP_Bool SCIPsdpiSolverIsDualInfeasible(SCIP_SDPISOLVER *sdpisolver)
EXTERN const char * SCIPsdpiSolverGetSolverName(void)
SCIP_RETCODE SCIPsdpiGetLowerObjbound(SCIP_SDPI *sdpi, SCIP_Real *objlb)
Definition: sdpi.c:3263
SCIP_Bool SCIPsdpiIsObjlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3074
#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
void * SCIPsdpiGetSolverPointer(SCIP_SDPI *sdpi)
Definition: sdpi.c:1396
EXTERN SCIP_RETCODE SCIPsdpiSolverGetPrimalNonzeros(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz)
int SCIPsdpiGetInternalStatus(SCIP_SDPI *sdpi)
Definition: sdpi.c:3153
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
EXTERN SCIP_Bool SCIPsdpiSolverIsPrimalInfeasible(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_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:4179
SCIP_RETCODE SCIPsdpiSetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int ival)
Definition: sdpi.c:4138
EXTERN SCIP_RETCODE SCIPsdpiSolverSettingsUsed(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPSOLVERSETTING *usedsetting)
SCIP_Bool SCIPsdpiIsPrimalUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:2915
SCIP_Real SCIPsdpiInfinity(SCIP_SDPI *sdpi)
Definition: sdpi.c:3985
#define CHECK_IF_SOLVED_BOOL(sdpi)
Definition: sdpi.c:80
EXTERN SCIP_Bool SCIPsdpiSolverIsIterlimExc(SCIP_SDPISOLVER *sdpisolver)
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
adds the main functionality to fix/unfix/(multi-)aggregate variables by merging two three-tuple-array...
static void ensureLowerTriangular(int *i, int *j)
Definition: sdpi.c:214
SCIP_RETCODE SCIPsdpiGetObjval(SCIP_SDPI *sdpi, SCIP_Real *objval)
Definition: sdpi.c:3228
EXTERN SCIP_RETCODE SCIPsdpiSolverGetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real *dval)
int SCIPsdpiGetDefaultSdpiSolverNpenaltyIncreases(void)
Definition: sdpi.c:1420
SCIP_Bool SCIPsdpiIsConverged(SCIP_SDPI *sdpi)
Definition: sdpi.c:3052
static SCIP_Bool isFixed(SCIP_SDPI *sdpi, int v)
Definition: sdpi.c:231
#define DEFAULT_MAXPENALTYPARAM
Definition: sdpi.c:138
EXTERN SCIP_Bool SCIPsdpiSolverIsTimelimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiWasSolved(SCIP_SDPI *sdpi)
Definition: sdpi.c:2850
SCIP_RETCODE SCIPsdpiReadSDP(SCIP_SDPI *sdpi, const char *fname)
Definition: sdpi.c:4227
SCIP_RETCODE SCIPsdpiComputeMaxPenaltyparam(SCIP_SDPI *sdpi, SCIP_Real penaltyparam, SCIP_Real *maxpenaltyparam)
Definition: sdpi.c:4193
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
EXTERN SCIP_RETCODE SCIPsdpiSolverGetObjval(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval)
SCIP_RETCODE SCIPsdpiChgObj(SCIP_SDPI *sdpi, int nvars, const int *ind, const SCIP_Real *obj)
Definition: sdpi.c:2152
EXTERN SCIP_Bool SCIPsdpiSolverIsDualUnbounded(SCIP_SDPISOLVER *sdpisolver)
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:3401
#define DEFAULT_NPENALTYINCR
Definition: sdpi.c:139
EXTERN SCIP_Real SCIPsdpiSolverGetMaxPrimalEntry(SCIP_SDPISOLVER *sdpisolver)
#define DEFAULT_PENALTYPARAM
Definition: sdpi.c:137
SCIP_Bool SCIPsdpiIsDualFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:3030
struct SCIP_SDPi SCIP_SDPI
Definition: type_sdpi.h:114
EXTERN SCIP_RETCODE SCIPsdpiSolverGetSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
SCIP_Bool SCIPsdpiIsPrimalFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2961
SCIP_RETCODE SCIPsdpiSetRealpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, SCIP_Real dval)
Definition: sdpi.c:4056
EXTERN SCIP_Bool SCIPsdpiSolverIsPrimalFeasible(SCIP_SDPISOLVER *sdpisolver)
enum SCIP_SDPSlater SCIP_SDPSLATER
Definition: type_sdpi.h:112
SCIP_Real SCIPsdpiGetMaxPrimalEntry(SCIP_SDPI *sdpi)
Definition: sdpi.c:3561
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:256
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:4006
EXTERN 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)
EXTERN SCIP_Real SCIPsdpiSolverGetDefaultSdpiSolverGaptol(void)
static SCIP_RETCODE compConstMatAfterFixings(SCIP_SDPI *sdpi, int *sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval)
Definition: sdpi.c:263
EXTERN SCIP_Real SCIPsdpiSolverGetDefaultSdpiSolverFeastol(void)
SCIP_Real SCIPsdpiGetDefaultSdpiSolverGaptol(void)
Definition: sdpi.c:1412
SCIP_RETCODE SCIPsdpiGetPreoptimalPrimalNonzeros(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz)
Definition: sdpi.c:3363
#define CHECK_IF_SOLVED(sdpi)
Definition: sdpi.c:69
#define DEFAULT_EPSILON
Definition: sdpi.c:136
EXTERN SCIP_Real SCIPsdpiSolverInfinity(SCIP_SDPISOLVER *sdpisolver)
enum SCIP_SDPParam SCIP_SDPPARAM
Definition: type_sdpi.h:69
EXTERN void * SCIPsdpiSolverGetSolverPointer(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Bool SCIPsdpiSolverIsInfinity(SCIP_SDPISOLVER *sdpisolver, SCIP_Real val)
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_RETCODE SCIPsdpiGetPrimalBoundVars(SCIP_SDPI *sdpi, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
Definition: sdpi.c:3472
interface methods for eigenvector computation and matrix multiplication using different versions of L...
SCIP_Bool SCIPsdpiSolvedOrig(SCIP_SDPI *sdpi)
Definition: sdpi.c:2860
SCIP_RETCODE SCIPsdpiSlater(SCIP_SDPI *sdpi, SCIP_SDPSLATER *primalslater, SCIP_SDPSLATER *dualslater)
Definition: sdpi.c:3941
#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:504
EXTERN SCIP_RETCODE SCIPsdpiSolverComputeLambdastar(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxguess)