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