SCIP-SDP  2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sdpi.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of SCIPSDP - a solving framework for mixed-integer */
4 /* semidefinite programms based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2015 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-2015 Zuse Institute Berlin */
28 /* SCIP is distributed under the terms of the SCIP Academic Licence, */
29 /* see file COPYING in the SCIP distribution. */
30 /* */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32 
33 /* #define SCIP_DEBUG*/
34 /* #define SCIP_MORE_DEBUG*/
35 
41 #include <assert.h>
42 
43 #include "sdpi/sdpisolver.h"
44 #include "sdpi/sdpi.h"
45 #include "scipsdp/SdpVarfixer.h"
46 
47 #include "blockmemshell/memory.h" /* for memory allocation */
48 #include "scip/def.h" /* for SCIP_Real, _Bool, ... */
49 #include "scip/pub_misc.h" /* for sorting */
50 
51 
53 #define BMS_CALL(x) do \
54  { \
55  if( NULL == (x) ) \
56  { \
57  SCIPerrorMessage("No memory in function call\n"); \
58  return SCIP_NOMEMORY; \
59  } \
60  } \
61  while( FALSE )
62 
64 #define CHECK_IF_SOLVED(sdpi) do \
65  { \
66  if ( ! (sdpi->solved) ) \
67  { \
68  SCIPerrorMessage("Tried to access solution information ahead of solving! \n"); \
69  return SCIP_LPERROR; \
70  } \
71  } \
72  while( FALSE )
73 
75 #define CHECK_IF_SOLVED_BOOL(sdpi) do \
76  { \
77  if ( ! (sdpi->solved) ) \
78  { \
79  SCIPerrorMessage("Tried to access solution information ahead of solving! \n"); \
80  return FALSE; \
81  } \
82  } \
83  while( FALSE )
84 
86 #define DUPLICATE_ARRAY_NULL(blkmem, target, source, size) do \
87  { \
88  if (size > 0) \
89  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, target, source, size) ); \
90  else \
91  *target = NULL; \
92  } \
93  while( FALSE )
94 
96 #define SCIP_CALL_PARAM(x) do \
97  { \
98  SCIP_RETCODE _restat_; \
99  if ( (_restat_ = (x)) != SCIP_OKAY ) \
100  { \
101  if ( _restat_ != SCIP_PARAMETERUNKNOWN ) \
102  { \
103  SCIPerrorMessage("Error <%d> in function call\n", _restat_); \
104  SCIPABORT(); \
105  } \
106  return _restat_; \
107  } \
108  } \
109  while( FALSE )
110 
112 struct SCIP_SDPi
113 {
114  SCIP_SDPISOLVER* sdpisolver;
115  SCIP_MESSAGEHDLR* messagehdlr;
116  BMS_BLKMEM* blkmem;
117  int nvars;
118  SCIP_Real* obj;
119  SCIP_Real* lb;
120  SCIP_Real* ub;
121  int nsdpblocks;
122  int* sdpblocksizes;
123  int* sdpnblockvars;
125  /* constant SDP data: */
126  int sdpconstnnonz;
127  int* sdpconstnblocknonz;
129  int** sdpconstrow;
130  int** sdpconstcol;
131  SCIP_Real** sdpconstval;
133  /* non-constant SDP data: */
134  int sdpnnonz;
135  int** sdpnblockvarnonz;
137  int** sdpvar;
139  int*** sdprow;
141  int*** sdpcol;
142  SCIP_Real*** sdpval;
144  /* lp data: */
145  int nlpcons;
146  SCIP_Real* lplhs;
147  SCIP_Real* lprhs;
148  int lpnnonz;
149  int* lprow;
150  int* lpcol;
151  SCIP_Real* lpval;
153  /* other data */
154  SCIP_Bool slatercheck;
155  SCIP_Bool solved;
156  SCIP_Bool penalty;
157  SCIP_Bool infeasible;
158  int sdpid;
159  SCIP_Real epsilon;
160  SCIP_Real feastol;
161 };
162 
163 /*
164  * Local Functions
165  */
166 
171 static
173  int* i,
174  int* j
175  )
176 {
177  if ( *i < *j )
178  {
179  int temp;
180  temp = *i;
181  *i = *j;
182  *j = temp;
183  }
184 }
185 
186 #ifndef NDEBUG
187 
188 static
189 SCIP_Bool isFixed(
190  SCIP_SDPI* sdpi,
191  int v
192  )
193 {
194  SCIP_Real lb;
195  SCIP_Real ub;
196 
197  assert ( sdpi != NULL );
198  assert ( v < sdpi->nvars );
199  assert ( sdpi->lb != NULL );
200  assert ( sdpi->ub != NULL );
201 
202  lb = sdpi->lb[v];
203  ub = sdpi->ub[v];
204 
205  assert( lb < ub + sdpi->feastol || sdpi->infeasible );
206 
207  return ( REALABS(ub-lb) <= sdpi->feastol );
208 }
209 #else
210 #define isFixed(sdpi, v) (REALABS(sdpi->ub[v] - sdpi->lb[v]) <= sdpi->epsilon)
211 #endif
212 
220 static
222  SCIP_SDPI* sdpi,
223  int* sdpconstnnonz,
224  int* sdpconstnblocknonz,
226  int** sdpconstrow,
227  int** sdpconstcol,
228  SCIP_Real** sdpconstval
229  )
230 {
231  int i;
232  int v;
233  int block;
234  int* nfixednonz;
235  int** fixedrows;
236  int** fixedcols;
237  SCIP_Real** fixedvals;
238 
239  assert ( sdpi != NULL );
240  assert ( sdpconstnnonz != NULL );
241  assert ( sdpconstnblocknonz != NULL );
242  assert ( sdpconstrow != NULL );
243  assert ( sdpconstcol != NULL );
244  assert ( sdpconstval != NULL );
245 #ifndef NDEBUG
246  for (block = 0; block < sdpi->nsdpblocks; block++)
247  {
248  assert ( sdpconstrow[block] != NULL );
249  assert ( sdpconstcol[block] != NULL );
250  assert ( sdpconstval[block] != NULL );
251  }
252 #endif
253 
254  fixedrows = NULL;
255  fixedcols = NULL;
256  fixedvals = NULL;
257 
258  /* allocate memory for the nonzeros that need to be fixed, as this is only temporarly needed, we allocate as much as theoretically possible */
259  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &nfixednonz, sdpi->nsdpblocks) );
260  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &fixedrows, sdpi->nsdpblocks) );
261  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &fixedcols, sdpi->nsdpblocks) );
262  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &fixedvals, sdpi->nsdpblocks) );
263 
264  for (block = 0; block < sdpi->nsdpblocks; block++)
265  {
266  /* compute the number of fixed nonzeros in this block */
267  nfixednonz[block] = 0;
268  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
269  {
270  if (isFixed(sdpi, sdpi->sdpvar[block][v]))
271  nfixednonz[block] += sdpi->sdpnblockvarnonz[block][v];
272  }
273 
274  fixedrows[block] = NULL;
275  fixedcols[block] = NULL;
276  fixedvals[block] = NULL;
277 
278  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(fixedrows[block]), nfixednonz[block]) );
279  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(fixedcols[block]), nfixednonz[block]) );
280  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(fixedvals[block]), nfixednonz[block]) );
281 
282  /* 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) */
283  nfixednonz[block] = 0;
284  }
285 
286  /* iterate over all variables, saving the nonzeros of the fixed ones */
287  for (block = 0; block < sdpi->nsdpblocks; block++)
288  {
289  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
290  {
291  if (isFixed(sdpi, sdpi->sdpvar[block][v]))
292  {
293  for (i = 0; i < sdpi->sdpnblockvarnonz[block][v]; i++)
294  {
295  fixedrows[block][nfixednonz[block]] = sdpi->sdprow[block][v][i];
296  fixedcols[block][nfixednonz[block]] = sdpi->sdpcol[block][v][i];
297  /* this is the final value to add, so we no longer have to remember, from which variable this nonzero comes,
298  * the -1 comes from +y_iA_i but -A_0 */
299  fixedvals[block][nfixednonz[block]] = - sdpi->sdpval[block][v][i] * sdpi->lb[sdpi->sdpvar[block][v]];
300  nfixednonz[block]++;
301  }
302  }
303  }
304  }
305 
306  /* compute the constant matrix */
307  *sdpconstnnonz = 0;
308  for (block = 0; block < sdpi->nsdpblocks; block++)
309  {
310  SCIP_CALL( SCIPsdpVarfixerMergeArraysIntoNew(sdpi->blkmem, sdpi->feastol, sdpi->sdpconstrow[block], sdpi->sdpconstcol[block], sdpi->sdpconstval[block],
311  sdpi->sdpconstnblocknonz[block], fixedrows[block], fixedcols[block], fixedvals[block], nfixednonz[block],
312  sdpconstrow[block], sdpconstcol[block], sdpconstval[block], &sdpconstnblocknonz[block]) );
313  *sdpconstnnonz += sdpconstnblocknonz[block];
314  }
315 
316  /* free all memory */
317  for (block = 0; block < sdpi->nsdpblocks; block++)
318  {
319  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(fixedvals[block]), nfixednonz[block]);
320  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(fixedcols[block]), nfixednonz[block]);
321  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(fixedrows[block]), nfixednonz[block]);
322  }
323  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &fixedvals, sdpi->nsdpblocks);
324  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &fixedcols, sdpi->nsdpblocks);
325  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &fixedrows, sdpi->nsdpblocks);
326  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &nfixednonz, sdpi->nsdpblocks);
327 
328  return SCIP_OKAY;
329 }
330 
334 static
335 SCIP_RETCODE findEmptyRowColsSDP(
336  SCIP_SDPI* sdpi,
337  int* sdpconstnblocknonz,
339  int** sdpconstrow,
340  int** sdpconstcol,
341  SCIP_Real** sdpconstval,
342  int** indchanges,
346  int* nremovedinds,
347  int* blockindchanges,
348  int* nremovedblocks
349  )
350 {
351  int block;
352  int v;
353  int i;
354  int nfoundinds;
355 
356  assert( sdpi != NULL );
357  assert( sdpconstnblocknonz != NULL );
358  assert( sdpconstrow != NULL );
359  assert( sdpconstcol != NULL );
360  assert( sdpconstval != NULL );
361  assert( indchanges != NULL );
362  assert( nremovedinds != NULL );
363  assert( blockindchanges != NULL );
364  assert( nremovedblocks != NULL );
365 
366  /* initialize indchanges with -1 */
367  for (block = 0; block < sdpi->nsdpblocks; block++)
368  {
369  for (i = 0; i < sdpi->sdpblocksizes[block]; i++)
370  indchanges[block][i] = -1;
371  }
372  *nremovedblocks = 0;
373 
374  /* 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
375  * index is still needed, it will later be set to the number of rows/cols deleted earlier) */
376  for (block = 0; block < sdpi->nsdpblocks; block++)
377  {
378  /* the number of indices already found in this block, saved for prematurely stopping the loops */
379  nfoundinds = 0;
380  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
381  {
382  if ( ! (isFixed(sdpi, sdpi->sdpvar[block][v])) )
383  {
384  for (i = 0; i < sdpi->sdpnblockvarnonz[block][v]; i++)
385  {
386  assert ( REALABS(sdpi->sdpval[block][v][i]) > sdpi->epsilon); /* this should really be a nonzero */
387  if ( indchanges[block][sdpi->sdprow[block][v][i]] == -1 )
388  {
389  indchanges[block][sdpi->sdprow[block][v][i]] = 1;
390  nfoundinds++;
391  }
392  if ( indchanges[block][sdpi->sdpcol[block][v][i]] == -1 )
393  {
394  indchanges[block][sdpi->sdpcol[block][v][i]] = 1;
395  nfoundinds++;
396  }
397  if ( nfoundinds == sdpi->sdpblocksizes[block] )
398  break; /* we're done for this block */
399  }
400  }
401  if (nfoundinds == sdpi->sdpblocksizes[block])
402  break; /* we're done for this block */
403  }
404 
405  if ( nfoundinds < sdpi->sdpblocksizes[block] )
406  {
407  /* if some indices haven't been found yet, look in the constant part for them */
408  for (i = 0; i < sdpconstnblocknonz[block]; i++)
409  {
410  assert ( REALABS(sdpconstval[block][i]) > sdpi->epsilon); /* this should really be a nonzero */
411  if ( indchanges[block][sdpconstrow[block][i]] == -1 )
412  {
413  indchanges[block][sdpconstrow[block][i]] = 1;
414  nfoundinds++;
415  }
416  if ( indchanges[block][sdpconstcol[block][i]] == -1 )
417  {
418  indchanges[block][sdpconstcol[block][i]] = 1;
419  nfoundinds++;
420  }
421  if ( nfoundinds == sdpi->sdpblocksizes[block] )
422  break; /* we're done for this block */
423  }
424  }
425 
426  /* 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 */
427  nremovedinds[block] = 0;
428  for (i = 0; i < sdpi->sdpblocksizes[block]; i++)
429  {
430  if ( indchanges[block][i] == -1 )
431  {
432  SCIPdebugMessage("empty row and col %d were removed from block %d of SDP %d\n", i, block, sdpi->sdpid);
433  /* this index wasn't found (indchanges was initialized with 0), so it can be removed */
434  nremovedinds[block]++;
435  }
436  else
437  {
438  /* this index has been found, so set the value to the number of removed inds before it */
439  indchanges[block][i] = nremovedinds[block];
440  }
441  }
442 
443  /* check if the block became empty */
444  if ( nremovedinds[block] == sdpi->sdpblocksizes[block] )
445  {
446  SCIPdebugMessage("empty block %d detected in SDP %d, this will be removed", block, sdpi->sdpid);
447  blockindchanges[block] = -1;
448  (*nremovedblocks)++;
449  }
450  else
451  blockindchanges[block] = *nremovedblocks;
452  }
453 
454  return SCIP_OKAY;
455 }
456 
461 static
463  SCIP_SDPI* sdpi,
464  int* nactivelpcons,
465  SCIP_Real* lplhsafterfix,
469  SCIP_Real* lprhsafterfix,
473  int* rownactivevars,
474  SCIP_Bool* fixingsfound
475  )
476 {
477  int i;
478  int c;
479  int lastrow = -1;
480  int nonzind = -1;
481  int nonzcol = -1;
482  SCIP_Real nonzval;
483 
484  assert( sdpi != NULL );
485  assert( nactivelpcons != NULL );
486  assert( sdpi->nlpcons == 0 || lplhsafterfix != NULL );
487  assert( sdpi->nlpcons == 0 || lprhsafterfix != NULL );
488  assert( sdpi->nlpcons == 0 || rownactivevars != NULL );
489  assert( sdpi->nlpcons == 0 || fixingsfound != NULL );
490 
491  /* if there is no LP-part, there is nothing to do */
492  if ( sdpi->nlpcons == 0 || sdpi->lpnnonz == 0 )
493  {
494  *nactivelpcons = 0;
495  return SCIP_OKAY;
496  }
497 
498  /* initialize rownactivevars */
499  for (c = 0; c < sdpi->nlpcons; c++)
500  rownactivevars[c] = 0;
501  *nactivelpcons = 0;
502 
503  /* sort the lp arrays by row indices */
504 #if 0 /* TODO thoroughly test this */
505  SCIPsortIntIntReal(sdpi->lprow, sdpi->lpcol, sdpi->lpval, sdpi->lpnnonz);
506 #endif
507 
508  for (i = 0; i < sdpi->lpnnonz; i++)
509  {
510  assert( i == 0 || sdpi->lprow[i-1] <= sdpi->lprow[i] );
511 
512  /* we reached a new row */
513  if ( sdpi->lprow[i] > lastrow )
514  {
515  /* if the last row had at least two active variables, we keep the lhs- and rhs-value */
516  if ( lastrow >= 0 && rownactivevars[lastrow] > 1 )
517  (*nactivelpcons)++;
518  else if ( lastrow >= 0 && rownactivevars[lastrow] == 1 )
519  {
520  assert( 0 <= nonzind && nonzind < sdpi->lpnnonz );
521 
522  nonzcol = sdpi->lpcol[nonzind];
523  assert( 0 <= nonzcol && nonzcol < sdpi->nvars );
524 
525  nonzval = sdpi->lpval[nonzind];
526  assert( REALABS(nonzval) > sdpi->feastol );
527 
528  /* we have to check if this is an improvement of the current bound */
529  if ( nonzval < 0.0 ) /* we have to compare with the upper bound for lhs and lower bound for rhs */
530  {
531  /* check for the left-hand-side */
532  if ( (lplhsafterfix[*nactivelpcons] > - SCIPsdpiInfinity(sdpi)) &&
533  ((lplhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->feastol) )
534  {
535  /* this bound is sharper than the original one */
536  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
537  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
538  sdpi->ub[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
539 
540  /* check if this leads to a fixing of this variable */
541  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->feastol )
542  {
543  *fixingsfound = TRUE;
544  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
545  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
546  }
547  /* check if this makes the problem infeasible */
548  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
549  {
550  sdpi->infeasible = TRUE;
551  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
552  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
553  return SCIP_OKAY;
554  }
555  }
556  /* check for the right-hand-side */
557  if ( (lprhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
558  ((lprhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] + sdpi->feastol) )
559  {
560  /* this bound is sharper than the original one */
561  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
562  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
563  sdpi->lb[nonzcol] = lprhsafterfix[*nactivelpcons] / nonzval;
564 
565  /* check if this leads to a fixing of this variable */
566  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->feastol )
567  {
568  *fixingsfound = TRUE;
569  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
570  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
571  }
572  /* check if this makes the problem infeasible */
573  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
574  {
575  sdpi->infeasible = TRUE;
576  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
577  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
578  return SCIP_OKAY;
579  }
580  }
581  }
582  else /* we compare with the lower bound for lhs and upper bound for rhs */
583  {
584  /* check for the left-hand-side */
585  if ( (lplhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
586  ((lplhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] + sdpi->feastol) )
587  {
588  /* this bound is sharper than the original one */
589  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
590  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
591  sdpi->lb[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
592 
593  /* check if this leads to a fixing of this variable */
594  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->feastol )
595  {
596  *fixingsfound = TRUE;
597  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
598  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
599  }
600  /* check if this makes the problem infeasible */
601  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
602  {
603  sdpi->infeasible = TRUE;
604  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
605  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
606  return SCIP_OKAY;
607  }
608  }
609  /* check for the right-hand-side */
610  if ( (lprhsafterfix[*nactivelpcons] > - SCIPsdpiInfinity(sdpi)) &&
611  ((lprhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->feastol) )
612  {
613  /* this bound is sharper than the original one */
614  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
615  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
616  sdpi->ub[nonzcol] = lprhsafterfix[*nactivelpcons] / nonzval;
617 
618  /* check if this leads to a fixing of this variable */
619  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->feastol )
620  {
621  *fixingsfound = TRUE;
622  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
623  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
624  }
625  /* check if this makes the problem infeasible */
626  if (sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol)
627  {
628  sdpi->infeasible = TRUE;
629  SCIPdebugMessage("We found an upper bound %f that is lower than the lower bound %f for variable %d, so the problem is infeasible !\n",
630  sdpi->ub[nonzcol], sdpi->lb[nonzcol], nonzcol);
631  return SCIP_OKAY;
632  }
633  }
634  }
635  }
636  else if ( lastrow >= 0 ) /* because of earlier ifs we have rownactivevars = 0 */
637  {
638  assert( lastrow == -1 || rownactivevars[lastrow] == 0 );
639  /* we have a constraint lhs <= 0 <= rhs, so lhs should be non-positive and rhs non-negative, otherwise the problem is infeasible */
640  if ( lplhsafterfix[*nactivelpcons] > sdpi->feastol || lprhsafterfix[*nactivelpcons] < -sdpi->feastol )
641  {
642  sdpi->infeasible = TRUE;
643  SCIPdebugMessage("We found a constraint which with given fixings reads %f <= 0 <= %f, so the current problem is infeasible !\n",
644  lplhsafterfix[*nactivelpcons], lprhsafterfix[*nactivelpcons] );
645  return SCIP_OKAY;
646  }
647  }
648 
649  /* update lastrow for new row */
650  lastrow = sdpi->lprow[i];
651 
652  /* start the next lhr & rhs with the original value */
653  lplhsafterfix[*nactivelpcons] = sdpi->lplhs[lastrow];
654  lprhsafterfix[*nactivelpcons] = sdpi->lprhs[lastrow];
655  }
656 
657  /* if the variable is active, we increase rownactivevars */
658  if ( ! isFixed(sdpi, sdpi->lpcol[i]) )
659  {
660  rownactivevars[lastrow]++;
661  nonzind = i;
662  }
663  else
664  {
665  /* otherwise we add the value (coefficient * value of fixed variable) to the lhs and rhs, the minus comes from +A_i but -A_0 */
666  lplhsafterfix[*nactivelpcons] -= sdpi->lpval[i] * sdpi->lb[sdpi->lpcol[i]];
667  lprhsafterfix[*nactivelpcons] -= sdpi->lpval[i] * sdpi->lb[sdpi->lpcol[i]];
668  }
669  }
670  /* 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 */
671  if ( rownactivevars[lastrow] > 1 )
672  (*nactivelpcons)++;
673  else if ( rownactivevars[lastrow] == 1 )
674  {
675  assert( 0 <= nonzind && nonzind < sdpi->lpnnonz );
676 
677  nonzcol = sdpi->lpcol[nonzind];
678  assert( 0 <= nonzcol && nonzcol < sdpi->nvars );
679 
680  nonzval = sdpi->lpval[nonzind];
681  assert( REALABS(nonzval) > sdpi->epsilon );
682 
683  /* we have to check if this is an improvement of the current bound */
684  if ( nonzval < 0.0 ) /* we have to compare with the upper bound for lhs and lower bound for rhs */
685  {
686  /* check for the left-hand-side */
687  if ( (lplhsafterfix[*nactivelpcons] > SCIPsdpiInfinity(sdpi)) &&
688  ((lplhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->feastol) )
689  {
690  /* this bound is sharper than the original one */
691  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
692  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
693  sdpi->ub[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
694 
695  /* check if this leads to a fixing of this variable */
696  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->feastol )
697  {
698  *fixingsfound = TRUE;
699  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
700  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
701  }
702  /* check if this makes the problem infeasible */
703  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
704  {
705  sdpi->infeasible = TRUE;
706  SCIPdebugMessage("We found an upper bound that is lower than the lower bound, so the problem is infeasible !\n");
707  return SCIP_OKAY;
708  }
709  }
710  /* check for the right-hand-side */
711  if ( (lprhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
712  ((lprhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] - sdpi->feastol) )
713  {
714  /* this bound is sharper than the original one */
715  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
716  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
717  sdpi->lb[nonzcol] = lprhsafterfix[*nactivelpcons] / nonzval;
718 
719  /* check if this leads to a fixing of this variable */
720  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->feastol )
721  {
722  *fixingsfound = TRUE;
723  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
724  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
725  }
726  /* check if this makes the problem infeasible */
727  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
728  {
729  sdpi->infeasible = TRUE;
730  SCIPdebugMessage("We found an upper bound that is lower than the lower bound, so the problem is infeasible !\n");
731  return SCIP_OKAY;
732  }
733  }
734  }
735  else /* we compare with the lower bound for lhs and upper bound for rhs */
736  {
737  /* check for the left-hand-side */
738  if ( (lplhsafterfix[*nactivelpcons] < SCIPsdpiInfinity(sdpi)) &&
739  ((lplhsafterfix[*nactivelpcons] / nonzval) > sdpi->lb[nonzcol] + sdpi->feastol) )
740  {
741  /* this bound is sharper than the original one */
742  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, lower bound of variable %d has been sharpened to %f "
743  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lplhsafterfix[*nactivelpcons] / nonzval, sdpi->lb[nonzcol]);
744  sdpi->lb[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
745 
746  /* check if this leads to a fixing of this variable */
747  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->feastol )
748  {
749  *fixingsfound = TRUE;
750  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
751  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
752  }
753  /* check if this makes the problem infeasible */
754  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
755  {
756  sdpi->infeasible = TRUE;
757  SCIPdebugMessage("We found a lower bound that is bigger than the upper bound, so the problem is infeasible !\n");
758  return SCIP_OKAY;
759  }
760  }
761  /* check for the right-hand-side */
762  if ( (lprhsafterfix[*nactivelpcons] > SCIPsdpiInfinity(sdpi)) &&
763  ((lprhsafterfix[*nactivelpcons] / nonzval) < sdpi->ub[nonzcol] - sdpi->feastol) )
764  {
765  /* this bound is sharper than the original one */
766  SCIPdebugMessage("empty LP-row %d has been removed from SDP %d, upper bound of variable %d has been sharpened to %f "
767  "(originally %f)\n", lastrow, sdpi->sdpid, nonzcol, lprhsafterfix[*nactivelpcons] / nonzval, sdpi->ub[nonzcol]);
768  sdpi->ub[nonzcol] = lplhsafterfix[*nactivelpcons] / nonzval;
769 
770  /* check if this leads to a fixing of this variable */
771  if ( REALABS(sdpi->lb[nonzcol] - sdpi->ub[nonzcol]) < sdpi->feastol )
772  {
773  *fixingsfound = TRUE;
774  SCIPdebugMessage("computeLpLhsRhsAfterFixings fixed variable %d to value %f in SDP %d\n",
775  nonzcol, sdpi->lb[nonzcol], sdpi->sdpid);
776  }
777  /* check if this makes the problem infeasible */
778  if ( sdpi->ub[nonzcol] < sdpi->lb[nonzcol] - sdpi->feastol )
779  {
780  sdpi->infeasible = TRUE;
781  SCIPdebugMessage("We found an upper bound that is lower than the lower bound, so the problem is infeasible !\n");
782  return SCIP_OKAY;
783  }
784  }
785  }
786  }
787  else
788  {
789  assert( lastrow == -1 || rownactivevars[lastrow] == 0 );
790  /* we have a constraint lhs <= 0 <= rhs, so lhs should be non-positive and rhs non-negative, otherwise the problem is infeasible */
791  if ( lplhsafterfix[*nactivelpcons] > sdpi->feastol || lprhsafterfix[*nactivelpcons] < -sdpi->feastol )
792  {
793  sdpi->infeasible = TRUE;
794  SCIPdebugMessage("We found a constraint which with given fixings reads %f <= 0 <= %f, so the current problem is infeasible !\n",
795  lplhsafterfix[*nactivelpcons], lprhsafterfix[*nactivelpcons] );
796  return SCIP_OKAY;
797  }
798  }
799 
800  return SCIP_OKAY;
801 }
802 
803 
804 /*
805  * Miscellaneous Methods
806  */
807 
814  void
815  )
816 {
818 }
819 
822  void
823  )
824 {
826 }
827 
835  SCIP_SDPI* sdpi
836  )
837 {
838  return SCIPsdpiSolverGetSolverPointer(sdpi->sdpisolver);
839 }
840 
844 /*
845  * SDPI Creation and Destruction Methods
846  */
847 
852 SCIP_RETCODE SCIPsdpiCreate(
853  SCIP_SDPI** sdpi,
854  SCIP_MESSAGEHDLR* messagehdlr,
855  BMS_BLKMEM* blkmem
856  )
857 {
858  assert ( sdpi != NULL );
859  assert ( blkmem != NULL );
860 
861  SCIPdebugMessage("Calling SCIPsdpiCreate\n");
862 
863  BMS_CALL(BMSallocBlockMemory(blkmem, sdpi));
864 
865  SCIP_CALL( SCIPsdpiSolverCreate(&((*sdpi)->sdpisolver), messagehdlr, blkmem) );
866 
867  (*sdpi)->messagehdlr = messagehdlr;
868  (*sdpi)->blkmem = blkmem;
869  (*sdpi)->sdpid = 1;
870  (*sdpi)->nvars = 0;
871  (*sdpi)->nsdpblocks = 0;
872  (*sdpi)->sdpconstnnonz = 0;
873  (*sdpi)->sdpnnonz = 0;
874  (*sdpi)->nlpcons = 0;
875  (*sdpi)->lpnnonz = 0;
876  (*sdpi)->slatercheck = FALSE;
877  (*sdpi)->solved = FALSE;
878  (*sdpi)->penalty = FALSE;
879  (*sdpi)->infeasible = FALSE;
880 
881  (*sdpi)->obj = NULL;
882  (*sdpi)->lb = NULL;
883  (*sdpi)->ub = NULL;
884  (*sdpi)->sdpblocksizes = NULL;
885  (*sdpi)->sdpnblockvars = NULL;
886  (*sdpi)->sdpconstnblocknonz = NULL;
887  (*sdpi)->sdpconstrow = NULL;
888  (*sdpi)->sdpconstcol = NULL;
889  (*sdpi)->sdpconstval = NULL;
890  (*sdpi)->sdpnblockvarnonz = NULL;
891  (*sdpi)->sdpvar = NULL;
892  (*sdpi)->sdprow = NULL;
893  (*sdpi)->sdpcol = NULL;
894  (*sdpi)->sdpval = NULL;
895  (*sdpi)->lplhs = NULL;
896  (*sdpi)->lprhs = NULL;
897  (*sdpi)->lprow = NULL;
898  (*sdpi)->lpcol = NULL;
899  (*sdpi)->lpval = NULL;
900 
901  (*sdpi)->epsilon = 1e-5;
902  (*sdpi)->feastol = 1e-4;
903 
904  return SCIP_OKAY;
905 }
906 
908 SCIP_RETCODE SCIPsdpiFree(
909  SCIP_SDPI** sdpi
910  )
911 {
912  int i;
913  int j;
914 
915  SCIPdebugMessage("Calling SCIPsdpiFree \n");
916  assert ( sdpi != NULL );
917  assert ( *sdpi != NULL );
918 
919  /* free the LP part */
920  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lpval), (*sdpi)->lpnnonz);
921  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lpcol), (*sdpi)->lpnnonz);
922  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lprow), (*sdpi)->lpnnonz);
923  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lprhs), (*sdpi)->nlpcons);
924  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lplhs), (*sdpi)->nlpcons);
925 
926  /* free the individual nonzeros */
927  for (i = 0; i < (*sdpi)->nsdpblocks; i++)
928  {
929  for (j = 0; j < (*sdpi)->sdpnblockvars[i]; j++)
930  {
931  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval[i][j]), (*sdpi)->sdpnblockvarnonz[i][j]);
932  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow[i][j]), (*sdpi)->sdpnblockvarnonz[i][j]);
933  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol[i][j]), (*sdpi)->sdpnblockvarnonz[i][j]);
934  }
935  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval[i]), (*sdpi)->sdpnblockvars[i]);
936  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow[i]), (*sdpi)->sdpnblockvars[i]);
937  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol[i]), (*sdpi)->sdpnblockvars[i]);
938  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpvar[i]), (*sdpi)->sdpnblockvars[i]);
939  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvarnonz[i]), (*sdpi)->sdpnblockvars[i]);
940  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstval[i]), (*sdpi)->sdpconstnblocknonz[i]);
941  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstrow[i]), (*sdpi)->sdpconstnblocknonz[i]);
942  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstcol[i]), (*sdpi)->sdpconstnblocknonz[i]);
943  }
944 
945  /* free the rest */
946  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvarnonz), (*sdpi)->nsdpblocks);
947  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstnblocknonz), (*sdpi)->nsdpblocks);
948  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval), (*sdpi)->nsdpblocks);
949  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol), (*sdpi)->nsdpblocks);
950  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow), (*sdpi)->nsdpblocks);
951  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpvar), (*sdpi)->nsdpblocks);
952  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstval), (*sdpi)->nsdpblocks);
953  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstcol), (*sdpi)->nsdpblocks);
954  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstrow), (*sdpi)->nsdpblocks);
955  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvars), (*sdpi)->nsdpblocks);
956  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpblocksizes), (*sdpi)->nsdpblocks);
957  BMSfreeBlockMemoryArray((*sdpi)->blkmem, &((*sdpi)->ub), (*sdpi)->nvars);
958  BMSfreeBlockMemoryArray((*sdpi)->blkmem, &((*sdpi)->lb), (*sdpi)->nvars);
959  BMSfreeBlockMemoryArray((*sdpi)->blkmem, &((*sdpi)->obj), (*sdpi)->nvars);
960 
961  /* free the solver */
962  SCIP_CALL( SCIPsdpiSolverFree(&((*sdpi)->sdpisolver)) );
963 
964  BMSfreeBlockMemory((*sdpi)->blkmem, sdpi);
965 
966  return SCIP_OKAY;
967 }
968 
971 SCIP_RETCODE SCIPsdpiClone(
972  SCIP_SDPI* oldsdpi,
973  SCIP_SDPI* newsdpi
974  )
975 {
976  BMS_BLKMEM* blkmem;
977  int nvars;
978  int nsdpblocks;
979  int lpnnonz;
980  int b;
981  int v;
982 
983  assert( oldsdpi != NULL );
984 
985  SCIPdebugMessage("Cloning SDPI %d\n", oldsdpi->sdpid);
986 
987  /* general data */
988  blkmem = oldsdpi->blkmem;
989  nvars = oldsdpi->nvars;
990  nsdpblocks = oldsdpi->nsdpblocks;
991  lpnnonz = oldsdpi->lpnnonz;
992 
993  BMS_CALL( BMSallocBlockMemory(blkmem, &newsdpi) );
994 
995  SCIP_CALL( SCIPsdpiSolverCreate(&(newsdpi->sdpisolver), oldsdpi->messagehdlr, oldsdpi->blkmem) ); /* create new SDP-Solver Interface */
996 
997  newsdpi->messagehdlr = oldsdpi->messagehdlr;
998  newsdpi->blkmem = blkmem;
999  newsdpi->nvars = nvars;
1000 
1001  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->obj), oldsdpi->obj, nvars) );
1002  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lb), oldsdpi->lb, nvars) );
1003  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->ub), oldsdpi->ub, nvars) );
1004 
1005  newsdpi->nsdpblocks = nsdpblocks;
1006 
1007  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpblocksizes), oldsdpi->sdpblocksizes, nsdpblocks) );
1008  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvars), oldsdpi->sdpnblockvars, nsdpblocks) );
1009 
1010  /* constant SDP data */
1011  newsdpi->sdpconstnnonz = oldsdpi->sdpconstnnonz;
1012 
1013  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstnblocknonz), oldsdpi->sdpconstnblocknonz, nsdpblocks) );
1014  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstrow), nsdpblocks) );
1015  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstcol), nsdpblocks) );
1016  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstval), nsdpblocks) );
1017 
1018  for (b = 0; b < nsdpblocks; b++)
1019  {
1020  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstrow[b]), oldsdpi->sdpconstrow[b], oldsdpi->sdpconstnblocknonz[b]) );
1021  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstcol[b]), oldsdpi->sdpconstcol[b], oldsdpi->sdpconstnblocknonz[b]) );
1022  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstval[b]), oldsdpi->sdpconstval[b], oldsdpi->sdpconstnblocknonz[b]) );
1023  }
1024 
1025  /* SDP data */
1026  newsdpi->sdpnnonz = oldsdpi->sdpnnonz;
1027 
1028  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvarnonz), nsdpblocks) );
1029  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpvar), nsdpblocks) );
1030  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdprow), nsdpblocks) );
1031  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpcol), nsdpblocks) );
1032  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpval), nsdpblocks) );
1033 
1034  for (b = 0; b < nsdpblocks; b++)
1035  {
1036  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvarnonz[b]), oldsdpi->sdpnblockvarnonz[b], oldsdpi->sdpnblockvars[b]) );
1037  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpvar[b]), oldsdpi->sdpvar[b], oldsdpi->sdpnblockvars[b]) );
1038 
1039  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdprow[b]), oldsdpi->sdpnblockvars[b]) );
1040  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpcol[b]), oldsdpi->sdpnblockvars[b]) );
1041  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpval[b]), oldsdpi->sdpnblockvars[b]) );
1042 
1043  for (v = 0; v < oldsdpi->sdpnblockvars[b]; v++)
1044  {
1045  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdprow[b][v]), oldsdpi->sdprow[b][v], oldsdpi->sdpnblockvarnonz[b][v]) );
1046  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpcol[b][v]), oldsdpi->sdpcol[b][v], oldsdpi->sdpnblockvarnonz[b][v]) );
1047  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpval[b][v]), oldsdpi->sdpval[b][v], oldsdpi->sdpnblockvarnonz[b][v]) );
1048  }
1049  }
1050 
1051  /* LP data */
1052  newsdpi->nlpcons = oldsdpi->nlpcons;
1053 
1054  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lplhs), oldsdpi->lplhs, oldsdpi->nlpcons) );
1055  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lprhs), oldsdpi->lprhs, oldsdpi->nlpcons) );
1056 
1057  newsdpi->lpnnonz = lpnnonz;
1058 
1059  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lprow), oldsdpi->lprow, lpnnonz) );
1060  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lpcol), oldsdpi->lpcol, lpnnonz) );
1061  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lpval), oldsdpi->lpval, lpnnonz) );
1062 
1063  /* other data */
1064  newsdpi->solved = FALSE; /* as we don't copy the sdpisolver, this needs to be set to false */
1065  newsdpi->penalty = FALSE; /* all things about SDP-solutions are set to false as well, as we didn't solve the problem */
1066  newsdpi->infeasible = FALSE;
1067  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 */
1068  newsdpi->epsilon = oldsdpi->epsilon;
1069  newsdpi->feastol = oldsdpi->feastol;
1070 
1071  return SCIP_OKAY;
1072 }
1073 
1077 /*
1078  * Modification Methods
1079  */
1080 
1089 SCIP_RETCODE SCIPsdpiLoadSDP(
1090  SCIP_SDPI* sdpi,
1091  int nvars,
1092  SCIP_Real* obj,
1093  SCIP_Real* lb,
1094  SCIP_Real* ub,
1095  int nsdpblocks,
1096  int* sdpblocksizes,
1097  int* sdpnblockvars,
1098  int sdpconstnnonz,
1099  int* sdpconstnblocknonz,
1101  int** sdpconstrow,
1102  int** sdpconstcol,
1103  SCIP_Real** sdpconstval,
1104  int sdpnnonz,
1105  int** sdpnblockvarnonz,
1107  int** sdpvar,
1109  int*** sdprow,
1112  int*** sdpcol,
1113  SCIP_Real*** sdpval,
1115  int nlpcons,
1116  SCIP_Real* lplhs,
1117  SCIP_Real* lprhs,
1118  int lpnnonz,
1119  int* lprow,
1120  int* lpcol,
1121  SCIP_Real* lpval
1122  )
1123 {
1124  int i;
1125  int v;
1126  int block;
1127 
1128  SCIPdebugMessage("Calling SCIPsdpiLoadSDP (%d)\n",sdpi->sdpid);
1129 
1130  assert ( sdpi != NULL );
1131  assert ( nvars > 0 );
1132  assert ( obj != NULL );
1133  assert ( lb != NULL );
1134  assert ( ub != NULL );
1135 
1136 #ifdef SCIP_DEBUG
1137  if (sdpconstnnonz > 0 || sdpnnonz > 0 || nsdpblocks > 0)
1138  {
1139  assert ( sdpblocksizes != NULL );
1140  assert ( sdpnblockvars != NULL );
1141  assert ( nsdpblocks > 0 );
1142  assert ( sdpconstnblocknonz != NULL );
1143  assert ( sdpnblockvarnonz != NULL );
1144 
1145  if (sdpconstnnonz > 0)
1146  {
1147  assert ( sdpconstrow != NULL );
1148  assert ( sdpconstcol != NULL );
1149  assert ( sdpconstval != NULL );
1150 
1151  for (i = 0; i < nsdpblocks; i++)
1152  {
1153  if (sdpconstnblocknonz[i] > 0)
1154  {
1155  assert ( sdpconstrow[i] != NULL );
1156  assert ( sdpconstcol[i] != NULL );
1157  assert ( sdpconstval[i] != NULL );
1158  }
1159  }
1160  }
1161 
1162  if (sdpnnonz > 0)
1163  {
1164  assert ( sdprow != NULL );
1165  assert ( sdpcol != NULL );
1166  assert ( sdpval != NULL );
1167 
1168  for ( i = 0; i < nsdpblocks; i++ )
1169  {
1170  assert ( sdpcol[i] != NULL );
1171  assert ( sdprow[i] != NULL );
1172  assert ( sdpval[i] != NULL );
1173 
1174  for ( v = 0; v < sdpnblockvars[i]; v++)
1175  {
1176  if (sdpnblockvarnonz[i][v] > 0)
1177  {
1178  assert ( sdpcol[i][v] != NULL );
1179  assert ( sdprow[i][v] != NULL );
1180  assert ( sdpval[i][v] != NULL );
1181  }
1182  }
1183  }
1184  }
1185  }
1186 #endif
1187 
1188  assert ( nlpcons == 0 || lplhs != NULL );
1189  assert ( nlpcons == 0 || lprhs != NULL );
1190  assert ( lpnnonz == 0 || lprow != NULL );
1191  assert ( lpnnonz == 0 || lpcol != NULL );
1192  assert ( lpnnonz == 0 || lpval != NULL );
1193 
1194  /* memory allocation */
1195 
1196  /* first free the old arrays */
1197  for (block = sdpi->nsdpblocks - 1; block >= 0; block--)
1198  {
1199  for (v = sdpi->sdpnblockvars[block] - 1; v >= 0; v--)
1200  {
1201  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpval[block][v]), sdpi->sdpnblockvarnonz[block][v]);
1202  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdprow[block][v]), sdpi->sdpnblockvarnonz[block][v]);
1203  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpcol[block][v]), sdpi->sdpnblockvarnonz[block][v]);
1204  }
1205 
1206  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpval[block]), sdpi->sdpnblockvars[block]);
1207  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdprow[block]), sdpi->sdpnblockvars[block]);
1208  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpcol[block]), sdpi->sdpnblockvars[block]);
1209  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstval[block]), sdpi->sdpconstnblocknonz[block]);
1210  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstrow[block]), sdpi->sdpconstnblocknonz[block]);
1211  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstcol[block]), sdpi->sdpconstnblocknonz[block]);
1212  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpnblockvarnonz[block]), sdpi->sdpnblockvars[block]);
1213  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpvar[block]), sdpi->sdpnblockvars[block]);
1214  }
1215 
1216  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->ub), sdpi->nvars);
1217  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lb), sdpi->nvars);
1218  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->obj), sdpi->nvars);
1219 
1220  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpblocksizes), sdpi->nsdpblocks);
1221  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpnblockvars), sdpi->nsdpblocks);
1222  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->sdpconstnblocknonz), sdpi->nsdpblocks);
1223 
1224  /* duplicate some arrays */
1225  BMS_CALL( BMSduplicateBlockMemoryArray(sdpi->blkmem, &(sdpi->obj), obj, nvars) );
1226  BMS_CALL( BMSduplicateBlockMemoryArray(sdpi->blkmem, &(sdpi->lb), lb, nvars) );
1227  BMS_CALL( BMSduplicateBlockMemoryArray(sdpi->blkmem, &(sdpi->ub), ub, nvars) );
1228  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpblocksizes), sdpblocksizes, nsdpblocks);
1229  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpnblockvars), sdpnblockvars, nsdpblocks);
1230  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstnblocknonz), sdpconstnblocknonz, nsdpblocks);
1231 
1232  /* allocate memory for the sdp arrays & duplicate them */
1233  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpnblockvarnonz), sdpi->nsdpblocks, nsdpblocks) );
1234  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstcol), sdpi->nsdpblocks, nsdpblocks) );
1235  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstrow), sdpi->nsdpblocks, nsdpblocks) );
1236  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstval), sdpi->nsdpblocks, nsdpblocks) );
1237  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpvar), sdpi->nsdpblocks, nsdpblocks) );
1238  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpcol), sdpi->nsdpblocks, nsdpblocks) );
1239  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdprow), sdpi->nsdpblocks, nsdpblocks) );
1240  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpval), sdpi->nsdpblocks, nsdpblocks) );
1241 
1242  for (block = 0; block < nsdpblocks; block++)
1243  {
1244  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpnblockvarnonz[block]), sdpnblockvarnonz[block], sdpnblockvars[block]);
1245 
1246  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstcol[block]), sdpconstcol[block], sdpconstnblocknonz[block]);
1247  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstrow[block]), sdpconstrow[block], sdpconstnblocknonz[block]);
1248  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpconstval[block]), sdpconstval[block], sdpconstnblocknonz[block]);
1249 
1250  /* make sure that we have a lower triangular matrix */
1251  for (i = 0; i < sdpi->sdpconstnblocknonz[block]; ++i)
1252  ensureLowerTriangular(&(sdpconstrow[block][i]), &(sdpconstcol[block][i]));
1253 
1254  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpvar[block]), sdpvar[block], sdpnblockvars[block]);
1255 
1256  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpcol[block]), sdpnblockvars[block]) );
1257  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdprow[block]), sdpnblockvars[block]) );
1258  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpval[block]), sdpnblockvars[block]) );
1259 
1260  for (v = 0; v < sdpi->sdpnblockvars[block]; v++)
1261  {
1262  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpcol[block][v]), sdpcol[block][v], sdpnblockvarnonz[block][v]);
1263  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdprow[block][v]), sdprow[block][v], sdpnblockvarnonz[block][v]);
1264  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->sdpval[block][v]), sdpval[block][v], sdpnblockvarnonz[block][v]);
1265 
1266  /* make sure that we have a lower triangular matrix */
1267  for (i = 0; i < sdpi->sdpnblockvarnonz[block][v]; ++i)
1268  ensureLowerTriangular(&(sdprow[block][v][i]), &(sdpcol[block][v][i]));
1269  }
1270  }
1271 
1272  /* free old and duplicate new arrays for the LP part */
1273  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz);
1274  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz);
1275  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz);
1276  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons);
1277  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons);
1278 
1279  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lplhs), lplhs, nlpcons);
1280  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lprhs), lprhs, nlpcons);
1281  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lprow), lprow, lpnnonz);
1282  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lpcol), lpcol, lpnnonz);
1283  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &(sdpi->lpval), lpval, lpnnonz);
1284 
1285  /* set the general information */
1286  sdpi->nvars = nvars;
1287  sdpi->nsdpblocks = nsdpblocks;
1288 
1289  sdpi->sdpconstnnonz = sdpconstnnonz;
1290  sdpi->sdpnnonz = sdpnnonz;
1291 
1292  /* LP part */
1293  sdpi->lpnnonz = lpnnonz;
1294  sdpi->nlpcons = nlpcons;
1295 
1296  sdpi->solved = FALSE;
1297  sdpi->infeasible = FALSE;
1298 
1299  return SCIP_OKAY;
1300 }
1301 
1306 SCIP_RETCODE SCIPsdpiAddLPRows(
1307  SCIP_SDPI* sdpi,
1308  int nrows,
1309  const SCIP_Real* lhs,
1310  const SCIP_Real* rhs,
1311  int nnonz,
1312  const int* row,
1314  const int* col,
1315  const SCIP_Real* val
1316  )
1317 {
1318  int i;
1319 
1320  SCIPdebugMessage("Adding %d LP-Constraints to SDP %d.\n", nrows, sdpi->sdpid);
1321 
1322  assert ( sdpi != NULL );
1323 
1324  if ( nrows == 0 )
1325  return SCIP_OKAY; /* nothing to do in this case */
1326 
1327  assert ( lhs != NULL );
1328  assert ( rhs != NULL );
1329  assert ( nnonz >= 0 );
1330  assert ( row != NULL );
1331  assert ( col != NULL );
1332  assert ( val != NULL );
1333 
1334  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons, sdpi->nlpcons + nrows) ); /*lint !e776*/
1335  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons, sdpi->nlpcons + nrows) ); /*lint !e776*/
1336 
1337  for (i = 0; i < nrows; i++)
1338  {
1339  sdpi->lplhs[sdpi->nlpcons + i] = lhs[i]; /*lint !e679*/
1340  sdpi->lprhs[sdpi->nlpcons + i] = rhs[i]; /*lint !e679*/
1341  }
1342 
1343  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz, sdpi->lpnnonz + nnonz) ); /*lint !e776*/
1344  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz, sdpi->lpnnonz + nnonz) ); /*lint !e776*/
1345  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz, sdpi->lpnnonz + nnonz) ); /*lint !e776*/
1346 
1347  for (i = 0; i < nnonz; i++)
1348  {
1349  assert ( 0 <= row[i] && row[i] < nrows );
1350  /* the new rows are added at the end, so the row indices are increased by the old number of LP-constraints */
1351  sdpi->lprow[sdpi->lpnnonz + i] = row[i] + sdpi->nlpcons; /*lint !e679*/
1352 
1353  assert ( 0 <= col[i] && col[i] < sdpi->nvars ); /* only existing vars should be added to the LP-constraints */
1354  sdpi->lpcol[sdpi->lpnnonz + i] = col[i]; /*lint !e679*/
1355 
1356  sdpi->lpval[sdpi->lpnnonz + i] = val[i]; /*lint !e679*/
1357  }
1358 
1359  sdpi->nlpcons = sdpi->nlpcons + nrows;
1360  sdpi->lpnnonz = sdpi->lpnnonz + nnonz;
1361 
1362  sdpi->solved = FALSE;
1363  sdpi->infeasible = FALSE;
1364 
1365  return SCIP_OKAY;
1366 }
1367 
1369 SCIP_RETCODE SCIPsdpiDelLPRows(
1370  SCIP_SDPI* sdpi,
1371  int firstrow,
1372  int lastrow
1373  )
1374 {
1375  int i;
1376  int deletedrows;
1377  int firstrowind;
1378  int lastrowind;
1379  int deletednonz;
1380 
1381  SCIPdebugMessage("Deleting rows %d to %d from SDP %d.\n", firstrow, lastrow, sdpi->sdpid);
1382 
1383  assert ( sdpi != NULL );
1384  assert ( firstrow >= 0 );
1385  assert ( firstrow <= lastrow );
1386  assert ( lastrow < sdpi->nlpcons );
1387 
1388  /* shorten the procedure if the whole LP-part is to be deleted */
1389  if (firstrow == 0 && lastrow == sdpi->nlpcons - 1)
1390  {
1391  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz);
1392  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz);
1393  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz);
1394  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons);
1395  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons);
1396 
1397  sdpi->lplhs = NULL;
1398  sdpi->lprhs = NULL;
1399  sdpi->lpcol = NULL;
1400  sdpi->lprow = NULL;
1401  sdpi->lpval = NULL;
1402 
1403  sdpi->nlpcons = 0;
1404  sdpi->lpnnonz = 0;
1405 
1406  sdpi->solved = FALSE;
1407  sdpi->infeasible = FALSE;
1408 
1409  return SCIP_OKAY;
1410  }
1411 
1412  deletedrows = lastrow - firstrow + 1; /*lint !e834*/
1413  deletednonz = 0;
1414 
1415  /* first delete the left- and right-hand-sides */
1416  for (i = lastrow + 1; i < sdpi->nlpcons; i++) /* shift all rhs after the deleted rows */
1417  {
1418  sdpi->lplhs[i - deletedrows] = sdpi->lplhs[i]; /*lint !e679*/
1419  sdpi->lprhs[i - deletedrows] = sdpi->lprhs[i]; /*lint !e679*/
1420  }
1421  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lplhs), sdpi->nlpcons, sdpi->nlpcons - deletedrows) ); /*lint !e776*/
1422  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprhs), sdpi->nlpcons, sdpi->nlpcons - deletedrows) ); /*lint !e776*/
1423 
1424  /* for deleting and reordering the lpnonzeroes, the arrays first have to be sorted to have the rows to be deleted together */
1425  SCIPsortIntIntReal(sdpi->lprow, sdpi->lpcol, sdpi->lpval, sdpi->lpnnonz); /* sort all arrays by non-decreasing row indices */
1426 
1427  firstrowind = -1;
1428  /*iterate over the lprowind array to find the first index belonging to a row that should be deleted */
1429  for (i = 0; i < sdpi->lpnnonz; i++)
1430  {
1431  if (sdpi->lprow[i] >= firstrow && sdpi->lprow[i] <= lastrow) /* the and part makes sure that there actually were some nonzeroes in these rows */
1432  {
1433  firstrowind = i;
1434  lastrowind = i;
1435  i++;
1436  break;
1437  }
1438  }
1439 
1440  if (firstrowind > -1) /* if this is still 0 there are no nonzeroes for the given rows */
1441  {
1442  /* 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) */
1443  while (i < sdpi->lpnnonz && sdpi->lprow[i] <= lastrow)
1444  {
1445  lastrowind++; /*lint !e644*/
1446  i++;
1447  }
1448  deletednonz = lastrowind - firstrowind + 1; /*lint !e834*/
1449 
1450  /* finally shift all LP-array-entries after the deleted rows */
1451  for (i = lastrowind + 1; i < sdpi->lpnnonz; i++)
1452  {
1453  sdpi->lpcol[i - deletednonz] = sdpi->lpcol[i]; /*lint !e679*/
1454  /* all rowindices after the deleted ones have to be lowered to still have ongoing indices from 0 to nlpcons-1 */
1455  sdpi->lprow[i - deletednonz] = sdpi->lprow[i] - deletedrows; /*lint !e679*/
1456  sdpi->lpval[i - deletednonz] = sdpi->lpval[i]; /*lint !e679*/
1457  }
1458  }
1459 
1460  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpcol), sdpi->lpnnonz, sdpi->lpnnonz - deletednonz) ); /*lint !e776*/
1461  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprow), sdpi->lpnnonz, sdpi->lpnnonz - deletednonz) ); /*lint !e776*/
1462  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpval), sdpi->lpnnonz, sdpi->lpnnonz - deletednonz) ); /*lint !e776*/
1463  sdpi->nlpcons = sdpi->nlpcons - deletedrows;
1464  sdpi->lpnnonz = sdpi->lpnnonz - deletednonz;
1465 
1466  sdpi->solved = FALSE;
1467  sdpi->infeasible = FALSE;
1468 
1469  return SCIP_OKAY;
1470 }
1471 
1473 SCIP_RETCODE SCIPsdpiDelLPRowset(
1474  SCIP_SDPI* sdpi,
1475  int* dstat
1478  )
1479 {
1480  int i;
1481  int oldnlpcons;
1482  int deletedrows;
1483 
1484  SCIPdebugMessage("Calling SCIPsdpiDelLPRowset for SDP %d.\n", sdpi->sdpid);
1485 
1486  assert ( sdpi != NULL );
1487  assert ( dstat != NULL );
1488 
1489  oldnlpcons = sdpi->nlpcons;
1490  deletedrows = 0;
1491 
1492  for (i = 0; i < oldnlpcons; i++)
1493  {
1494  if (dstat[i] == 1)
1495  {
1496  /* delete this row, it is shifted by - deletedrows, because in this problem the earlier rows have already been deleted */
1497  SCIP_CALL( SCIPsdpiDelLPRows(sdpi, i - deletedrows, i - deletedrows) );
1498  dstat[i] = -1;
1499  deletedrows++;
1500  }
1501  else
1502  dstat[i] = i - deletedrows;
1503  }
1504 
1505  sdpi->solved = FALSE;
1506  sdpi->infeasible = FALSE;
1507 
1508  return SCIP_OKAY;
1509 }
1510 
1512 SCIP_RETCODE SCIPsdpiClear(
1513  SCIP_SDPI* sdpi
1514  )
1515 {
1516  assert( sdpi != NULL );
1517 
1518  SCIPdebugMessage("Called SCIPsdpiClear in SDP %d.\n", sdpi->sdpid);
1519 
1520  /* we reset all counters */
1521  sdpi->sdpid = 1;
1522  SCIP_CALL( SCIPsdpiSolverResetCounter(sdpi->sdpisolver) );
1523 
1524  return SCIP_OKAY;
1525 }
1526 
1528 SCIP_RETCODE SCIPsdpiChgBounds(
1529  SCIP_SDPI* sdpi,
1530  int nvars,
1531  const int* ind,
1532  const SCIP_Real* lb,
1533  const SCIP_Real* ub
1534  )
1535 {
1536  int i;
1537 
1538  SCIPdebugMessage("Changing %d variable bounds in SDP %d\n", nvars, sdpi->sdpid);
1539 
1540  assert ( sdpi != NULL );
1541  assert ( ind != NULL );
1542  assert ( lb != NULL );
1543  assert ( ub != NULL );
1544 
1545  for (i = 0; i < nvars; i++)
1546  {
1547  assert ( 0 <= ind[i] && ind[i] < sdpi->nvars );
1548  sdpi->lb[ind[i]] = lb[i];
1549  sdpi->ub[ind[i]] = ub[i];
1550  }
1551 
1552  sdpi->solved = FALSE;
1553 
1554  return SCIP_OKAY;
1555 }
1556 
1559  SCIP_SDPI* sdpi,
1560  int nrows,
1561  const int* ind,
1562  const SCIP_Real* lhs,
1563  const SCIP_Real* rhs
1564  )
1565 {
1566  int i;
1567 
1568  SCIPdebugMessage("Changing %d left and right hand sides of SDP %d\n", nrows, sdpi->sdpid);
1569 
1570  assert( sdpi != NULL );
1571  assert( 0 <= nrows && nrows <= sdpi->nlpcons );
1572  assert( ind != NULL );
1573  assert( lhs != NULL );
1574  assert( rhs != NULL );
1575 
1576  for (i = 0; i < nrows; i++)
1577  {
1578  assert ( ind[i] >= 0 );
1579  assert ( ind[i] < sdpi->nlpcons );
1580  sdpi->lplhs[ind[i]] = lhs[i];
1581  sdpi->lprhs[ind[i]] = rhs[i];
1582  }
1583 
1584  sdpi->solved = FALSE;
1585 
1586  return SCIP_OKAY;
1587 }
1588 
1589 
1590 /*
1591  * Data Accessing Methods
1592  */
1593 
1598 SCIP_RETCODE SCIPsdpiGetNLPRows(
1599  SCIP_SDPI* sdpi,
1600  int* nlprows
1601  )
1602 {
1603  assert( sdpi != NULL );
1604 
1605  *nlprows = sdpi->nlpcons;
1606 
1607  return SCIP_OKAY;
1608 }
1609 
1612  SCIP_SDPI* sdpi,
1613  int* nsdpblocks
1614  )
1615 {
1616  assert( sdpi != NULL );
1617 
1618  *nsdpblocks = sdpi->nsdpblocks;
1619 
1620  return SCIP_OKAY;
1621 }
1622 
1624 SCIP_RETCODE SCIPsdpiGetNVars(
1625  SCIP_SDPI* sdpi,
1626  int* nvars
1627  )
1628 {
1629  assert( sdpi != NULL );
1630 
1631  *nvars = sdpi->nvars; return SCIP_OKAY;
1632 }
1633 
1635 SCIP_RETCODE SCIPsdpiGetSDPNNonz(
1636  SCIP_SDPI* sdpi,
1637  int* nnonz
1638  )
1639 {
1640  assert( sdpi != NULL );
1641 
1642  *nnonz = sdpi->sdpnnonz;
1643 
1644  return SCIP_OKAY;
1645 }
1646 
1649  SCIP_SDPI* sdpi,
1650  int* nnonz
1651  )
1652 {
1653  assert( sdpi != NULL );
1654 
1655  *nnonz = sdpi->sdpconstnnonz;
1656 
1657  return SCIP_OKAY;
1658 }
1659 
1661 SCIP_RETCODE SCIPsdpiGetLPNNonz(
1662  SCIP_SDPI* sdpi,
1663  int* nnonz
1664  )
1665 {
1666  assert( sdpi != NULL );
1667 
1668  *nnonz = sdpi->lpnnonz;
1669 
1670  return SCIP_OKAY;
1671 }
1672 
1674 SCIP_RETCODE SCIPsdpiGetObj(
1675  SCIP_SDPI* sdpi,
1676  int firstvar,
1677  int lastvar,
1678  SCIP_Real* vals
1679  )
1680 {
1681  int i;
1682 
1683  assert( sdpi != NULL );
1684  assert( firstvar >= 0 );
1685  assert( firstvar <= lastvar );
1686  assert( lastvar < sdpi->nvars);
1687  assert( vals != NULL );
1688 
1689  for (i = 0; i < lastvar - firstvar + 1; i++) /*lint !e834*/
1690  vals[i] = sdpi->obj[firstvar + i]; /*lint !e679*/
1691 
1692  return SCIP_OKAY;
1693 }
1694 
1696 SCIP_RETCODE SCIPsdpiGetBounds(
1697  SCIP_SDPI* sdpi,
1698  int firstvar,
1699  int lastvar,
1700  SCIP_Real* lbs,
1701  SCIP_Real* ubs
1702  )
1703 {
1704  int i;
1705 
1706  assert( sdpi != NULL );
1707  assert( firstvar >= 0 );
1708  assert( firstvar <= lastvar );
1709  assert( lastvar < sdpi->nvars);
1710  assert( lbs != NULL );
1711  assert( ubs != NULL );
1712 
1713  for (i = 0; i < lastvar - firstvar + 1; i++) /*lint !e834*/
1714  {
1715  if (lbs != NULL)
1716  lbs[i] = sdpi->lb[firstvar + i]; /*lint !e679*/
1717  if (ubs != NULL)
1718  ubs[i] = sdpi->ub[firstvar + i]; /*lint !e679*/
1719  }
1720  return SCIP_OKAY;
1721 }
1722 
1724 SCIP_RETCODE SCIPsdpiGetLhSides(
1725  SCIP_SDPI* sdpi,
1726  int firstrow,
1727  int lastrow,
1728  SCIP_Real* lhss
1729  )
1730 {
1731  int i;
1732 
1733  assert( sdpi != NULL );
1734  assert( firstrow >= 0 );
1735  assert( firstrow <= lastrow );
1736  assert( lastrow < sdpi->nlpcons);
1737  assert( lhss != NULL );
1738 
1739  for (i = 0; i < lastrow - firstrow + 1; i++) /*lint !e834*/
1740  lhss[firstrow + i] = sdpi->lplhs[i]; /*lint !e679*/
1741 
1742  return SCIP_OKAY;
1743 }
1744 
1746 SCIP_RETCODE SCIPsdpiGetRhSides(
1747  SCIP_SDPI* sdpi,
1748  int firstrow,
1749  int lastrow,
1750  SCIP_Real* rhss
1751  )
1752 {
1753  int i;
1754 
1755  assert( sdpi != NULL );
1756  assert( firstrow >= 0 );
1757  assert( firstrow <= lastrow );
1758  assert( lastrow < sdpi->nlpcons);
1759  assert( rhss != NULL );
1760 
1761  for (i = 0; i < lastrow - firstrow + 1; i++) /*lint !e834*/
1762  rhss[firstrow + i] = sdpi->lprhs[i]; /*lint !e679*/
1763 
1764  return SCIP_OKAY;
1765 }
1766 
1767 
1772 /*
1773  * Solving Methods
1774  */
1775 
1780 SCIP_RETCODE SCIPsdpiSolve(
1781  SCIP_SDPI* sdpi,
1782  SCIP_Real* start,
1783  int* totalsdpiterations,
1784  SCIP_Bool enforceslatercheck
1786  )
1787 {
1788  int block;
1789  int sdpconstnnonz;
1790  int* sdpconstnblocknonz;
1791  int** sdpconstrow;
1792  int** sdpconstcol;
1793  SCIP_Real** sdpconstval;
1794  int** indchanges;
1795  int* nremovedinds;
1796  int newiterations;
1797  SCIP_Real* lplhsafterfix;
1798  SCIP_Real* lprhsafterfix;
1799  int* rowsnactivevars;
1800  SCIP_Bool fixingfound;
1801  int nactivelpcons;
1802  int* blockindchanges;
1803  int nremovedblocks;
1804 
1805  assert ( sdpi != NULL );
1806  assert ( totalsdpiterations != NULL );
1807 
1808  SCIPdebugMessage("Forwarding SDP %d to solver!\n", sdpi->sdpid);
1809 
1810  sdpconstnblocknonz = NULL;
1811  sdpconstrow = NULL;
1812  sdpconstcol = NULL;
1813  sdpconstval = NULL;
1814  indchanges = NULL;
1815  nremovedinds = NULL;
1816  nremovedblocks = 0;
1817 
1818  /* allocate memory for computing the constant matrix after fixings and finding empty rows and columns, this is as much as might possibly be
1819  * needed, this will be shrinked again before solving */
1820  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstnblocknonz, sdpi->nsdpblocks) );
1821  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstrow, sdpi->nsdpblocks) );
1822  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstcol, sdpi->nsdpblocks) );
1823  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstval, sdpi->nsdpblocks) );
1824  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &indchanges, sdpi->nsdpblocks) );
1825  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &nremovedinds, sdpi->nsdpblocks) );
1826  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &blockindchanges, sdpi->nsdpblocks) );
1827  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &lplhsafterfix, sdpi->nlpcons) );
1828  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &lprhsafterfix, sdpi->nlpcons) );
1829  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &rowsnactivevars, sdpi->nlpcons) );
1830 
1831  for (block = 0; block < sdpi->nsdpblocks; block++)
1832  {
1833  sdpconstrow[block] = NULL;
1834  sdpconstcol[block] = NULL;
1835  sdpconstval[block] = NULL;
1836  indchanges[block] = NULL;
1837  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(indchanges[block]), sdpi->sdpblocksizes[block]) );
1838  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
1839  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
1840  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz) ); /*lint !e776*/
1841  }
1842 
1843  /* compute the lplphss and lprhss, detect empty rows and check for additional variable fixings caused by boundchanges from
1844  * lp rows with a single active variable */
1845  do
1846  {
1847  fixingfound = FALSE;
1848  SCIP_CALL( computeLpLhsRhsAfterFixings(sdpi, &nactivelpcons, lplhsafterfix, lprhsafterfix, rowsnactivevars, &fixingfound) );
1849  }
1850  while (fixingfound);
1851 
1852  /* initialize sdpconstnblocknonz */
1853  for (block = 0; block < sdpi->nsdpblocks; block++)
1854  sdpconstnblocknonz[block] = sdpi->sdpnnonz + sdpi->sdpconstnnonz;
1855 
1856  SCIP_CALL( compConstMatAfterFixings(sdpi, &sdpconstnnonz, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval) );
1857 
1858  /* shrink the constant arrays after the number of fixed nonzeros is known */
1859  for (block = 0; block < sdpi->nsdpblocks; block++)
1860  {
1861  assert ( sdpconstnblocknonz[block] <= sdpi->sdpnnonz + sdpi->sdpconstnnonz ); /* otherwise the memory wasn't sufficient,
1862  * but we allocated more than enough */
1863  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
1864  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
1865  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpconstnblocknonz[block]) ); /*lint !e776*/
1866  }
1867 
1868  SCIP_CALL (findEmptyRowColsSDP(sdpi, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges, nremovedinds, blockindchanges, &nremovedblocks) );
1869 
1870  if ( sdpi->infeasible )
1871  {
1872  SCIPdebugMessage("SDP %d not given to solver, as infeasibility was detected during presolving!\n", sdpi->sdpid++);
1873  SCIP_CALL( SCIPsdpiSolverIncreaseCounter(sdpi->sdpisolver) );
1874 
1875  sdpi->solved = TRUE;
1876  }
1877  else
1878  {
1879  if ( sdpi->slatercheck )
1880  {
1881  SCIP_Real objval;
1882  SCIP_Bool origfeas;
1883 
1884  /* 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
1885  * still feasible for r < feastol, then we have an interior point with smallest eigenvalue > feastol, otherwise the Slater condition is harmed */
1886  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, 1.0, FALSE, FALSE, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
1887  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
1888  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
1889  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
1890  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
1891  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, start, &origfeas) );
1892 
1893  /* if we didn't succeed, then probably the primal problem is troublesome */
1894  if ( (! SCIPsdpiSolverIsOptimal(sdpi->sdpisolver)) && (! SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver)) )
1895  printf("Unable to check Slater condition for dual problem of SDP %d, could mean that the Slater conidition for the primal problem"
1896  " is not fullfilled.\n", sdpi->sdpid);
1897  else
1898  {
1899  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) );
1900 
1901  if ( objval < - sdpi->feastol )
1902  SCIPdebugMessage("Slater condition for SDP %d is fullfilled for dual problem with smallest eigenvalue %f.\n", sdpi->sdpid, -1.0 * objval);
1903  else
1904  printf("Slater condition for SDP %d not fullfilled for dual problem as smallest eigenvalue was %f, expect numerical trouble.\n",
1905  sdpi->sdpid, -1.0 * objval);
1906  }
1907  }
1908 
1909  /* try to solve the problem */
1910  SCIP_CALL( SCIPsdpiSolverLoadAndSolve(sdpi->sdpisolver, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
1911  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
1912  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
1913  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
1914  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
1915  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, start) );
1916 
1917  sdpi->penalty = FALSE;
1918  sdpi->solved = TRUE;
1919 
1920  /* if the solver didn't produce a satisfactory result, we have to try with penalty formulations */
1921  if ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) )
1922  {
1923  SCIP_Real penaltyparam;
1924  SCIP_Bool feasorig;
1925 
1926  penaltyparam = 1.0;
1927  feasorig = FALSE;
1928 
1929  /* if we didn't converge, first try to check feasibility with a penalty formulation */
1930  SCIPdebugMessage("Solver did not produce an acceptable result, trying SDP %d again with penalty formulation\n", sdpi->sdpid);
1931 
1932  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, 1.0, FALSE, TRUE, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
1933  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
1934  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
1935  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
1936  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
1937  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, start, &feasorig) );
1938 
1939  /* if the solver converged and the solution is feasible for our original problem, the problem is feasible and we can continue to search for an
1940  * optimal solution, if the solver converged but the solution isn't feasible for our original problem, the problem is infeasible, if we still
1941  * didn't converge, we are out of luck */
1942  if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && feasorig)
1943  {
1944  /* increase the penalty parameter until we are able to solve the problem and get a solution that is feasible for our original problem and
1945  * the problem isn't unbounded (this can be caused by a too small penalty parameter) or the penalty parameter gets too large */
1946  do
1947  {
1948  SCIPdebugMessage("Solver did not produce an acceptable result, trying SDP %d again with penaltyparameter %f\n", sdpi->sdpid, penaltyparam);
1949 
1950  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, penaltyparam, TRUE, TRUE, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
1951  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
1952  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
1953  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
1954  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
1955  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, start, &feasorig) );
1956 
1957  penaltyparam *= 10.0;
1958  }
1959  while ( (! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) || ! feasorig || SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver)) &&
1960  ! SCIPsdpiSolverIsGEMaxPenParam(sdpi->sdpisolver, penaltyparam) );
1961 
1962  /* check if we were able to solve the problem in the end */
1963  if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && feasorig )
1964  sdpi->penalty = TRUE;
1965  else
1966  {
1967  /* TODO: Do we want to give the computed lower bound? Do we want to tell that we showed that the problem is feasible? */
1968  sdpi->solved = FALSE;
1969  sdpi->penalty = TRUE;
1970  }
1971  }
1972  else if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && ! feasorig )
1973  {
1974  SCIPdebugMessage("Problem was found to be infeasible using a penalty formulation \n");
1975  sdpi->infeasible = TRUE;
1976  sdpi->penalty = TRUE;
1977  }
1978  else
1979  {
1980  SCIPdebugMessage("SDP-Solver could not solve the problem even after using a penalty formulation \n");
1981  sdpi->solved = FALSE;
1982  sdpi->penalty = TRUE;
1983  }
1984  /* if we still didn't succeed and enforceslatercheck was set, we finally test for the Slater condition to give a reason for failure */
1985  if ( sdpi->solved == FALSE && enforceslatercheck)
1986  {
1987  SCIP_Real objval;
1988  SCIP_Bool origfeas;
1989 
1990  /* 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
1991  * still feasible for r < feastol, then we have an interior point with smallest eigenvalue > feastol, otherwise the Slater condition is harmed */
1992  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, 1.0, FALSE, FALSE, sdpi->nvars, sdpi->obj, sdpi->lb, sdpi->ub,
1993  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
1994  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
1995  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
1996  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->nlpcons, lplhsafterfix, lprhsafterfix,
1997  rowsnactivevars, sdpi->lpnnonz, sdpi->lprow, sdpi->lpcol, sdpi->lpval, start, &origfeas) );
1998 
1999  /* if we didn't succeed, then probably the primal problem is troublesome */
2000  if ( (! SCIPsdpiSolverIsOptimal(sdpi->sdpisolver)) && (! SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver)) )
2001  printf("SDP-solver could not solve root node relaxation, unable to check Slater condition for dual problem of SDP %d, could mean that the "
2002  "Slater conidition for the primal problem is not fullfilled.\n", sdpi->sdpid);
2003  else
2004  {
2005  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) );
2006 
2007  if ( objval < - sdpi->feastol )
2008  printf("SDP-solver could not solve root node relaxation even though the Slater condition is fullfilled for the dual problem with smallest eigenvalue %f.\n",
2009  -1.0 * objval);
2010  else
2011  printf("SDP-solver could not solve root node relaxation, Slater condition is not fullfilled for the dual problem as smallest eigenvalue was %f.\n",
2012  -1.0 * objval);
2013  }
2014  }
2015  else if ( sdpi->solved == FALSE )
2016  printf("Numerical trouble\n");
2017  }
2018  }
2019 
2020  /* empty the memory allocated here */
2021  for (block = 0; block < sdpi->nsdpblocks; block++)
2022  {
2023  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstval[block]), sdpconstnblocknonz[block]);
2024  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[block]), sdpconstnblocknonz[block]);
2025  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[block]), sdpconstnblocknonz[block]);
2026  BMSfreeBlockMemoryArray(sdpi->blkmem, &(indchanges[block]), sdpi->sdpblocksizes[block]);
2027  }
2028  BMSfreeBlockMemoryArray(sdpi->blkmem, &rowsnactivevars, sdpi->nlpcons);
2029  BMSfreeBlockMemoryArray(sdpi->blkmem, &lprhsafterfix, sdpi->nlpcons);
2030  BMSfreeBlockMemoryArray(sdpi->blkmem, &lplhsafterfix, sdpi->nlpcons);
2031  BMSfreeBlockMemoryArray(sdpi->blkmem, &blockindchanges, sdpi->nsdpblocks);
2032  BMSfreeBlockMemoryArray(sdpi->blkmem, &nremovedinds, sdpi->nsdpblocks);
2033  BMSfreeBlockMemoryArray(sdpi->blkmem, &indchanges, sdpi->nsdpblocks);
2034  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstval, sdpi->nsdpblocks);
2035  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstcol, sdpi->nsdpblocks);
2036  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstrow, sdpi->nsdpblocks);
2037  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstnblocknonz, sdpi->nsdpblocks);
2038 
2039  /* add the iterations needed to solve this SDP */
2040  if ( ! sdpi->infeasible )
2041  {
2042  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &newiterations) );
2043  *totalsdpiterations += newiterations;
2044  }
2045 
2046  sdpi->sdpid++;
2047 
2048  return SCIP_OKAY;
2049 }
2050 
2051 
2052 
2053 
2054 /*
2055  * Solution Information Methods
2056  */
2057 
2063  SCIP_SDPI* sdpi
2064  )
2065 {
2066  assert( sdpi != NULL );
2067 
2068  return sdpi->solved;
2069 }
2070 
2073  SCIP_SDPI* sdpi
2074  )
2075 {
2076  assert( sdpi != NULL );
2077 
2078  return ( ! sdpi->penalty );
2079 }
2080 
2085  SCIP_SDPI* sdpi
2086  )
2087 {
2088  assert( sdpi != NULL );
2089  CHECK_IF_SOLVED_BOOL(sdpi);
2090 
2091  if (sdpi->infeasible)
2092  return TRUE;
2093 
2094  return SCIPsdpiSolverFeasibilityKnown(sdpi->sdpisolver);
2095 }
2096 
2099  SCIP_SDPI* sdpi,
2100  SCIP_Bool* primalfeasible,
2101  SCIP_Bool* dualfeasible
2102  )
2103 {
2104  assert( sdpi != NULL );
2105  CHECK_IF_SOLVED(sdpi);
2106 
2107  if ( sdpi->infeasible )
2108  {
2109  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2110  *dualfeasible = FALSE;
2111  return SCIP_OKAY;
2112  }
2113 
2114  SCIP_CALL( SCIPsdpiSolverGetSolFeasibility(sdpi->sdpisolver, primalfeasible, dualfeasible) );
2115 
2116  return SCIP_OKAY;
2117 }
2118 
2122  SCIP_SDPI* sdpi
2123  )
2124 {
2125  assert( sdpi != NULL );
2126  CHECK_IF_SOLVED_BOOL(sdpi);
2127 
2128  if ( sdpi->infeasible )
2129  {
2130  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal unboundedness not available\n");
2131  return FALSE;
2132  }
2133 
2134  return SCIPsdpiSolverIsPrimalUnbounded(sdpi->sdpisolver);
2135 }
2136 
2140  SCIP_SDPI* sdpi
2141  )
2142 {
2143  assert( sdpi != NULL );
2144  CHECK_IF_SOLVED_BOOL(sdpi);
2145 
2146  if ( sdpi->infeasible )
2147  {
2148  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2149  return FALSE;
2150  }
2151 
2152  return SCIPsdpiSolverIsPrimalInfeasible(sdpi->sdpisolver);
2153 }
2154 
2158  SCIP_SDPI* sdpi
2159  )
2160 {
2161  assert(sdpi != NULL );
2162  CHECK_IF_SOLVED_BOOL(sdpi);
2163 
2164  if ( sdpi->infeasible )
2165  {
2166  SCIPdebugMessage("Problem was found infeasible during preprocessing, primal feasibility not available\n");
2167  return FALSE;
2168  }
2169 
2170  return SCIPsdpiSolverIsPrimalFeasible(sdpi->sdpisolver);
2171 }
2172 
2176  SCIP_SDPI* sdpi
2177  )
2178 {
2179  assert( sdpi != NULL );
2180  CHECK_IF_SOLVED_BOOL(sdpi);
2181 
2182  if ( sdpi->infeasible )
2183  {
2184  SCIPdebugMessage("Problem was found infeasible during preprocessing, dual unboundedness not available\n");
2185  return FALSE;
2186  }
2187 
2188  return SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver);
2189 }
2190 
2194  SCIP_SDPI* sdpi
2195  )
2196 {
2197  assert( sdpi != NULL );
2198  CHECK_IF_SOLVED_BOOL(sdpi);
2199 
2200  if ( sdpi->infeasible )
2201  {
2202  SCIPdebugMessage("Problem was found infeasible during preprocessing\n");
2203  return TRUE;
2204  }
2205 
2206  return SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver);
2207 }
2208 
2212  SCIP_SDPI* sdpi
2213  )
2214 {
2215  assert( sdpi != NULL );
2216  CHECK_IF_SOLVED_BOOL(sdpi);
2217 
2218  if ( sdpi->infeasible )
2219  {
2220  SCIPdebugMessage("Problem was found infeasible during preprocessing\n");
2221  return FALSE;
2222  }
2223 
2224  return SCIPsdpiSolverIsDualFeasible(sdpi->sdpisolver);
2225 }
2226 
2229  SCIP_SDPI* sdpi
2230  )
2231 {
2232  assert( sdpi != NULL );
2233  CHECK_IF_SOLVED_BOOL(sdpi);
2234 
2235  if ( sdpi->infeasible )
2236  {
2237  SCIPdebugMessage("Problem was found infeasible during preprocessing, this counts as converged.\n");
2238  return TRUE;
2239  }
2240 
2241  return SCIPsdpiSolverIsConverged(sdpi->sdpisolver);
2242 }
2243 
2246  SCIP_SDPI* sdpi
2247  )
2248 {
2249  assert( sdpi != NULL );
2250  CHECK_IF_SOLVED_BOOL(sdpi);
2251 
2252  if ( sdpi->infeasible )
2253  {
2254  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective limit available.\n");
2255  return FALSE;
2256  }
2257 
2258  return SCIPsdpiSolverIsObjlimExc(sdpi->sdpisolver);
2259 }
2260 
2263  SCIP_SDPI* sdpi
2264  )
2265 {
2266  assert( sdpi != NULL );
2267  CHECK_IF_SOLVED_BOOL(sdpi);
2268 
2269  if ( sdpi->infeasible )
2270  {
2271  SCIPdebugMessage("Problem was found infeasible during preprocessing, no iteration limit available.\n");
2272  return FALSE;
2273  }
2274 
2275  return SCIPsdpiSolverIsIterlimExc(sdpi->sdpisolver);
2276 }
2277 
2280  SCIP_SDPI* sdpi
2281  )
2282 {
2283  assert( sdpi != NULL );
2284  CHECK_IF_SOLVED_BOOL(sdpi);
2285 
2286  if ( sdpi->infeasible )
2287  {
2288  SCIPdebugMessage("Problem was found infeasible during preprocessing, no time limit available.\n");
2289  return FALSE;
2290  }
2291 
2292  return SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver);
2293 }
2294 
2306  SCIP_SDPI* sdpi
2307  )
2308 {
2309  assert( sdpi != NULL );
2310 
2311  if ( ! sdpi->solved )
2312  {
2313  SCIPdebugMessage("Problem wasn't solved yet.\n");
2314  return -1;
2315  }
2316  else if ( sdpi->infeasible )
2317  {
2318  SCIPdebugMessage("Problem was found infeasible during preprocessing, no internal status available.\n");
2319  return 0;
2320  }
2321 
2322  return SCIPsdpiSolverGetInternalStatus(sdpi->sdpisolver);
2323 }
2324 
2327  SCIP_SDPI* sdpi
2328  )
2329 {
2330  assert( sdpi != NULL );
2331  CHECK_IF_SOLVED_BOOL(sdpi);
2332 
2333  if ( sdpi->infeasible )
2334  {
2335  SCIPdebugMessage("Problem was found infeasible during preprocessing, therefore there is no optimal solution.\n");
2336  return FALSE;
2337  }
2338 
2339  return SCIPsdpiSolverIsOptimal(sdpi->sdpisolver);
2340 }
2341 
2345  SCIP_SDPI* sdpi
2346  )
2347 {
2348  assert( sdpi != NULL );
2349  CHECK_IF_SOLVED_BOOL(sdpi);
2350 
2351  if ( sdpi->infeasible )
2352  {
2353  SCIPdebugMessage("Problem was found infeasible during preprocessing, this is acceptable in a B&B context.\n");
2354  return TRUE;
2355  }
2356 
2357  return SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver);
2358 }
2359 
2361 SCIP_RETCODE SCIPsdpiGetObjval(
2362  SCIP_SDPI* sdpi,
2363  SCIP_Real* objval
2364  )
2365 {
2366  assert( sdpi != NULL );
2367  assert( objval != NULL );
2368  CHECK_IF_SOLVED(sdpi);
2369 
2370  if ( sdpi->infeasible )
2371  {
2372  SCIPdebugMessage("Problem was found infeasible during preprocessing, no objective value available.\n");
2373  return SCIP_OKAY;
2374  }
2375 
2376  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, objval) );
2377 
2378  return SCIP_OKAY;
2379 }
2380 
2383 SCIP_RETCODE SCIPsdpiGetSol(
2384  SCIP_SDPI* sdpi,
2385  SCIP_Real* objval,
2386  SCIP_Real* dualsol,
2387  int* dualsollength
2389  )
2390 {
2391  assert( sdpi != NULL );
2392  assert( dualsollength != NULL );
2393  assert( *dualsollength == 0 || dualsol != NULL );
2394  CHECK_IF_SOLVED(sdpi);
2395 
2396  if ( sdpi->infeasible )
2397  {
2398  SCIPdebugMessage("Problem was found infeasible during preprocessing, no solution available.\n");
2399  return SCIP_OKAY;
2400  }
2401 
2402  SCIP_CALL( SCIPsdpiSolverGetSol(sdpi->sdpisolver, objval, dualsol, dualsollength) );
2403 
2404  return SCIP_OKAY;
2405 }
2406 
2411  SCIP_SDPI* sdpi,
2412  SCIP_Real* lbvars,
2413  SCIP_Real* ubvars,
2414  int* arraylength
2416  )
2417 {
2418  assert( sdpi != NULL );
2419  assert( lbvars != NULL );
2420  assert( ubvars != NULL );
2421  assert( arraylength != NULL );
2422  assert( *arraylength >= 0 );
2423  CHECK_IF_SOLVED(sdpi);
2424 
2425  if ( sdpi->infeasible )
2426  {
2427  SCIPdebugMessage("Problem was found infeasible during preprocessing, no primal variables available.\n");
2428  return SCIP_OKAY;
2429  }
2430 
2431  SCIP_CALL( SCIPsdpiSolverGetPrimalBoundVars(sdpi->sdpisolver, lbvars, ubvars, arraylength) );
2432 
2433  return SCIP_OKAY;
2434 }
2435 
2438  SCIP_SDPI* sdpi,
2439  int* iterations
2440  )
2441 {
2442  assert( sdpi != NULL );
2443  CHECK_IF_SOLVED(sdpi);
2444 
2445  if ( sdpi->infeasible )
2446  {
2447  SCIPdebugMessage("Problem was found infeasible during preprocessing, no iterations needed.\n");
2448  *iterations = 0;
2449  return SCIP_OKAY;
2450  }
2451 
2452  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, iterations) );
2453 
2454  return SCIP_OKAY;
2455 }
2456 
2462 /*
2463  * Numerical Methods
2464  */
2465 
2471  SCIP_SDPI* sdpi
2472  )
2473 {
2474  assert( sdpi != NULL );
2475 
2476  return SCIPsdpiSolverInfinity(sdpi->sdpisolver);
2477 }
2478 
2481  SCIP_SDPI* sdpi,
2482  SCIP_Real val
2483  )
2484 {
2485  assert( sdpi != NULL );
2486 
2487  return ((val <= -SCIPsdpiInfinity(sdpi)) || (val >= SCIPsdpiInfinity(sdpi)));
2488 }
2489 
2492  SCIP_SDPI* sdpi
2493  )
2494 {
2495  assert( sdpi != NULL );
2496 
2497  return SCIPsdpiSolverMaxPenParam(sdpi->sdpisolver);
2498 }
2499 
2502  SCIP_SDPI* sdpi,
2503  SCIP_Real val
2504  )
2505 {
2506  assert( sdpi != NULL );
2507 
2508  return ((val <= -SCIPsdpiMaxPenParam(sdpi)) || (val >= SCIPsdpiMaxPenParam(sdpi)));
2509 }
2510 
2512 SCIP_RETCODE SCIPsdpiGetRealpar(
2513  SCIP_SDPI* sdpi,
2514  SCIP_SDPPARAM type,
2515  SCIP_Real* dval
2516  )
2517 {
2518  assert( sdpi != NULL );
2519  assert( sdpi->sdpisolver != NULL );
2520  assert( dval != NULL );
2521 
2522  switch( type )/*lint --e{788}*/
2523  {
2524  case SCIP_SDPPAR_EPSILON:
2525  *dval = sdpi->epsilon;
2526  break;
2527  case SCIP_SDPPAR_FEASTOL:
2528  *dval = sdpi->feastol;
2529  break;
2530  case SCIP_SDPPAR_OBJLIMIT:
2531  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
2532  break;
2533  default:
2534  return SCIP_PARAMETERUNKNOWN;
2535  }
2536 
2537 #ifndef NDEBUG
2538  {
2539  SCIP_Real val;
2540  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, &val) );
2541  assert( REALABS(*dval - val) < sdpi->epsilon );
2542  }
2543 #endif
2544 
2545  return SCIP_OKAY;
2546 }
2547 
2549 SCIP_RETCODE SCIPsdpiSetRealpar(
2550  SCIP_SDPI* sdpi,
2551  SCIP_SDPPARAM type,
2552  SCIP_Real dval
2553  )
2554 {
2555  assert( sdpi != NULL );
2556  assert( sdpi->sdpisolver != NULL );
2557 
2558  switch( type )/*lint --e{788}*/
2559  {
2560  case SCIP_SDPPAR_EPSILON:
2561  sdpi->epsilon = dval;
2562  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
2563  break;
2564  case SCIP_SDPPAR_FEASTOL:
2565  sdpi->feastol = dval;
2566  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
2567  break;
2568  case SCIP_SDPPAR_OBJLIMIT:
2569  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
2570  break;
2571  default:
2572  return SCIP_PARAMETERUNKNOWN;
2573  }
2574 
2575 #ifndef NDEBUG
2576  {
2577  SCIP_Real val;
2578  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, &val) );
2579  assert( REALABS(dval - val) < sdpi->epsilon );
2580  }
2581 #endif
2582 
2583  return SCIP_OKAY;
2584 }
2585 
2587 SCIP_RETCODE SCIPsdpiGetIntpar(
2588  SCIP_SDPI* sdpi,
2589  SCIP_SDPPARAM type,
2590  int* ival
2591  )
2592 {
2593  assert( sdpi != NULL );
2594  assert( sdpi->sdpisolver != NULL );
2595  assert( ival != NULL );
2596 
2597  switch( type )/*lint --e{788}*/
2598  {
2599 #if 0
2600  case SCIP_SDPPAR_THREADS:
2601  SCIP_CALL_PARAM( SCIPsdpiSolverGetIntpar(sdpi->sdpisolver, type, ival) );
2602  break;
2603 #endif
2604  case SCIP_SDPPAR_SDPINFO:
2605  SCIP_CALL_PARAM( SCIPsdpiSolverGetIntpar(sdpi->sdpisolver, type, ival) );
2606  break;
2608  *ival = (int) sdpi->slatercheck;
2609  break;
2610  default:
2611  return SCIP_PARAMETERUNKNOWN;
2612  }
2613 
2614 #ifndef NDEBUG
2615  {
2616  if ( type != SCIP_SDPPAR_SLATERCHECK )
2617  {
2618  int val;
2619  SCIP_CALL_PARAM( SCIPsdpiSolverGetIntpar(sdpi->sdpisolver, type, &val) );
2620  assert( *ival == val );
2621  }
2622  }
2623 #endif
2624 
2625  return SCIP_OKAY;
2626 }
2627 
2629 SCIP_RETCODE SCIPsdpiSetIntpar(
2630  SCIP_SDPI* sdpi,
2631  SCIP_SDPPARAM type,
2632  int ival
2633  )
2634 {
2635  assert( sdpi != NULL );
2636  assert( sdpi->sdpisolver != NULL );
2637 
2638  switch( type )/*lint --e{788}*/
2639  {
2640 #if 0
2641  case SCIP_SDPPAR_THREADS:
2642  SCIP_CALL_PARAM( SCIPsdpiSolverSetIntpar(sdpi->sdpisolver, type, ival) );
2643  break;
2644 #endif
2645  case SCIP_SDPPAR_SDPINFO:
2646  assert( ival == 0 || ival == 1 ); /* this is a boolean parameter */
2647  SCIP_CALL_PARAM( SCIPsdpiSolverSetIntpar(sdpi->sdpisolver, type, ival) );
2648  break;
2650  assert( ival == 0 || ival == 1 ); /* this is a boolean parameter */
2651  sdpi->slatercheck = (SCIP_Bool) ival;
2652  break;
2653  default:
2654  return SCIP_PARAMETERUNKNOWN;
2655  }
2656 
2657 #ifndef NDEBUG
2658  {
2659  if ( type != SCIP_SDPPAR_SLATERCHECK )
2660  {
2661  int val;
2662  SCIP_CALL_PARAM( SCIPsdpiSolverGetIntpar(sdpi->sdpisolver, type, &val) );
2663  assert( ival == val );
2664  }
2665  }
2666 #endif
2667 
2668  return SCIP_OKAY;
2669 }
2670 
2676 /*
2677  * File Interface Methods
2678  */
2679 
2684 SCIP_RETCODE SCIPsdpiReadSDP(
2685  SCIP_SDPI* sdpi,
2686  const char* fname
2687  )
2688 {/*lint --e{715}*/
2689  SCIPdebugMessage("Not implemented yet\n");
2690  return SCIP_LPERROR;
2691 }
2692 
2694 SCIP_RETCODE SCIPsdpiWriteSDP(
2695  SCIP_SDPI* sdpi,
2696  const char* fname
2697  )
2698 {/*lint --e{715}*/
2699  SCIPdebugMessage("Not implemented yet\n");
2700  return SCIP_LPERROR;
2701 }
2702 
SCIP_RETCODE SCIPsdpiFree(SCIP_SDPI **sdpi)
Definition: sdpi.c:908
SCIP_Bool SCIPsdpiIsDualUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:2175
EXTERN SCIP_RETCODE SCIPsdpiSolverIncreaseCounter(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiDelLPRows(SCIP_SDPI *sdpi, int firstrow, int lastrow)
Definition: sdpi.c:1369
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:1558
EXTERN SCIP_RETCODE SCIPsdpiSolverSetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real dval)
EXTERN SCIP_Bool SCIPsdpiSolverIsObjlimExc(SCIP_SDPISOLVER *sdpisolver)
#define BMS_CALL(x)
Definition: sdpi.c:53
SCIP_RETCODE SCIPsdpiGetSolFeasibility(SCIP_SDPI *sdpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: sdpi.c:2098
SCIP_RETCODE SCIPsdpiWriteSDP(SCIP_SDPI *sdpi, const char *fname)
Definition: sdpi.c:2694
EXTERN SCIP_Bool SCIPsdpiSolverIsAcceptable(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetLPNNonz(SCIP_SDPI *sdpi, int *nnonz)
Definition: sdpi.c:1661
EXTERN SCIP_RETCODE SCIPsdpiSolverResetCounter(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Bool SCIPsdpiSolverFeasibilityKnown(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Bool SCIPsdpiSolverIsConverged(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_RETCODE SCIPsdpiSolverGetPrimalBoundVars(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
SCIP_Bool SCIPsdpiIsOptimal(SCIP_SDPI *sdpi)
Definition: sdpi.c:2326
SCIP_RETCODE SCIPsdpVarfixerMergeArraysIntoNew(BMS_BLKMEM *blkmem, SCIP_Real feastol, 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:249
SCIP_RETCODE SCIPsdpiGetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int *ival)
Definition: sdpi.c:2587
SCIP_RETCODE SCIPsdpiGetSDPNNonz(SCIP_SDPI *sdpi, int *nnonz)
Definition: sdpi.c:1635
SCIP_Bool SCIPsdpiIsInfinity(SCIP_SDPI *sdpi, SCIP_Real val)
Definition: sdpi.c:2480
const char * SCIPsdpiGetSolverName(void)
Definition: sdpi.c:813
EXTERN SCIP_RETCODE SCIPsdpiSolverFree(SCIP_SDPISOLVER **sdpisolver)
EXTERN SCIP_RETCODE SCIPsdpiSolverLoadAndSolve(SCIP_SDPISOLVER *sdpisolver, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, int noldlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int *rownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *start)
SCIP_RETCODE SCIPsdpiGetNSDPBlocks(SCIP_SDPI *sdpi, int *nsdpblocks)
Definition: sdpi.c:1611
SCIP_RETCODE SCIPsdpiGetSol(SCIP_SDPI *sdpi, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
Definition: sdpi.c:2383
interface methods for specific SDP solvers
SCIP_Bool SCIPsdpiIsPrimalInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2139
SCIP_Bool SCIPsdpiIsGEMaxPenParam(SCIP_SDPI *sdpi, SCIP_Real val)
Definition: sdpi.c:2501
SCIP_Bool SCIPsdpiFeasibilityKnown(SCIP_SDPI *sdpi)
Definition: sdpi.c:2084
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:1089
SCIP_RETCODE SCIPsdpiGetIterations(SCIP_SDPI *sdpi, int *iterations)
Definition: sdpi.c:2437
EXTERN SCIP_Bool SCIPsdpiSolverIsDualFeasible(SCIP_SDPISOLVER *sdpisolver)
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:335
SCIP_Bool SCIPsdpiIsAcceptable(SCIP_SDPI *sdpi)
Definition: sdpi.c:2344
EXTERN SCIP_Bool SCIPsdpiSolverIsGEMaxPenParam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real val)
EXTERN SCIP_Bool SCIPsdpiSolverIsPrimalUnbounded(SCIP_SDPISOLVER *sdpisolver)
EXTERN int SCIPsdpiSolverGetInternalStatus(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiIsIterlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:2262
SCIP_Bool SCIPsdpiIsTimelimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:2279
SCIP_Bool SCIPsdpiIsDualInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2193
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:1648
SCIP_RETCODE SCIPsdpiClone(SCIP_SDPI *oldsdpi, SCIP_SDPI *newsdpi)
Definition: sdpi.c:971
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:1528
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:1473
EXTERN SCIP_Bool SCIPsdpiSolverIsDualInfeasible(SCIP_SDPISOLVER *sdpisolver)
EXTERN const char * SCIPsdpiSolverGetSolverName(void)
SCIP_Bool SCIPsdpiIsObjlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:2245
SCIP_RETCODE SCIPsdpiGetObj(SCIP_SDPI *sdpi, int firstvar, int lastvar, SCIP_Real *vals)
Definition: sdpi.c:1674
void * SCIPsdpiGetSolverPointer(SCIP_SDPI *sdpi)
Definition: sdpi.c:834
int SCIPsdpiGetInternalStatus(SCIP_SDPI *sdpi)
Definition: sdpi.c:2305
SCIP_RETCODE SCIPsdpiCreate(SCIP_SDPI **sdpi, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem)
Definition: sdpi.c:852
EXTERN SCIP_RETCODE SCIPsdpiSolverLoadAndSolveWithPenalty(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Bool withobj, SCIP_Bool rbound, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, int noldlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int *rownactivevars, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *start, SCIP_Bool *feasorig)
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:1306
SCIP_RETCODE SCIPsdpiGetNVars(SCIP_SDPI *sdpi, int *nvars)
Definition: sdpi.c:1624
const char * SCIPsdpiGetSolverDesc(void)
Definition: sdpi.c:821
SCIP_RETCODE SCIPsdpiSetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int ival)
Definition: sdpi.c:2629
SCIP_Bool SCIPsdpiIsPrimalUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:2121
SCIP_Real SCIPsdpiInfinity(SCIP_SDPI *sdpi)
Definition: sdpi.c:2470
#define CHECK_IF_SOLVED_BOOL(sdpi)
Definition: sdpi.c:75
EXTERN SCIP_Bool SCIPsdpiSolverIsIterlimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetRhSides(SCIP_SDPI *sdpi, int firstrow, int lastrow, SCIP_Real *rhss)
Definition: sdpi.c:1746
#define DUPLICATE_ARRAY_NULL(blkmem, target, source, size)
Definition: sdpi.c:86
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:172
SCIP_RETCODE SCIPsdpiSolve(SCIP_SDPI *sdpi, SCIP_Real *start, int *totalsdpiterations, SCIP_Bool enforceslatercheck)
Definition: sdpi.c:1780
SCIP_RETCODE SCIPsdpiGetObjval(SCIP_SDPI *sdpi, SCIP_Real *objval)
Definition: sdpi.c:2361
EXTERN SCIP_RETCODE SCIPsdpiSolverGetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real *dval)
SCIP_Bool SCIPsdpiIsConverged(SCIP_SDPI *sdpi)
Definition: sdpi.c:2228
static SCIP_Bool isFixed(SCIP_SDPI *sdpi, int v)
Definition: sdpi.c:189
EXTERN SCIP_Bool SCIPsdpiSolverIsTimelimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiWasSolved(SCIP_SDPI *sdpi)
Definition: sdpi.c:2062
SCIP_RETCODE SCIPsdpiReadSDP(SCIP_SDPI *sdpi, const char *fname)
Definition: sdpi.c:2684
SCIP_RETCODE SCIPsdpiClear(SCIP_SDPI *sdpi)
Definition: sdpi.c:1512
SCIP_RETCODE SCIPsdpiGetBounds(SCIP_SDPI *sdpi, int firstvar, int lastvar, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: sdpi.c:1696
EXTERN SCIP_RETCODE SCIPsdpiSolverGetObjval(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval)
EXTERN SCIP_Bool SCIPsdpiSolverIsDualUnbounded(SCIP_SDPISOLVER *sdpisolver)
SCIP_Real SCIPsdpiMaxPenParam(SCIP_SDPI *sdpi)
Definition: sdpi.c:2491
SCIP_Bool SCIPsdpiIsDualFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2211
struct SCIP_SDPi SCIP_SDPI
Definition: type_sdpi.h:65
EXTERN SCIP_RETCODE SCIPsdpiSolverGetSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
SCIP_Bool SCIPsdpiIsPrimalFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2157
SCIP_RETCODE SCIPsdpiSetRealpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, SCIP_Real dval)
Definition: sdpi.c:2549
EXTERN SCIP_Bool SCIPsdpiSolverIsPrimalFeasible(SCIP_SDPISOLVER *sdpisolver)
EXTERN SCIP_Real SCIPsdpiSolverMaxPenParam(SCIP_SDPISOLVER *sdpisolver)
struct SCIP_SDPiSolver SCIP_SDPISOLVER
Definition: sdpisolver.h:71
SCIP_RETCODE SCIPsdpiGetRealpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, SCIP_Real *dval)
Definition: sdpi.c:2512
EXTERN SCIP_RETCODE SCIPsdpiSolverCreate(SCIP_SDPISOLVER **sdpisolver, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem)
static SCIP_RETCODE compConstMatAfterFixings(SCIP_SDPI *sdpi, int *sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval)
Definition: sdpi.c:221
#define CHECK_IF_SOLVED(sdpi)
Definition: sdpi.c:64
EXTERN SCIP_Real SCIPsdpiSolverInfinity(SCIP_SDPISOLVER *sdpisolver)
enum SCIP_SDPParam SCIP_SDPPARAM
Definition: type_sdpi.h:63
EXTERN void * SCIPsdpiSolverGetSolverPointer(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetNLPRows(SCIP_SDPI *sdpi, int *nlprows)
Definition: sdpi.c:1598
SCIP_RETCODE SCIPsdpiGetLhSides(SCIP_SDPI *sdpi, int firstrow, int lastrow, SCIP_Real *lhss)
Definition: sdpi.c:1724
SCIP_RETCODE SCIPsdpiGetPrimalBoundVars(SCIP_SDPI *sdpi, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
Definition: sdpi.c:2410
SCIP_Bool SCIPsdpiSolvedOrig(SCIP_SDPI *sdpi)
Definition: sdpi.c:2072
#define SCIP_CALL_PARAM(x)
Definition: sdpi.c:96
static SCIP_RETCODE computeLpLhsRhsAfterFixings(SCIP_SDPI *sdpi, int *nactivelpcons, SCIP_Real *lplhsafterfix, SCIP_Real *lprhsafterfix, int *rownactivevars, SCIP_Bool *fixingsfound)
Definition: sdpi.c:462