SCIP-SDP  3.1.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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1058  SCIP_SDPSOLVERSETTING_UNSOLVED, solvertimelimit, &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, NULL, NULL, NULL,
1284  NULL, NULL, NULL, NULL, NULL, 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 
1419  void
1420  )
1421 {
1423 }
1424 
1427  void
1428  )
1429 {
1431 }
1432 
1436 /*
1437  * SDPI Creation and Destruction Methods
1438  */
1439 
1444 SCIP_RETCODE SCIPsdpiCreate(
1445  SCIP_SDPI** sdpi,
1446  SCIP_MESSAGEHDLR* messagehdlr,
1447  BMS_BLKMEM* blkmem,
1448  BMS_BUFMEM* bufmem
1449  )
1450 {
1451  assert ( sdpi != NULL );
1452  assert ( blkmem != NULL );
1453 
1454  SCIPdebugMessage("Calling SCIPsdpiCreate\n");
1455 
1456  BMS_CALL( BMSallocBlockMemory(blkmem, sdpi) );
1457 
1458  SCIP_CALL( SCIPsdpiSolverCreate(&((*sdpi)->sdpisolver), messagehdlr, blkmem, bufmem) );
1459 
1460  (*sdpi)->messagehdlr = messagehdlr;
1461  (*sdpi)->blkmem = blkmem;
1462  (*sdpi)->bufmem = bufmem;
1463  (*sdpi)->sdpid = 1;
1464  (*sdpi)->niterations = 0;
1465  (*sdpi)->nsdpcalls = 0;
1466  (*sdpi)->nvars = 0;
1467  (*sdpi)->nsdpblocks = 0;
1468  (*sdpi)->sdpconstnnonz = 0;
1469  (*sdpi)->sdpnnonz = 0;
1470  (*sdpi)->nlpcons = 0;
1471  (*sdpi)->lpnnonz = 0;
1472  (*sdpi)->slatercheck = 0;
1473  (*sdpi)->solved = FALSE;
1474  (*sdpi)->penalty = FALSE;
1475  (*sdpi)->infeasible = FALSE;
1476  (*sdpi)->allfixed = FALSE;
1477 
1478  (*sdpi)->obj = NULL;
1479  (*sdpi)->lb = NULL;
1480  (*sdpi)->ub = NULL;
1481  (*sdpi)->sdpblocksizes = NULL;
1482  (*sdpi)->sdpnblockvars = NULL;
1483  (*sdpi)->sdpconstnblocknonz = NULL;
1484  (*sdpi)->sdpconstrow = NULL;
1485  (*sdpi)->sdpconstcol = NULL;
1486  (*sdpi)->sdpconstval = NULL;
1487  (*sdpi)->sdpnblockvarnonz = NULL;
1488  (*sdpi)->sdpvar = NULL;
1489  (*sdpi)->sdprow = NULL;
1490  (*sdpi)->sdpcol = NULL;
1491  (*sdpi)->sdpval = NULL;
1492  (*sdpi)->lplhs = NULL;
1493  (*sdpi)->lprhs = NULL;
1494  (*sdpi)->lprow = NULL;
1495  (*sdpi)->lpcol = NULL;
1496  (*sdpi)->lpval = NULL;
1497 
1498  (*sdpi)->epsilon = DEFAULT_EPSILON;
1499  (*sdpi)->gaptol = DEFAULT_SDPSOLVERGAPTOL;
1500  (*sdpi)->feastol = DEFAULT_FEASTOL;
1501  (*sdpi)->penaltyparam = DEFAULT_PENALTYPARAM;
1502  (*sdpi)->maxpenaltyparam = DEFAULT_MAXPENALTYPARAM;
1503  (*sdpi)->npenaltyincr = DEFAULT_NPENALTYINCR;
1504  (*sdpi)->bestbound = -SCIPsdpiSolverInfinity((*sdpi)->sdpisolver);
1505  (*sdpi)->primalslater = SCIP_SDPSLATER_NOINFO;
1506  (*sdpi)->dualslater = SCIP_SDPSLATER_NOINFO;
1507 
1508  return SCIP_OKAY;
1509 }
1510 
1512 SCIP_RETCODE SCIPsdpiFree(
1513  SCIP_SDPI** sdpi
1514  )
1515 {
1516  int i;
1517  int j;
1518 
1519  SCIPdebugMessage("Calling SCIPsdpiFree \n");
1520  assert ( sdpi != NULL );
1521  assert ( *sdpi != NULL );
1522 
1523  /* free the LP part */
1524  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lpval), (*sdpi)->lpnnonz);
1525  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lpcol), (*sdpi)->lpnnonz);
1526  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lprow), (*sdpi)->lpnnonz);
1527  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lprhs), (*sdpi)->nlpcons);
1528  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lplhs), (*sdpi)->nlpcons);
1529 
1530  /* free the individual nonzeros */
1531  for (i = 0; i < (*sdpi)->nsdpblocks; i++)
1532  {
1533  for (j = 0; j < (*sdpi)->sdpnblockvars[i]; j++)
1534  {
1535  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval[i][j]), (*sdpi)->sdpnblockvarnonz[i][j]);
1536  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow[i][j]), (*sdpi)->sdpnblockvarnonz[i][j]);
1537  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol[i][j]), (*sdpi)->sdpnblockvarnonz[i][j]);
1538  }
1539  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval[i]), (*sdpi)->sdpnblockvars[i]);
1540  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow[i]), (*sdpi)->sdpnblockvars[i]);
1541  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol[i]), (*sdpi)->sdpnblockvars[i]);
1542  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpvar[i]), (*sdpi)->sdpnblockvars[i]);
1543  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvarnonz[i]), (*sdpi)->sdpnblockvars[i]);
1544  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstval[i]), (*sdpi)->sdpconstnblocknonz[i]);
1545  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstrow[i]), (*sdpi)->sdpconstnblocknonz[i]);
1546  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstcol[i]), (*sdpi)->sdpconstnblocknonz[i]);
1547  }
1548 
1549  /* free the rest */
1550  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvarnonz), (*sdpi)->nsdpblocks);
1551  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstnblocknonz), (*sdpi)->nsdpblocks);
1552  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval), (*sdpi)->nsdpblocks);
1553  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol), (*sdpi)->nsdpblocks);
1554  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow), (*sdpi)->nsdpblocks);
1555  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpvar), (*sdpi)->nsdpblocks);
1556  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstval), (*sdpi)->nsdpblocks);
1557  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstcol), (*sdpi)->nsdpblocks);
1558  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstrow), (*sdpi)->nsdpblocks);
1559  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvars), (*sdpi)->nsdpblocks);
1560  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpblocksizes), (*sdpi)->nsdpblocks);
1561  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->ub), (*sdpi)->nvars);/*lint !e737*/
1562  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lb), (*sdpi)->nvars);/*lint !e737*/
1563  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->obj), (*sdpi)->nvars);/*lint !e737*/
1564 
1565  /* free the solver */
1566  SCIP_CALL( SCIPsdpiSolverFree(&((*sdpi)->sdpisolver)) );
1567 
1568  BMSfreeBlockMemory((*sdpi)->blkmem, sdpi);
1569 
1570  return SCIP_OKAY;
1571 }
1572 
1577 SCIP_RETCODE SCIPsdpiClone(
1578  SCIP_SDPI* oldsdpi,
1579  SCIP_SDPI* newsdpi
1580  )
1581 {
1582  BMS_BLKMEM* blkmem;
1583  int nvars;
1584  int nsdpblocks;
1585  int lpnnonz;
1586  int b;
1587  int v;
1588 
1589  assert( oldsdpi != NULL );
1590 
1591  SCIPdebugMessage("Cloning SDPI %d\n", oldsdpi->sdpid);
1592 
1593  /* general data */
1594  blkmem = oldsdpi->blkmem;
1595  nvars = oldsdpi->nvars;
1596  nsdpblocks = oldsdpi->nsdpblocks;
1597  lpnnonz = oldsdpi->lpnnonz;
1598 
1599  BMS_CALL( BMSallocBlockMemory(blkmem, &newsdpi) );
1600 
1601  SCIP_CALL( SCIPsdpiSolverCreate(&(newsdpi->sdpisolver), oldsdpi->messagehdlr, oldsdpi->blkmem, oldsdpi->bufmem) ); /* create new SDP-Solver Interface */
1602 
1603  newsdpi->messagehdlr = oldsdpi->messagehdlr;
1604  newsdpi->blkmem = blkmem;
1605  newsdpi->nvars = nvars;
1606 
1607  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->obj), oldsdpi->obj, nvars) );
1608  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lb), oldsdpi->lb, nvars) );
1609  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->ub), oldsdpi->ub, nvars) );
1610 
1611  newsdpi->nsdpblocks = nsdpblocks;
1612 
1613  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpblocksizes), oldsdpi->sdpblocksizes, nsdpblocks) );
1614  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvars), oldsdpi->sdpnblockvars, nsdpblocks) );
1615 
1616  /* constant SDP data */
1617  newsdpi->sdpconstnnonz = oldsdpi->sdpconstnnonz;
1618 
1619  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstnblocknonz), oldsdpi->sdpconstnblocknonz, nsdpblocks) );
1620  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstrow), nsdpblocks) );
1621  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstcol), nsdpblocks) );
1622  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstval), nsdpblocks) );
1623 
1624  for (b = 0; b < nsdpblocks; b++)
1625  {
1626  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstrow[b]), oldsdpi->sdpconstrow[b], oldsdpi->sdpconstnblocknonz[b]) );
1627  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstcol[b]), oldsdpi->sdpconstcol[b], oldsdpi->sdpconstnblocknonz[b]) );
1628  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstval[b]), oldsdpi->sdpconstval[b], oldsdpi->sdpconstnblocknonz[b]) );
1629  }
1630 
1631  /* SDP data */
1632  newsdpi->sdpnnonz = oldsdpi->sdpnnonz;
1633 
1634  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvarnonz), nsdpblocks) );
1635  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpvar), nsdpblocks) );
1636  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdprow), nsdpblocks) );
1637  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpcol), nsdpblocks) );
1638  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpval), nsdpblocks) );
1639 
1640  for (b = 0; b < nsdpblocks; b++)
1641  {
1642  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvarnonz[b]), oldsdpi->sdpnblockvarnonz[b], oldsdpi->sdpnblockvars[b]) );
1643  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpvar[b]), oldsdpi->sdpvar[b], oldsdpi->sdpnblockvars[b]) );
1644 
1645  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdprow[b]), oldsdpi->sdpnblockvars[b]) );
1646  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpcol[b]), oldsdpi->sdpnblockvars[b]) );
1647  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpval[b]), oldsdpi->sdpnblockvars[b]) );
1648 
1649  for (v = 0; v < oldsdpi->sdpnblockvars[b]; v++)
1650  {
1651  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdprow[b][v]), oldsdpi->sdprow[b][v], oldsdpi->sdpnblockvarnonz[b][v]) );
1652  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpcol[b][v]), oldsdpi->sdpcol[b][v], oldsdpi->sdpnblockvarnonz[b][v]) );
1653  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpval[b][v]), oldsdpi->sdpval[b][v], oldsdpi->sdpnblockvarnonz[b][v]) );
1654  }
1655  }
1656 
1657  /* LP data */
1658  newsdpi->nlpcons = oldsdpi->nlpcons;
1659 
1660  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lplhs), oldsdpi->lplhs, oldsdpi->nlpcons) );
1661  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lprhs), oldsdpi->lprhs, oldsdpi->nlpcons) );
1662 
1663  newsdpi->lpnnonz = lpnnonz;
1664 
1665  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lprow), oldsdpi->lprow, lpnnonz) );
1666  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lpcol), oldsdpi->lpcol, lpnnonz) );
1667  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lpval), oldsdpi->lpval, lpnnonz) );
1668 
1669  /* other data */
1670  newsdpi->solved = FALSE; /* as we don't copy the sdpisolver, this needs to be set to false */
1671  newsdpi->penalty = FALSE; /* all things about SDP-solutions are set to false as well, as we didn't solve the problem */
1672  newsdpi->infeasible = FALSE;
1673  newsdpi->allfixed = FALSE;
1674  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 */
1675  newsdpi->epsilon = oldsdpi->epsilon;
1676  newsdpi->gaptol = oldsdpi->gaptol;
1677  newsdpi->feastol = oldsdpi->feastol;
1678 
1679  return SCIP_OKAY;
1680 }
1681 
1685 /*
1686  * Modification Methods
1687  */
1688 
1697 SCIP_RETCODE SCIPsdpiLoadSDP(
1698  SCIP_SDPI* sdpi,
1699  int nvars,
1700  SCIP_Real* obj,
1701  SCIP_Real* lb,
1702  SCIP_Real* ub,
1703  int nsdpblocks,
1704  int* sdpblocksizes,
1705  int* sdpnblockvars,
1706  int sdpconstnnonz,
1707  int* sdpconstnblocknonz,
1709  int** sdpconstrow,
1710  int** sdpconstcol,
1711  SCIP_Real** sdpconstval,
1712  int sdpnnonz,
1713  int** sdpnblockvarnonz,
1715  int** sdpvar,
1717  int*** sdprow,
1720  int*** sdpcol,
1721  SCIP_Real*** sdpval,
1723  int nlpcons,
1724  SCIP_Real* lplhs,
1725  SCIP_Real* lprhs,
1726  int lpnnonz,
1727  int* lprow,
1728  int* lpcol,
1729  SCIP_Real* lpval
1730  )
1731 {
1732  int i;
1733  int v;
1734  int block;
1735 
1736  SCIPdebugMessage("Calling SCIPsdpiLoadSDP (%d)\n",sdpi->sdpid);
1737 
1738  assert ( sdpi != NULL );
1739  assert ( nvars > 0 );
1740  assert ( obj != NULL );
1741  assert ( lb != NULL );
1742  assert ( ub != NULL );
1743 
1744 #ifdef SCIP_DEBUG
1745  if (sdpconstnnonz > 0 || sdpnnonz > 0 || nsdpblocks > 0)
1746  {
1747  assert ( sdpblocksizes != NULL );
1748  assert ( sdpnblockvars != NULL );
1749  assert ( nsdpblocks > 0 );
1750  assert ( sdpconstnblocknonz != NULL );
1751  assert ( sdpnblockvarnonz != NULL );
1752 
1753  if (sdpconstnnonz > 0)
1754  {
1755  assert ( sdpconstrow != NULL );
1756  assert ( sdpconstcol != NULL );
1757  assert ( sdpconstval != NULL );
1758 
1759  for (i = 0; i < nsdpblocks; i++)
1760  {
1761  if (sdpconstnblocknonz[i] > 0)
1762  {
1763  assert ( sdpconstrow[i] != NULL );
1764  assert ( sdpconstcol[i] != NULL );
1765  assert ( sdpconstval[i] != NULL );
1766  }
1767  }
1768  }
1769 
1770  if (sdpnnonz > 0)
1771  {
1772  assert ( sdprow != NULL );
1773  assert ( sdpcol != NULL );
1774  assert ( sdpval != NULL );
1775 
1776  for ( i = 0; i < nsdpblocks; i++ )
1777  {
1778  assert ( sdpcol[i] != NULL );
1779  assert ( sdprow[i] != NULL );
1780  assert ( sdpval[i] != NULL );
1781 
1782  for ( v = 0; v < sdpnblockvars[i]; v++)
1783  {
1784  if (sdpnblockvarnonz[i][v] > 0)
1785  {
1786  assert ( sdpcol[i][v] != NULL );
1787  assert ( sdprow[i][v] != NULL );
1788  assert ( sdpval[i][v] != NULL );
1789  }
1790  }
1791  }
1792  }
1793  }
1794 #endif
1795 
1796  assert ( nlpcons == 0 || lplhs != NULL );
1797  assert ( nlpcons == 0 || lprhs != NULL );
1798  assert ( lpnnonz == 0 || lprow != NULL );
1799  assert ( lpnnonz == 0 || lpcol != NULL );
1800  assert ( lpnnonz == 0 || lpval != NULL );
1801 
1802  /* memory allocation */
1803 
1804  /* first free the old arrays */
1805  for (block = sdpi->nsdpblocks - 1; block >= 0; block--)
1806  {
1807  for (v = sdpi->sdpnblockvars[block] - 1; v >= 0; v--)
1808  {
1809  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpval[block][v]), sdpi->sdpnblockvarnonz[block][v]);
1810  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdprow[block][v]), sdpi->sdpnblockvarnonz[block][v]);
1811  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpcol[block][v]), sdpi->sdpnblockvarnonz[block][v]);
1812  }
1813 
1814  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpval[block]), sdpi->sdpnblockvars[block]);
1815  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdprow[block]), sdpi->sdpnblockvars[block]);
1816  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpcol[block]), sdpi->sdpnblockvars[block]);
1817  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstval[block]), sdpi->sdpconstnblocknonz[block]);
1818  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstrow[block]), sdpi->sdpconstnblocknonz[block]);
1819  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstcol[block]), sdpi->sdpconstnblocknonz[block]);
1820  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpnblockvarnonz[block]), sdpi->sdpnblockvars[block]);
1821  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpvar[block]), sdpi->sdpnblockvars[block]);
1822  }
1823 
1824  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->ub), sdpi->nvars);
1825  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lb), sdpi->nvars);
1826  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->obj), sdpi->nvars);
1827 
1828  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpblocksizes), sdpi->nsdpblocks);
1829  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpnblockvars), sdpi->nsdpblocks);
1830  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstnblocknonz), sdpi->nsdpblocks);
1831 
1832  /* duplicate some arrays */
1833  BMS_CALL( BMSduplicateBlockMemoryArray(sdpi->blkmem, &(sdpi->obj), obj, nvars) );
1834  BMS_CALL( BMSduplicateBlockMemoryArray(sdpi->blkmem, &(sdpi->lb), lb, nvars) );
1835  BMS_CALL( BMSduplicateBlockMemoryArray(sdpi->blkmem, &(sdpi->ub), ub, nvars) );
1836  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpblocksizes), sdpblocksizes, nsdpblocks);
1837  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpnblockvars), sdpnblockvars, nsdpblocks);
1838  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstnblocknonz), sdpconstnblocknonz, nsdpblocks);
1839 
1840  /* allocate memory for the sdp arrays & duplicate them */
1841  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpnblockvarnonz), sdpi->nsdpblocks, nsdpblocks) );
1842  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstcol), sdpi->nsdpblocks, nsdpblocks) );
1843  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstrow), sdpi->nsdpblocks, nsdpblocks) );
1844  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstval), sdpi->nsdpblocks, nsdpblocks) );
1845  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpvar), sdpi->nsdpblocks, nsdpblocks) );
1846  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpcol), sdpi->nsdpblocks, nsdpblocks) );
1847  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdprow), sdpi->nsdpblocks, nsdpblocks) );
1848  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpval), sdpi->nsdpblocks, nsdpblocks) );
1849 
1850  for (block = 0; block < nsdpblocks; block++)
1851  {
1852  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpnblockvarnonz[block]), sdpnblockvarnonz[block], sdpnblockvars[block]);
1853 
1854  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstcol[block]), sdpconstcol[block], sdpconstnblocknonz[block]);
1855  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstrow[block]), sdpconstrow[block], sdpconstnblocknonz[block]);
1856  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstval[block]), sdpconstval[block], sdpconstnblocknonz[block]);
1857 
1858  /* make sure that we have a lower triangular matrix */
1859  for (i = 0; i < sdpi->sdpconstnblocknonz[block]; ++i)
1860  ensureLowerTriangular(&(sdpconstrow[block][i]), &(sdpconstcol[block][i]));
1861 
1862  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpvar[block]), sdpvar[block], sdpnblockvars[block]);
1863 
1864  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpcol[block]), sdpnblockvars[block]) );
1865  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdprow[block]), sdpnblockvars[block]) );
1866  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpval[block]), sdpnblockvars[block]) );
1867 
1868  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
1869  {
1870  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpcol[block][v]), sdpcol[block][v], sdpnblockvarnonz[block][v]);
1871  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdprow[block][v]), sdprow[block][v], sdpnblockvarnonz[block][v]);
1872  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpval[block][v]), sdpval[block][v], sdpnblockvarnonz[block][v]);
1873 
1874  /* make sure that we have a lower triangular matrix */
1875  for (i = 0; i < sdpi->sdpnblockvarnonz[block][v]; ++i)
1876  ensureLowerTriangular(&(sdprow[block][v][i]), &(sdpcol[block][v][i]));
1877  }
1878  }
1879 
1880  /* free old and duplicate new arrays for the LP part */
1881  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz);
1882  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz);
1883  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz);
1884  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons);
1885  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons);
1886 
1887  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lplhs), lplhs, nlpcons);
1888  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lprhs), lprhs, nlpcons);
1889  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lprow), lprow, lpnnonz);
1890  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lpcol), lpcol, lpnnonz);
1891  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lpval), lpval, lpnnonz);
1892 
1893  /* set the general information */
1894  sdpi->nvars = nvars;
1895  sdpi->nsdpblocks = nsdpblocks;
1896 
1897  sdpi->sdpconstnnonz = sdpconstnnonz;
1898  sdpi->sdpnnonz = sdpnnonz;
1899 
1900  /* LP part */
1901  sdpi->lpnnonz = lpnnonz;
1902  sdpi->nlpcons = nlpcons;
1903 
1904  sdpi->solved = FALSE;
1905  sdpi->infeasible = FALSE;
1906  sdpi->allfixed = FALSE;
1907  sdpi->nsdpcalls = 0;
1908  sdpi->niterations = 0;
1909 
1910  return SCIP_OKAY;
1911 }
1912 
1917 SCIP_RETCODE SCIPsdpiAddLPRows(
1918  SCIP_SDPI* sdpi,
1919  int nrows,
1920  const SCIP_Real* lhs,
1921  const SCIP_Real* rhs,
1922  int nnonz,
1923  const int* row,
1925  const int* col,
1926  const SCIP_Real* val
1927  )
1928 {
1929  int i;
1930 
1931  SCIPdebugMessage("Adding %d LP-Constraints to SDP %d.\n", nrows, sdpi->sdpid);
1932 
1933  assert ( sdpi != NULL );
1934 
1935  if ( nrows == 0 )
1936  return SCIP_OKAY; /* nothing to do in this case */
1937 
1938  assert ( lhs != NULL );
1939  assert ( rhs != NULL );
1940  assert ( nnonz >= 0 );
1941  assert ( row != NULL );
1942  assert ( col != NULL );
1943  assert ( val != NULL );
1944 
1945  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons, sdpi->nlpcons + nrows) ); /*lint !e776*/
1946  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons, sdpi->nlpcons + nrows) ); /*lint !e776*/
1947 
1948  for (i = 0; i < nrows; i++)
1949  {
1950  sdpi->lplhs[sdpi->nlpcons + i] = lhs[i]; /*lint !e679*/
1951  sdpi->lprhs[sdpi->nlpcons + i] = rhs[i]; /*lint !e679*/
1952  }
1953 
1954  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz, sdpi->lpnnonz + nnonz) ); /*lint !e776*/
1955  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz, sdpi->lpnnonz + nnonz) ); /*lint !e776*/
1956  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz, sdpi->lpnnonz + nnonz) ); /*lint !e776*/
1957 
1958  for (i = 0; i < nnonz; i++)
1959  {
1960  assert ( 0 <= row[i] && row[i] < nrows );
1961  /* the new rows are added at the end, so the row indices are increased by the old number of LP-constraints */
1962  sdpi->lprow[sdpi->lpnnonz + i] = row[i] + sdpi->nlpcons; /*lint !e679*/
1963 
1964  assert ( 0 <= col[i] && col[i] < sdpi->nvars ); /* only existing vars should be added to the LP-constraints */
1965  sdpi->lpcol[sdpi->lpnnonz + i] = col[i]; /*lint !e679*/
1966 
1967  sdpi->lpval[sdpi->lpnnonz + i] = val[i]; /*lint !e679*/
1968  }
1969 
1970  sdpi->nlpcons = sdpi->nlpcons + nrows;
1971  sdpi->lpnnonz = sdpi->lpnnonz + nnonz;
1972 
1973  sdpi->solved = FALSE;
1974  sdpi->infeasible = FALSE;
1975  sdpi->nsdpcalls = 0;
1976  sdpi->niterations = 0;
1977 
1978  return SCIP_OKAY;
1979 }
1980 
1982 SCIP_RETCODE SCIPsdpiDelLPRows(
1983  SCIP_SDPI* sdpi,
1984  int firstrow,
1985  int lastrow
1986  )
1987 {
1988  int i;
1989  int deletedrows;
1990  int firstrowind;
1991  int lastrowind;
1992  int deletednonz;
1993 
1994  SCIPdebugMessage("Deleting rows %d to %d from SDP %d.\n", firstrow, lastrow, sdpi->sdpid);
1995 
1996  assert ( sdpi != NULL );
1997  assert ( firstrow >= 0 );
1998  assert ( firstrow <= lastrow );
1999  assert ( lastrow < sdpi->nlpcons );
2000 
2001  /* shorten the procedure if the whole LP-part is to be deleted */
2002  if (firstrow == 0 && lastrow == sdpi->nlpcons - 1)
2003  {
2004  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz);/*lint !e737*/
2005  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz);/*lint !e737*/
2006  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz);/*lint !e737*/
2007  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons);/*lint !e737*/
2008  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons);/*lint !e737*/
2009 
2010  sdpi->lplhs = NULL;
2011  sdpi->lprhs = NULL;
2012  sdpi->lpcol = NULL;
2013  sdpi->lprow = NULL;
2014  sdpi->lpval = NULL;
2015 
2016  sdpi->nlpcons = 0;
2017  sdpi->lpnnonz = 0;
2018 
2019  sdpi->solved = FALSE;
2020  sdpi->infeasible = FALSE;
2021  sdpi->allfixed = FALSE;
2022  sdpi->nsdpcalls = 0;
2023  sdpi->niterations = 0;
2024 
2025  return SCIP_OKAY;
2026  }
2027 
2028  deletedrows = lastrow - firstrow + 1; /*lint !e834*/
2029  deletednonz = 0;
2030 
2031  /* first delete the left- and right-hand-sides */
2032  for (i = lastrow + 1; i < sdpi->nlpcons; i++) /* shift all rhs after the deleted rows */
2033  {
2034  sdpi->lplhs[i - deletedrows] = sdpi->lplhs[i]; /*lint !e679*/
2035  sdpi->lprhs[i - deletedrows] = sdpi->lprhs[i]; /*lint !e679*/
2036  }
2037  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons, sdpi->nlpcons - deletedrows) ); /*lint !e776*/
2038  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons, sdpi->nlpcons - deletedrows) ); /*lint !e776*/
2039 
2040  /* for deleting and reordering the lpnonzeroes, the arrays first have to be sorted to have the rows to be deleted together */
2041  SCIPsortIntIntReal(sdpi->lprow, sdpi->lpcol, sdpi->lpval, sdpi->lpnnonz); /* sort all arrays by non-decreasing row indices */
2042 
2043  firstrowind = -1;
2044  /*iterate over the lprowind array to find the first index belonging to a row that should be deleted */
2045  for (i = 0; i < sdpi->lpnnonz; i++)
2046  {
2047  if (sdpi->lprow[i] >= firstrow && sdpi->lprow[i] <= lastrow) /* the and part makes sure that there actually were some nonzeroes in these rows */
2048  {
2049  firstrowind = i;
2050  lastrowind = i;
2051  i++;
2052  break;
2053  }
2054  }
2055 
2056  if (firstrowind > -1) /* if this is still 0 there are no nonzeroes for the given rows */
2057  {
2058  /* 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) */
2059  while (i < sdpi->lpnnonz && sdpi->lprow[i] <= lastrow)
2060  {
2061  lastrowind++; /*lint !e644*/
2062  i++;
2063  }
2064  deletednonz = lastrowind - firstrowind + 1; /*lint !e834*/
2065 
2066  /* finally shift all LP-array-entries after the deleted rows */
2067  for (i = lastrowind + 1; i < sdpi->lpnnonz; i++)
2068  {
2069  sdpi->lpcol[i - deletednonz] = sdpi->lpcol[i]; /*lint !e679*/
2070  /* all rowindices after the deleted ones have to be lowered to still have ongoing indices from 0 to nlpcons-1 */
2071  sdpi->lprow[i - deletednonz] = sdpi->lprow[i] - deletedrows; /*lint !e679*/
2072  sdpi->lpval[i - deletednonz] = sdpi->lpval[i]; /*lint !e679*/
2073  }
2074  }
2075 
2076  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz, sdpi->lpnnonz - deletednonz) ); /*lint !e776*/
2077  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz, sdpi->lpnnonz - deletednonz) ); /*lint !e776*/
2078  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz, sdpi->lpnnonz - deletednonz) ); /*lint !e776*/
2079  sdpi->nlpcons = sdpi->nlpcons - deletedrows;
2080  sdpi->lpnnonz = sdpi->lpnnonz - deletednonz;
2081 
2082  sdpi->solved = FALSE;
2083  sdpi->infeasible = FALSE;
2084  sdpi->allfixed = FALSE;
2085  sdpi->nsdpcalls = 0;
2086  sdpi->niterations = 0;
2087 
2088  return SCIP_OKAY;
2089 }
2090 
2092 SCIP_RETCODE SCIPsdpiDelLPRowset(
2093  SCIP_SDPI* sdpi,
2094  int* dstat
2097  )
2098 {
2099  int i;
2100  int oldnlpcons;
2101  int deletedrows;
2102 
2103  SCIPdebugMessage("Calling SCIPsdpiDelLPRowset for SDP %d.\n", sdpi->sdpid);
2104 
2105  assert ( sdpi != NULL );
2106  assert ( dstat != NULL );
2107 
2108  oldnlpcons = sdpi->nlpcons;
2109  deletedrows = 0;
2110 
2111  for (i = 0; i < oldnlpcons; i++)
2112  {
2113  if (dstat[i] == 1)
2114  {
2115  /* delete this row, it is shifted by - deletedrows, because in this problem the earlier rows have already been deleted */
2116  SCIP_CALL( SCIPsdpiDelLPRows(sdpi, i - deletedrows, i - deletedrows) );
2117  dstat[i] = -1;
2118  deletedrows++;
2119  }
2120  else
2121  dstat[i] = i - deletedrows;
2122  }
2123 
2124  sdpi->solved = FALSE;
2125  sdpi->infeasible = FALSE;
2126  sdpi->allfixed = FALSE;
2127  sdpi->nsdpcalls = 0;
2128  sdpi->niterations = 0;
2129 
2130  return SCIP_OKAY;
2131 }
2132 
2134 SCIP_RETCODE SCIPsdpiClear(
2135  SCIP_SDPI* sdpi
2136  )
2137 {
2138  assert( sdpi != NULL );
2139 
2140  SCIPdebugMessage("Called SCIPsdpiClear in SDP %d.\n", sdpi->sdpid);
2141 
2142  /* we reset all counters */
2143  sdpi->sdpid = 1;
2144  SCIP_CALL( SCIPsdpiSolverResetCounter(sdpi->sdpisolver) );
2145 
2146  return SCIP_OKAY;
2147 }
2148 
2150 SCIP_RETCODE SCIPsdpiChgObj(
2151  SCIP_SDPI* sdpi,
2152  int nvars,
2153  const int* ind,
2154  const SCIP_Real* obj
2155  )
2156 {
2157  int i;
2158 
2159  SCIPdebugMessage("Changing %d objective coefficients in SDP %d\n", nvars, sdpi->sdpid);
2160 
2161  assert( sdpi != NULL );
2162  assert( ind != NULL );
2163  assert( obj != NULL );
2164 
2165  for (i = 0; i < nvars; i++)
2166  {
2167  assert( 0 <= ind[i] && ind[i] < sdpi->nvars );
2168  sdpi->obj[ind[i]] = obj[i];
2169  }
2170 
2171  sdpi->solved = FALSE;
2172  sdpi->nsdpcalls = 0;
2173  sdpi->niterations = 0;
2174 
2175  return SCIP_OKAY;
2176 }
2177 
2179 SCIP_RETCODE SCIPsdpiChgBounds(
2180  SCIP_SDPI* sdpi,
2181  int nvars,
2182  const int* ind,
2183  const SCIP_Real* lb,
2184  const SCIP_Real* ub
2185  )
2186 {
2187  int i;
2188 
2189  SCIPdebugMessage("Changing %d variable bounds in SDP %d\n", nvars, sdpi->sdpid);
2190 
2191  assert( sdpi != NULL );
2192  assert( ind != NULL );
2193  assert( lb != NULL );
2194  assert( ub != NULL );
2195 
2196  for (i = 0; i < nvars; i++)
2197  {
2198  assert( 0 <= ind[i] && ind[i] < sdpi->nvars );
2199  sdpi->lb[ind[i]] = lb[i];
2200  sdpi->ub[ind[i]] = ub[i];
2201  }
2202 
2203  sdpi->solved = FALSE;
2204  sdpi->infeasible = FALSE;
2205  sdpi->allfixed = FALSE;
2206  sdpi->nsdpcalls = 0;
2207  sdpi->niterations = 0;
2208 
2209  return SCIP_OKAY;
2210 }
2211 
2214  SCIP_SDPI* sdpi,
2215  int nrows,
2216  const int* ind,
2217  const SCIP_Real* lhs,
2218  const SCIP_Real* rhs
2219  )
2220 {
2221  int i;
2222 
2223  SCIPdebugMessage("Changing %d left and right hand sides of SDP %d\n", nrows, sdpi->sdpid);
2224 
2225  assert( sdpi != NULL );
2226  assert( 0 <= nrows && nrows <= sdpi->nlpcons );
2227  assert( ind != NULL );
2228  assert( lhs != NULL );
2229  assert( rhs != NULL );
2230 
2231  for (i = 0; i < nrows; i++)
2232  {
2233  assert ( ind[i] >= 0 );
2234  assert ( ind[i] < sdpi->nlpcons );
2235  sdpi->lplhs[ind[i]] = lhs[i];
2236  sdpi->lprhs[ind[i]] = rhs[i];
2237  }
2238 
2239  sdpi->solved = FALSE;
2240  sdpi->infeasible = FALSE;
2241  sdpi->allfixed = FALSE;
2242  sdpi->nsdpcalls = 0;
2243  sdpi->niterations = 0;
2244 
2245  return SCIP_OKAY;
2246 }
2247 
2248 
2249 /*
2250  * Data Accessing Methods
2251  */
2252 
2257 SCIP_RETCODE SCIPsdpiGetNLPRows(
2258  SCIP_SDPI* sdpi,
2259  int* nlprows
2260  )
2261 {
2262  assert( sdpi != NULL );
2263  assert( nlprows != NULL );
2264 
2265  *nlprows = sdpi->nlpcons;
2266 
2267  return SCIP_OKAY;
2268 }
2269 
2272  SCIP_SDPI* sdpi,
2273  int* nsdpblocks
2274  )
2275 {
2276  assert( sdpi != NULL );
2277  assert( nsdpblocks != NULL );
2278 
2279  *nsdpblocks = sdpi->nsdpblocks;
2280 
2281  return SCIP_OKAY;
2282 }
2283 
2285 SCIP_RETCODE SCIPsdpiGetNVars(
2286  SCIP_SDPI* sdpi,
2287  int* nvars
2288  )
2289 {
2290  assert( sdpi != NULL );
2291  assert( nvars != NULL );
2292 
2293  *nvars = sdpi->nvars;
2294 
2295  return SCIP_OKAY;
2296 }
2297 
2299 SCIP_RETCODE SCIPsdpiGetSDPNNonz(
2300  SCIP_SDPI* sdpi,
2301  int* nnonz
2302  )
2303 {
2304  assert( sdpi != NULL );
2305  assert( nnonz != NULL );
2306 
2307  *nnonz = sdpi->sdpnnonz;
2308 
2309  return SCIP_OKAY;
2310 }
2311 
2314  SCIP_SDPI* sdpi,
2315  int* nnonz
2316  )
2317 {
2318  assert( sdpi != NULL );
2319  assert( nnonz != NULL );
2320 
2321  *nnonz = sdpi->sdpconstnnonz;
2322 
2323  return SCIP_OKAY;
2324 }
2325 
2327 SCIP_RETCODE SCIPsdpiGetLPNNonz(
2328  SCIP_SDPI* sdpi,
2329  int* nnonz
2330  )
2331 {
2332  assert( sdpi != NULL );
2333  assert( nnonz != NULL );
2334 
2335  *nnonz = sdpi->lpnnonz;
2336 
2337  return SCIP_OKAY;
2338 }
2339 
2341 SCIP_RETCODE SCIPsdpiGetObj(
2342  SCIP_SDPI* sdpi,
2343  int firstvar,
2344  int lastvar,
2345  SCIP_Real* vals
2346  )
2347 {
2348  int i;
2349 
2350  assert( sdpi != NULL );
2351  assert( firstvar >= 0 );
2352  assert( firstvar <= lastvar );
2353  assert( lastvar < sdpi->nvars);
2354  assert( vals != NULL );
2355 
2356  for (i = 0; i < lastvar - firstvar + 1; i++) /*lint !e834*/
2357  vals[i] = sdpi->obj[firstvar + i]; /*lint !e679*/
2358 
2359  return SCIP_OKAY;
2360 }
2361 
2363 SCIP_RETCODE SCIPsdpiGetBounds(
2364  SCIP_SDPI* sdpi,
2365  int firstvar,
2366  int lastvar,
2367  SCIP_Real* lbs,
2368  SCIP_Real* ubs
2369  )
2370 {
2371  int i;
2372 
2373  assert( sdpi != NULL );
2374  assert( firstvar >= 0 );
2375  assert( firstvar <= lastvar );
2376  assert( lastvar < sdpi->nvars);
2377  assert( lbs != NULL );
2378  assert( ubs != NULL );
2379 
2380  for (i = 0; i < lastvar - firstvar + 1; i++) /*lint !e834*/
2381  {
2382  if (lbs != NULL)
2383  lbs[i] = sdpi->lb[firstvar + i]; /*lint !e679*/
2384  if (ubs != NULL)
2385  ubs[i] = sdpi->ub[firstvar + i]; /*lint !e679*/
2386  }
2387  return SCIP_OKAY;
2388 }
2389 
2391 SCIP_RETCODE SCIPsdpiGetLhSides(
2392  SCIP_SDPI* sdpi,
2393  int firstrow,
2394  int lastrow,
2395  SCIP_Real* lhss
2396  )
2397 {
2398  int i;
2399 
2400  assert( sdpi != NULL );
2401  assert( firstrow >= 0 );
2402  assert( firstrow <= lastrow );
2403  assert( lastrow < sdpi->nlpcons);
2404  assert( lhss != NULL );
2405 
2406  for (i = 0; i < lastrow - firstrow + 1; i++) /*lint !e834*/
2407  lhss[firstrow + i] = sdpi->lplhs[i]; /*lint !e679*/
2408 
2409  return SCIP_OKAY;
2410 }
2411 
2413 SCIP_RETCODE SCIPsdpiGetRhSides(
2414  SCIP_SDPI* sdpi,
2415  int firstrow,
2416  int lastrow,
2417  SCIP_Real* rhss
2418  )
2419 {
2420  int i;
2421 
2422  assert( sdpi != NULL );
2423  assert( firstrow >= 0 );
2424  assert( firstrow <= lastrow );
2425  assert( lastrow < sdpi->nlpcons);
2426  assert( rhss != NULL );
2427 
2428  for (i = 0; i < lastrow - firstrow + 1; i++) /*lint !e834*/
2429  rhss[firstrow + i] = sdpi->lprhs[i]; /*lint !e679*/
2430 
2431  return SCIP_OKAY;
2432 }
2433 
2434 
2439 /*
2440  * Solving Methods
2441  */
2442 
2451 SCIP_RETCODE SCIPsdpiSolve(
2452  SCIP_SDPI* sdpi,
2453  SCIP_Real* starty,
2454  int* startZnblocknonz,
2456  int** startZrow,
2458  int** startZcol,
2460  SCIP_Real** startZval,
2462  int* startXnblocknonz,
2464  int** startXrow,
2466  int** startXcol,
2468  SCIP_Real** startXval,
2470  SCIP_SDPSOLVERSETTING startsettings,
2472  SCIP_Bool enforceslatercheck,
2474  SCIP_Real timelimit
2475  )
2476 {
2477  int* sdpconstnblocknonz = NULL;
2478  int** sdpconstrow = NULL;
2479  int** sdpconstcol = NULL;
2480  SCIP_Real** sdpconstval = NULL;
2481  int** indchanges = NULL;
2482  int* nremovedinds = NULL;
2483  SCIP_Real* lplhsafterfix;
2484  SCIP_Real* lprhsafterfix;
2485  SCIP_Real solvertimelimit;
2486  SCIP_Bool fixingfound;
2487  clock_t starttime;
2488  clock_t currenttime;
2489  int* rowsnactivevars;
2490  int* blockindchanges;
2491  int sdpconstnnonz;
2492  int nactivelpcons;
2493  int nremovedblocks = 0;
2494  int block;
2495  int naddediterations;
2496  int naddedsdpcalls;
2497 
2498  assert( sdpi != NULL );
2499 
2500  starttime = clock();
2501 
2502  SCIPdebugMessage("Forwarding SDP %d to solver!\n", sdpi->sdpid);
2503 
2504  sdpi->penalty = FALSE;
2505  sdpi->bestbound = -SCIPsdpiSolverInfinity(sdpi->sdpisolver);
2506  sdpi->solved = FALSE;
2507  sdpi->nsdpcalls = 0;
2508  sdpi->niterations = 0;
2509 
2510  /* allocate memory for computing the constant matrix after fixings and finding empty rows and columns, this is as much as might possibly be
2511  * needed, this will be shrinked again before solving */
2512  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstnblocknonz, sdpi->nsdpblocks) );
2513  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstrow, sdpi->nsdpblocks) );
2514  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstcol, sdpi->nsdpblocks) );
2515  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstval, sdpi->nsdpblocks) );
2516  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &indchanges, sdpi->nsdpblocks) );
2517  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &nremovedinds, sdpi->nsdpblocks) );
2518  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &blockindchanges, sdpi->nsdpblocks) );
2519  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &lplhsafterfix, sdpi->nlpcons) );
2520  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &lprhsafterfix, sdpi->nlpcons) );
2521  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &rowsnactivevars, sdpi->nlpcons) );
2522 
2523  for (block = 0; block < sdpi->nsdpblocks; block++)
2524  {
2525  sdpconstrow[block] = NULL;
2526  sdpconstcol[block] = NULL;
2527  sdpconstval[block] = NULL;
2528  indchanges[block] = NULL;
2529  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(indchanges[block]), sdpi->sdpblocksizes[block]) );
2530  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
2531  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
2532  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
2533  }
2534 
2535  /* compute the lplphss and lprhss, detect empty rows and check for additional variable fixings caused by boundchanges from
2536  * lp rows with a single active variable */
2537  do
2538  {
2539  fixingfound = FALSE;
2540  SCIP_CALL( computeLpLhsRhsAfterFixings(sdpi, &nactivelpcons, lplhsafterfix, lprhsafterfix, rowsnactivevars, &fixingfound) );
2541  }
2542  while ( fixingfound );
2543 
2544  /* initialize sdpconstnblocknonz */
2545  for (block = 0; block < sdpi->nsdpblocks; block++)
2546  sdpconstnblocknonz[block] = sdpi->sdpnnonz + sdpi->sdpconstnnonz;
2547 
2548  SCIP_CALL( compConstMatAfterFixings(sdpi, &sdpconstnnonz, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval) );
2549 
2550  /* shrink the constant arrays after the number of fixed nonzeros is known */
2551  for (block = 0; block < sdpi->nsdpblocks; block++)
2552  {
2553  assert ( sdpconstnblocknonz[block] <= sdpi->sdpnnonz + sdpi->sdpconstnnonz ); /* otherwise the memory wasn't sufficient,
2554  * but we allocated more than enough */
2555  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
2556  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
2557  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
2558  }
2559 
2560  SCIP_CALL( findEmptyRowColsSDP(sdpi, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges, nremovedinds, blockindchanges, &nremovedblocks) );
2561 
2562  /* 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,
2563  * the linear constraints were already checked in computeLpLhsRhsAfterFixings) */
2564  SCIP_CALL( checkAllFixed(sdpi) );
2565  if ( sdpi->allfixed && ! sdpi->infeasible )
2566  {
2567  SCIP_CALL( checkFixedFeasibilitySdp(sdpi, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges, nremovedinds, blockindchanges) );
2568  }
2569 
2570  if ( sdpi->infeasible )
2571  {
2572  SCIPdebugMessage("SDP %d not given to solver, as infeasibility was detected during presolving!\n", sdpi->sdpid++);
2573  SCIP_CALL( SCIPsdpiSolverIncreaseCounter(sdpi->sdpisolver) );
2574 
2575  sdpi->solved = TRUE;
2576  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2577  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2578  }
2579  else if ( sdpi->allfixed )
2580  {
2581  SCIPdebugMessage("SDP %d not given to solver, as all variables were fixed during presolving (the solution was feasible)!\n", sdpi->sdpid++);
2582  SCIP_CALL( SCIPsdpiSolverIncreaseCounter(sdpi->sdpisolver) );
2583 
2584  sdpi->solved = TRUE;
2585  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2586  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2587  }
2588  else
2589  {
2590  if ( sdpi->slatercheck )
2591  {
2592  SCIP_CALL( checkSlaterCondition(sdpi, timelimit, starttime, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges,
2593  nremovedinds, lplhsafterfix, lprhsafterfix, rowsnactivevars, blockindchanges, sdpconstnnonz, nactivelpcons, nremovedblocks, FALSE) );
2594  }
2595 
2596  /* compute the timit limit to set for the solver */
2597  solvertimelimit = timelimit;
2598  if ( ! SCIPsdpiIsInfinity(sdpi, solvertimelimit) )
2599  {
2600  currenttime = clock();
2601  solvertimelimit -= (SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC;/*lint !e620*/
2602  }
2603 
2604  /* try to solve the problem */
2605  SCIP_CALL( SCIPsdpiSolverLoadAndSolve(sdpi->sdpisolver, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
2606  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2607  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2608  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2609  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
2610  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2611  startXnblocknonz, startXrow, startXcol, startXval, startsettings, solvertimelimit) );
2612 
2613  sdpi->solved = TRUE;
2614 
2615  /* add iterations and sdpcalls */
2616  naddediterations = 0;
2617  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2618  sdpi->niterations += naddediterations;
2619  naddedsdpcalls = 0;
2620  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2621  sdpi->nsdpcalls += naddedsdpcalls;
2622 
2623  /* if the solver didn't produce a satisfactory result, we have to try with a penalty formulation */
2624  if ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && ! SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver) )
2625  {
2626  SCIP_Real penaltyparam;
2627  SCIP_Real penaltyparamfact;
2628  SCIP_Real gaptol;
2629  SCIP_Real gaptolfact;
2630  SCIP_Bool feasorig;
2631  SCIP_Bool penaltybound;
2632  SCIP_Real objbound;
2633  SCIP_Real objval;
2634 
2635  feasorig = FALSE;
2636  penaltybound = TRUE;
2637 
2638  /* first check feasibility using the penalty approach */
2639 
2640  /* compute the timit limit to set for the solver */
2641  solvertimelimit = timelimit;
2642  if ( ! SCIPsdpiIsInfinity(sdpi, solvertimelimit) )
2643  {
2644  currenttime = clock();
2645  solvertimelimit -= (SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC;/*lint !e620*/
2646  }
2647 
2648  /* we solve the problem with a slack variable times identity added to the constraints and trying to minimize this slack variable r, if
2649  * the optimal objective is bigger than feastol, then we know that the problem is infeasible */
2650  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, 1.0, FALSE, FALSE, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
2651  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2652  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2653  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2654  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
2655  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2656  startXnblocknonz, startXrow, startXcol, startXval, SCIP_SDPSOLVERSETTING_UNSOLVED, solvertimelimit, &feasorig, &penaltybound) );
2657 
2658  /* add iterations and sdpcalls */
2659  naddediterations = 0;
2660  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2661  sdpi->niterations += naddediterations;
2662  naddedsdpcalls = 0;
2663  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2664  sdpi->nsdpcalls += naddedsdpcalls;
2665 
2666  /* get objective value */
2667  if ( SCIPsdpiSolverWasSolved(sdpi->sdpisolver) )
2668  {
2669  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) );
2670  }
2671  else
2672  objval = -SCIPsdpiInfinity(sdpi);
2673 
2674  /* If the penalty formulation was successfully solved and has a strictly positive objective value, we know that
2675  * the problem is infeasible. Note that we need to check against the maximum of feastol and gaptol, since this
2676  * is the objective of an SDP which is only exact up to gaptol, and cutting a feasible node off is an error
2677  * while continueing with an infeasible problem only takes additional time until we found out again later.
2678  */
2679  if ( (SCIPsdpiSolverIsOptimal(sdpi->sdpisolver) && (objval > (sdpi->feastol > sdpi->gaptol ? sdpi->feastol : sdpi->gaptol))) ||
2680  (SCIPsdpiSolverWasSolved(sdpi->sdpisolver) && SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver)) )
2681  {
2682  SCIPdebugMessage("SDP %d found infeasible using penalty formulation, maximum of smallest eigenvalue is %f.\n", sdpi->sdpid, -1.0 * objval);
2683  sdpi->penalty = TRUE;
2684  sdpi->infeasible = TRUE;
2685  }
2686  else
2687  {
2688  feasorig = FALSE;
2689  penaltybound = TRUE;
2690 
2691  penaltyparam = sdpi->penaltyparam;
2692 
2693  /* 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
2694  * (for npenaltyincr = 0 we make sure that the parameter is too large after the first change)
2695  */
2696  penaltyparamfact = sdpi->npenaltyincr > 0 ? pow((sdpi->maxpenaltyparam / sdpi->penaltyparam), 1.0/sdpi->npenaltyincr) :
2697  2*sdpi->maxpenaltyparam / sdpi->penaltyparam;
2698  gaptol = sdpi->gaptol;
2699  gaptolfact = sdpi->npenaltyincr > 0 ? pow((MIN_GAPTOL / sdpi->gaptol), 1.0/sdpi->npenaltyincr) : 0.5 * MIN_GAPTOL / sdpi->gaptol;
2700 
2701  /* increase penalty-param and decrease feasibility tolerance until we find a feasible solution or reach the final bound for either one of them */
2702  while ( ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) || ! feasorig ) &&
2703  ( penaltyparam < sdpi->maxpenaltyparam + sdpi->epsilon ) && ( gaptol > 0.99 * MIN_GAPTOL ) && ( ! SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver) ))
2704  {
2705  SCIPdebugMessage("Solver did not produce an acceptable result, trying SDP %d again with penaltyparameter %f\n", sdpi->sdpid, penaltyparam);
2706 
2707  /* compute the timit limit to set for the solver */
2708  solvertimelimit = timelimit;
2709  if ( ! SCIPsdpiIsInfinity(sdpi, solvertimelimit) )
2710  {
2711  currenttime = clock();
2712  solvertimelimit -= (SCIP_Real)(currenttime - starttime) / (SCIP_Real) CLOCKS_PER_SEC;/*lint !e620*/
2713 
2714  if ( solvertimelimit <= 0 )
2715  break;
2716  }
2717 
2718  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, penaltyparam, TRUE, TRUE, sdpi->nvars, sdpi->obj,
2719  sdpi->lb, sdpi->ub, sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2720  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2721  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2722  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
2723  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2724  startXnblocknonz, startXrow, startXcol, startXval, startsettings, solvertimelimit, &feasorig, &penaltybound) );
2725 
2726  /* add iterations and sdpcalls */
2727  naddediterations = 0;
2728  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2729  sdpi->niterations += naddediterations;
2730  naddedsdpcalls = 0;
2731  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2732  sdpi->nsdpcalls += naddedsdpcalls;
2733 
2734  /* If the solver did not converge, we increase the penalty parameter */
2735  if ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) )
2736  {
2737  penaltyparam *= penaltyparamfact;
2738  SCIPdebugMessage("Solver did not converge even with penalty formulation, increasing penaltyparameter.\n");
2739  continue;
2740  }
2741 
2742  /* if we succeeded to solve the problem, update the bound */
2743  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objbound) );
2744  if ( objbound > sdpi->bestbound + sdpi->gaptol )
2745  sdpi->bestbound = objbound;
2746 
2747  /* If we don't get a feasible solution to our original problem we have to update either Gamma (if the penalty bound was active
2748  * in the primal problem) or gaptol (otherwise) */
2749  if ( ! feasorig )
2750  {
2751  if ( penaltybound )
2752  {
2753  penaltyparam *= penaltyparamfact;
2754  SCIPdebugMessage("Penalty formulation produced a result which is infeasible for the original problem, increasing penaltyparameter\n");
2755  }
2756  else
2757  {
2758  gaptol *= gaptolfact;
2759  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, SCIP_SDPPAR_GAPTOL, gaptol) );
2760  SCIPdebugMessage("Penalty formulation produced a result which is infeasible for the original problem, even though primal penalty "
2761  "bound was not reached, decreasing tolerance for duality gap in SDP-solver\n");
2762  }
2763  }
2764  }
2765 
2766  /* reset the tolerance in the SDP-solver */
2767  if ( gaptol > sdpi->gaptol )
2768  {
2769  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, SCIP_SDPPAR_GAPTOL, sdpi->gaptol) );
2770  }
2771 
2772  /* check if we were able to solve the problem in the end */
2773  if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && feasorig )
2774  {
2775  sdpi->penalty = TRUE;
2776  sdpi->solved = TRUE;
2777  }
2778 #if 0 /* we don't really know if it is infeasible or just ill-posed (no KKT-point) */
2779  else if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && ! feasorig )
2780  {
2781  SCIPdebugMessage("Problem was found to be infeasible using a penalty formulation \n");
2782  sdpi->infeasible = TRUE;
2783  sdpi->penalty = TRUE;
2784  sdpi->solved = TRUE;
2785  }
2786 #endif
2787  else
2788  {
2789  SCIPdebugMessage("SDP-Solver could not solve the problem even after using a penalty formulation \n");
2790  sdpi->solved = FALSE;
2791  sdpi->penalty = TRUE;
2792  }
2793 
2794  /* if we still didn't succeed and enforceslatercheck was set, we finally test for the Slater condition to give a reason for failure */
2795  if ( sdpi->solved == FALSE && enforceslatercheck)
2796  {
2797  SCIP_CALL( checkSlaterCondition(sdpi, timelimit, starttime, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges,
2798  nremovedinds, lplhsafterfix, lprhsafterfix, rowsnactivevars, blockindchanges, sdpconstnnonz, nactivelpcons, nremovedblocks, TRUE) );
2799  }
2800  else if ( sdpi->solved == FALSE )
2801  {
2802 #if 0
2803  SCIPmessagePrintInfo(sdpi->messagehdlr, "Numerical trouble\n");
2804 #else
2805  SCIPdebugMessage("SDP-Interface was unable to solve SDP %d\n", sdpi->sdpid);/*lint !e687*/
2806 #endif
2807  }
2808  }
2809  }
2810  }
2811 
2812  /* empty the memory allocated here */
2813  for (block = 0; block < sdpi->nsdpblocks; block++)
2814  {
2815  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpconstnblocknonz[block]);/*lint !e737*/
2816  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpconstnblocknonz[block]);/*lint !e737*/
2817  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpconstnblocknonz[block]);/*lint !e737*/
2818  BMSfreeBlockMemoryArray(sdpi->blkmem, &(indchanges[block]), sdpi->sdpblocksizes[block]);/*lint !e737*/
2819  }
2820  BMSfreeBlockMemoryArray(sdpi->blkmem, &rowsnactivevars, sdpi->nlpcons);/*lint !e737*/
2821  BMSfreeBlockMemoryArray(sdpi->blkmem, &lprhsafterfix, sdpi->nlpcons);/*lint !e737*/
2822  BMSfreeBlockMemoryArray(sdpi->blkmem, &lplhsafterfix, sdpi->nlpcons);/*lint !e737*/
2823  BMSfreeBlockMemoryArray(sdpi->blkmem, &blockindchanges, sdpi->nsdpblocks);/*lint !e737*/
2824  BMSfreeBlockMemoryArray(sdpi->blkmem, &nremovedinds, sdpi->nsdpblocks);/*lint !e737*/
2825  BMSfreeBlockMemoryArray(sdpi->blkmem, &indchanges, sdpi->nsdpblocks);/*lint !e737*/
2826  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstval, sdpi->nsdpblocks);/*lint !e737*/
2827  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstcol, sdpi->nsdpblocks);/*lint !e737*/
2828  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstrow, sdpi->nsdpblocks);/*lint !e737*/
2829  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstnblocknonz, sdpi->nsdpblocks);/*lint !e737*/
2830 
2831  sdpi->sdpid++;
2832 
2833  return SCIP_OKAY;
2834 }
2835 
2836 
2837 
2838 
2839 /*
2840  * Solution Information Methods
2841  */
2842 
2848  SCIP_SDPI* sdpi
2849  )
2850 {
2851  assert( sdpi != NULL );
2852 
2853  return ( sdpi->solved && SCIPsdpiSolverWasSolved(sdpi->sdpisolver) );
2854 }
2855 
2858  SCIP_SDPI* sdpi
2859  )
2860 {
2861  assert( sdpi != NULL );
2862 
2863  return ( SCIPsdpiWasSolved(sdpi) && (! sdpi->penalty) );
2864 }
2865 
2870  SCIP_SDPI* sdpi
2871  )
2872 {
2873  assert( sdpi != NULL );
2874  CHECK_IF_SOLVED_BOOL(sdpi);
2875 
2876  if ( sdpi->infeasible || sdpi->allfixed )
2877  return TRUE;
2878 
2879  return SCIPsdpiSolverFeasibilityKnown(sdpi->sdpisolver);
2880 }
2881 
2884  SCIP_SDPI* sdpi,
2885  SCIP_Bool* primalfeasible,
2886  SCIP_Bool* dualfeasible
2887  )
2888 {
2889  assert( sdpi != NULL );
2890  CHECK_IF_SOLVED(sdpi);
2891 
2892  if ( sdpi->infeasible )
2893  {
2894  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2895  *dualfeasible = FALSE;
2896  return SCIP_OKAY;
2897  }
2898  else if ( sdpi->allfixed )
2899  {
2900  SCIPdebugMessage("All variables were fixed during preprocessing, dual problem is feasible, primal feasibility not available\n");
2901  *dualfeasible = TRUE;
2902  return SCIP_OKAY;
2903  }
2904 
2905  SCIP_CALL( SCIPsdpiSolverGetSolFeasibility(sdpi->sdpisolver, primalfeasible, dualfeasible) );
2906 
2907  return SCIP_OKAY;
2908 }
2909 
2913  SCIP_SDPI* sdpi
2914  )
2915 {
2916  assert( sdpi != NULL );
2917  CHECK_IF_SOLVED_BOOL(sdpi);
2918 
2919  if ( sdpi->infeasible )
2920  {
2921  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal unboundedness not available\n");
2922  return FALSE;
2923  }
2924  else if ( sdpi->allfixed )
2925  {
2926  SCIPdebugMessage("All variables were fixed during preprocessing, primal unboundedness not available\n");
2927  return FALSE;
2928  }
2929 
2930  return SCIPsdpiSolverIsPrimalUnbounded(sdpi->sdpisolver);
2931 }
2932 
2936  SCIP_SDPI* sdpi
2937  )
2938 {
2939  assert( sdpi != NULL );
2940  CHECK_IF_SOLVED_BOOL(sdpi);
2941 
2942  if ( sdpi->infeasible )
2943  {
2944  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2945  return FALSE;
2946  }
2947  else if ( sdpi->allfixed )
2948  {
2949  SCIPdebugMessage("All variables were fixed during preprocessing, primal feasibility not available\n");
2950  return FALSE;
2951  }
2952 
2953  return SCIPsdpiSolverIsPrimalInfeasible(sdpi->sdpisolver);
2954 }
2955 
2959  SCIP_SDPI* sdpi
2960  )
2961 {
2962  assert(sdpi != NULL );
2963  CHECK_IF_SOLVED_BOOL(sdpi);
2964 
2965  if ( sdpi->infeasible )
2966  {
2967  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2968  return FALSE;
2969  }
2970  else if ( sdpi->allfixed )
2971  {
2972  SCIPdebugMessage("All variables fixed during preprocessing, primal feasibility not available\n");
2973  return FALSE;
2974  }
2975 
2976  return SCIPsdpiSolverIsPrimalFeasible(sdpi->sdpisolver);
2977 }
2978 
2982  SCIP_SDPI* sdpi
2983  )
2984 {
2985  assert( sdpi != NULL );
2986  CHECK_IF_SOLVED_BOOL(sdpi);
2987 
2988  if ( sdpi->infeasible )
2989  {
2990  SCIPdebugMessage("Problem was found infeasible during preprocessing, therefore is not unbounded\n");
2991  return FALSE;
2992  }
2993  else if ( sdpi->allfixed )
2994  {
2995  SCIPdebugMessage("All variables were fixed during preprocessing, therefore the problem is not unbounded\n");
2996  return FALSE;
2997  }
2998 
2999  return SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver);
3000 }
3001 
3005  SCIP_SDPI* sdpi
3006  )
3007 {
3008  assert( sdpi != NULL );
3009  CHECK_IF_SOLVED_BOOL(sdpi);
3010 
3011  if ( sdpi->infeasible )
3012  {
3013  SCIPdebugMessage("Problem was found infeasible during preprocessing\n");
3014  return TRUE;
3015  }
3016  else if ( sdpi->allfixed )
3017  {
3018  SCIPdebugMessage("All variables were fixed during preprocessing, solution is feasible\n");
3019  return FALSE;
3020  }
3021 
3022  return SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver);
3023 }
3024 
3028  SCIP_SDPI* sdpi
3029  )
3030 {
3031  assert( sdpi != NULL );
3032  CHECK_IF_SOLVED_BOOL(sdpi);
3033 
3034  if ( sdpi->infeasible )
3035  {
3036  SCIPdebugMessage("Problem was found infeasible during preprocessing\n");
3037  return FALSE;
3038  }
3039  else if ( sdpi->allfixed )
3040  {
3041  SCIPdebugMessage("All variables fixed during preprocessing, solution is feasible\n");
3042  return TRUE;
3043  }
3044 
3045  return SCIPsdpiSolverIsDualFeasible(sdpi->sdpisolver);
3046 }
3047 
3050  SCIP_SDPI* sdpi
3051  )
3052 {
3053  assert( sdpi != NULL );
3054  CHECK_IF_SOLVED_BOOL(sdpi);
3055 
3056  if ( sdpi->infeasible )
3057  {
3058  SCIPdebugMessage("Problem was found infeasible during preprocessing, this counts as converged.\n");
3059  return TRUE;
3060  }
3061  else if ( sdpi->allfixed )
3062  {
3063  SCIPdebugMessage("All variables were fixed during preprocessing, this counts as converged.\n");
3064  return TRUE;
3065  }
3066 
3067  return SCIPsdpiSolverIsConverged(sdpi->sdpisolver);
3068 }
3069 
3072  SCIP_SDPI* sdpi
3073  )
3074 {
3075  assert( sdpi != NULL );
3076  CHECK_IF_SOLVED_BOOL(sdpi);
3077 
3078  if ( sdpi->infeasible )
3079  {
3080  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective limit available.\n");
3081  return FALSE;
3082  }
3083  else if ( sdpi->allfixed )
3084  {
3085  SCIPdebugMessage("All variables were fixed during preprocessing, no objective limit available.\n");
3086  return FALSE;
3087  }
3088 
3089  return SCIPsdpiSolverIsObjlimExc(sdpi->sdpisolver);
3090 }
3091 
3094  SCIP_SDPI* sdpi
3095  )
3096 {
3097  assert( sdpi != NULL );
3098  CHECK_IF_SOLVED_BOOL(sdpi);
3099 
3100  if ( sdpi->infeasible )
3101  {
3102  SCIPdebugMessage("Problem was found infeasible during preprocessing, no iteration limit available.\n");
3103  return FALSE;
3104  }
3105  else if ( sdpi->allfixed )
3106  {
3107  SCIPdebugMessage("All variables were fixed during preprocessing, no iteration limit available.\n");
3108  return FALSE;
3109  }
3110 
3111  return SCIPsdpiSolverIsIterlimExc(sdpi->sdpisolver);
3112 }
3113 
3116  SCIP_SDPI* sdpi
3117  )
3118 {
3119  assert( sdpi != NULL );
3120 
3121  if ( sdpi->infeasible )
3122  {
3123  SCIPdebugMessage("Problem was found infeasible during preprocessing, no time limit available.\n");
3124  return FALSE;
3125  }
3126  else if ( sdpi->allfixed )
3127  {
3128  SCIPdebugMessage("All variables were fixed during preprocessing, no time limit available.\n");
3129  return FALSE;
3130  }
3131  else if ( ! sdpi->solved )
3132  {
3133  SCIPdebugMessage("Problem was not solved, time limit not exceeded.\n");
3134  return FALSE;
3135  }
3136 
3137  return SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver);
3138 }
3139 
3151  SCIP_SDPI* sdpi
3152  )
3153 {
3154  assert( sdpi != NULL );
3155 
3156  if ( ! sdpi->solved )
3157  {
3158  SCIPdebugMessage("Problem wasn't solved yet.\n");
3159  return -1;
3160  }
3161  else if ( sdpi->infeasible )
3162  {
3163  SCIPdebugMessage("Problem was found infeasible during preprocessing, no internal status available.\n");
3164  return 0;
3165  }
3166  else if ( sdpi->allfixed )
3167  {
3168  SCIPdebugMessage("All variables were fixed during preprocessing, no internal status available.\n");
3169  return 0;
3170  }
3171 
3172  return SCIPsdpiSolverGetInternalStatus(sdpi->sdpisolver);
3173 }
3174 
3177  SCIP_SDPI* sdpi
3178  )
3179 {
3180  assert( sdpi != NULL );
3181  CHECK_IF_SOLVED_BOOL(sdpi);
3182 
3183  if ( sdpi->infeasible )
3184  {
3185  SCIPdebugMessage("Problem was found infeasible during preprocessing, therefore there is no optimal solution.\n");
3186  return FALSE;
3187  }
3188  else if ( sdpi->allfixed )
3189  {
3190  SCIPdebugMessage("All variables were fixed during preprocessing, therefore there is no optimal solution.\n");
3191  return FALSE;
3192  }
3193 
3194  return SCIPsdpiSolverIsOptimal(sdpi->sdpisolver);
3195 }
3196 
3200  SCIP_SDPI* sdpi
3201  )
3202 {
3203  assert( sdpi != NULL );
3204 
3205  if ( sdpi->infeasible )
3206  {
3207  SCIPdebugMessage("Problem was found infeasible during preprocessing, this is acceptable in a B&B context.\n");
3208  return TRUE;
3209  }
3210  else if ( sdpi->allfixed )
3211  {
3212  SCIPdebugMessage("All variables fixed during preprocessing, this is acceptable in a B&B context.\n");
3213  return TRUE;
3214  }
3215  else if ( ! sdpi->solved )
3216  {
3217  SCIPdebugMessage("Problem not solved succesfully, this is not acceptable in a B&B context.\n");
3218  return FALSE;
3219  }
3220 
3221  return SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver);
3222 }
3223 
3225 SCIP_RETCODE SCIPsdpiGetObjval(
3226  SCIP_SDPI* sdpi,
3227  SCIP_Real* objval
3228  )
3229 {
3230  assert( sdpi != NULL );
3231  assert( objval != NULL );
3232  CHECK_IF_SOLVED(sdpi);
3233 
3234  if ( sdpi->infeasible )
3235  {
3236  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective value available.\n");
3237  return SCIP_OKAY;
3238  }
3239 
3240  if ( sdpi->allfixed )
3241  {
3242  int v;
3243 
3244  /* As all variables were fixed during preprocessing, we have to compute it ourselves here */
3245  *objval = 0;
3246 
3247  for (v = 0; v < sdpi->nvars; v++)
3248  *objval += sdpi->lb[v] * sdpi->obj[v];
3249 
3250  return SCIP_OKAY;
3251  }
3252 
3253  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, objval) );
3254 
3255  return SCIP_OKAY;
3256 }
3257 
3261  SCIP_SDPI* sdpi,
3262  SCIP_Real* objlb
3263  )
3264 {
3265  assert( sdpi != NULL );
3266  assert( objlb != NULL );
3267 
3268  /* if we could successfully solve the problem, the best bound is the optimal objective */
3269  if ( sdpi->solved )
3270  {
3271  if ( sdpi->infeasible )
3272  {
3273  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective value available.\n");
3274  return SCIP_OKAY;
3275  }
3276 
3277  if ( sdpi->allfixed )
3278  {
3279  int v;
3280 
3281  /* As all variables were fixed during preprocessing, we have to compute it ourselves here */
3282  *objlb = 0;
3283 
3284  for (v = 0; v < sdpi->nvars; v++)
3285  *objlb += sdpi->lb[v] * sdpi->obj[v];
3286 
3287  return SCIP_OKAY;
3288  }
3289 
3290  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, objlb) );
3291  return SCIP_OKAY;
3292  }
3293 
3294  /* if we could not solve it, but tried the penalty formulation, we take the best bound computed by the penalty approach */
3295  if ( sdpi->penalty )
3296  {
3297  *objlb = sdpi->bestbound;
3298  return SCIP_OKAY;
3299  }
3300 
3301  /* 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 */
3302 
3303  *objlb = -SCIPsdpiInfinity(sdpi);
3304  return SCIP_OKAY;
3305 }
3306 
3309 SCIP_RETCODE SCIPsdpiGetSol(
3310  SCIP_SDPI* sdpi,
3311  SCIP_Real* objval,
3312  SCIP_Real* dualsol,
3313  int* dualsollength
3315  )
3316 {
3317  assert( sdpi != NULL );
3318  assert( dualsollength != NULL );
3319  assert( *dualsollength == 0 || dualsol != NULL );
3320  CHECK_IF_SOLVED(sdpi);
3321 
3322  if ( sdpi->infeasible )
3323  {
3324  SCIPdebugMessage("Problem was found infeasible during preprocessing, no solution available.\n");
3325  return SCIP_OKAY;
3326  }
3327  else if ( sdpi->allfixed )
3328  {
3329  if ( objval != NULL )
3330  {
3331  SCIP_CALL( SCIPsdpiGetObjval(sdpi, objval) );
3332  }
3333  if ( *dualsollength > 0 )
3334  {
3335  int v;
3336 
3337  assert( dualsol != NULL );
3338  if ( *dualsollength < sdpi->nvars )
3339  {
3340  SCIPdebugMessage("The given array in SCIPsdpiGetSol only had length %d, but %d was needed", *dualsollength, sdpi->nvars);
3341  *dualsollength = sdpi->nvars;
3342 
3343  return SCIP_OKAY;
3344  }
3345 
3346  /* we give the fixed values as the solution */
3347  for (v = 0; v < sdpi->nvars; v++)
3348  dualsol[v] = sdpi->lb[v];
3349 
3350  return SCIP_OKAY;
3351  }
3352  }
3353 
3354  SCIP_CALL( SCIPsdpiSolverGetSol(sdpi->sdpisolver, objval, dualsol, dualsollength) );
3355 
3356  return SCIP_OKAY;
3357 }
3358 
3361  SCIP_SDPI* sdpi,
3362  int nblocks,
3363  int* startXnblocknonz
3365  )
3366 {
3367  assert( sdpi != NULL );
3368  assert( nblocks >= 0 );
3369  assert( startXnblocknonz != NULL );
3370 
3371  if ( sdpi->infeasible )
3372  {
3373  SCIPdebugMessage("Problem was found infeasible during preprocessing, no preoptimal solution available.\n");
3374  startXnblocknonz[0] = -1;
3375 
3376  return SCIP_OKAY;
3377  }
3378  else if ( sdpi->allfixed )
3379  {
3380  SCIPdebugMessage("No primal solution available, as problem was solved during preprocessing\n");
3381  startXnblocknonz[0] = -1;
3382 
3383  return SCIP_OKAY;
3384  }
3385 
3386  SCIP_CALL( SCIPsdpiSolverGetPreoptimalPrimalNonzeros(sdpi->sdpisolver, nblocks, startXnblocknonz) );
3387 
3388  return SCIP_OKAY;
3389 }
3390 
3399  SCIP_SDPI* sdpi,
3400  SCIP_Bool* success,
3401  SCIP_Real* dualsol,
3402  int* dualsollength,
3404  int nblocks,
3405  int* startXnblocknonz,
3407  int** startXrow,
3408  int** startXcol,
3409  SCIP_Real** startXval
3410  )
3411 {
3412  assert( sdpi != NULL );
3413  assert( success != NULL );
3414  assert( dualsol != NULL );
3415  assert( dualsollength != NULL );
3416  assert( *dualsollength >= 0 );
3417  assert( startXnblocknonz != NULL || nblocks == -1 );
3418  assert( startXrow != NULL || nblocks == -1 );
3419  assert( startXcol != NULL || nblocks == -1 );
3420  assert( startXval != NULL || nblocks == -1 );
3421 
3422  if ( sdpi->infeasible )
3423  {
3424  *success = FALSE;
3425  SCIPdebugMessage("Problem was found infeasible during preprocessing, no preoptimal solution available.\n");
3426  startXnblocknonz[0] = -1;
3427 
3428  return SCIP_OKAY;
3429  }
3430  else if ( sdpi->allfixed )
3431  {
3432  int v;
3433 
3434  assert( dualsol != NULL );
3435 
3436  *success = FALSE;
3437 
3438  if ( *dualsollength < sdpi->nvars )
3439  {
3440  SCIPdebugMessage("The given array in SCIPsdpiGetPreoptimalSol only had length %d, but %d was needed", *dualsollength, sdpi->nvars);
3441  *dualsollength = sdpi->nvars;
3442 
3443  return SCIP_OKAY;
3444  }
3445 
3446  /* we give the fixed values as the solution */
3447  for (v = 0; v < sdpi->nvars; v++)
3448  dualsol[v] = sdpi->lb[v];
3449 
3450  if ( nblocks > -1 )
3451  {
3452  SCIPdebugMessage("No primal solution available, as problem was solved during preprocessing\n");
3453  startXnblocknonz[0] = -1;
3454  }
3455 
3456  return SCIP_OKAY;
3457  }
3458 
3459  SCIP_CALL( SCIPsdpiSolverGetPreoptimalSol(sdpi->sdpisolver, success, dualsol, dualsollength, nblocks, startXnblocknonz,
3460  startXrow, startXcol, startXval) );
3461 
3462  return SCIP_OKAY;
3463 }
3464 
3470  SCIP_SDPI* sdpi,
3471  SCIP_Real* lbvars,
3472  SCIP_Real* ubvars,
3473  int* arraylength
3475  )
3476 {
3477  assert( sdpi != NULL );
3478  assert( lbvars != NULL );
3479  assert( ubvars != NULL );
3480  assert( arraylength != NULL );
3481  assert( *arraylength >= 0 );
3482  CHECK_IF_SOLVED(sdpi);
3483 
3484  if ( sdpi->infeasible )
3485  {
3486  SCIPdebugMessage("Problem was found infeasible during preprocessing, no primal variables available.\n");
3487  return SCIP_OKAY;
3488  }
3489  else if ( sdpi->allfixed )
3490  {
3491  SCIPdebugMessage("All variables fixed during preprocessing, no primal variables available.\n");
3492  return SCIP_OKAY;
3493  }
3494 
3495  SCIP_CALL( SCIPsdpiSolverGetPrimalBoundVars(sdpi->sdpisolver, lbvars, ubvars, arraylength) );
3496 
3497  return SCIP_OKAY;
3498 }
3499 
3502  SCIP_SDPI* sdpi,
3503  int nblocks,
3504  int* startXnblocknonz
3505  )
3506 {
3507  assert( sdpi != NULL );
3508 
3509  if ( sdpi->infeasible )
3510  {
3511  SCIPdebugMessage("Problem was found infeasible during preprocessing, no primal solution available.\n");
3512  return SCIP_OKAY;
3513  }
3514  else if ( sdpi->allfixed )
3515  {
3516  SCIPdebugMessage("All variables fixed during preprocessing, no primal solution available.\n");
3517  return SCIP_OKAY;
3518  }
3519 
3520  SCIP_CALL( SCIPsdpiSolverGetPrimalNonzeros(sdpi->sdpisolver, nblocks, startXnblocknonz) );
3521 
3522  return SCIP_OKAY;
3523 }
3524 
3530  SCIP_SDPI* sdpi,
3531  int nblocks,
3532  int* startXnblocknonz,
3534  int** startXrow,
3535  int** startXcol,
3536  SCIP_Real** startXval
3537  )
3538 {/* TODO: should also set startXnblocknonz[0] = -1 in case the problem was solved in presolving */
3539  assert( sdpi != NULL );
3540 
3541  if ( sdpi->infeasible )
3542  {
3543  SCIPdebugMessage("Problem was found infeasible during preprocessing, no primal solution available.\n");
3544  return SCIP_OKAY;
3545  }
3546  else if ( sdpi->allfixed )
3547  {
3548  SCIPdebugMessage("All variables fixed during preprocessing, no primal solution available.\n");
3549  return SCIP_OKAY;
3550  }
3551 
3552  SCIP_CALL( SCIPsdpiSolverGetPrimalMatrix(sdpi->sdpisolver, nblocks, startXnblocknonz, startXrow, startXcol, startXval) );
3553 
3554  return SCIP_OKAY;
3555 }
3556 
3559  SCIP_SDPI* sdpi
3560  )
3561 {
3562  assert( sdpi != NULL );
3563 
3564  return SCIPsdpiSolverGetMaxPrimalEntry( sdpi->sdpisolver );
3565 }
3566 
3569  SCIP_SDPI* sdpi,
3570  int* iterations
3571  )
3572 {
3573  assert( sdpi != NULL );
3574  assert( iterations != NULL );
3575 
3576  *iterations = sdpi->niterations;
3577 
3578  return SCIP_OKAY;
3579 }
3580 
3582 SCIP_RETCODE SCIPsdpiGetSdpCalls(
3583  SCIP_SDPI* sdpi,
3584  int* calls
3585  )
3586 {
3587  assert( sdpi != NULL );
3588  assert( calls != NULL );
3589 
3590  *calls = sdpi->nsdpcalls;
3591 
3592  return SCIP_OKAY;
3593 }
3594 
3597  SCIP_SDPI* sdpi,
3598  SCIP_SDPSOLVERSETTING* usedsetting
3599  )
3600 {
3601  assert( sdpi != NULL );
3602  assert( usedsetting != NULL );
3603 
3604  if ( ! sdpi->solved )
3605  {
3606  SCIPdebugMessage("Problem was not solved successfully.\n");
3607  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3608  return SCIP_OKAY;
3609  }
3610  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 */
3611  {
3612  SCIPdebugMessage("Problem was found infeasible during preprocessing, no settings used.\n");
3613  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3614  return SCIP_OKAY;
3615  }
3616  else if ( sdpi->allfixed )
3617  {
3618  SCIPdebugMessage("All varialbes fixed during preprocessing, no settings used.\n");
3619  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3620  return SCIP_OKAY;
3621  }
3622  else if ( sdpi->penalty )
3623  {
3624  *usedsetting = SCIP_SDPSOLVERSETTING_PENALTY;
3625  return SCIP_OKAY;
3626  }
3627 
3628  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, usedsetting) );
3629  return SCIP_OKAY;
3630 }
3631 
3634  SCIP_SDPI* sdpi,
3635  SCIP_SDPSLATERSETTING* slatersetting
3636  )
3637 {
3638  SCIP_SDPSOLVERSETTING usedsetting;
3639 
3640  assert( sdpi != NULL );
3641  assert( slatersetting != NULL );
3642 
3643  if ( ! sdpi->solved )
3644  {
3645  SCIPdebugMessage("Problem was not solved successfully");
3646  if ( sdpi->bestbound > -SCIPsdpiSolverInfinity(sdpi->sdpisolver) )
3647  {
3648  SCIPdebugMessage(", but we could at least compute a lower bound. \n");
3649  if ( sdpi->dualslater == SCIP_SDPSLATER_INF)
3650  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDINFEASIBLE;
3651  else
3652  {
3653  switch( sdpi->primalslater )/*lint --e{788}*/
3654  {
3655  case SCIP_SDPSLATER_NOINFO:
3656  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3657  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
3658  else
3659  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3660  break;
3661  case SCIP_SDPSLATER_NOT:
3662  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
3663  break;
3664  case SCIP_SDPSLATER_HOLDS:
3665  switch( sdpi->dualslater )/*lint --e{788}*/
3666  {
3667  case SCIP_SDPSLATER_NOINFO:
3668  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3669  break;
3670  case SCIP_SDPSLATER_NOT:
3671  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
3672  break;
3673  case SCIP_SDPSLATER_HOLDS:
3674  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDWSLATER;
3675  break;
3676  default:
3677  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3678  break;
3679  }
3680  break;
3681  default:
3682  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3683  break;
3684  }
3685  }
3686  }
3687  else
3688  {
3689  SCIPdebugMessage(".\n");
3690  if ( sdpi->dualslater == SCIP_SDPSLATER_INF)
3692  else
3693  {
3694  switch( sdpi->primalslater )/*lint --e{788}*/
3695  {
3696  case SCIP_SDPSLATER_NOINFO:
3697  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3698  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
3699  else
3700  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3701  break;
3702  case SCIP_SDPSLATER_NOT:
3703  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
3704  break;
3705  case SCIP_SDPSLATER_HOLDS:
3706  switch( sdpi->dualslater )/*lint --e{788}*/
3707  {
3708  case SCIP_SDPSLATER_NOINFO:
3709  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3710  break;
3711  case SCIP_SDPSLATER_NOT:
3712  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
3713  break;
3714  case SCIP_SDPSLATER_HOLDS:
3715  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDWSLATER;
3716  break;
3717  default:
3718  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3719  break;
3720  }
3721  break;
3722  default:
3723  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3724  break;
3725  }
3726  }
3727  }
3728  return SCIP_OKAY;
3729  }
3730  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 */
3731  {
3732  SCIPdebugMessage("Problem was found infeasible during preprocessing, no settings used.\n");
3733  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3734  return SCIP_OKAY;
3735  }
3736  else if ( sdpi->allfixed )
3737  {
3738  SCIPdebugMessage("All varialbes fixed during preprocessing, no settings used.\n");
3739  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3740  return SCIP_OKAY;
3741  }
3742  else if ( sdpi->penalty )
3743  {
3744  switch( sdpi->primalslater )/*lint --e{788}*/
3745  {
3746  case SCIP_SDPSLATER_NOINFO:
3747  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3748  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
3749  else if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3750  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
3751  else
3752  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3753  break;
3754  case SCIP_SDPSLATER_NOT:
3755  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3756  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
3757  else
3758  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
3759  break;
3760  case SCIP_SDPSLATER_HOLDS:
3761  switch( sdpi->dualslater )/*lint --e{788}*/
3762  {
3763  case SCIP_SDPSLATER_NOINFO:
3764  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3765  break;
3766  case SCIP_SDPSLATER_NOT:
3767  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
3768  break;
3769  case SCIP_SDPSLATER_HOLDS:
3770  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYWSLATER;
3771  break;
3772  case SCIP_SDPSLATER_INF:
3773  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
3774  break;
3775  default:
3776  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3777  break;
3778  }
3779  break;
3780  default:
3781  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3782  break;
3783  }
3784  return SCIP_OKAY;
3785  }
3786 
3787  switch( sdpi->primalslater )/*lint --e{788}*/
3788  {
3789  case SCIP_SDPSLATER_NOINFO:
3790  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
3791  {
3792  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3793  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3794  switch( usedsetting )/*lint --e{788}*/
3795  {
3797  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
3798  break;
3801  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
3802  break;
3803  default:
3804  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3805  break;
3806  }
3807  }
3808  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3809  {
3810  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3811  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3812  switch( usedsetting )/*lint --e{788}*/
3813  {
3815  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
3816  break;
3820  break;
3821  default:
3822  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3823  break;
3824  }
3825  }
3826  else
3827  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3828  break;
3829  case SCIP_SDPSLATER_NOT:
3830  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
3831  {
3832  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3833  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3834  switch( usedsetting )/*lint --e{788}*/
3835  {
3837  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
3838  break;
3842  break;
3843  default:
3844  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3845  break;
3846  }
3847  }
3848  else
3849  {
3850  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3851  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3852  switch( usedsetting )/*lint --e{788}*/
3853  {
3855  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
3856  break;
3859  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
3860  break;
3861  default:
3862  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3863  break;
3864  }
3865  }
3866  break;
3867  case SCIP_SDPSLATER_HOLDS:
3868  switch( sdpi->dualslater )/*lint --e{788}*/
3869  {
3870  case SCIP_SDPSLATER_NOINFO:
3871  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3872  break;
3873  case SCIP_SDPSLATER_NOT:
3874  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3875  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3876  switch( usedsetting )/*lint --e{788}*/
3877  {
3879  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
3880  break;
3883  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
3884  break;
3885  default:
3886  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3887  break;
3888  }
3889  break;
3890  case SCIP_SDPSLATER_INF:
3891  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3892  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3893  switch( usedsetting )/*lint --e{788}*/
3894  {
3896  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
3897  break;
3901  break;
3902  default:
3903  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3904  break;
3905  }
3906  break;
3907  case SCIP_SDPSLATER_HOLDS:
3908  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
3909  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
3910  switch( usedsetting )/*lint --e{788}*/
3911  {
3913  *slatersetting = SCIP_SDPSLATERSETTING_STABLEWSLATER;
3914  break;
3917  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLEWSLATER;
3918  break;
3919  default:
3920  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3921  break;
3922  }
3923  break;
3924  default:
3925  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3926  break;
3927  }
3928  break;
3929  default:
3930  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
3931  break;
3932  }
3933 
3934  return SCIP_OKAY;
3935 }
3936 
3938 SCIP_RETCODE SCIPsdpiSlater(
3939  SCIP_SDPI* sdpi,
3940  SCIP_SDPSLATER* primalslater,
3941  SCIP_SDPSLATER* dualslater
3942  )
3943 {
3944  assert( sdpi != NULL );
3945  assert( primalslater != NULL );
3946  assert( dualslater != NULL );
3947 
3948 
3949  if ( sdpi->infeasible )
3950  {
3951  *primalslater = SCIP_SDPSLATER_NOINFO;
3952  *dualslater = sdpi->dualslater;
3953  return SCIP_OKAY;
3954  }
3955 
3956  if (sdpi->allfixed )
3957  {
3958  *primalslater = SCIP_SDPSLATER_NOINFO;
3959  *dualslater = SCIP_SDPSLATER_NOINFO;
3960  return SCIP_OKAY;
3961  }
3962 
3963  *primalslater = sdpi->primalslater;
3964  *dualslater = sdpi->dualslater;
3965 
3966  return SCIP_OKAY;
3967 }
3968 
3974 /*
3975  * Numerical Methods
3976  */
3977 
3983  SCIP_SDPI* sdpi
3984  )
3985 {
3986  assert( sdpi != NULL );
3987 
3988  return SCIPsdpiSolverInfinity(sdpi->sdpisolver);
3989 }
3990 
3993  SCIP_SDPI* sdpi,
3994  SCIP_Real val
3995  )
3996 {
3997  assert( sdpi != NULL );
3998 
3999  return ((val <= -SCIPsdpiInfinity(sdpi)) || (val >= SCIPsdpiInfinity(sdpi)));
4000 }
4001 
4003 SCIP_RETCODE SCIPsdpiGetRealpar(
4004  SCIP_SDPI* sdpi,
4005  SCIP_SDPPARAM type,
4006  SCIP_Real* dval
4007  )
4008 {
4009  assert( sdpi != NULL );
4010  assert( sdpi->sdpisolver != NULL );
4011  assert( dval != NULL );
4012 
4013  switch( type )/*lint --e{788}*/
4014  {
4015  case SCIP_SDPPAR_EPSILON:
4016  *dval = sdpi->epsilon;
4017  break;
4018  case SCIP_SDPPAR_GAPTOL:
4019  *dval = sdpi->gaptol;
4020  break;
4021  case SCIP_SDPPAR_FEASTOL:
4022  *dval = sdpi->feastol;
4023  break;
4025  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4026  break;
4027  case SCIP_SDPPAR_OBJLIMIT:
4028  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4029  break;
4031  *dval = sdpi->penaltyparam;
4032  break;
4034  *dval = sdpi->maxpenaltyparam;
4035  break;
4037  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4038  break;
4040  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4041  break;
4042  default:
4043  return SCIP_PARAMETERUNKNOWN;
4044  }
4045 
4046  return SCIP_OKAY;
4047 }
4048 
4050 SCIP_RETCODE SCIPsdpiSetRealpar(
4051  SCIP_SDPI* sdpi,
4052  SCIP_SDPPARAM type,
4053  SCIP_Real dval
4054  )
4055 {
4056  assert( sdpi != NULL );
4057 
4058  switch( type )/*lint --e{788}*/
4059  {
4060  case SCIP_SDPPAR_EPSILON:
4061  sdpi->epsilon = dval;
4062  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4063  break;
4064  case SCIP_SDPPAR_GAPTOL:
4065  sdpi->gaptol = dval;
4066  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4067  break;
4068  case SCIP_SDPPAR_FEASTOL:
4069  sdpi->feastol = dval;
4070  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4071  break;
4073  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4074  break;
4075  case SCIP_SDPPAR_OBJLIMIT:
4076  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4077  break;
4079  sdpi->penaltyparam = dval;
4080  SCIP_CALL_PARAM_IGNORE_UNKNOWN( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4081  break;
4083  sdpi->maxpenaltyparam = dval;
4084  break;
4086  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4087  break;
4089  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4090  break;
4091  default:
4092  return SCIP_PARAMETERUNKNOWN;
4093  }
4094 
4095  return SCIP_OKAY;
4096 }
4097 
4099 SCIP_RETCODE SCIPsdpiGetIntpar(
4100  SCIP_SDPI* sdpi,
4101  SCIP_SDPPARAM type,
4102  int* ival
4103  )
4104 {
4105  assert( sdpi != NULL );
4106  assert( sdpi->sdpisolver != NULL );
4107  assert( ival != NULL );
4108 
4109  switch( type )/*lint --e{788}*/
4110  {
4111  case SCIP_SDPPAR_SDPINFO:
4112  case SCIP_SDPPAR_NTHREADS:
4113  SCIP_CALL_PARAM( SCIPsdpiSolverGetIntpar(sdpi->sdpisolver, type, ival) );
4114  break;
4116  *ival = sdpi->slatercheck;
4117  break;
4119  *ival = sdpi->npenaltyincr;
4120  break;
4121  default:
4122  return SCIP_PARAMETERUNKNOWN;
4123  }
4124 
4125  return SCIP_OKAY;
4126 }
4127 
4129 SCIP_RETCODE SCIPsdpiSetIntpar(
4130  SCIP_SDPI* sdpi,
4131  SCIP_SDPPARAM type,
4132  int ival
4133  )
4134 {
4135  assert( sdpi != NULL );
4136  assert( sdpi->sdpisolver != NULL );
4137 
4138  switch( type )/*lint --e{788}*/
4139  {
4140  case SCIP_SDPPAR_SDPINFO:
4141  assert( ival == 0 || ival == 1 ); /* this is a boolean parameter */
4142  SCIP_CALL_PARAM( SCIPsdpiSolverSetIntpar(sdpi->sdpisolver, type, ival) );
4143  break;
4144  case SCIP_SDPPAR_NTHREADS:
4145  SCIP_CALL_PARAM( SCIPsdpiSolverSetIntpar(sdpi->sdpisolver, type, ival) );
4146  break;
4148  sdpi->slatercheck = ival;
4149  break;
4151  sdpi->npenaltyincr = ival;
4152  break;
4153  default:
4154  return SCIP_PARAMETERUNKNOWN;
4155  }
4156 
4157  return SCIP_OKAY;
4158 }
4159 
4162  SCIP_SDPI* sdpi,
4163  SCIP_Real maxguess
4164  )
4165 {
4166  return SCIPsdpiSolverComputeLambdastar(sdpi->sdpisolver, maxguess);
4167 }
4168 
4171  SCIP_SDPI* sdpi,
4172  SCIP_Real maxcoeff,
4173  SCIP_Real* penaltyparam
4174  )
4175 {
4176  SCIP_CALL( SCIPsdpiSolverComputePenaltyparam(sdpi->sdpisolver, maxcoeff, penaltyparam) );
4177 
4178  sdpi->penaltyparam = *penaltyparam;
4179 
4180  return SCIP_OKAY;
4181 }
4182 
4185  SCIP_SDPI* sdpi,
4186  SCIP_Real penaltyparam,
4187  SCIP_Real* maxpenaltyparam
4188  )
4189 {
4190  SCIP_CALL( SCIPsdpiSolverComputeMaxPenaltyparam(sdpi->sdpisolver, penaltyparam, maxpenaltyparam) );
4191 
4192  sdpi->maxpenaltyparam = *maxpenaltyparam;
4193 
4194  /* if the initial penalty parameter is smaller than the maximum one, we decrease the initial correspondingly */
4195  /* if the maximum penalty parameter is smaller than the initial penalty paramater, we decrease the initial one correspondingly */
4196  if ( sdpi->penaltyparam > *maxpenaltyparam )
4197  {
4198  SCIPdebugMessage("Decreasing penaltyparameter of %f to maximum penalty paramater of %f.\n", sdpi->penaltyparam, *maxpenaltyparam);
4199  sdpi->penaltyparam = *maxpenaltyparam;
4200  }
4201 
4202  return SCIP_OKAY;
4203 }
4204 
4210 /*
4211  * File Interface Methods
4212  */
4213 
4218 SCIP_RETCODE SCIPsdpiReadSDP(
4219  SCIP_SDPI* sdpi,
4220  const char* fname
4221  )
4222 {/*lint --e{715}*/
4223  SCIPdebugMessage("Not implemented yet\n");
4224  return SCIP_LPERROR;
4225 }
4226 
4228 SCIP_RETCODE SCIPsdpiWriteSDP(
4229  SCIP_SDPI* sdpi,
4230  const char* fname
4231  )
4232 {/*lint --e{715}*/
4233  SCIPdebugMessage("Not implemented yet\n");
4234  return SCIP_LPERROR;
4235 }
4236 
SCIP_RETCODE SCIPsdpiFree(SCIP_SDPI **sdpi)
Definition: sdpi.c:1512
SCIP_Bool SCIPsdpiIsDualUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:2981
#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:1982
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:2213
EXTERN SCIP_RETCODE SCIPsdpiSolverSetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real dval)
SCIP_RETCODE SCIPsdpiGetSdpCalls(SCIP_SDPI *sdpi, int *calls)
Definition: sdpi.c:3582
EXTERN SCIP_RETCODE SCIPlapackComputeIthEigenvalue(BMS_BUFMEM *bufmem, SCIP_Bool geteigenvectors, int n, SCIP_Real *A, int i, SCIP_Real *eigenvalue, SCIP_Real *eigenvector)
EXTERN SCIP_Bool SCIPsdpiSolverIsObjlimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiDoesWarmstartNeedPrimal(void)
Definition: sdpi.c:1426
#define BMS_CALL(x)
Definition: sdpi.c:57
SCIP_RETCODE SCIPsdpiGetSolFeasibility(SCIP_SDPI *sdpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: sdpi.c:2883
SCIP_RETCODE SCIPsdpiWriteSDP(SCIP_SDPI *sdpi, const char *fname)
Definition: sdpi.c:4228
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:2327
EXTERN SCIP_RETCODE SCIPsdpiSolverLoadAndSolve(SCIP_SDPISOLVER *sdpisolver, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, int noldlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int *rownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit)
EXTERN SCIP_RETCODE SCIPsdpiSolverResetCounter(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Bool SCIPsdpiSolverFeasibilityKnown(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Bool SCIPsdpiSolverIsConverged(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetPrimalMatrix(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
Definition: sdpi.c:3529
EXTERN SCIP_RETCODE SCIPsdpiSolverGetPrimalBoundVars(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
enum SCIP_SDPSolverSetting SCIP_SDPSOLVERSETTING
Definition: type_sdpi.h:79
SCIP_Bool SCIPsdpiIsOptimal(SCIP_SDPI *sdpi)
Definition: sdpi.c:3176
SCIP_RETCODE SCIPsdpiGetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int *ival)
Definition: sdpi.c:4099
SCIP_RETCODE SCIPsdpiGetSDPNNonz(SCIP_SDPI *sdpi, int *nnonz)
Definition: sdpi.c:2299
#define MIN_GAPTOL
Definition: sdpi.c:131
SCIP_Bool SCIPsdpiIsInfinity(SCIP_SDPI *sdpi, SCIP_Real val)
Definition: sdpi.c:3992
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)
EXTERN SCIP_RETCODE SCIPsdpiSolverGetPreoptimalPrimalNonzeros(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz)
SCIP_RETCODE SCIPsdpiGetNSDPBlocks(SCIP_SDPI *sdpi, int *nsdpblocks)
Definition: sdpi.c:2271
SCIP_RETCODE SCIPsdpiGetSol(SCIP_SDPI *sdpi, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
Definition: sdpi.c:3309
interface methods for specific SDP-solvers
SCIP_Bool SCIPsdpiIsPrimalInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2935
#define DEFAULT_FEASTOL
Definition: sdpi.c:134
SCIP_RETCODE SCIPsdpiSolve(SCIP_SDPI *sdpi, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Bool enforceslatercheck, SCIP_Real timelimit)
Definition: sdpi.c:2451
SCIP_Bool SCIPsdpiFeasibilityKnown(SCIP_SDPI *sdpi)
Definition: sdpi.c:2869
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:1697
SCIP_RETCODE SCIPsdpiComputeLambdastar(SCIP_SDPI *sdpi, SCIP_Real maxguess)
Definition: sdpi.c:4161
EXTERN int SCIPsdpiSolverGetDefaultSdpiSolverNpenaltyIncreases(void)
SCIP_RETCODE SCIPsdpiGetPrimalNonzeros(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz)
Definition: sdpi.c:3501
EXTERN SCIP_Bool SCIPsdpiSolverWasSolved(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Bool SCIPsdpiSolverDoesWarmstartNeedPrimal(void)
SCIP_RETCODE SCIPsdpiGetIterations(SCIP_SDPI *sdpi, int *iterations)
Definition: sdpi.c:3568
SCIP_RETCODE SCIPsdpiSettingsUsed(SCIP_SDPI *sdpi, SCIP_SDPSOLVERSETTING *usedsetting)
Definition: sdpi.c:3596
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:3633
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:3199
EXTERN SCIP_RETCODE SCIPsdpiSolverLoadAndSolveWithPenalty(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Bool withobj, SCIP_Bool rbound, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, int noldlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int *rownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit, SCIP_Bool *feasorig, SCIP_Bool *penaltybound)
EXTERN SCIP_Bool SCIPsdpiSolverIsPrimalUnbounded(SCIP_SDPISOLVER *sdpisolver)
EXTERN int SCIPsdpiSolverGetInternalStatus(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiIsIterlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3093
SCIP_Bool SCIPsdpiIsTimelimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3115
SCIP_Bool SCIPsdpiIsDualInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:3004
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:2313
enum SCIP_SDPSlaterSetting SCIP_SDPSLATERSETTING
Definition: type_sdpi.h:101
SCIP_RETCODE SCIPsdpiClone(SCIP_SDPI *oldsdpi, SCIP_SDPI *newsdpi)
Definition: sdpi.c:1577
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:2179
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:2092
EXTERN SCIP_RETCODE SCIPsdpiSolverGetPrimalMatrix(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
EXTERN SCIP_Bool SCIPsdpiSolverIsDualInfeasible(SCIP_SDPISOLVER *sdpisolver)
EXTERN const char * SCIPsdpiSolverGetSolverName(void)
SCIP_RETCODE SCIPsdpiGetLowerObjbound(SCIP_SDPI *sdpi, SCIP_Real *objlb)
Definition: sdpi.c:3260
SCIP_Bool SCIPsdpiIsObjlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3071
#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:2341
void * SCIPsdpiGetSolverPointer(SCIP_SDPI *sdpi)
Definition: sdpi.c:1394
EXTERN SCIP_RETCODE SCIPsdpiSolverGetPrimalNonzeros(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz)
int SCIPsdpiGetInternalStatus(SCIP_SDPI *sdpi)
Definition: sdpi.c:3150
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:1917
SCIP_RETCODE SCIPsdpiGetNVars(SCIP_SDPI *sdpi, int *nvars)
Definition: sdpi.c:2285
const char * SCIPsdpiGetSolverDesc(void)
Definition: sdpi.c:1381
SCIP_RETCODE SCIPsdpiComputePenaltyparam(SCIP_SDPI *sdpi, SCIP_Real maxcoeff, SCIP_Real *penaltyparam)
Definition: sdpi.c:4170
SCIP_RETCODE SCIPsdpiSetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int ival)
Definition: sdpi.c:4129
EXTERN SCIP_RETCODE SCIPsdpiSolverSettingsUsed(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPSOLVERSETTING *usedsetting)
SCIP_Bool SCIPsdpiIsPrimalUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:2912
SCIP_Real SCIPsdpiInfinity(SCIP_SDPI *sdpi)
Definition: sdpi.c:3982
#define CHECK_IF_SOLVED_BOOL(sdpi)
Definition: sdpi.c:79
EXTERN SCIP_Bool SCIPsdpiSolverIsIterlimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetRhSides(SCIP_SDPI *sdpi, int firstrow, int lastrow, SCIP_Real *rhss)
Definition: sdpi.c:2413
SCIP_RETCODE SCIPsdpiCreate(SCIP_SDPI **sdpi, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem)
Definition: sdpi.c:1444
#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
SCIP_RETCODE SCIPsdpiGetObjval(SCIP_SDPI *sdpi, SCIP_Real *objval)
Definition: sdpi.c:3225
EXTERN SCIP_RETCODE SCIPsdpiSolverGetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real *dval)
int SCIPsdpiGetDefaultSdpiSolverNpenaltyIncreases(void)
Definition: sdpi.c:1418
SCIP_Bool SCIPsdpiIsConverged(SCIP_SDPI *sdpi)
Definition: sdpi.c:3049
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:2847
SCIP_RETCODE SCIPsdpiReadSDP(SCIP_SDPI *sdpi, const char *fname)
Definition: sdpi.c:4218
SCIP_RETCODE SCIPsdpiComputeMaxPenaltyparam(SCIP_SDPI *sdpi, SCIP_Real penaltyparam, SCIP_Real *maxpenaltyparam)
Definition: sdpi.c:4184
SCIP_RETCODE SCIPsdpiClear(SCIP_SDPI *sdpi)
Definition: sdpi.c:2134
SCIP_RETCODE SCIPsdpiGetBounds(SCIP_SDPI *sdpi, int firstvar, int lastvar, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: sdpi.c:2363
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:2150
EXTERN SCIP_Bool SCIPsdpiSolverIsDualUnbounded(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetPreoptimalSol(SCIP_SDPI *sdpi, SCIP_Bool *success, SCIP_Real *dualsol, int *dualsollength, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
Definition: sdpi.c:3398
#define DEFAULT_NPENALTYINCR
Definition: sdpi.c:138
EXTERN SCIP_Real SCIPsdpiSolverGetMaxPrimalEntry(SCIP_SDPISOLVER *sdpisolver)
#define DEFAULT_PENALTYPARAM
Definition: sdpi.c:136
SCIP_Bool SCIPsdpiIsDualFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:3027
struct SCIP_SDPi SCIP_SDPI
Definition: type_sdpi.h:113
EXTERN SCIP_RETCODE SCIPsdpiSolverGetSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
SCIP_Bool SCIPsdpiIsPrimalFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2958
SCIP_RETCODE SCIPsdpiSetRealpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, SCIP_Real dval)
Definition: sdpi.c:4050
EXTERN SCIP_Bool SCIPsdpiSolverIsPrimalFeasible(SCIP_SDPISOLVER *sdpisolver)
enum SCIP_SDPSlater SCIP_SDPSLATER
Definition: type_sdpi.h:111
SCIP_Real SCIPsdpiGetMaxPrimalEntry(SCIP_SDPI *sdpi)
Definition: sdpi.c:3558
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:4003
EXTERN SCIP_RETCODE SCIPsdpiSolverGetPreoptimalSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *success, SCIP_Real *dualsol, int *dualsollength, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
EXTERN SCIP_Real SCIPsdpiSolverGetDefaultSdpiSolverGaptol(void)
static SCIP_RETCODE compConstMatAfterFixings(SCIP_SDPI *sdpi, int *sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval)
Definition: sdpi.c:261
EXTERN SCIP_Real SCIPsdpiSolverGetDefaultSdpiSolverFeastol(void)
SCIP_Real SCIPsdpiGetDefaultSdpiSolverGaptol(void)
Definition: sdpi.c:1410
SCIP_RETCODE SCIPsdpiGetPreoptimalPrimalNonzeros(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz)
Definition: sdpi.c:3360
#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:68
EXTERN void * SCIPsdpiSolverGetSolverPointer(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Bool SCIPsdpiSolverIsInfinity(SCIP_SDPISOLVER *sdpisolver, SCIP_Real val)
SCIP_RETCODE SCIPsdpiGetNLPRows(SCIP_SDPI *sdpi, int *nlprows)
Definition: sdpi.c:2257
SCIP_RETCODE SCIPsdpiGetLhSides(SCIP_SDPI *sdpi, int firstrow, int lastrow, SCIP_Real *lhss)
Definition: sdpi.c:2391
SCIP_RETCODE SCIPsdpiGetPrimalBoundVars(SCIP_SDPI *sdpi, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
Definition: sdpi.c:3469
interface methods for eigenvector computation and matrix multiplication using different versions of L...
SCIP_Bool SCIPsdpiSolvedOrig(SCIP_SDPI *sdpi)
Definition: sdpi.c:2857
SCIP_RETCODE SCIPsdpiSlater(SCIP_SDPI *sdpi, SCIP_SDPSLATER *primalslater, SCIP_SDPSLATER *dualslater)
Definition: sdpi.c:3938
#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)