SCIP-SDP  4.0.0
sdpi.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of SCIPSDP - a solving framework for mixed-integer */
4 /* semidefinite programs based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2021 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-2021 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 
102 #include <assert.h>
103 #include <math.h>
104 
105 #include "sdpi/sdpisolver.h"
106 #include "sdpi/sdpi.h"
107 #include "scipsdp/SdpVarfixer.h"
108 #include "sdpi/lapack_interface.h" /* to check feasibility if all variables are fixed during preprocessing */
109 #include "sdpi/sdpiclock.h"
110 #include "sdpi/solveonevarsdp.h"
111 
112 #include "blockmemshell/memory.h" /* for memory allocation */
113 #include "scip/def.h" /* for SCIP_Real, _Bool, ... */
114 #include "scip/pub_misc.h" /* for sorting */
115 #include "scip/pub_message.h" /* for debug and error message */
116 
117 /* turn off lint warnings for whole file: */
118 /*lint --e{788,818}*/
119 
120 
122 #define BMS_CALL(x) do \
123  { \
124  if( NULL == (x) ) \
125  { \
126  SCIPerrorMessage("No memory in function call\n"); \
127  return SCIP_NOMEMORY; \
128  } \
129  } \
130  while( FALSE )
131 
133 #define CHECK_IF_SOLVED(sdpi) do \
134  { \
135  if ( ! (sdpi->solved) ) \
136  { \
137  SCIPerrorMessage("Tried to access solution information ahead of solving! \n"); \
138  return SCIP_LPERROR; \
139  } \
140  } \
141  while( FALSE )
142 
144 #define CHECK_IF_SOLVED_BOOL(sdpi) do \
145  { \
146  if ( ! (sdpi->solved) ) \
147  { \
148  SCIPerrorMessage("Tried to access solution information ahead of solving! \n"); \
149  return FALSE; \
150  } \
151  } \
152  while( FALSE )
153 
155 #define DUPLICATE_ARRAY_NULL(blkmem, target, source, size) do \
156  { \
157  if (size > 0) \
158  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, target, source, size) ); \
159  else \
160  *target = NULL; \
161  } \
162  while( FALSE )
163 
165 #define SCIP_CALL_PARAM(x) do \
166  { \
167  SCIP_RETCODE _restat_; \
168  if ( (_restat_ = (x)) != SCIP_OKAY ) \
169  { \
170  if ( _restat_ != SCIP_PARAMETERUNKNOWN ) \
171  { \
172  SCIPerrorMessage("Error <%d> in function call\n", _restat_); \
173  SCIPABORT(); \
174  } \
175  return _restat_; \
176  } \
177  } \
178  while( FALSE )
179 
181 #define SCIP_CALL_PARAM_IGNORE_UNKNOWN(x) do \
182  { \
183  SCIP_RETCODE _restat_; \
184  if ( (_restat_ = (x)) != SCIP_OKAY ) \
185  { \
186  if ( _restat_ != SCIP_PARAMETERUNKNOWN ) \
187  { \
188  SCIPerrorMessage("Error <%d> in function call\n", _restat_); \
189  SCIPABORT(); \
190  } \
191  } \
192  } \
193  while( FALSE )
194 
195 /* #define PRINTSLATER */
196 #define MIN_GAPTOL 1e-10
197 #define DEFAULT_SDPSOLVERGAPTOL 1e-4
198 #define DEFAULT_FEASTOL 1e-6
199 #define DEFAULT_EPSILON 1e-9
200 #define DEFAULT_PENALTYPARAM 1e+5
201 #define DEFAULT_MAXPENALTYPARAM 1e+10
202 #define DEFAULT_NPENALTYINCR 8
205 enum SCIP_Onevar_Status
206 {
210 };
212 
213 
215 struct SCIP_SDPi
216 {
217  SCIP_SDPISOLVER* sdpisolver;
218  SCIP_MESSAGEHDLR* messagehdlr;
219  BMS_BLKMEM* blkmem;
220  BMS_BUFMEM* bufmem;
221  int nvars;
222  int maxnvars;
223  SCIP_Real* obj;
224  SCIP_Real* lb;
225  SCIP_Real* ub;
226  SCIP_Real* sdpilb;
227  SCIP_Real* sdpiub;
228  int nsdpblocks;
229  int maxnsdpblocks;
230  int* sdpblocksizes;
231  int* sdpnblockvars;
232  int* maxsdpnblockvars;
234  /* constant SDP data: */
235  int sdpconstnnonz;
236  int* sdpconstnblocknonz;
238  int* maxsdpconstnblocknonz;
239  int** sdpconstrow;
240  int** sdpconstcol;
241  SCIP_Real** sdpconstval;
243  /* non-constant SDP data: */
244  int sdpnnonz;
245  int** sdpnblockvarnonz;
246  int** sdpvar;
247  int*** sdprow;
248  int*** sdpcol;
249  SCIP_Real*** sdpval;
251  int maxsdpstore;
252  int* sdprowstore;
253  int* sdpcolstore;
254  SCIP_Real* sdpvalstore;
256  /* lp data: */
257  int nlpcons;
258  int maxnlpcons;
259  SCIP_Real* lplhs;
260  SCIP_Real* lprhs;
261  SCIP_Real* sdpilplhs;
262  SCIP_Real* sdpilprhs;
263  int lpnnonz;
264  int maxlpnnonz;
265  int* lprow;
266  int* lpcol;
267  SCIP_Real* lpval;
268  int* sdpilprow;
269  int* sdpilpcol;
270  SCIP_Real* sdpilpval;
272  /* statistics */
273  int ninfeasible;
274  int nallfixed;
275  int nonevarsdp;
277  /* other data */
278  int slatercheck;
279  int sdpid;
280  int niterations;
281  SCIP_Real opttime;
282  int nsdpcalls;
283  SCIP_Bool solved;
284  SCIP_Bool penalty;
285  SCIP_Bool infeasible;
286  SCIP_Bool allfixed;
287  SCIP_Real epsilon;
288  SCIP_Real gaptol;
289  SCIP_Real feastol;
290  SCIP_Real penaltyparam;
291  SCIP_Real maxpenaltyparam;
292  int npenaltyincr;
293  SCIP_Real peninfeasadjust;
294  SCIP_Real bestbound;
295  SCIP_SDPSLATER primalslater;
296  SCIP_SDPSLATER dualslater;
297  SDPI_CLOCK* usedsdpitime;
298  SCIP_ONEVAR_STATUS solvedonevarsdp;
299  SCIP_Real onevarsdpobjval;
300  SCIP_Real onevarsdpoptval;
301  int onevarsdpidx;
302 };
303 
304 
305 /*
306  * Local Functions
307  */
308 
309 #ifndef NDEBUG
310 
311 static
312 SCIP_Bool isFixed(
313  const SCIP_SDPI* sdpi,
314  int v
315  )
316 {
317  SCIP_Real lb;
318  SCIP_Real ub;
319 
320  assert( sdpi != NULL );
321  assert( sdpi->sdpilb != NULL );
322  assert( sdpi->sdpiub != NULL );
323  assert( 0 <= v && v < sdpi->nvars );
324 
325  lb = sdpi->sdpilb[v];
326  ub = sdpi->sdpiub[v];
327  assert( lb <= ub + sdpi->epsilon );
328 
329  return ( ub - lb <= sdpi->epsilon );
330 }
331 #else
332 #define isFixed(sdpi, v) (sdpi->sdpiub[v] - sdpi->sdpilb[v] <= sdpi->epsilon)
333 #endif
334 
336 static
338  int initsize,
339  int num
340  )
341 {
342  int oldsize;
343  int size;
344 
345  assert( initsize >= 0 );
346  assert( num >= 0 );
347 
348  /* calculate the size with loop, such that the resulting numbers are always the same (-> block memory) */
349  initsize = MAX(initsize, SCIP_DEFAULT_MEM_ARRAYGROWINIT);
350  size = initsize;
351  oldsize = size - 1;
352 
353  /* second condition checks against overflow */
354  while ( size < num && size > oldsize )
355  {
356  oldsize = size;
357  size = (int)(SCIP_DEFAULT_MEM_ARRAYGROWFAC * size + initsize);
358  }
359 
360  /* if an overflow happened, set the correct value */
361  if ( size <= oldsize )
362  size = num;
363 
364  assert( size >= initsize );
365  assert( size >= num );
366 
367  return size;
368 }
369 
371 static
373  SCIP_SDPI* sdpi,
374  int nvars
375  )
376 {
377  int newsize;
378 
379  assert( sdpi != NULL );
380 
381  if ( nvars > sdpi->maxnvars )
382  {
383  newsize = calcGrowSize(sdpi->maxnvars, nvars);
384 
385  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->obj), sdpi->maxnvars, newsize) );
386  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lb), sdpi->maxnvars, newsize) );
387  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->ub), sdpi->maxnvars, newsize) );
388  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpilb), sdpi->maxnvars, newsize) );
389  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpiub), sdpi->maxnvars, newsize) );
390  sdpi->maxnvars = newsize;
391  }
392 
393  return SCIP_OKAY;
394 }
395 
397 static
398 SCIP_RETCODE ensureLPDataMemory(
399  SCIP_SDPI* sdpi,
400  int nlpcons,
401  int nlpnonz
402  )
403 {
404  int newsize;
405 
406  assert( sdpi != NULL );
407 
408  if ( nlpcons > sdpi->maxnlpcons )
409  {
410  newsize = calcGrowSize(sdpi->maxnlpcons, nlpcons);
411 
412  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lplhs), sdpi->maxnlpcons, newsize) );
413  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprhs), sdpi->maxnlpcons, newsize) );
414 
415  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpilplhs), sdpi->maxnlpcons, newsize) );
416  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpilprhs), sdpi->maxnlpcons, newsize) );
417  sdpi->maxnlpcons = newsize;
418  }
419 
420  if ( nlpnonz > sdpi->maxlpnnonz )
421  {
422  newsize = calcGrowSize(sdpi->maxlpnnonz, nlpnonz);
423 
424  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lprow), sdpi->maxlpnnonz, newsize) );
425  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpcol), sdpi->maxlpnnonz, newsize) );
426  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->lpval), sdpi->maxlpnnonz, newsize) );
427 
428  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpilprow), sdpi->maxlpnnonz, newsize) );
429  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpilpcol), sdpi->maxlpnnonz, newsize) );
430  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpilpval), sdpi->maxlpnnonz, newsize) );
431 
432  sdpi->maxlpnnonz = newsize;
433  }
434 
435  return SCIP_OKAY;
436 }
437 
439 static
440 SCIP_RETCODE ensureSDPDataMemory(
441  SCIP_SDPI* sdpi,
442  int nsdpblocks,
443  int* sdpnblockvars,
444  int** sdpnblockvarnonz,
445  int* sdpconstnblocknonz,
446  int sdpnnonz
447  )
448 {
449  int oldnsdpblocks;
450  int cnt = 0;
451  int b;
452  int v;
453 
454  assert( sdpi != NULL );
455 
456  if ( nsdpblocks <= 0 )
457  return SCIP_OKAY;
458 
459  assert( sdpnblockvars != NULL );
460  assert( sdpnblockvarnonz != NULL );
461  assert( sdpconstnblocknonz != NULL );
462 
463  if ( sdpnnonz > sdpi->maxsdpstore )
464  {
465  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdprowstore), sdpi->maxsdpstore, sdpnnonz) );
466  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpcolstore), sdpi->maxsdpstore, sdpnnonz) );
467  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpvalstore), sdpi->maxsdpstore, sdpnnonz) );
468  sdpi->maxsdpstore = sdpnnonz;
469  }
470  sdpi->sdpnnonz = sdpnnonz;
471 
472  /* we assume that the sizes for SDP constraints only change seldomly, so we do not use a grow factor */
473  if ( nsdpblocks > sdpi->maxnsdpblocks )
474  {
475  oldnsdpblocks = sdpi->maxnsdpblocks;
476 
477  /* the following array pointers are all initialized (possibly with NULL) */
478  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpblocksizes), sdpi->maxnsdpblocks, nsdpblocks) );
479  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpnblockvars), sdpi->maxnsdpblocks, nsdpblocks) );
480  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->maxsdpnblockvars), sdpi->maxnsdpblocks, nsdpblocks) );
481  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstnblocknonz), sdpi->maxnsdpblocks, nsdpblocks) );
482  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->maxsdpconstnblocknonz), sdpi->maxnsdpblocks, nsdpblocks) );
483  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpnblockvarnonz), sdpi->maxnsdpblocks, nsdpblocks) );
484  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstcol), sdpi->maxnsdpblocks, nsdpblocks) );
485  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstrow), sdpi->maxnsdpblocks, nsdpblocks) );
486  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstval), sdpi->maxnsdpblocks, nsdpblocks) );
487  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpvar), sdpi->maxnsdpblocks, nsdpblocks) );
488  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpcol), sdpi->maxnsdpblocks, nsdpblocks) );
489  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdprow), sdpi->maxnsdpblocks, nsdpblocks) );
490  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpval), sdpi->maxnsdpblocks, nsdpblocks) );
491  sdpi->maxnsdpblocks = nsdpblocks;
492  }
493  else
494  oldnsdpblocks = nsdpblocks;
495 
496  /* loop through previously existing blocks */
497  for (b = 0; b < oldnsdpblocks; ++b)
498  {
499  /* the following array pointers should be initialized */
500  if ( sdpconstnblocknonz[b] > sdpi->maxsdpconstnblocknonz[b] )
501  {
502  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstcol[b]), sdpi->maxsdpconstnblocknonz[b], sdpconstnblocknonz[b]) );
503  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstrow[b]), sdpi->maxsdpconstnblocknonz[b], sdpconstnblocknonz[b]) );
504  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstval[b]), sdpi->maxsdpconstnblocknonz[b], sdpconstnblocknonz[b]) );
505  sdpi->maxsdpconstnblocknonz[b] = sdpconstnblocknonz[b];
506  }
507 
508  if ( sdpnblockvars[b] > sdpi->maxsdpnblockvars[b] )
509  {
510  assert( sdpi->sdpnblockvarnonz[b] != NULL );
511  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpnblockvarnonz[b]), sdpi->maxsdpnblockvars[b], sdpnblockvars[b]) );
512  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpvar[b]), sdpi->maxsdpnblockvars[b], sdpnblockvars[b]) );
513  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdprow[b]), sdpi->maxsdpnblockvars[b], sdpnblockvars[b]) );
514  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpcol[b]), sdpi->maxsdpnblockvars[b], sdpnblockvars[b]) );
515  BMS_CALL( BMSreallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpval[b]), sdpi->maxsdpnblockvars[b], sdpnblockvars[b]) );
516  sdpi->maxsdpnblockvars[b] = sdpnblockvars[b];
517  }
518 
519  /* set pointers into storage */
520  for (v = 0; v < sdpnblockvars[b]; ++v)
521  {
522  sdpi->sdprow[b][v] = &sdpi->sdprowstore[cnt];
523  sdpi->sdpcol[b][v] = &sdpi->sdpcolstore[cnt];
524  sdpi->sdpval[b][v] = &sdpi->sdpvalstore[cnt];
525  cnt += sdpnblockvarnonz[b][v];
526  }
527  assert( cnt <= sdpi->maxsdpstore );
528  }
529 
530  /* loop through new blocks */
531  for (b = oldnsdpblocks; b < nsdpblocks; ++b)
532  {
533  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpnblockvarnonz[b]), sdpnblockvars[b]) );
534  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpvar[b]), sdpnblockvars[b]) );
535  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdprow[b]), sdpnblockvars[b]) );
536  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpcol[b]), sdpnblockvars[b]) );
537  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpval[b]), sdpnblockvars[b]) );
538  sdpi->maxsdpnblockvars[b] = sdpnblockvars[b];
539 
540  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstcol[b]), sdpconstnblocknonz[b]) );
541  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstrow[b]), sdpconstnblocknonz[b]) );
542  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpi->sdpconstval[b]), sdpconstnblocknonz[b]) );
543  sdpi->maxsdpconstnblocknonz[b] = sdpconstnblocknonz[b];
544 
545  /* set pointers into storage */
546  for (v = 0; v < sdpnblockvars[b]; ++v)
547  {
548  sdpi->sdprow[b][v] = &sdpi->sdprowstore[cnt];
549  sdpi->sdpcol[b][v] = &sdpi->sdpcolstore[cnt];
550  sdpi->sdpval[b][v] = &sdpi->sdpvalstore[cnt];
551  cnt += sdpnblockvarnonz[b][v];
552  }
553  }
554 
555  return SCIP_OKAY;
556 }
557 
558 
565 static
567  const SCIP_SDPI* sdpi,
568  const SCIP_Real* sdpilb,
569  const SCIP_Real* sdpiub,
570  int* sdpconstnnonz,
571  int* sdpconstnblocknonz,
572  int** sdpconstrow,
573  int** sdpconstcol,
574  SCIP_Real** sdpconstval
575  )
576 {
577  int i;
578  int v;
579  int b;
580  int* fixedrows;
581  int* fixedcols;
582  SCIP_Real* fixedvals;
583 
584  assert( sdpi != NULL );
585  assert( sdpilb != NULL );
586  assert( sdpiub != NULL );
587  assert( sdpconstnnonz != NULL );
588  assert( sdpconstnblocknonz != NULL );
589  assert( sdpconstrow != NULL );
590  assert( sdpconstcol != NULL );
591  assert( sdpconstval != NULL );
592 
593  *sdpconstnnonz = 0;
594 
595  /* allocate memory for the nonzeros that need to be fixed */
596  BMS_CALL( BMSallocBufferMemoryArray(sdpi->bufmem, &fixedrows, sdpi->sdpnnonz) );
597  BMS_CALL( BMSallocBufferMemoryArray(sdpi->bufmem, &fixedcols, sdpi->sdpnnonz) );
598  BMS_CALL( BMSallocBufferMemoryArray(sdpi->bufmem, &fixedvals, sdpi->sdpnnonz) );
599 
600  /* iterate over all variables, saving the nonzeros of the fixed ones */
601  for (b = 0; b < sdpi->nsdpblocks; ++b)
602  {
603  int nfixednonz = 0;
604  int varidx;
605 
606  for (v = 0; v < sdpi->sdpnblockvars[b]; ++v)
607  {
608  varidx = sdpi->sdpvar[b][v];
609  if ( isFixed(sdpi, varidx) && REALABS(sdpilb[varidx]) > sdpi->epsilon )
610  {
611  for (i = 0; i < sdpi->sdpnblockvarnonz[b][v]; ++i)
612  {
613  fixedrows[nfixednonz] = sdpi->sdprow[b][v][i];
614  fixedcols[nfixednonz] = sdpi->sdpcol[b][v][i];
615  fixedvals[nfixednonz] = - sdpi->sdpval[b][v][i] * sdpilb[varidx]; /* the -1 comes from +y_i A_i but -A_0 */
616  ++nfixednonz;
617  }
618  }
619  }
620 
621  SCIP_CALL( SCIPsdpVarfixerMergeArraysIntoNew(sdpi->blkmem, sdpi->epsilon,
622  sdpi->sdpconstrow[b], sdpi->sdpconstcol[b], sdpi->sdpconstval[b], sdpi->sdpconstnblocknonz[b],
623  fixedrows, fixedcols, fixedvals, nfixednonz,
624  sdpconstrow[b], sdpconstcol[b], sdpconstval[b], &sdpconstnblocknonz[b]) );
625  *sdpconstnnonz += sdpconstnblocknonz[b];
626  }
627 
628  /* free memory */
629  BMSfreeBufferMemoryArray(sdpi->bufmem, &fixedvals);
630  BMSfreeBufferMemoryArray(sdpi->bufmem, &fixedcols);
631  BMSfreeBufferMemoryArray(sdpi->bufmem, &fixedrows);
632 
633  return SCIP_OKAY;
634 }
635 
642 static
643 SCIP_RETCODE findEmptyRowColsSDP(
644  SCIP_SDPI* sdpi,
645  int* sdpconstnblocknonz,
646  int** sdpconstrow,
647  int** sdpconstcol,
648  SCIP_Real** sdpconstval,
649  int** indchanges,
653  int* nremovedinds,
654  int* blockindchanges,
655  int* nremovedblocks
656  )
657 {
658  int b;
659  int v;
660  int i;
661 
662  assert( sdpi != NULL );
663  assert( sdpconstnblocknonz != NULL );
664  assert( sdpconstrow != NULL );
665  assert( sdpconstcol != NULL );
666  assert( sdpconstval != NULL );
667  assert( indchanges != NULL );
668  assert( nremovedinds != NULL );
669  assert( blockindchanges != NULL );
670  assert( nremovedblocks != NULL );
671 
672  /* initialize indchanges with -1 */
673  for (b = 0; b < sdpi->nsdpblocks; ++b)
674  {
675  for (i = 0; i < sdpi->sdpblocksizes[b]; i++)
676  indchanges[b][i] = -1;
677  }
678  *nremovedblocks = 0;
679 
680  /* 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
681  * index is still needed, it will later be set to the number of rows/cols deleted earlier) */
682  for (b = 0; b < sdpi->nsdpblocks; ++b)
683  {
684  int nfoundinds = 0; /* number of indices already found, saved for prematurely stopping the loops */
685 
686  for (v = 0; v < sdpi->sdpnblockvars[b]; ++v)
687  {
688  if ( ! isFixed(sdpi, sdpi->sdpvar[b][v]) )
689  {
690  for (i = 0; i < sdpi->sdpnblockvarnonz[b][v]; ++i)
691  {
692  assert( REALABS(sdpi->sdpval[b][v][i]) > sdpi->epsilon ); /* this should really be a nonzero */
693 
694  if ( indchanges[b][sdpi->sdprow[b][v][i]] == -1 )
695  {
696  indchanges[b][sdpi->sdprow[b][v][i]] = 1;
697  ++nfoundinds;
698  }
699 
700  if ( indchanges[b][sdpi->sdpcol[b][v][i]] == -1 )
701  {
702  indchanges[b][sdpi->sdpcol[b][v][i]] = 1;
703  ++nfoundinds;
704  }
705  if ( nfoundinds == sdpi->sdpblocksizes[b] )
706  break; /* we're done for this block */
707  }
708  }
709 
710  if ( nfoundinds == sdpi->sdpblocksizes[b] )
711  break; /* we're done for this block */
712  }
713 
714  if ( nfoundinds < sdpi->sdpblocksizes[b] )
715  {
716  /* if some indices haven't been found yet, look in the constant matrix for them */
717  for (i = 0; i < sdpconstnblocknonz[b]; ++i)
718  {
719  assert( REALABS(sdpconstval[b][i]) > sdpi->epsilon ); /* this should really be a nonzero */
720 
721  if ( indchanges[b][sdpconstrow[b][i]] == -1 )
722  {
723  indchanges[b][sdpconstrow[b][i]] = 1;
724  ++nfoundinds;
725  }
726 
727  if ( indchanges[b][sdpconstcol[b][i]] == -1 )
728  {
729  indchanges[b][sdpconstcol[b][i]] = 1;
730  ++nfoundinds;
731  }
732 
733  if ( nfoundinds == sdpi->sdpblocksizes[b] )
734  break; /* we're done for this block */
735  }
736  }
737 
738  /* 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 */
739  nremovedinds[b] = 0;
740  for (i = 0; i < sdpi->sdpblocksizes[b]; ++i)
741  {
742  if ( indchanges[b][i] == -1 )
743  {
744  SCIPdebugMessage("empty row and col %d were removed from block %d of SDP %d.\n", i, b, sdpi->sdpid);
745  /* this index wasn't found (indchanges was initialized with -1), so it can be removed */
746  ++nremovedinds[b];
747  }
748  else
749  {
750  /* this index has been found, so set the value to the number of removed inds before it */
751  indchanges[b][i] = nremovedinds[b];
752  }
753  }
754 
755  /* check if the block became empty */
756  if ( nremovedinds[b] == sdpi->sdpblocksizes[b] )
757  {
758  SCIPdebugMessage("empty block %d detected in SDP %d, this will be removed.\n", b, sdpi->sdpid);
759  blockindchanges[b] = -1;
760  ++(*nremovedblocks);
761  }
762  else
763  blockindchanges[b] = *nremovedblocks;
764  }
765 
766  return SCIP_OKAY;
767 }
768 
777 static
778 SCIP_RETCODE prepareLPData(
779  SCIP_SDPI* sdpi,
780  SCIP_Real* sdpilb,
781  SCIP_Real* sdpiub,
782  int* nsdpilpcons,
783  SCIP_Real* sdpilplhs,
784  SCIP_Real* sdpilprhs,
785  int* sdpilpnnonz,
786  int* sdpilprow,
787  int* sdpilpcol,
788  SCIP_Real* sdpilpval,
789  SCIP_Bool* fixingsfound
790  )
791 {
792  SCIP_Real rowconst = 0.0;
793  int oldsdpilpnnonz = 0;
794  int nrownonz = 0;
795  int nonzind = -1;
796  int currentrow;
797  int i;
798 
799  assert( sdpi != NULL );
800  assert( sdpilb != NULL );
801  assert( sdpiub != NULL );
802  assert( nsdpilpcons != NULL );
803  assert( sdpi->nlpcons == 0 || sdpilplhs != NULL );
804  assert( sdpi->nlpcons == 0 || sdpilprhs != NULL );
805  assert( sdpilpnnonz != NULL );
806  assert( sdpi->nlpcons == 0 || sdpilprow != NULL );
807  assert( sdpi->nlpcons == 0 || sdpilpcol != NULL );
808  assert( sdpi->nlpcons == 0 || sdpilpval != NULL );
809  assert( fixingsfound != NULL );
810 
811  *nsdpilpcons = 0;
812  *sdpilpnnonz = 0;
813  *fixingsfound = FALSE;
814 
815  /* if there is no LP-part, there is nothing to do */
816  if ( sdpi->nlpcons == 0 || sdpi->lpnnonz == 0 )
817  return SCIP_OKAY;
818 
819  currentrow = sdpi->lprow[0];
820  for (i = 0; i < sdpi->lpnnonz; ++i)
821  {
822  assert( i == 0 || sdpi->lprow[i-1] <= sdpi->lprow[i] ); /* rows should be sorted */
823 
824  /* count number of contained active variables */
825  if ( ! isFixed(sdpi, sdpi->lpcol[i]) )
826  {
827  ++nrownonz;
828  nonzind = i;
829  sdpilprow[*sdpilpnnonz] = *nsdpilpcons;
830  sdpilpcol[*sdpilpnnonz] = sdpi->lpcol[i];
831  sdpilpval[*sdpilpnnonz] = sdpi->lpval[i];
832  ++(*sdpilpnnonz);
833  }
834  else
835  rowconst += sdpi->lpval[i] * sdpilb[sdpi->lpcol[i]]; /* contribution of the fixed variables */
836  assert( ! SCIPsdpiIsInfinity(sdpi, rowconst) );
837 
838  /* we finished a new row */
839  if ( i == sdpi->lpnnonz - 1 || sdpi->lprow[i+1] > currentrow )
840  {
841  SCIP_Real lhs;
842  SCIP_Real rhs;
843 
844  if ( sdpi->lplhs[currentrow] > - SCIPsdpiInfinity(sdpi) )
845  lhs = sdpi->lplhs[currentrow] - rowconst;
846  else
847  lhs = - SCIPsdpiInfinity(sdpi);
848 
849  if ( sdpi->lprhs[currentrow] < SCIPsdpiInfinity(sdpi) )
850  rhs = sdpi->lprhs[currentrow] - rowconst;
851  else
852  rhs = SCIPsdpiInfinity(sdpi);
853 
854  /* if the last row had at least two active variables, we keep the lhs- and rhs-value */
855  if ( nrownonz >= 2 )
856  {
857  sdpilplhs[*nsdpilpcons] = lhs;
858  sdpilprhs[*nsdpilpcons] = rhs;
859  ++(*nsdpilpcons);
860  oldsdpilpnnonz = *sdpilpnnonz;
861  }
862  else if ( nrownonz == 1 )
863  {
864  SCIP_Real lpval;
865  SCIP_Real lb;
866  SCIP_Real ub;
867  int lpcol;
868 
869  assert( 0 <= nonzind && nonzind < sdpi->lpnnonz );
870 
871  /* check whether the row leads to an improvement in the variables bounds */
872  lpcol = sdpi->lpcol[nonzind];
873  assert( 0 <= lpcol && lpcol < sdpi->nvars );
874 
875  lpval = sdpi->lpval[nonzind];
876  assert( REALABS(lpval) > sdpi->epsilon );
877 
878  /* compute new lower and upper bounds */
879  if ( lpval > 0.0 )
880  {
881  if ( lhs > - SCIPsdpiInfinity(sdpi) )
882  lb = lhs / lpval;
883  else
884  lb = - SCIPsdpiInfinity(sdpi);
885 
886  if ( rhs < SCIPsdpiInfinity(sdpi) )
887  ub = rhs / lpval;
888  else
889  ub = SCIPsdpiInfinity(sdpi);
890  }
891  else
892  {
893  if ( rhs < SCIPsdpiInfinity(sdpi) )
894  lb = rhs / lpval;
895  else
896  lb = - SCIPsdpiInfinity(sdpi);
897 
898  if ( lhs > - SCIPsdpiInfinity(sdpi) )
899  ub = lhs / lpval;
900  else
901  ub = SCIPsdpiInfinity(sdpi);
902  }
903 
904  /* check whether lower bound is stronger */
905  if ( lb > sdpilb[lpcol] + sdpi->epsilon )
906  {
907  /* this bound is stronger than the original one */
908  SCIPdebugMessage("LP-row %d with one nonzero has been removed from SDP %d, lower bound of variable %d has been strenghened to %g "
909  "(originally %g)\n", currentrow, sdpi->sdpid, lpcol, lb, sdpilb[lpcol]);
910  sdpilb[lpcol] = lb;
911  }
912 
913  /* check whether upper bound is stronger */
914  if ( ub < sdpiub[lpcol] - sdpi->epsilon )
915  {
916  /* this bound is stronger than the original one */
917  SCIPdebugMessage("LP-row %d with one nonzero has been removed from SDP %d, upper bound of variable %d has been strenghened to %g "
918  "(originally %g)\n", currentrow, sdpi->sdpid, lpcol, ub, sdpiub[lpcol]);
919  sdpiub[lpcol] = ub;
920  }
921 
922  /* check whether this makes the problem infeasible */
923  if ( sdpiub[lpcol] < sdpilb[lpcol] - sdpi->epsilon )
924  {
925  SCIPdebugMessage("Found upper bound %g < lower bound %g for variable %d -> infeasible!\n", sdpiub[lpcol], sdpilb[lpcol], lpcol);
926  sdpi->infeasible = TRUE;
927  return SCIP_OKAY;
928  }
929 
930  /* check if this leads to a fixing of this variable */
931  if ( REALABS(sdpilb[lpcol] - sdpiub[lpcol]) < sdpi->epsilon )
932  {
933  SCIPdebugMessage("Fixed variable %d to value %g in SDP %d.\n", lpcol, sdpilb[lpcol], sdpi->sdpid);
934  *fixingsfound = TRUE;
935  }
936 
937  /* reset counter to ignore current row */
938  *sdpilpnnonz = oldsdpilpnnonz;
939  }
940  else /* rows with no entries */
941  {
942  assert( nrownonz == 0 );
943 
944  /* we have a constraint lhs <= 0 <= rhs, so lhs should be non-positive and rhs non-negative, otherwise the problem is infeasible */
945  if ( lhs > sdpi->feastol || rhs < -sdpi->feastol )
946  {
947  SCIPdebugMessage("Found constraint %g <= 0 <= %g after fixings -> infeasible!\n", lhs, rhs );
948  sdpi->infeasible = TRUE;
949  return SCIP_OKAY;
950  }
951 
952  /* reset counter to ignore current row */
953  *sdpilpnnonz = oldsdpilpnnonz;
954  }
955 
956  /* reset variables for next row */
957  rowconst = 0.0;
958  nrownonz = 0;
959  if ( i < sdpi->lpnnonz )
960  currentrow = sdpi->lprow[i+1];
961  }
962  }
963 
964  return SCIP_OKAY;
965 }
966 
970 static
972  SCIP_SDPI* sdpi,
973  SCIP_Real* sdpilb,
974  SCIP_Real* sdpiub
975  )
976 {
977  SCIP_Real* fullmatrix; /* we need to give the full matrix to LAPACK */
978  int maxsize = -1;
979  int b;
980  int i;
981  int v;
982 
983  assert( sdpi->allfixed );
984  assert( ! sdpi->infeasible );
985 
986  /* as we don't want to allocate memory newly for every SDP-block, we allocate memory according to the size of the largest block */
987  for (b = 0; b < sdpi->nsdpblocks; b++)
988  {
989  if ( sdpi->sdpblocksizes[b] > maxsize )
990  maxsize = sdpi->sdpblocksizes[b];
991  }
992  if ( maxsize < 0 )
993  return SCIP_OKAY;
994 
995  /* allocate memory */
996  BMS_CALL( BMSallocBufferMemoryArray(sdpi->bufmem, &fullmatrix, maxsize * maxsize) ); /*lint !e647*/
997 
998  /* iterate over all SDP-blocks and check if the smallest eigenvalue is non-negative */
999  for (b = 0; b < sdpi->nsdpblocks; b++)
1000  {
1001  SCIP_Real eigenvalue;
1002  SCIP_Real fixedval;
1003  int size;
1004  int r;
1005  int c;
1006 
1007  size = sdpi->sdpblocksizes[b];
1008  assert( size <= maxsize );
1009 
1010  /* initialize the matrix with zero */
1011  for (i = 0; i < size * size; i++)
1012  fullmatrix[i] = 0.0;
1013 
1014  /* add the constant matrix (with negative sign) */
1015  for (i = 0; i < sdpi->sdpconstnblocknonz[b]; i++)
1016  {
1017  r = sdpi->sdpconstrow[b][i];
1018  c = sdpi->sdpconstcol[b][i];
1019 
1020  assert( 0 <= r && r < size );
1021  assert( 0 <= c && c < size );
1022  fullmatrix[r * size + c] = - sdpi->sdpconstval[b][i]; /*lint !e679*/
1023  if ( r != c )
1024  fullmatrix[c * size + r] = - sdpi->sdpconstval[b][i]; /*lint !e679*/
1025  }
1026 
1027  /* add the contributions of the fixed variables */
1028  for (v = 0; v < sdpi->sdpnblockvars[b]; v++)
1029  {
1030  fixedval = sdpilb[sdpi->sdpvar[b][v]];
1031  assert( REALABS(fixedval - sdpiub[sdpi->sdpvar[b][v]]) <= sdpi->epsilon );
1032 
1033  /* if the variable is fixed to zero, we can ignore its contributions */
1034  if ( REALABS(fixedval) < sdpi->epsilon )
1035  continue;
1036 
1037  /* iterate over all nonzeros */
1038  for (i = 0; i < sdpi->sdpnblockvarnonz[b][v]; i++)
1039  {
1040  r = sdpi->sdprow[b][v][i];
1041  c = sdpi->sdpcol[b][v][i];
1042 
1043  assert( 0 <= r && r < size );
1044  assert( 0 <= c && c < size );
1045  fullmatrix[r * size + c] += fixedval * sdpi->sdpval[b][v][i]; /*lint !e679*/
1046  if ( r != c )
1047  fullmatrix[c * size + r] += fixedval * sdpi->sdpval[b][v][i]; /*lint !e679*/
1048  }
1049  }
1050 
1051  /* compute the smallest eigenvalue */
1052  SCIP_CALL( SCIPlapackComputeIthEigenvalue(sdpi->bufmem, FALSE, size, fullmatrix, 1, &eigenvalue, NULL) );
1053 
1054  /* check if the eigenvalue is negative */
1055  if ( eigenvalue < - sdpi->feastol )
1056  {
1057  sdpi->infeasible = TRUE;
1058  SCIPdebugMessage("Detected infeasibility for SDP %d with all variables fixed (minimal eigenvalue: %g)!\n", sdpi->sdpid, eigenvalue);
1059  break;
1060  }
1061  }
1062 
1063  /* free memory */
1064  BMSfreeBufferMemoryArray(sdpi->bufmem, &fullmatrix);
1065 
1066  return SCIP_OKAY;
1067 }
1068 
1072 static
1074  SCIP_SDPI* sdpi,
1075  SCIP_Real timelimit,
1076  SCIP_Real* sdpilb,
1077  SCIP_Real* sdpiub,
1078  int* sdpconstnblocknonz,
1080  int sdpconstnnonz,
1081  int** sdpconstrow,
1082  int** sdpconstcol,
1083  SCIP_Real** sdpconstval,
1084  int** indchanges,
1086  int* nremovedinds,
1087  int nactivelpcons,
1088  SCIP_Real* sdpilplhs,
1089  SCIP_Real* sdpilprhs,
1090  int sdpilpnnonz,
1091  int* sdpilprow,
1092  int* sdpilpcol,
1093  SCIP_Real* sdpilpval,
1094  int* blockindchanges,
1096  int nremovedblocks,
1097  SCIP_Bool rootnodefailed
1099  )
1100 {
1101  SCIP_Real objval;
1102  SCIP_Bool origfeas = FALSE;
1103  SCIP_Bool penaltybound = FALSE;
1104  int* slaterlprow;
1105  int* slaterlpcol;
1106  SCIP_Real* slaterlpval;
1107  SCIP_Real* slaterlplhs;
1108  SCIP_Real* slaterlprhs;
1109  int nremovedslaterlpinds;
1110  int slaternactivelpcons;
1111  SCIP_Real* slaterlb;
1112  SCIP_Real* slaterub;
1113  int slaternremovedvarbounds;
1114  int i;
1115  int v;
1116  int b;
1117 
1118  assert( sdpi != NULL );
1119  assert( sdpconstnnonz == 0 || sdpconstnblocknonz != NULL );
1120  assert( sdpconstnnonz == 0 || sdpconstrow != NULL );
1121  assert( sdpconstnnonz == 0 || sdpconstcol != NULL );
1122  assert( sdpconstnnonz == 0 || sdpconstval != NULL );
1123  assert( sdpi->nsdpblocks == 0 || indchanges != NULL );
1124  assert( sdpi->nsdpblocks == 0 || nremovedinds != NULL );
1125  assert( nactivelpcons == 0 || sdpilplhs != NULL );
1126  assert( nactivelpcons == 0 || sdpilprhs != NULL );
1127  assert( sdpi->nsdpblocks == 0 || blockindchanges != NULL );
1128 
1129  /* 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
1130  * still feasible for r < - feastol, then we have an interior point with smallest eigenvalue > feastol, otherwise the Slater condition is not fulfilled */
1131  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, 1.0, FALSE, FALSE, sdpi->nvars, sdpi->obj, sdpilb, sdpiub,
1132  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
1133  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
1134  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol, sdpi->sdpval,
1135  indchanges, nremovedinds, blockindchanges, nremovedblocks,
1136  nactivelpcons, sdpilplhs, sdpilprhs, sdpilpnnonz, sdpilprow, sdpilpcol, sdpilpval,
1137  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1138  SCIP_SDPSOLVERSETTING_UNSOLVED, timelimit, sdpi->usedsdpitime, &origfeas, &penaltybound) );
1139 
1140  /* analyze result */
1141  if ( SCIPsdpiSolverIsOptimal(sdpi->sdpisolver) )
1142  {
1143  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) );
1144 
1145  if ( objval < - sdpi->feastol )
1146  {
1147  if ( rootnodefailed )
1148  {
1149  SCIPmessagePrintInfo(sdpi->messagehdlr, "Aborting: Failed to solve root node relaxation; Slater condition for dual problem holds (smallest eigenvalue %g).\n", - objval);
1150  }
1151  else
1152  SCIPdebugMessage("Slater condition for SDP %d is fulfilled for dual problem with smallest eigenvalue %g.\n", sdpi->sdpid, -1.0 * objval);/*lint !e687*/
1153  sdpi->dualslater = SCIP_SDPSLATER_HOLDS;
1154  }
1155  else if ( objval < sdpi->feastol )
1156  {
1157  if ( rootnodefailed )
1158  {
1159  SCIPmessagePrintInfo(sdpi->messagehdlr, "Aborting: Failed to solve root node relaxation; Slater condition for dual problem does not hold (smallest eigenvalue %g).\n", -objval);
1160  }
1161  else if ( sdpi->slatercheck == 2 )
1162  {
1163  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for SDP %d not fulfilled for dual problem (smallest eigenvalue %g) - expecting numerical trouble.\n",
1164  sdpi->sdpid, - objval);
1165  }
1166  sdpi->dualslater = SCIP_SDPSLATER_NOT;
1167  }
1168  else
1169  {
1170  if ( sdpi->slatercheck == 2 )
1171  {
1172  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for SDP %d not fulfilled for dual problem (smallest eigenvalue %g; problem infeasible).\n", sdpi->sdpid, -objval);
1173  }
1174  sdpi->dualslater = SCIP_SDPSLATER_INF;
1175  }
1176  }
1177  else if ( SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver) )
1178  {
1179  if ( rootnodefailed )
1180  {
1181  SCIPmessagePrintInfo(sdpi->messagehdlr, "Aborting: Failed to solve root node relaxation; Slater condition for dual problem holds (problem unbounded).\n");
1182  }
1183  else
1184  {
1185  SCIPdebugMessage("Slater condition for dual problem for SDP %d fulfilled.\n", sdpi->sdpid);/*lint !e687*/
1186  }
1187  sdpi->dualslater = SCIP_SDPSLATER_HOLDS;
1188  }
1189  else if ( SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver) )
1190  {
1191  if ( rootnodefailed )
1192  {
1193  SCIPmessagePrintInfo(sdpi->messagehdlr, "Aborting: Faild to solve root node relaxation; Slater condition for dual problem does not hold (problem infeasible).\n");
1194  }
1195  else if ( sdpi->slatercheck == 2 )
1196  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for dual problem for SDP %d not fulfilled (problem infeasible).\n", sdpi->sdpid);
1197  sdpi->dualslater = SCIP_SDPSLATER_NOT;
1198  }
1199  else
1200  {
1201  assert( ! SCIPsdpiSolverIsOptimal(sdpi->sdpisolver) && ! SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver) && ! SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver) );
1202 
1203  if ( rootnodefailed )
1204  {
1205  SCIPmessagePrintInfo(sdpi->messagehdlr, "Aborting: Failed to solve root node relaxation; Slater condition for dual problem could not be checked.\n");
1206  }
1207  else if ( sdpi->slatercheck == 2 )
1208  SCIPmessagePrintInfo(sdpi->messagehdlr, "Unable to check Slater condition for dual problem.\n");
1209  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
1210  }
1211 
1212 
1213  /* check the Slater condition also for the primal problem */
1214 
1215  /* As we do not want to give equality constraints to the solver by reformulating the primal problem as a dual problem, we instead
1216  * solve the primal dual pair
1217  *
1218  * (P) max (0 0) * Y' s.t. (A_i 0 ) * Y' = c_i forall i, Y' psd
1219  * (0 1) ( 0 sum_j [(A_i)_jj])
1220  *
1221  * (D) min sum_i [c_i x_i] s.t. sum_i [A_i x_i] psd, sum_i[(sum_j [(A_i)_jj]) x_i] >= 1
1222  *
1223  * where we also set all finite lhs/rhs of all lp-constraints and varbounds to zero.
1224  * If the objective is strictly positive, then we know that there exists some r > 0 such that
1225  * Y is psd and Y+rI is feasible for the equality constraints in our original primal problem,
1226  * so Y+rI is also feasible for the original primal problem and is strictly positive definite
1227  * so the primal Slater condition holds.
1228  */
1229 
1230  /* allocate the LP-arrays, as we have to add the additional LP-constraint. Because we want to add extra entries, we cannot use BMSduplicate... */
1231  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterlprow, sdpilpnnonz + sdpi->nvars) );/*lint !e776*/
1232  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterlpcol, sdpilpnnonz + sdpi->nvars) );/*lint !e776*/
1233  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterlpval, sdpilpnnonz + sdpi->nvars) );/*lint !e776*/
1234 
1235  /* copy all old LP-entries */
1236  for (i = 0; i < sdpilpnnonz; i++)
1237  {
1238  slaterlprow[i] = sdpilprow[i];
1239  slaterlpcol[i] = sdpilpcol[i];
1240  slaterlpval[i] = sdpilpval[i];
1241  }
1242 
1243  /* add the new entries sum_j [(A_i)_jj], for this we have to iterate over the whole sdp-matrices (for all blocks), adding all diagonal entries */
1244  for (v = 0; v < sdpi->nvars; v++)
1245  {
1246  /* fill in all variables - filter out fixed variables below */
1247  slaterlprow[sdpilpnnonz + v] = nactivelpcons;/*lint !e679*/
1248  slaterlpcol[sdpilpnnonz + v] = v;/*lint !e679*/
1249  slaterlpval[sdpilpnnonz + v] = 0.0;/*lint !e679*/
1250  }
1251 
1252  for (b = 0; b < sdpi->nsdpblocks; b++)
1253  {
1254  for (v = 0; v < sdpi->sdpnblockvars[b]; v++)
1255  {
1256  if ( ! isFixed(sdpi, v) )
1257  {
1258  for (i = 0; i < sdpi->sdpnblockvarnonz[b][v]; i++)
1259  {
1260  if ( sdpi->sdprow[b][v][i] == sdpi->sdpcol[b][v][i] ) /* it is a diagonal entry */
1261  slaterlpval[sdpilpnnonz + sdpi->sdpvar[b][v]] += sdpi->sdpval[b][v][i];/*lint !e679*/
1262  }
1263  }
1264  }
1265  }
1266 
1267  /* iterate over all added LP-entries and remove all zeros or fixed variables (by shifting further variables) */
1268  nremovedslaterlpinds = 0;
1269  for (v = 0; v < sdpi->nvars; v++)
1270  {
1271  if ( isFixed(sdpi, v) || REALABS(slaterlpval[sdpilpnnonz + v]) <= sdpi->epsilon )/*lint !e679*/
1272  ++nremovedslaterlpinds;
1273  else
1274  {
1275  /* shift the entries */
1276  slaterlprow[sdpilpnnonz + v - nremovedslaterlpinds] = slaterlprow[sdpilpnnonz + v];/*lint !e679*/
1277  slaterlpcol[sdpilpnnonz + v - nremovedslaterlpinds] = slaterlpcol[sdpilpnnonz + v];/*lint !e679*/
1278  slaterlpval[sdpilpnnonz + v - nremovedslaterlpinds] = slaterlpval[sdpilpnnonz + v];/*lint !e679*/
1279  }
1280  }
1281 
1282  /* allocate memory for l/r-hs */
1283  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterlplhs, nactivelpcons + 1) );/*lint !e776*/
1284  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &slaterlprhs, nactivelpcons + 1) );/*lint !e776*/
1285 
1286  /* set the old entries to zero (if existing), as A_0 (including the LP-part) is removed because of the changed primal objective */
1287  for (i = 0; i < nactivelpcons; i++)
1288  {
1289  if ( SCIPsdpiSolverIsInfinity(sdpi->sdpisolver, sdpilplhs[i]) )
1290  slaterlplhs[i] = sdpilplhs[i];
1291  else
1292  slaterlplhs[i] = 0.0;
1293 
1294  if ( SCIPsdpiSolverIsInfinity(sdpi->sdpisolver, sdpilprhs[i]) )
1295  slaterlprhs[i] = sdpilprhs[i];
1296  else
1297  slaterlprhs[i] = 0.0;
1298  }
1299 
1300  /* add the new ones */
1301  slaterlplhs[nactivelpcons] = 1.0;
1302  slaterlprhs[nactivelpcons] = SCIPsdpiSolverInfinity(sdpi->sdpisolver);
1303 
1304  /* determine number of LP constraints */
1305  if ( nremovedslaterlpinds < sdpi->nvars )
1306  slaternactivelpcons = nactivelpcons + 1;
1307  else
1308  slaternactivelpcons = nactivelpcons; /* in this case there are no entries in the last row, so we skip it */
1309 
1310  /* copy the varbound arrays to change all finite varbounds to zero */
1311  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &slaterlb, sdpilb, sdpi->nvars);
1312  DUPLICATE_ARRAY_NULL(sdpi->blkmem, &slaterub, sdpiub, sdpi->nvars);
1313 
1314  /* set all finite varbounds to zero */
1315  slaternremovedvarbounds = 0;
1316  for (v = 0; v < sdpi->nvars; v++)
1317  {
1318  if ( slaterlb[v] > -1 * SCIPsdpiSolverInfinity(sdpi->sdpisolver) )
1319  {
1320  slaterlb[v] = 0.0;
1321  slaternremovedvarbounds++;
1322  }
1323  if ( slaterub[v] < SCIPsdpiSolverInfinity(sdpi->sdpisolver) )
1324  {
1325  slaterub[v] = 0.0;
1326  slaternremovedvarbounds++;
1327  }
1328  }
1329 
1330  /* if all variables have finite upper and lower bounds these add variables to every constraint of the
1331  * primal problem that allow us to make the problem feasible for every primal matrix X, so the primal
1332  * Slater condition holds */
1333  if ( slaternremovedvarbounds == 2 * sdpi->nvars )
1334  {
1335  if ( rootnodefailed )
1336  {
1337  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problem holds since all variables have finite upper and lower bounds.\n");
1338  }
1339  else
1340  SCIPdebugMessage("Slater condition for primal problem for SDP %d fulfilled since all variables have finite upper and lower bounds.\n", sdpi->sdpid);/*lint !e687*/
1341  sdpi->primalslater = SCIP_SDPSLATER_HOLDS;
1342  }
1343  else
1344  {
1345  /* solve the problem to check Slater condition for primal of original problem */
1346  SCIP_CALL( SCIPsdpiSolverLoadAndSolve(sdpi->sdpisolver, sdpi->nvars, sdpi->obj, slaterlb, slaterub,
1347  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, 0, NULL, NULL, NULL, NULL,
1348  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
1349  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, slaternactivelpcons, slaterlplhs, slaterlprhs,
1350  sdpilpnnonz + sdpi->nvars - nremovedslaterlpinds, slaterlprow, slaterlpcol, slaterlpval, NULL, NULL, NULL, NULL,
1351  NULL, NULL, NULL, NULL, NULL, SCIP_SDPSOLVERSETTING_UNSOLVED, timelimit, sdpi->usedsdpitime) );
1352 
1353  /* analyze result */
1354  if ( SCIPsdpiSolverIsOptimal(sdpi->sdpisolver) )
1355  {
1356  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) );
1357 
1358  if ( objval > - sdpi->feastol)
1359  {
1360  if ( rootnodefailed )
1361  {
1362  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problem not fulfilled (smallest eigenvalue %g).\n", - objval);
1363  }
1364  else if ( sdpi->slatercheck == 2 )
1365  {
1366  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problem for SDP %d not fulfilled "
1367  "(smallest eigenvalue %g) - expect numerical trouble or infeasible problem.\n",sdpi->sdpid, - objval);
1368  }
1369  sdpi->primalslater = SCIP_SDPSLATER_NOT;
1370  }
1371  else
1372  {
1373  if ( rootnodefailed )
1374  {
1375  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problem fulfilled (smallest eigenvalue %g).\n", - objval);
1376  }
1377  else
1378  SCIPdebugMessage("Slater condition for primal problem of SDP %d is fulfilled (smallest eigenvalue %g).\n", sdpi->sdpid, - objval);/*lint !e687*/
1379  sdpi->primalslater = SCIP_SDPSLATER_HOLDS;
1380  }
1381  }
1382  else if ( SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver) )
1383  {
1384  if ( rootnodefailed )
1385  {
1386  SCIPmessagePrintInfo(sdpi->messagehdlr, "Primal Slater condition shows infeasibility.\\n");
1387  }
1388  else if ( sdpi->slatercheck == 2 )
1389  {
1390  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problem for SDP %d not fulfilled "
1391  "(smallest eigenvalue has to be negative, so primal problem is infeasible; if the dual slater condition holds,"
1392  "this means, that the original (dual) problem is unbounded).\n", sdpi->sdpid);
1393  }
1394  sdpi->primalslater = SCIP_SDPSLATER_NOT;
1395  }
1396  else if ( SCIPsdpiSolverIsPrimalUnbounded(sdpi->sdpisolver) )
1397  {
1398  if ( rootnodefailed )
1399  {
1400  SCIPmessagePrintInfo(sdpi->messagehdlr, "Slater condition for primal problems holds sunce smallest eigenvalue maximization problem is unbounded.\n");
1401  }
1402  else
1403  SCIPdebugMessage("Slater condition for primal problem for SDP %d fulfilled, smallest eigenvalue maximization problem unbounded.\n", sdpi->sdpid);/*lint !e687*/
1404  sdpi->primalslater = SCIP_SDPSLATER_HOLDS;
1405  }
1406  else
1407  {
1408  assert( ! SCIPsdpiSolverIsOptimal(sdpi->sdpisolver) && ! SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver) && ! SCIPsdpiSolverIsPrimalUnbounded(sdpi->sdpisolver) );
1409 
1410  if ( rootnodefailed )
1411  {
1412  SCIPmessagePrintInfo(sdpi->messagehdlr, "Unable to check Slater condition for primal problem.\n");
1413  }
1414  else if ( sdpi->slatercheck == 2 )
1415  SCIPmessagePrintInfo(sdpi->messagehdlr, "Unable to check Slater condition for primal problem, could not solve auxilliary problem.\n");
1416  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
1417  }
1418  }
1419 
1420  /* free all memory */
1421  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterub, sdpi->nvars);/*lint !e737*/
1422  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlb, sdpi->nvars);/*lint !e737*/
1423  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlprhs, nactivelpcons + 1);/*lint !e737*//*lint !e776*/
1424  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlplhs, nactivelpcons + 1);/*lint !e737*//*lint !e776*/
1425  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlpval, sdpilpnnonz + sdpi->nvars);/*lint !e737*//*lint !e776*/
1426  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlpcol, sdpilpnnonz + sdpi->nvars);/*lint !e737*//*lint !e776*/
1427  BMSfreeBlockMemoryArray(sdpi->blkmem, &slaterlprow, sdpilpnnonz + sdpi->nvars);/*lint !e737*//*lint !e776*/
1428 
1429  return SCIP_OKAY;
1430 }
1431 
1432 /*
1433  * Miscellaneous Methods
1434  */
1435 
1442  void
1443  )
1444 {
1445  return SCIPsdpiSolverGetSolverName();
1446 }
1447 
1450  void
1451  )
1452 {
1453  return SCIPsdpiSolverGetSolverDesc();
1454 }
1455 
1463  SCIP_SDPI* sdpi
1464  )
1465 {
1466  return SCIPsdpiSolverGetSolverPointer(sdpi->sdpisolver);
1467 }
1468 
1471  void
1472  )
1473 {
1475 }
1476 
1479  void
1480  )
1481 {
1483 }
1484 
1488 /*
1489  * SDPI Creation and Destruction Methods
1490  */
1491 
1496 SCIP_RETCODE SCIPsdpiCreate(
1497  SCIP_SDPI** sdpi,
1498  SCIP_MESSAGEHDLR* messagehdlr,
1499  BMS_BLKMEM* blkmem,
1500  BMS_BUFMEM* bufmem
1501  )
1502 {
1503  assert( sdpi != NULL );
1504  assert( blkmem != NULL );
1505 
1506  SCIPdebugMessage("Calling SCIPsdpiCreate\n");
1507 
1508  BMS_CALL( BMSallocBlockMemory(blkmem, sdpi) );
1509 
1510  SCIP_CALL( SCIPsdpiSolverCreate(&((*sdpi)->sdpisolver), messagehdlr, blkmem, bufmem) );
1511 
1512  (*sdpi)->messagehdlr = messagehdlr;
1513  (*sdpi)->blkmem = blkmem;
1514  (*sdpi)->bufmem = bufmem;
1515  (*sdpi)->sdpid = 1;
1516  (*sdpi)->niterations = 0;
1517  (*sdpi)->opttime = 0.0;
1518  (*sdpi)->nsdpcalls = 0;
1519  (*sdpi)->nvars = 0;
1520  (*sdpi)->maxnvars = 0;
1521  (*sdpi)->nsdpblocks = 0;
1522  (*sdpi)->maxnsdpblocks = 0;
1523  (*sdpi)->sdpconstnnonz = 0;
1524  (*sdpi)->sdpnnonz = 0;
1525  (*sdpi)->nlpcons = 0;
1526  (*sdpi)->maxnlpcons = 0;
1527  (*sdpi)->lpnnonz = 0;
1528  (*sdpi)->maxlpnnonz = 0;
1529  (*sdpi)->slatercheck = 0;
1530  (*sdpi)->solved = FALSE;
1531  (*sdpi)->penalty = FALSE;
1532  (*sdpi)->infeasible = FALSE;
1533  (*sdpi)->allfixed = FALSE;
1534 
1535  (*sdpi)->obj = NULL;
1536  (*sdpi)->lb = NULL;
1537  (*sdpi)->ub = NULL;
1538  (*sdpi)->sdpilb = NULL;
1539  (*sdpi)->sdpiub = NULL;
1540  (*sdpi)->sdpblocksizes = NULL;
1541  (*sdpi)->sdpnblockvars = NULL;
1542  (*sdpi)->maxsdpnblockvars = NULL;
1543  (*sdpi)->sdpconstnblocknonz = NULL;
1544  (*sdpi)->maxsdpconstnblocknonz = NULL;
1545  (*sdpi)->sdpconstrow = NULL;
1546  (*sdpi)->sdpconstcol = NULL;
1547  (*sdpi)->sdpconstval = NULL;
1548  (*sdpi)->sdpnblockvarnonz = NULL;
1549  (*sdpi)->sdpvar = NULL;
1550  (*sdpi)->sdprow = NULL;
1551  (*sdpi)->sdpcol = NULL;
1552  (*sdpi)->sdpval = NULL;
1553  (*sdpi)->maxsdpstore = 0;
1554  (*sdpi)->sdprowstore = NULL;
1555  (*sdpi)->sdpcolstore = NULL;
1556  (*sdpi)->sdpvalstore = NULL;
1557 
1558  (*sdpi)->lplhs = NULL;
1559  (*sdpi)->lprhs = NULL;
1560  (*sdpi)->lprow = NULL;
1561  (*sdpi)->lpcol = NULL;
1562  (*sdpi)->lpval = NULL;
1563 
1564  (*sdpi)->sdpilplhs = NULL;
1565  (*sdpi)->sdpilprhs = NULL;
1566  (*sdpi)->sdpilprow = NULL;
1567  (*sdpi)->sdpilpcol = NULL;
1568  (*sdpi)->sdpilpval = NULL;
1569 
1570  (*sdpi)->epsilon = DEFAULT_EPSILON;
1571  (*sdpi)->gaptol = DEFAULT_SDPSOLVERGAPTOL;
1572  (*sdpi)->feastol = DEFAULT_FEASTOL;
1573  (*sdpi)->penaltyparam = DEFAULT_PENALTYPARAM;
1574  (*sdpi)->maxpenaltyparam = DEFAULT_MAXPENALTYPARAM;
1575  (*sdpi)->npenaltyincr = DEFAULT_NPENALTYINCR;
1576  (*sdpi)->bestbound = -SCIPsdpiSolverInfinity((*sdpi)->sdpisolver);
1577  (*sdpi)->primalslater = SCIP_SDPSLATER_NOINFO;
1578  (*sdpi)->dualslater = SCIP_SDPSLATER_NOINFO;
1579  (*sdpi)->solvedonevarsdp = SCIP_ONEVAR_UNSOLVED;
1580  (*sdpi)->onevarsdpobjval = SCIP_INVALID;
1581  (*sdpi)->onevarsdpoptval = SCIP_INVALID;
1582  (*sdpi)->onevarsdpidx = -1;
1583 
1584  (*sdpi)->nallfixed = 0;
1585  (*sdpi)->ninfeasible = 0;
1586  (*sdpi)->nonevarsdp = 0;
1587 
1588  SCIP_CALL( SDPIclockCreate(&(*sdpi)->usedsdpitime) );
1589 
1590  return SCIP_OKAY;
1591 }
1592 
1594 SCIP_RETCODE SCIPsdpiFree(
1595  SCIP_SDPI** sdpi
1596  )
1597 {
1598  int i;
1599 
1600  SCIPdebugMessage("Calling SCIPsdpiFree ...\n");
1601 
1602  assert( sdpi != NULL );
1603  assert( *sdpi != NULL );
1604 
1605  /* free clock */
1606  SDPIclockFree(&(*sdpi)->usedsdpitime);
1607 
1608  /* free the LP part */
1609  assert( 0 <= (*sdpi)->lpnnonz && (*sdpi)->lpnnonz <= (*sdpi)->maxlpnnonz );
1610  assert( 0 <= (*sdpi)->nlpcons && (*sdpi)->nlpcons <= (*sdpi)->maxnlpcons );
1611 
1612  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpilprow), (*sdpi)->maxlpnnonz);
1613  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpilpcol), (*sdpi)->maxlpnnonz);
1614  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpilpval), (*sdpi)->maxlpnnonz);
1615  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpilprhs), (*sdpi)->maxnlpcons);
1616  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpilplhs), (*sdpi)->maxnlpcons);
1617 
1618  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lpval), (*sdpi)->maxlpnnonz);
1619  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lpcol), (*sdpi)->maxlpnnonz);
1620  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lprow), (*sdpi)->maxlpnnonz);
1621  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lprhs), (*sdpi)->maxnlpcons);
1622  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lplhs), (*sdpi)->maxnlpcons);
1623 
1624  /* free the individual SDP nonzeros */
1625  assert( 0 <= (*sdpi)->nsdpblocks && (*sdpi)->nsdpblocks <= (*sdpi)->maxnsdpblocks );
1626  for (i = 0; i < (*sdpi)->maxnsdpblocks; i++)
1627  {
1628  assert( 0 <= (*sdpi)->sdpnblockvars[i] && (*sdpi)->sdpnblockvars[i] <= (*sdpi)->maxsdpnblockvars[i] );
1629  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval[i]), (*sdpi)->maxsdpnblockvars[i]);
1630  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow[i]), (*sdpi)->maxsdpnblockvars[i]);
1631  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol[i]), (*sdpi)->maxsdpnblockvars[i]);
1632  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpvar[i]), (*sdpi)->maxsdpnblockvars[i]);
1633  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvarnonz[i]), (*sdpi)->maxsdpnblockvars[i]);
1634  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstval[i]), (*sdpi)->maxsdpconstnblocknonz[i]);
1635  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstrow[i]), (*sdpi)->maxsdpconstnblocknonz[i]);
1636  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstcol[i]), (*sdpi)->maxsdpconstnblocknonz[i]);
1637  }
1638 
1639  /* free the rest */
1640  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvarnonz), (*sdpi)->maxnsdpblocks);
1641  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstnblocknonz), (*sdpi)->maxnsdpblocks);
1642  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->maxsdpconstnblocknonz), (*sdpi)->maxnsdpblocks);
1643  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpval), (*sdpi)->maxnsdpblocks);
1644  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpcol), (*sdpi)->maxnsdpblocks);
1645  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdprow), (*sdpi)->maxnsdpblocks);
1646  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpvar), (*sdpi)->maxnsdpblocks);
1647  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstval), (*sdpi)->maxnsdpblocks);
1648  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstcol), (*sdpi)->maxnsdpblocks);
1649  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpconstrow), (*sdpi)->maxnsdpblocks);
1650  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpnblockvars), (*sdpi)->maxnsdpblocks);
1651  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->maxsdpnblockvars), (*sdpi)->maxnsdpblocks);
1652  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpblocksizes), (*sdpi)->maxnsdpblocks);
1653 
1654  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &(*sdpi)->sdpvalstore, (*sdpi)->maxsdpstore);
1655  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &(*sdpi)->sdpcolstore, (*sdpi)->maxsdpstore);
1656  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &(*sdpi)->sdprowstore, (*sdpi)->maxsdpstore);
1657 
1658  assert( 0 <= (*sdpi)->nvars && (*sdpi)->nvars <= (*sdpi)->maxnvars );
1659  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpiub), (*sdpi)->maxnvars);/*lint !e737*/
1660  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->sdpilb), (*sdpi)->maxnvars);/*lint !e737*/
1661  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->ub), (*sdpi)->maxnvars);/*lint !e737*/
1662  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->lb), (*sdpi)->maxnvars);/*lint !e737*/
1663  BMSfreeBlockMemoryArrayNull((*sdpi)->blkmem, &((*sdpi)->obj), (*sdpi)->maxnvars);/*lint !e737*/
1664 
1665  /* free the solver */
1666  SCIP_CALL( SCIPsdpiSolverFree(&((*sdpi)->sdpisolver)) );
1667 
1668  BMSfreeBlockMemory((*sdpi)->blkmem, sdpi);
1669 
1670  return SCIP_OKAY;
1671 }
1672 
1677 SCIP_RETCODE SCIPsdpiClone(
1678  SCIP_SDPI* oldsdpi,
1679  SCIP_SDPI* newsdpi
1680  )
1681 {
1682  BMS_BLKMEM* blkmem;
1683  int nvars;
1684  int nsdpblocks;
1685  int lpnnonz;
1686  int cnt = 0;
1687  int b;
1688  int v;
1689 
1690  assert( oldsdpi != NULL );
1691 
1692  SCIPdebugMessage("Cloning SDPI %d\n", oldsdpi->sdpid);
1693 
1694  /* general data */
1695  blkmem = oldsdpi->blkmem;
1696  nvars = oldsdpi->nvars;
1697  nsdpblocks = oldsdpi->nsdpblocks;
1698  lpnnonz = oldsdpi->lpnnonz;
1699 
1700  BMS_CALL( BMSallocBlockMemory(blkmem, &newsdpi) );
1701 
1702  SCIP_CALL( SCIPsdpiSolverCreate(&(newsdpi->sdpisolver), oldsdpi->messagehdlr, oldsdpi->blkmem, oldsdpi->bufmem) ); /* create new SDP-Solver Interface */
1703 
1704  newsdpi->messagehdlr = oldsdpi->messagehdlr;
1705  newsdpi->blkmem = blkmem;
1706  newsdpi->nvars = nvars;
1707  newsdpi->maxnvars = nvars;
1708 
1709  assert( 0 <= oldsdpi->nvars && oldsdpi->nvars <= oldsdpi->maxnvars );
1710  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->obj), oldsdpi->obj, nvars) );
1711  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lb), oldsdpi->lb, nvars) );
1712  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->ub), oldsdpi->ub, nvars) );
1713  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpilb), nvars) );
1714  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpiub), nvars) );
1715 
1716  newsdpi->nsdpblocks = nsdpblocks;
1717  newsdpi->maxnsdpblocks = nsdpblocks;
1718 
1719  assert( 0 <= oldsdpi->nsdpblocks && oldsdpi->nsdpblocks <= oldsdpi->maxnsdpblocks );
1720  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpblocksizes), oldsdpi->sdpblocksizes, nsdpblocks) );
1721  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvars), oldsdpi->sdpnblockvars, nsdpblocks) );
1722  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->maxsdpnblockvars), oldsdpi->sdpnblockvars, nsdpblocks) );
1723 
1724  /* constant SDP data */
1725  newsdpi->sdpconstnnonz = oldsdpi->sdpconstnnonz;
1726 
1727  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstnblocknonz), oldsdpi->sdpconstnblocknonz, nsdpblocks) );
1728  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->maxsdpconstnblocknonz), oldsdpi->sdpconstnblocknonz, nsdpblocks) );
1729  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstrow), nsdpblocks) );
1730  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstcol), nsdpblocks) );
1731  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpconstval), nsdpblocks) );
1732 
1733  for (b = 0; b < nsdpblocks; b++)
1734  {
1735  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstrow[b]), oldsdpi->sdpconstrow[b], oldsdpi->sdpconstnblocknonz[b]) );
1736  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstcol[b]), oldsdpi->sdpconstcol[b], oldsdpi->sdpconstnblocknonz[b]) );
1737  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpconstval[b]), oldsdpi->sdpconstval[b], oldsdpi->sdpconstnblocknonz[b]) );
1738  }
1739 
1740  /* SDP data */
1741  newsdpi->sdpnnonz = oldsdpi->sdpnnonz;
1742  newsdpi->maxsdpstore = oldsdpi->sdpnnonz;
1743 
1744  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvarnonz), nsdpblocks) );
1745  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpvar), nsdpblocks) );
1746  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdprow), nsdpblocks) );
1747  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpcol), nsdpblocks) );
1748  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpval), nsdpblocks) );
1749 
1750  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdprowstore), newsdpi->maxsdpstore) );
1751  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpcolstore), newsdpi->maxsdpstore) );
1752  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpvalstore), newsdpi->maxsdpstore) );
1753 
1754  for (b = 0; b < nsdpblocks; b++)
1755  {
1756  assert( 0 <= oldsdpi->sdpnblockvars[b] && oldsdpi->sdpnblockvars[b] <= oldsdpi->maxsdpnblockvars[b] );
1757  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpnblockvarnonz[b]), oldsdpi->sdpnblockvarnonz[b], oldsdpi->sdpnblockvars[b]) );
1758  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->sdpvar[b]), oldsdpi->sdpvar[b], oldsdpi->sdpnblockvars[b]) );
1759 
1760  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdprow[b]), oldsdpi->sdpnblockvars[b]) );
1761  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpcol[b]), oldsdpi->sdpnblockvars[b]) );
1762  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpval[b]), oldsdpi->sdpnblockvars[b]) );
1763 
1764  /* set pointers into storage */
1765  for (v = 0; v < newsdpi->sdpnblockvars[b]; ++v)
1766  {
1767  newsdpi->sdprow[b][v] = &newsdpi->sdprowstore[cnt];
1768  newsdpi->sdpcol[b][v] = &newsdpi->sdpcolstore[cnt];
1769  newsdpi->sdpval[b][v] = &newsdpi->sdpvalstore[cnt];
1770  cnt += newsdpi->sdpnblockvarnonz[b][v];
1771  }
1772  assert( cnt <= newsdpi->maxsdpstore );
1773  }
1774 
1775  /* LP data */
1776  newsdpi->nlpcons = oldsdpi->nlpcons;
1777  newsdpi->maxnlpcons = oldsdpi->nlpcons;
1778 
1779  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lplhs), oldsdpi->lplhs, oldsdpi->nlpcons) );
1780  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lprhs), oldsdpi->lprhs, oldsdpi->nlpcons) );
1781 
1782  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpilplhs), oldsdpi->nlpcons) );
1783  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpilprhs), oldsdpi->nlpcons) );
1784 
1785  newsdpi->lpnnonz = lpnnonz;
1786  newsdpi->maxlpnnonz = lpnnonz;
1787 
1788  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lprow), oldsdpi->lprow, lpnnonz) );
1789  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lpcol), oldsdpi->lpcol, lpnnonz) );
1790  BMS_CALL( BMSduplicateBlockMemoryArray(blkmem, &(newsdpi->lpval), oldsdpi->lpval, lpnnonz) );
1791 
1792  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpilprow), lpnnonz) );
1793  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpilpcol), lpnnonz) );
1794  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &(newsdpi->sdpilpval), lpnnonz) );
1795 
1796  /* other data */
1797  newsdpi->solved = FALSE; /* as we don't copy the sdpisolver, this needs to be set to false */
1798  newsdpi->penalty = FALSE; /* all things about SDP-solutions are set to false as well, as we didn't solve the problem */
1799  newsdpi->infeasible = FALSE;
1800  newsdpi->allfixed = FALSE;
1801  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 */
1802  newsdpi->epsilon = oldsdpi->epsilon;
1803  newsdpi->gaptol = oldsdpi->gaptol;
1804  newsdpi->feastol = oldsdpi->feastol;
1805 
1806  newsdpi->solvedonevarsdp = SCIP_ONEVAR_UNSOLVED;
1807  newsdpi->onevarsdpobjval = SCIP_INVALID;
1808  newsdpi->onevarsdpoptval = SCIP_INVALID;
1809  newsdpi->onevarsdpidx = -1;
1810 
1811  newsdpi->nallfixed = 0;
1812  newsdpi->ninfeasible = 0;
1813  newsdpi->nonevarsdp = 0;
1814 
1815  SCIP_CALL( SDPIclockCreate(&newsdpi->usedsdpitime) );
1816 
1817  return SCIP_OKAY;
1818 }
1819 
1823 /*
1824  * Modification Methods
1825  */
1826 
1836 SCIP_RETCODE SCIPsdpiLoadSDP(
1837  SCIP_SDPI* sdpi,
1838  int nvars,
1839  SCIP_Real* obj,
1840  SCIP_Real* lb,
1841  SCIP_Real* ub,
1842  int nsdpblocks,
1843  int* sdpblocksizes,
1844  int* sdpnblockvars,
1845  int sdpconstnnonz,
1846  int* sdpconstnblocknonz,
1848  int** sdpconstrow,
1849  int** sdpconstcol,
1850  SCIP_Real** sdpconstval,
1851  int sdpnnonz,
1852  int** sdpnblockvarnonz,
1854  int** sdpvar,
1856  int*** sdprow,
1859  int*** sdpcol,
1860  SCIP_Real*** sdpval,
1862  int nlpcons,
1863  SCIP_Real* lplhs,
1864  SCIP_Real* lprhs,
1865  int lpnnonz,
1866  int* lprow,
1867  int* lpcol,
1868  SCIP_Real* lpval
1869  )
1870 {
1871  int cnt = 0;
1872  int v;
1873  int b;
1874 #ifdef SCIP_DEBUG
1875  int i;
1876 #endif
1877 
1878  SCIPdebugMessage("Calling SCIPsdpiLoadSDP (%d) ...\n", sdpi->sdpid);
1879 
1880  assert( sdpi != NULL );
1881  assert( nvars >= 0 );
1882  assert( obj != NULL );
1883  assert( lb != NULL );
1884  assert( ub != NULL );
1885 
1886 #ifdef SCIP_DEBUG
1887  if ( sdpconstnnonz > 0 || sdpnnonz > 0 || nsdpblocks > 0 )
1888  {
1889  assert( sdpblocksizes != NULL );
1890  assert( sdpnblockvars != NULL );
1891  assert( nsdpblocks > 0 );
1892  assert( sdpconstnblocknonz != NULL );
1893  assert( sdpnblockvarnonz != NULL );
1894 
1895  if ( sdpconstnnonz > 0 )
1896  {
1897  assert( sdpconstrow != NULL );
1898  assert( sdpconstcol != NULL );
1899  assert( sdpconstval != NULL );
1900 
1901  for (i = 0; i < nsdpblocks; i++)
1902  {
1903  if ( sdpconstnblocknonz[i] > 0 )
1904  {
1905  assert( sdpconstrow[i] != NULL );
1906  assert( sdpconstcol[i] != NULL );
1907  assert( sdpconstval[i] != NULL );
1908  }
1909  }
1910  }
1911 
1912  if ( sdpnnonz > 0 )
1913  {
1914  assert( sdprow != NULL );
1915  assert( sdpcol != NULL );
1916  assert( sdpval != NULL );
1917 
1918  for (i = 0; i < nsdpblocks; i++)
1919  {
1920  assert( sdpcol[i] != NULL );
1921  assert( sdprow[i] != NULL );
1922  assert( sdpval[i] != NULL );
1923 
1924  for (v = 0; v < sdpnblockvars[i]; v++)
1925  {
1926  if ( sdpnblockvarnonz[i][v] > 0 )
1927  {
1928  assert( sdpcol[i][v] != NULL );
1929  assert( sdprow[i][v] != NULL );
1930  assert( sdpval[i][v] != NULL );
1931  }
1932  }
1933  }
1934  }
1935  }
1936  for (i = 0; i < nvars; ++i)
1937  {
1938  assert( lb[i] < SCIPsdpiInfinity(sdpi) ); /* lower bound should not be infinity */
1939  assert( ub[i] > -SCIPsdpiInfinity(sdpi) ); /* upper bound should not be - infinity */
1940  }
1941 #endif
1942 
1943  assert( nlpcons == 0 || lplhs != NULL );
1944  assert( nlpcons == 0 || lprhs != NULL );
1945  assert( lpnnonz == 0 || lprow != NULL );
1946  assert( lpnnonz == 0 || lpcol != NULL );
1947  assert( lpnnonz == 0 || lpval != NULL );
1948 
1949  /* ensure memory */
1950  SCIP_CALL( ensureBoundDataMemory(sdpi, nvars) );
1951  SCIP_CALL( ensureLPDataMemory(sdpi, nlpcons, lpnnonz) );
1952  SCIP_CALL( ensureSDPDataMemory(sdpi, nsdpblocks, sdpnblockvars, sdpnblockvarnonz, sdpconstnblocknonz, sdpnnonz) );
1953 
1954  /* copy data in arrays */
1955  BMScopyMemoryArray(sdpi->obj, obj, nvars);
1956  BMScopyMemoryArray(sdpi->lb, lb, nvars);
1957  BMScopyMemoryArray(sdpi->ub, ub, nvars);
1958  BMScopyMemoryArray(sdpi->sdpblocksizes, sdpblocksizes, nsdpblocks);
1959  BMScopyMemoryArray(sdpi->sdpnblockvars, sdpnblockvars, nsdpblocks);
1960  BMScopyMemoryArray(sdpi->sdpconstnblocknonz, sdpconstnblocknonz, nsdpblocks);
1961 
1962  for (b = 0; b < nsdpblocks; ++b)
1963  {
1964 #ifndef NDEBUG
1965  /* make sure that we have a lower triangular matrix */
1966  for (v = 0; v < sdpi->sdpconstnblocknonz[b]; ++v)
1967  assert( sdpconstrow[b][v] >= sdpconstcol[b][v] );
1968 #endif
1969 
1970  BMScopyMemoryArray(sdpi->sdpnblockvarnonz[b], sdpnblockvarnonz[b], sdpnblockvars[b]);
1971  BMScopyMemoryArray(sdpi->sdpvar[b], sdpvar[b], sdpnblockvars[b]);
1972 
1973  if ( sdpconstnblocknonz[b] > 0 )
1974  {
1975  BMScopyMemoryArray(sdpi->sdpconstval[b], sdpconstval[b], sdpconstnblocknonz[b]);
1976  BMScopyMemoryArray(sdpi->sdpconstcol[b], sdpconstcol[b], sdpconstnblocknonz[b]);
1977  BMScopyMemoryArray(sdpi->sdpconstrow[b], sdpconstrow[b], sdpconstnblocknonz[b]);
1978  }
1979 
1980  assert( 0 <= sdpnblockvars[b] && sdpnblockvars[b] <= nvars );
1981  for (v = 0; v < sdpi->sdpnblockvars[b]; v++)
1982  {
1983 #ifndef NDEBUG
1984  int j;
1985 
1986  /* make sure that we have a lower triangular matrix */
1987  for (j = 0; j < sdpi->sdpnblockvarnonz[b][v]; ++j)
1988  assert( sdprow[b][v][j] >= sdpcol[b][v][j] );
1989 #endif
1990  assert( 0 <= sdpvar[b][v] && sdpvar[b][v] < nvars );
1991 
1992  assert( sdpi->sdpvalstore != NULL );
1993  assert( sdpi->sdpcolstore != NULL );
1994  assert( sdpi->sdprowstore != NULL );
1995 
1996  BMScopyMemoryArray(&sdpi->sdpvalstore[cnt], sdpval[b][v], sdpnblockvarnonz[b][v]);
1997  BMScopyMemoryArray(&sdpi->sdpcolstore[cnt], sdpcol[b][v], sdpnblockvarnonz[b][v]);
1998  BMScopyMemoryArray(&sdpi->sdprowstore[cnt], sdprow[b][v], sdpnblockvarnonz[b][v]);
1999  cnt += sdpnblockvarnonz[b][v];
2000  assert( cnt <= sdpnnonz );
2001  }
2002  }
2003 
2004  if ( nlpcons > 0 )
2005  {
2006  BMScopyMemoryArray(sdpi->lplhs, lplhs, nlpcons);
2007  BMScopyMemoryArray(sdpi->lprhs, lprhs, nlpcons);
2008  BMScopyMemoryArray(sdpi->lprow, lprow, lpnnonz);
2009  BMScopyMemoryArray(sdpi->lpcol, lpcol, lpnnonz);
2010  BMScopyMemoryArray(sdpi->lpval, lpval, lpnnonz);
2011  }
2012 
2013  /* set the general information */
2014  sdpi->nvars = nvars;
2015  sdpi->nsdpblocks = nsdpblocks;
2016 
2017  sdpi->sdpconstnnonz = sdpconstnnonz;
2018  sdpi->sdpnnonz = sdpnnonz;
2019 
2020  /* LP part */
2021  sdpi->lpnnonz = lpnnonz;
2022  sdpi->nlpcons = nlpcons;
2023 
2024  sdpi->solved = FALSE;
2025  sdpi->infeasible = FALSE;
2026  sdpi->allfixed = FALSE;
2027  sdpi->nsdpcalls = 0;
2028  sdpi->niterations = 0;
2029  sdpi->opttime = 0.0;
2030 
2031  return SCIP_OKAY;
2032 }
2033 
2038 SCIP_RETCODE SCIPsdpiAddLPRows(
2039  SCIP_SDPI* sdpi,
2040  int nrows,
2041  const SCIP_Real* lhs,
2042  const SCIP_Real* rhs,
2043  int nnonz,
2044  const int* row,
2046  const int* col,
2047  const SCIP_Real* val
2048  )
2049 {
2050  int i;
2051 
2052  SCIPdebugMessage("Adding %d LP-Constraints to SDP %d.\n", nrows, sdpi->sdpid);
2053 
2054  assert( sdpi != NULL );
2055 
2056  if ( nrows == 0 )
2057  return SCIP_OKAY; /* nothing to do in this case */
2058 
2059  assert( lhs != NULL );
2060  assert( rhs != NULL );
2061  assert( nnonz >= 0 );
2062  assert( row != NULL );
2063  assert( col != NULL );
2064  assert( val != NULL );
2065 
2066  /* speed up things if LP part is emtpy */
2067  if ( sdpi->nlpcons == 0 )
2068  {
2069  assert( sdpi->lpnnonz == 0 );
2070 
2071  SCIP_CALL( ensureLPDataMemory(sdpi, nrows, nnonz) );
2072  BMScopyMemoryArray(sdpi->lplhs, lhs, nrows);
2073  BMScopyMemoryArray(sdpi->lprhs, rhs, nrows);
2074  BMScopyMemoryArray(sdpi->lprow, row, nnonz);
2075  BMScopyMemoryArray(sdpi->lpcol, col, nnonz);
2076  BMScopyMemoryArray(sdpi->lpval, val, nnonz);
2077  sdpi->nlpcons = nrows;
2078  sdpi->lpnnonz = nnonz;
2079 
2080 #ifndef NDEBUG
2081  for (i = 0; i < nnonz; i++)
2082  {
2083  assert( 0 <= row[i] && row[i] < nrows );
2084  assert( 0 <= col[i] && col[i] < sdpi->nvars );
2085  }
2086 #endif
2087  }
2088  else
2089  {
2090  SCIP_CALL( ensureLPDataMemory(sdpi, sdpi->nlpcons + nrows, sdpi->lpnnonz + nnonz) );
2091  BMScopyMemoryArray(&(sdpi->lplhs[sdpi->nlpcons]), lhs, nrows);
2092  BMScopyMemoryArray(&(sdpi->lprhs[sdpi->nlpcons]), rhs, nrows);
2093 
2094  for (i = 0; i < nnonz; i++)
2095  {
2096  assert( 0 <= row[i] && row[i] < nrows );
2097 
2098  /* the new rows are added at the end, so the row indices are increased by the old number of LP-constraints */
2099  sdpi->lprow[sdpi->lpnnonz + i] = row[i] + sdpi->nlpcons; /*lint !e679*/
2100 
2101  assert( 0 <= col[i] && col[i] < sdpi->nvars ); /* only existing vars should be added to the LP-constraints */
2102  sdpi->lpcol[sdpi->lpnnonz + i] = col[i]; /*lint !e679*/
2103  sdpi->lpval[sdpi->lpnnonz + i] = val[i]; /*lint !e679*/
2104  }
2105 
2106  sdpi->nlpcons = sdpi->nlpcons + nrows;
2107  sdpi->lpnnonz = sdpi->lpnnonz + nnonz;
2108  }
2109 
2110  sdpi->solved = FALSE;
2111  sdpi->infeasible = FALSE;
2112  sdpi->nsdpcalls = 0;
2113  sdpi->niterations = 0;
2114  sdpi->opttime = 0.0;
2115 
2116  return SCIP_OKAY;
2117 }
2118 
2120 SCIP_RETCODE SCIPsdpiDelLPRows(
2121  SCIP_SDPI* sdpi,
2122  int firstrow,
2123  int lastrow
2124  )
2125 {
2126  int i;
2127  int deletedrows;
2128  int firstrowind;
2129  int lastrowind;
2130  int deletednonz;
2131 
2132  SCIPdebugMessage("Deleting rows %d to %d from SDP %d.\n", firstrow, lastrow, sdpi->sdpid);
2133 
2134  assert( sdpi != NULL );
2135  assert( firstrow >= 0 );
2136  assert( firstrow <= lastrow );
2137  assert( lastrow < sdpi->nlpcons );
2138 
2139  /* shorten the procedure if the whole LP-part is to be deleted */
2140  if (firstrow == 0 && lastrow == sdpi->nlpcons - 1)
2141  {
2142  sdpi->nlpcons = 0;
2143  sdpi->lpnnonz = 0;
2144 
2145  sdpi->solved = FALSE;
2146  sdpi->infeasible = FALSE;
2147  sdpi->allfixed = FALSE;
2148  sdpi->nsdpcalls = 0;
2149  sdpi->niterations = 0;
2150  sdpi->opttime = 0.0;
2151 
2152  return SCIP_OKAY;
2153  }
2154 
2155  deletedrows = lastrow - firstrow + 1; /*lint !e834*/
2156  deletednonz = 0;
2157 
2158  /* first delete the left- and right-hand-sides */
2159  for (i = lastrow + 1; i < sdpi->nlpcons; i++) /* shift all rhs after the deleted rows */
2160  {
2161  sdpi->lplhs[i - deletedrows] = sdpi->lplhs[i]; /*lint !e679*/
2162  sdpi->lprhs[i - deletedrows] = sdpi->lprhs[i]; /*lint !e679*/
2163  }
2164 
2165  /* for deleting and reordering the lpnonzeroes, the arrays first have to be sorted to have the rows to be deleted together */
2166  SCIPsortIntIntReal(sdpi->lprow, sdpi->lpcol, sdpi->lpval, sdpi->lpnnonz); /* sort all arrays by non-decreasing row indices */
2167 
2168  firstrowind = -1;
2169  /* iterate over the lprowind array to find the first index belonging to a row that should be deleted */
2170  for (i = 0; i < sdpi->lpnnonz; i++)
2171  {
2172  if (sdpi->lprow[i] >= firstrow && sdpi->lprow[i] <= lastrow) /* the and part makes sure that there actually were some nonzeroes in these rows */
2173  {
2174  firstrowind = i;
2175  lastrowind = i;
2176  i++; /*lint !e850*/
2177  break;
2178  }
2179  }
2180 
2181  if ( firstrowind > -1 ) /* if this is still -1 there are no nonzeroes for the given rows */
2182  {
2183  /* 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) */
2184  while (i < sdpi->lpnnonz && sdpi->lprow[i] <= lastrow)
2185  {
2186  lastrowind++; /*lint !e644*/
2187  i++;
2188  }
2189  deletednonz = lastrowind - firstrowind + 1; /*lint !e834*/
2190 
2191  /* finally shift all LP-array-entries after the deleted rows */
2192  for (i = lastrowind + 1; i < sdpi->lpnnonz; i++)
2193  {
2194  sdpi->lpcol[i - deletednonz] = sdpi->lpcol[i]; /*lint !e679*/
2195  /* all rowindices after the deleted ones have to be lowered to still have ongoing indices from 0 to nlpcons-1 */
2196  sdpi->lprow[i - deletednonz] = sdpi->lprow[i] - deletedrows; /*lint !e679*/
2197  sdpi->lpval[i - deletednonz] = sdpi->lpval[i]; /*lint !e679*/
2198  }
2199  }
2200 
2201  sdpi->nlpcons = sdpi->nlpcons - deletedrows;
2202  sdpi->lpnnonz = sdpi->lpnnonz - deletednonz;
2203 
2204  sdpi->solved = FALSE;
2205  sdpi->infeasible = FALSE;
2206  sdpi->allfixed = FALSE;
2207  sdpi->nsdpcalls = 0;
2208  sdpi->niterations = 0;
2209  sdpi->opttime = 0.0;
2210 
2211  return SCIP_OKAY;
2212 }
2213 
2215 SCIP_RETCODE SCIPsdpiDelLPRowset(
2216  SCIP_SDPI* sdpi,
2217  int* dstat
2220  )
2221 {
2222  int i;
2223  int oldnlpcons;
2224  int deletedrows;
2225 
2226  SCIPdebugMessage("Calling SCIPsdpiDelLPRowset for SDP %d.\n", sdpi->sdpid);
2227 
2228  assert( sdpi != NULL );
2229  assert( dstat != NULL );
2230 
2231  oldnlpcons = sdpi->nlpcons;
2232  deletedrows = 0;
2233 
2234  for (i = 0; i < oldnlpcons; i++)
2235  {
2236  if ( dstat[i] == 1 )
2237  {
2238  /* delete this row, it is shifted by - deletedrows, because in this problem the earlier rows have already been deleted */
2239  SCIP_CALL( SCIPsdpiDelLPRows(sdpi, i - deletedrows, i - deletedrows) );
2240  dstat[i] = -1;
2241  deletedrows++;
2242  }
2243  else
2244  dstat[i] = i - deletedrows;
2245  }
2246 
2247  sdpi->solved = FALSE;
2248  sdpi->infeasible = FALSE;
2249  sdpi->allfixed = FALSE;
2250  sdpi->nsdpcalls = 0;
2251  sdpi->niterations = 0;
2252  sdpi->opttime = 0.0;
2253 
2254  return SCIP_OKAY;
2255 }
2256 
2258 SCIP_RETCODE SCIPsdpiClear(
2259  SCIP_SDPI* sdpi
2260  )
2261 {
2262  int b;
2263  int v;
2264 
2265  assert( sdpi != NULL );
2266 
2267  SCIPdebugMessage("SCIPsdpiClear in SDP %d.\n", sdpi->sdpid);
2268 
2269  /* reset all counters */
2270  sdpi->nlpcons = 0;
2271  sdpi->lpnnonz = 0;
2272 
2273  for (b = 0; b < sdpi->nsdpblocks; ++b)
2274  {
2275  for (v = 0; v < sdpi->sdpnblockvars[b]; ++v)
2276  sdpi->sdpnblockvarnonz[b][v] = 0;
2277  sdpi->sdpnblockvars[b] = 0;
2278  sdpi->sdpconstnblocknonz[b] = 0;
2279  sdpi->sdpblocksizes[b] = 0;
2280  }
2281  sdpi->sdpconstnnonz = 0;
2282  sdpi->sdpnnonz = 0;
2283 
2284  sdpi->nsdpblocks = 0;
2285  sdpi->nvars = 0;
2286  sdpi->sdpid = 1;
2287  SCIP_CALL( SCIPsdpiSolverResetCounter(sdpi->sdpisolver) );
2288 
2289  return SCIP_OKAY;
2290 }
2291 
2293 SCIP_RETCODE SCIPsdpiChgObj(
2294  SCIP_SDPI* sdpi,
2295  int nvars,
2296  const int* ind,
2297  const SCIP_Real* obj
2298  )
2299 {
2300  int i;
2301 
2302  SCIPdebugMessage("Changing %d objective coefficients in SDP %d\n", nvars, sdpi->sdpid);
2303 
2304  assert( sdpi != NULL );
2305  assert( ind != NULL );
2306  assert( obj != NULL );
2307 
2308  for (i = 0; i < nvars; i++)
2309  {
2310  assert( 0 <= ind[i] && ind[i] < sdpi->nvars );
2311  sdpi->obj[ind[i]] = obj[i];
2312  }
2313 
2314  sdpi->solved = FALSE;
2315  sdpi->nsdpcalls = 0;
2316  sdpi->niterations = 0;
2317  sdpi->opttime = 0.0;
2318 
2319  return SCIP_OKAY;
2320 }
2321 
2323 SCIP_RETCODE SCIPsdpiChgBounds(
2324  SCIP_SDPI* sdpi,
2325  int nvars,
2326  const int* ind,
2327  const SCIP_Real* lb,
2328  const SCIP_Real* ub
2329  )
2330 {
2331  int i;
2332 
2333  SCIPdebugMessage("Changing %d variable bounds in SDP %d\n", nvars, sdpi->sdpid);
2334 
2335  assert( sdpi != NULL );
2336  assert( ind != NULL );
2337  assert( lb != NULL );
2338  assert( ub != NULL );
2339 
2340  for (i = 0; i < nvars; i++)
2341  {
2342  assert( 0 <= ind[i] && ind[i] < sdpi->nvars );
2343  sdpi->lb[ind[i]] = lb[i];
2344  sdpi->ub[ind[i]] = ub[i];
2345  }
2346 
2347  sdpi->solved = FALSE;
2348  sdpi->infeasible = FALSE;
2349  sdpi->allfixed = FALSE;
2350  sdpi->nsdpcalls = 0;
2351  sdpi->niterations = 0;
2352  sdpi->opttime = 0.0;
2353 
2354  return SCIP_OKAY;
2355 }
2356 
2359  SCIP_SDPI* sdpi,
2360  int nrows,
2361  const int* ind,
2362  const SCIP_Real* lhs,
2363  const SCIP_Real* rhs
2364  )
2365 {
2366  int i;
2367 
2368  SCIPdebugMessage("Changing %d left and right hand sides of SDP %d\n", nrows, sdpi->sdpid);
2369 
2370  assert( sdpi != NULL );
2371  assert( 0 <= nrows && nrows <= sdpi->nlpcons );
2372  assert( ind != NULL );
2373  assert( lhs != NULL );
2374  assert( rhs != NULL );
2375 
2376  for (i = 0; i < nrows; i++)
2377  {
2378  assert( ind[i] >= 0 );
2379  assert( ind[i] < sdpi->nlpcons );
2380  sdpi->lplhs[ind[i]] = lhs[i];
2381  sdpi->lprhs[ind[i]] = rhs[i];
2382  }
2383 
2384  sdpi->solved = FALSE;
2385  sdpi->infeasible = FALSE;
2386  sdpi->allfixed = FALSE;
2387  sdpi->nsdpcalls = 0;
2388  sdpi->niterations = 0;
2389  sdpi->opttime = 0.0;
2390 
2391  return SCIP_OKAY;
2392 }
2393 
2394 
2395 /*
2396  * Data Accessing Methods
2397  */
2398 
2403 SCIP_MESSAGEHDLR* SCIPsdpiGetMessagehdlr(
2404  SCIP_SDPI* sdpi
2405  )
2406 {
2407  return sdpi->messagehdlr;
2408 }
2409 
2411 SCIP_RETCODE SCIPsdpiGetNLPRows(
2412  SCIP_SDPI* sdpi,
2413  int* nlprows
2414  )
2415 {
2416  assert( sdpi != NULL );
2417  assert( nlprows != NULL );
2418 
2419  *nlprows = sdpi->nlpcons;
2420 
2421  return SCIP_OKAY;
2422 }
2423 
2426  SCIP_SDPI* sdpi,
2427  int* nsdpblocks
2428  )
2429 {
2430  assert( sdpi != NULL );
2431  assert( nsdpblocks != NULL );
2432 
2433  *nsdpblocks = sdpi->nsdpblocks;
2434 
2435  return SCIP_OKAY;
2436 }
2437 
2439 SCIP_RETCODE SCIPsdpiGetNVars(
2440  SCIP_SDPI* sdpi,
2441  int* nvars
2442  )
2443 {
2444  assert( sdpi != NULL );
2445  assert( nvars != NULL );
2446 
2447  *nvars = sdpi->nvars;
2448 
2449  return SCIP_OKAY;
2450 }
2451 
2453 SCIP_RETCODE SCIPsdpiGetSDPNNonz(
2454  SCIP_SDPI* sdpi,
2455  int* nnonz
2456  )
2457 {
2458  assert( sdpi != NULL );
2459  assert( nnonz != NULL );
2460 
2461  *nnonz = sdpi->sdpnnonz;
2462 
2463  return SCIP_OKAY;
2464 }
2465 
2468  SCIP_SDPI* sdpi,
2469  int* nnonz
2470  )
2471 {
2472  assert( sdpi != NULL );
2473  assert( nnonz != NULL );
2474 
2475  *nnonz = sdpi->sdpconstnnonz;
2476 
2477  return SCIP_OKAY;
2478 }
2479 
2481 SCIP_RETCODE SCIPsdpiGetLPNNonz(
2482  SCIP_SDPI* sdpi,
2483  int* nnonz
2484  )
2485 {
2486  assert( sdpi != NULL );
2487  assert( nnonz != NULL );
2488 
2489  *nnonz = sdpi->lpnnonz;
2490 
2491  return SCIP_OKAY;
2492 }
2493 
2495 SCIP_RETCODE SCIPsdpiGetObj(
2496  SCIP_SDPI* sdpi,
2497  int firstvar,
2498  int lastvar,
2499  SCIP_Real* vals
2500  )
2501 {
2502  int i;
2503 
2504  assert( sdpi != NULL );
2505  assert( firstvar >= 0 );
2506  assert( firstvar <= lastvar );
2507  assert( lastvar < sdpi->nvars);
2508  assert( vals != NULL );
2509 
2510  for (i = 0; i < lastvar - firstvar + 1; i++) /*lint !e834*/
2511  vals[i] = sdpi->obj[firstvar + i]; /*lint !e679*/
2512 
2513  return SCIP_OKAY;
2514 }
2515 
2517 SCIP_RETCODE SCIPsdpiGetBounds(
2518  SCIP_SDPI* sdpi,
2519  int firstvar,
2520  int lastvar,
2521  SCIP_Real* lbs,
2522  SCIP_Real* ubs
2523  )
2524 {
2525  int i;
2526 
2527  assert( sdpi != NULL );
2528  assert( firstvar >= 0 );
2529  assert( firstvar <= lastvar );
2530  assert( lastvar < sdpi->nvars);
2531  assert( lbs != NULL );
2532  assert( ubs != NULL );
2533 
2534  for (i = 0; i < lastvar - firstvar + 1; i++) /*lint !e834*/
2535  {
2536  if (lbs != NULL)
2537  lbs[i] = sdpi->lb[firstvar + i]; /*lint !e679*/
2538  if (ubs != NULL)
2539  ubs[i] = sdpi->ub[firstvar + i]; /*lint !e679*/
2540  }
2541 
2542  return SCIP_OKAY;
2543 }
2544 
2546 SCIP_RETCODE SCIPsdpiGetLhSides(
2547  SCIP_SDPI* sdpi,
2548  int firstrow,
2549  int lastrow,
2550  SCIP_Real* lhss
2551  )
2552 {
2553  int i;
2554 
2555  assert( sdpi != NULL );
2556  assert( firstrow >= 0 );
2557  assert( firstrow <= lastrow );
2558  assert( lastrow < sdpi->nlpcons);
2559  assert( lhss != NULL );
2560 
2561  for (i = 0; i < lastrow - firstrow + 1; i++) /*lint !e834*/
2562  lhss[firstrow + i] = sdpi->lplhs[i]; /*lint !e679*/
2563 
2564  return SCIP_OKAY;
2565 }
2566 
2568 SCIP_RETCODE SCIPsdpiGetRhSides(
2569  SCIP_SDPI* sdpi,
2570  int firstrow,
2571  int lastrow,
2572  SCIP_Real* rhss
2573  )
2574 {
2575  int i;
2576 
2577  assert( sdpi != NULL );
2578  assert( firstrow >= 0 );
2579  assert( firstrow <= lastrow );
2580  assert( lastrow < sdpi->nlpcons);
2581  assert( rhss != NULL );
2582 
2583  for (i = 0; i < lastrow - firstrow + 1; i++) /*lint !e834*/
2584  rhss[firstrow + i] = sdpi->lprhs[i]; /*lint !e679*/
2585 
2586  return SCIP_OKAY;
2587 }
2588 
2589 
2594 /*
2595  * Solving Methods
2596  */
2597 
2607 SCIP_RETCODE SCIPsdpiSolve(
2608  SCIP_SDPI* sdpi,
2609  SCIP_Real* starty,
2610  int* startZnblocknonz,
2612  int** startZrow,
2614  int** startZcol,
2616  SCIP_Real** startZval,
2618  int* startXnblocknonz,
2620  int** startXrow,
2622  int** startXcol,
2624  SCIP_Real** startXval,
2626  SCIP_SDPSOLVERSETTING startsettings,
2628  SCIP_Bool enforceslatercheck,
2630  SCIP_Real timelimit
2631  )
2632 {
2633  int* sdpconstnblocknonz = NULL;
2634  int* maxsdpconstnblocknonz = NULL;
2635  int** sdpconstrow = NULL;
2636  int** sdpconstcol = NULL;
2637  SCIP_Real** sdpconstval = NULL;
2638  int** indchanges = NULL;
2639  int* nremovedinds = NULL;
2640  SCIP_Real addedopttime;
2641  SCIP_Real fixedvarsobjcontr = 0.0;
2642  SCIP_Bool fixingfound;
2643  int* blockindchanges;
2644  int sdpconstnnonz;
2645  int sdpilpnnonz = 0;
2646  int nactivelpcons;
2647  int nactivevars = 0;
2648  int activevaridx = -1;
2649  int nremovedblocks = 0;
2650  int naddediterations;
2651  int naddedsdpcalls;
2652  int b;
2653  int v;
2654 
2655  assert( sdpi != NULL );
2656 
2657  SCIPdebugMessage("Forwarding SDP %d to solver!\n", sdpi->sdpid);
2658 
2659  sdpi->penalty = FALSE;
2660  sdpi->bestbound = -SCIPsdpiSolverInfinity(sdpi->sdpisolver);
2661  sdpi->solved = FALSE;
2662  sdpi->infeasible = FALSE;
2663  sdpi->allfixed = FALSE;
2664  sdpi->nsdpcalls = 0;
2665  sdpi->niterations = 0;
2666  sdpi->opttime = 0.0;
2667  sdpi->solvedonevarsdp = SCIP_ONEVAR_UNSOLVED;
2668  sdpi->onevarsdpobjval = SCIP_INVALID;
2669  sdpi->onevarsdpoptval = SCIP_INVALID;
2670  sdpi->onevarsdpidx = -1;
2671 
2672  if ( timelimit <= 0.0 )
2673  return SCIP_OKAY;
2674 
2675  SDPIclockStart(sdpi->usedsdpitime);
2676 
2677  /* copy bounds */
2678  for (v = 0; v < sdpi->nvars && ! sdpi->infeasible; v++)
2679  {
2680  sdpi->sdpilb[v] = sdpi->lb[v];
2681  sdpi->sdpiub[v] = sdpi->ub[v];
2682  if ( sdpi->sdpiub[v] < sdpi->sdpilb[v] - sdpi->feastol )
2683  sdpi->infeasible = TRUE;
2684  }
2685 
2686  /* exit if infeasible */
2687  if ( sdpi->infeasible )
2688  {
2689  SCIPdebugMessage("SDP %d not given to solver, as infeasibility was detected during problem preparation!\n", sdpi->sdpid++);
2690  SCIP_CALL( SCIPsdpiSolverIncreaseCounter(sdpi->sdpisolver) );
2691 
2692  sdpi->solved = TRUE;
2693  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2694  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2695  ++sdpi->ninfeasible;
2696 
2697  SDPIclockStop(sdpi->usedsdpitime);
2698 
2699  return SCIP_OKAY;
2700  }
2701  assert( ! sdpi->infeasible );
2702 
2703  /* Compute the lplphs and lprhs, detect empty rows and check for additional variable fixings caused by boundchanges from
2704  * lp rows with a single active variable. Note that this changes sdpi->sdpilb and sdpi->sdpiub, but not sdpi->lb and sdpi->ub. */
2705  do
2706  {
2707  /* we expect that additional fixings are only found seldomly, so this function is usually called only once per solve */
2708  SCIP_CALL( prepareLPData(sdpi, sdpi->sdpilb, sdpi->sdpiub, &nactivelpcons, sdpi->sdpilplhs, sdpi->sdpilprhs, &sdpilpnnonz,
2709  sdpi->sdpilprow, sdpi->sdpilpcol, sdpi->sdpilpval, &fixingfound) );
2710 
2711  SCIPdebugMessage("Number of active LP constraints: %d (original: %d); %d nonzeros.\n", nactivelpcons, sdpi->nlpcons, sdpilpnnonz);
2712  }
2713  while ( fixingfound && ! sdpi->infeasible );
2714 
2715  /* exit if infeasible */
2716  if ( sdpi->infeasible )
2717  {
2718  SCIPdebugMessage("SDP %d not given to solver, since infeasibility was detected during problem preparation!\n", sdpi->sdpid++);
2719  SCIP_CALL( SCIPsdpiSolverIncreaseCounter(sdpi->sdpisolver) );
2720 
2721  sdpi->solved = TRUE;
2722  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2723  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2724  ++sdpi->ninfeasible;
2725 
2726  SDPIclockStop(sdpi->usedsdpitime);
2727 
2728  return SCIP_OKAY;
2729  }
2730  assert( ! sdpi->infeasible );
2731 
2732  /* Checks whether all variables are fixed; this cannot be done in prepareLPData() because not all variables need to be contained in LP-constraints. */
2733  for (v = 0; v < sdpi->nvars; v++)
2734  {
2735  if ( ! isFixed(sdpi, v) )
2736  {
2737  ++nactivevars;
2738  activevaridx = v;
2739  }
2740  else
2741  fixedvarsobjcontr += sdpi->obj[v] * sdpi->sdpilb[v];
2742  }
2743 
2744  if ( nactivevars == 0 )
2745  sdpi->allfixed = TRUE;
2746 
2747  /* check if all variables are fixed, if this is the case, check if the remaining solution for feasibility */
2748  if ( sdpi->allfixed )
2749  {
2750  /* check feasibility of SDP constraints - LP constraints have been checked in prepareLPData() */
2751  SCIP_CALL( checkFixedFeasibilitySdp(sdpi, sdpi->sdpilb, sdpi->sdpiub) );
2752 
2753  SCIPdebugMessage("SDP %d not given to solver, since all variables are fixed; problem is %sfeasible!\n", sdpi->sdpid++, sdpi->infeasible ? "in" : "");
2754 
2755  SCIP_CALL( SCIPsdpiSolverIncreaseCounter(sdpi->sdpisolver) );
2756  sdpi->solved = TRUE;
2757  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2758  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2759  ++sdpi->nallfixed;
2760  SDPIclockStop(sdpi->usedsdpitime);
2761 
2762  return SCIP_OKAY;
2763  }
2764  assert( ! sdpi->allfixed );
2765  assert( ! sdpi->infeasible );
2766 
2767  /* allocate memory for computing the constant matrix after fixings and finding empty rows and columns */
2768  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstnblocknonz, sdpi->nsdpblocks) );
2769  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &maxsdpconstnblocknonz, sdpi->nsdpblocks) );
2770  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstrow, sdpi->nsdpblocks) );
2771  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstcol, sdpi->nsdpblocks) );
2772  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &sdpconstval, sdpi->nsdpblocks) );
2773  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &indchanges, sdpi->nsdpblocks) );
2774  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &nremovedinds, sdpi->nsdpblocks) );
2775  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &blockindchanges, sdpi->nsdpblocks) );
2776 
2777  for (b = 0; b < sdpi->nsdpblocks; ++b)
2778  {
2779  maxsdpconstnblocknonz[b] = MIN(sdpi->sdpnnonz + sdpi->sdpconstnnonz, sdpi->sdpblocksizes[b] * (sdpi->sdpblocksizes[b] + 1) / 2);
2780  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[b]), maxsdpconstnblocknonz[b]) ); /*lint !e776*/
2781  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[b]), maxsdpconstnblocknonz[b]) ); /*lint !e776*/
2782  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(sdpconstval[b]), maxsdpconstnblocknonz[b]) ); /*lint !e776*/
2783  sdpconstnblocknonz[b] = maxsdpconstnblocknonz[b];
2784 
2785  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &(indchanges[b]), sdpi->sdpblocksizes[b]) );
2786  }
2787 
2788  /* compute constant matrix after fixings */
2789  SCIP_CALL( compConstMatAfterFixings(sdpi, sdpi->sdpilb, sdpi->sdpiub, &sdpconstnnonz, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval) );
2790  assert( ! sdpi->allfixed );
2791  assert( ! sdpi->infeasible );
2792 
2793  /* check whether problem contains one variable and one SDP block */
2794  if ( nactivevars == 1 && sdpi->nsdpblocks <= 1 )
2795  {
2796  SCIP_Real objval;
2797  SCIP_Real optval;
2798 
2799  assert( nactivelpcons == 0 ); /* all LP constraints should have been converted to variable bounds in preprocessing */
2800  assert( 0 <= activevaridx && activevaridx < sdpi->nvars );
2801 
2802  /* treat LPs */
2803  if ( sdpi->nsdpblocks == 0 )
2804  {
2805  /* If there are no SDP constraints, we have an LP with one variable. Preprocessing above has reduced the
2806  * problem to a variable and its corresponding bounds and no further constraints. */
2807  if ( ! SCIPsdpiIsInfinity(sdpi, sdpi->sdpilb[activevaridx]) && ! SCIPsdpiIsInfinity(sdpi, sdpi->sdpiub[activevaridx]) )
2808  {
2809  if ( sdpi->obj[activevaridx] >= 0.0 )
2810  {
2811  sdpi->onevarsdpoptval = sdpi->sdpilb[activevaridx];
2812  sdpi->onevarsdpobjval = sdpi->obj[activevaridx] * sdpi->sdpilb[activevaridx];
2813  }
2814  else
2815  {
2816  sdpi->onevarsdpoptval = sdpi->sdpiub[activevaridx];
2817  sdpi->onevarsdpobjval = sdpi->obj[activevaridx] * sdpi->sdpiub[activevaridx];
2818  }
2819 
2820  sdpi->solved = TRUE;
2821  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2822  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2823  sdpi->onevarsdpidx = activevaridx;
2824  sdpi->solvedonevarsdp = SCIP_ONEVAR_OPTIMAL;
2825  sdpi->onevarsdpobjval += fixedvarsobjcontr;
2826  ++sdpi->nonevarsdp;
2827  }
2828  }
2829  else
2830  {
2831  /* search for matrix index corresponding to active variable */
2832  for (v = 0; v < sdpi->sdpnblockvars[0]; ++v)
2833  {
2834  if ( sdpi->sdpvar[0][v] == activevaridx )
2835  break;
2836  }
2837 
2838  SCIP_CALL( SCIPsolveOneVarSDP(sdpi->bufmem, sdpi->obj[activevaridx], sdpi->sdpilb[activevaridx], sdpi->sdpiub[activevaridx], sdpi->sdpblocksizes[0],
2839  sdpconstnblocknonz[0], sdpconstrow[0], sdpconstcol[0], sdpconstval[0],
2840  sdpi->sdpnblockvarnonz[0][v], sdpi->sdprow[0][v], sdpi->sdpcol[0][v], sdpi->sdpval[0][v],
2841  SCIPsdpiInfinity(sdpi), sdpi->feastol, &objval, &optval) );
2842 
2843  if ( objval != SCIP_INVALID ) /*lint !e777*/
2844  {
2845  sdpi->solved = TRUE;
2846  sdpi->dualslater = SCIP_SDPSLATER_NOINFO;
2847  sdpi->primalslater = SCIP_SDPSLATER_NOINFO;
2848  sdpi->onevarsdpobjval = objval;
2849  sdpi->onevarsdpoptval = optval;
2850  sdpi->onevarsdpidx = activevaridx;
2851 
2852  if ( SCIPsdpiIsInfinity(sdpi, objval) )
2853  sdpi->solvedonevarsdp = SCIP_ONEVAR_INFEASIBLE;
2854  else
2855  {
2856  sdpi->solvedonevarsdp = SCIP_ONEVAR_OPTIMAL;
2857  sdpi->onevarsdpobjval += fixedvarsobjcontr;
2858  }
2859  ++sdpi->nonevarsdp;
2860  }
2861  }
2862  }
2863 
2864  /* solve SDP if not yet done */
2865  if ( ! sdpi->solved )
2866  {
2867  /* remove empty rows and columns */
2868  SCIP_CALL( findEmptyRowColsSDP(sdpi, sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval, indchanges, nremovedinds, blockindchanges, &nremovedblocks) );
2869 
2870  if ( sdpi->slatercheck )
2871  {
2872  SCIP_CALL( checkSlaterCondition(sdpi, timelimit, sdpi->sdpilb, sdpi->sdpiub,
2873  sdpconstnblocknonz, sdpconstnnonz, sdpconstrow, sdpconstcol, sdpconstval,
2874  indchanges, nremovedinds, nactivelpcons,
2875  sdpi->sdpilplhs, sdpi->sdpilprhs, sdpilpnnonz, sdpi->sdpilprow, sdpi->sdpilpcol, sdpi->sdpilpval,
2876  blockindchanges, nremovedblocks, FALSE) );
2877  }
2878 
2879  /* try to solve the problem */
2880  SCIP_CALL( SCIPsdpiSolverLoadAndSolve(sdpi->sdpisolver, sdpi->nvars, sdpi->obj, sdpi->sdpilb, sdpi->sdpiub,
2881  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2882  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2883  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2884  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->sdpilplhs, sdpi->sdpilprhs,
2885  sdpilpnnonz, sdpi->sdpilprow, sdpi->sdpilpcol, sdpi->sdpilpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2886  startXnblocknonz, startXrow, startXcol, startXval, startsettings, timelimit, sdpi->usedsdpitime) );
2887 
2888  sdpi->solved = TRUE;
2889 
2890  /* add time, iterations and sdpcalls */
2891  addedopttime = 0.0;
2892  SCIP_CALL( SCIPsdpiSolverGetTime(sdpi->sdpisolver, &addedopttime) );
2893  sdpi->opttime += addedopttime;
2894  naddediterations = 0;
2895  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2896  sdpi->niterations += naddediterations;
2897  naddedsdpcalls = 0;
2898  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2899  sdpi->nsdpcalls += naddedsdpcalls;
2900 
2901 #if 0
2902  if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && SCIPsdpiSolverWasSolved(sdpi->sdpisolver) && solveonevarsdpobjval != SCIP_INVALID )
2903  {
2904  SCIP_Real objval;
2905  SCIP_Real* dualsol;
2906  int dualsollength;
2907 
2908  dualsollength = sdpi->nvars;
2909  BMS_CALL( BMSallocBlockMemoryArray(sdpi->blkmem, &dualsol, dualsollength) );
2910  SCIP_CALL( SCIPsdpiGetSol(sdpi, &objval, dualsol, &dualsollength) );
2911  printf("dual sol: %.15g\n", dualsol[activevaridx]);
2912  BMSfreeBlockMemoryArrayNull(sdpi->blkmem, &dualsol, dualsollength);
2913 
2914  /* SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) ); */
2915  assert( REALABS(objval - solveonevarsdpobjval)/MAX3(1.0, REALABS(objval), REALABS(solveonevarsdpobjval)) <= 2.0 * sdpi->gaptol );
2916  }
2917 #endif
2918 
2919  /* if the solver didn't produce a satisfactory result, we have to try with a penalty formulation */
2920  if ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && ! SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver) )
2921  {
2922  SCIP_Real penaltyparam;
2923  SCIP_Real penaltyparamfact;
2924  SCIP_Real gaptol;
2925  SCIP_Real gaptolfact;
2926  SCIP_Bool feasorig;
2927  SCIP_Bool penaltybound;
2928  SCIP_Real objbound;
2929  SCIP_Real objval;
2930 
2931  feasorig = FALSE;
2932  penaltybound = TRUE;
2933 
2934  /* first check feasibility using the penalty approach */
2935  SCIPdebugMessage("SDP %d returned inacceptable result, trying penalty formulation.\n", sdpi->sdpid);
2936 
2937  /* we solve the problem with a slack variable times identity added to the constraints and trying to minimize this slack variable r, if
2938  * the optimal objective is bigger than feastol, then we know that the problem is infeasible */
2939  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, 1.0, FALSE, FALSE, sdpi->nvars, sdpi->obj, sdpi->sdpilb, sdpi->sdpiub,
2940  sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
2941  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
2942  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
2943  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->sdpilplhs, sdpi->sdpilprhs,
2944  sdpilpnnonz, sdpi->sdpilprow, sdpi->sdpilpcol, sdpi->sdpilpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
2945  startXnblocknonz, startXrow, startXcol, startXval, SCIP_SDPSOLVERSETTING_UNSOLVED, timelimit, sdpi->usedsdpitime, &feasorig, &penaltybound) );
2946 
2947  /* add time, iterations and sdpcalls */
2948  addedopttime = 0.0;
2949  SCIP_CALL( SCIPsdpiSolverGetTime(sdpi->sdpisolver, &addedopttime) );
2950  sdpi->opttime += addedopttime;
2951  naddediterations = 0;
2952  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
2953  sdpi->niterations += naddediterations;
2954  naddedsdpcalls = 0;
2955  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
2956  sdpi->nsdpcalls += naddedsdpcalls;
2957 
2958  /* get objective value */
2959  if ( SCIPsdpiSolverWasSolved(sdpi->sdpisolver) )
2960  {
2961  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objval) );
2962  }
2963  else
2964  objval = -SCIPsdpiInfinity(sdpi);
2965 
2966  /* If the penalty formulation was successfully solved and has a strictly positive objective value, we know that
2967  * the problem is infeasible. Note that we need to check against the maximum of feastol and gaptol, since this
2968  * is the objective of an SDP which is only exact up to gaptol, and cutting a feasible node off is an error
2969  * while continueing with an infeasible problem only takes additional time until we found out again later.
2970  */
2971  if ( (SCIPsdpiSolverIsOptimal(sdpi->sdpisolver) && (objval > (sdpi->feastol > sdpi->gaptol ?
2972  sdpi->peninfeasadjust * sdpi->feastol : sdpi->peninfeasadjust * sdpi->gaptol))) ||
2973  (SCIPsdpiSolverWasSolved(sdpi->sdpisolver) && SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver)) )
2974  {
2975  SCIPdebugMessage("SDP %d found infeasible using penalty formulation, maximum of smallest eigenvalue is %g.\n", sdpi->sdpid, -1.0 * objval);
2976  sdpi->penalty = TRUE;
2977  sdpi->infeasible = TRUE;
2978  }
2979  else
2980  {
2981  feasorig = FALSE;
2982  penaltybound = TRUE;
2983 
2984  penaltyparam = sdpi->penaltyparam;
2985 
2986  SCIPdebugMessage("SDP %d not found infeasible using penalty formulation, maximum of smallest eigenvalue is %g.\n", sdpi->sdpid, -1.0 * objval);
2987 
2988  /* we compute the factor to increase with as n-th root of the total increase until the maximum, where n is the number of iterations
2989  * (for npenaltyincr = 0 we make sure that the parameter is too large after the first change)
2990  */
2991  penaltyparamfact = sdpi->npenaltyincr > 0 ? pow((sdpi->maxpenaltyparam / sdpi->penaltyparam), 1.0/sdpi->npenaltyincr) :
2992  2*sdpi->maxpenaltyparam / sdpi->penaltyparam;
2993  gaptol = sdpi->gaptol;
2994  gaptolfact = sdpi->npenaltyincr > 0 ? pow((MIN_GAPTOL / sdpi->gaptol), 1.0/sdpi->npenaltyincr) : 0.5 * MIN_GAPTOL / sdpi->gaptol;
2995 
2996  /* increase penalty-param and decrease feasibility tolerance until we find a feasible solution or reach the final bound for either one of them */
2997  while ( ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) || ! feasorig ) &&
2998  ( penaltyparam < sdpi->maxpenaltyparam + sdpi->epsilon ) && ( gaptol > 0.99 * MIN_GAPTOL ) && ( ! SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver) ))
2999  {
3000  SCIPdebugMessage("Solver did not produce an acceptable result, trying SDP %d again with penaltyparameter %g.\n", sdpi->sdpid, penaltyparam);
3001 
3002  SCIP_CALL( SCIPsdpiSolverLoadAndSolveWithPenalty(sdpi->sdpisolver, penaltyparam, TRUE, TRUE, sdpi->nvars, sdpi->obj,
3003  sdpi->sdpilb, sdpi->sdpiub, sdpi->nsdpblocks, sdpi->sdpblocksizes, sdpi->sdpnblockvars, sdpconstnnonz,
3004  sdpconstnblocknonz, sdpconstrow, sdpconstcol, sdpconstval,
3005  sdpi->sdpnnonz, sdpi->sdpnblockvarnonz, sdpi->sdpvar, sdpi->sdprow, sdpi->sdpcol,
3006  sdpi->sdpval, indchanges, nremovedinds, blockindchanges, nremovedblocks, nactivelpcons, sdpi->sdpilplhs, sdpi->sdpilprhs,
3007  sdpilpnnonz, sdpi->sdpilprow, sdpi->sdpilpcol, sdpi->sdpilpval, starty, startZnblocknonz, startZrow, startZcol, startZval,
3008  startXnblocknonz, startXrow, startXcol, startXval, startsettings, timelimit, sdpi->usedsdpitime, &feasorig, &penaltybound) );
3009 
3010  /* add time, iterations and sdpcalls */
3011  addedopttime = 0.0;
3012  SCIP_CALL( SCIPsdpiSolverGetTime(sdpi->sdpisolver, &addedopttime) );
3013  sdpi->opttime += addedopttime;
3014  naddediterations = 0;
3015  SCIP_CALL( SCIPsdpiSolverGetIterations(sdpi->sdpisolver, &naddediterations) );
3016  sdpi->niterations += naddediterations;
3017  naddedsdpcalls = 0;
3018  SCIP_CALL( SCIPsdpiSolverGetSdpCalls(sdpi->sdpisolver, &naddedsdpcalls) );
3019  sdpi->nsdpcalls += naddedsdpcalls;
3020 
3021  /* If the solver did not converge, we increase the penalty parameter */
3022  if ( ! SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) )
3023  {
3024  penaltyparam *= penaltyparamfact;
3025  SCIPdebugMessage("Solver did not converge even with penalty formulation, increasing penaltyparameter.\n");
3026  continue;
3027  }
3028 
3029  /* if we succeeded to solve the problem, update the bound */
3030  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, &objbound) );
3031  if ( objbound > sdpi->bestbound + sdpi->gaptol )
3032  sdpi->bestbound = objbound;
3033 
3034  /* If we don't get a feasible solution to our original problem we have to update either Gamma (if the penalty bound was active
3035  * in the primal problem) or gaptol (otherwise) */
3036  if ( ! feasorig )
3037  {
3038  if ( penaltybound )
3039  {
3040  penaltyparam *= penaltyparamfact;
3041  SCIPdebugMessage("Penalty formulation produced a result which is infeasible for the original problem, increasing penaltyparameter.\n");
3042  }
3043  else
3044  {
3045  gaptol *= gaptolfact;
3046  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, SCIP_SDPPAR_GAPTOL, gaptol) );
3047  SCIPdebugMessage("Penalty formulation produced a result which is infeasible for the original problem, even though primal penalty "
3048  "bound was not reached, decreasing tolerance for duality gap in SDP-solver.\n");
3049  }
3050  }
3051  }
3052 
3053  /* reset the tolerance in the SDP-solver */
3054  if ( gaptol > sdpi->gaptol )
3055  {
3056  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, SCIP_SDPPAR_GAPTOL, sdpi->gaptol) );
3057  }
3058 
3059  /* check if we were able to solve the problem in the end */
3060  if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && feasorig )
3061  {
3062  sdpi->penalty = TRUE;
3063  sdpi->solved = TRUE;
3064  }
3065 #if 0 /* we don't really know if it is infeasible or just ill-posed (no KKT-point) */
3066  else if ( SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver) && ! feasorig )
3067  {
3068  SCIPdebugMessage("Problem was found to be infeasible using a penalty formulation.\n");
3069  sdpi->infeasible = TRUE;
3070  sdpi->penalty = TRUE;
3071  sdpi->solved = TRUE;
3072  }
3073 #endif
3074  else
3075  {
3076  SCIPdebugMessage("SDP-Solver could not solve the problem even after using a penalty formulation.\n");
3077  sdpi->solved = FALSE;
3078  sdpi->penalty = TRUE;
3079  }
3080 
3081  /* if we still didn't succeed and enforceslatercheck was set, we finally test for the Slater condition to give a reason for failure */
3082  if ( sdpi->solved == FALSE && enforceslatercheck )
3083  {
3084  SCIP_CALL( checkSlaterCondition(sdpi, timelimit, sdpi->sdpilb, sdpi->sdpiub,
3085  sdpconstnblocknonz, sdpconstnnonz, sdpconstrow, sdpconstcol, sdpconstval,
3086  indchanges, nremovedinds, nactivelpcons,
3087  sdpi->sdpilplhs, sdpi->sdpilprhs, sdpilpnnonz, sdpi->sdpilprow, sdpi->sdpilpcol, sdpi->sdpilpval,
3088  blockindchanges, nremovedblocks, TRUE) );
3089  }
3090  else if ( sdpi->solved == FALSE )
3091  {
3092 #if 0
3093  SCIPmessagePrintInfo(sdpi->messagehdlr, "Numerical trouble.\n");
3094 #else
3095  SCIPdebugMessage("SDP-Interface was unable to solve SDP %d.\n", sdpi->sdpid);/*lint !e687*/
3096 #endif
3097  }
3098  }
3099  }
3100  }
3101 
3102  /* empty the memory allocated here */
3103  for (b = sdpi->nsdpblocks - 1; b >= 0; --b)
3104  {
3105  BMSfreeBlockMemoryArray(sdpi->blkmem, &(indchanges[b]), sdpi->sdpblocksizes[b]);/*lint !e737*/
3106  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstval[b]), maxsdpconstnblocknonz[b]);/*lint !e737*/
3107  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstcol[b]), maxsdpconstnblocknonz[b]);/*lint !e737*/
3108  BMSfreeBlockMemoryArray(sdpi->blkmem, &(sdpconstrow[b]), maxsdpconstnblocknonz[b]);/*lint !e737*/
3109  }
3110  BMSfreeBlockMemoryArray(sdpi->blkmem, &blockindchanges, sdpi->nsdpblocks);/*lint !e737*/
3111  BMSfreeBlockMemoryArray(sdpi->blkmem, &nremovedinds, sdpi->nsdpblocks);/*lint !e737*/
3112  BMSfreeBlockMemoryArray(sdpi->blkmem, &indchanges, sdpi->nsdpblocks);/*lint !e737*/
3113  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstval, sdpi->nsdpblocks);/*lint !e737*/
3114  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstcol, sdpi->nsdpblocks);/*lint !e737*/
3115  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstrow, sdpi->nsdpblocks);/*lint !e737*/
3116  BMSfreeBlockMemoryArray(sdpi->blkmem, &maxsdpconstnblocknonz, sdpi->nsdpblocks);/*lint !e737*/
3117  BMSfreeBlockMemoryArray(sdpi->blkmem, &sdpconstnblocknonz, sdpi->nsdpblocks);/*lint !e737*/
3118 
3119  sdpi->sdpid++;
3120 
3121  SDPIclockStop(sdpi->usedsdpitime);
3122 
3123  return SCIP_OKAY;
3124 }
3125 
3126 
3127 
3128 
3129 /*
3130  * Solution Information Methods
3131  */
3132 
3138  SCIP_SDPI* sdpi
3139  )
3140 {
3141  assert( sdpi != NULL );
3142 
3143  return sdpi->solved;
3144 }
3145 
3148  SCIP_SDPI* sdpi
3149  )
3150 {
3151  assert( sdpi != NULL );
3152 
3153  return ( SCIPsdpiWasSolved(sdpi) && (! sdpi->penalty) );
3154 }
3155 
3161  SCIP_SDPI* sdpi
3162  )
3163 {
3164  assert( sdpi != NULL );
3165  CHECK_IF_SOLVED_BOOL(sdpi);
3166 
3167  if ( sdpi->infeasible || sdpi->allfixed || sdpi->onevarsdpobjval > SCIP_ONEVAR_UNSOLVED )
3168  return TRUE;
3169 
3170  return SCIPsdpiSolverFeasibilityKnown(sdpi->sdpisolver);
3171 }
3172 
3175  SCIP_SDPI* sdpi,
3176  SCIP_Bool* primalfeasible,
3177  SCIP_Bool* dualfeasible
3178  )
3179 {
3180  assert( sdpi != NULL );
3181  CHECK_IF_SOLVED(sdpi);
3182 
3183  if ( sdpi->infeasible )
3184  {
3185  /* infeasibility was detected while preparing dual problem, primal problem is feasible if all variables are fixed,
3186  * otherwise primal feasibility status cannot be determined */
3187  if ( sdpi->allfixed )
3188  *primalfeasible = TRUE;
3189  else
3190  *primalfeasible = FALSE;
3191  *dualfeasible = FALSE;
3192  return SCIP_OKAY;
3193  }
3194  else if ( sdpi->allfixed )
3195  {
3196  /* all variables are fixed and dual problem is feasible, primal problem is feasible as well */
3197  *primalfeasible = TRUE;
3198  *dualfeasible = TRUE;
3199  return SCIP_OKAY;
3200  }
3201  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_OPTIMAL )
3202  {
3203  *dualfeasible = TRUE;
3204  *primalfeasible = TRUE;
3205  return SCIP_OKAY;
3206  }
3207  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_INFEASIBLE )
3208  {
3209  *dualfeasible = FALSE;
3210  *primalfeasible = TRUE; /* one variable SDP is only solved for bounded problems, for which the primal is feasible */
3211  return SCIP_OKAY;
3212  }
3213 
3214  SCIP_CALL( SCIPsdpiSolverGetSolFeasibility(sdpi->sdpisolver, primalfeasible, dualfeasible) );
3215 
3216  return SCIP_OKAY;
3217 }
3218 
3221  SCIP_SDPI* sdpi
3222  )
3223 {
3224  assert( sdpi != NULL );
3225  CHECK_IF_SOLVED_BOOL(sdpi);
3226 
3227  if ( sdpi->infeasible )
3228  {
3229  /* infeasibility was detected while preparing dual problem, primal problem always has a ray and is feasible if all
3230  * variables are fixed (else it is not necessarily feasible) */
3231  if ( sdpi->allfixed )
3232  return TRUE;
3233  else
3234  return FALSE;
3235  }
3236  else if ( sdpi->allfixed )
3237  {
3238  /* all variables are fixed and dual problem is feasible, primal problem is feasible and bounded */
3239  return FALSE;
3240  }
3241  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_OPTIMAL )
3242  return FALSE;
3243  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_INFEASIBLE )
3244  return TRUE; /* primal is always feasible, since dual is bounded */
3245 
3246  return SCIPsdpiSolverIsPrimalUnbounded(sdpi->sdpisolver);
3247 }
3248 
3251  SCIP_SDPI* sdpi
3252  )
3253 {
3254  assert( sdpi != NULL );
3255  CHECK_IF_SOLVED_BOOL(sdpi);
3256 
3257  if ( sdpi->infeasible )
3258  {
3259  /* infeasibility was detected while preparing dual problem, primal status is feasible if all variables are fixed
3260  * and unknown else */
3261  return FALSE;
3262  }
3263  else if ( sdpi->allfixed )
3264  {
3265  /* all variables are fixed and dual problem is feasible, primal problem is feasible as well */
3266  return FALSE;
3267  }
3268  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3269  return FALSE; /* primal is always feasible */
3270 
3271  return SCIPsdpiSolverIsPrimalInfeasible(sdpi->sdpisolver);
3272 }
3273 
3276  SCIP_SDPI* sdpi
3277  )
3278 {
3279  assert(sdpi != NULL );
3280  CHECK_IF_SOLVED_BOOL(sdpi);
3281 
3282  if ( sdpi->infeasible )
3283  {
3284  /* infeasibility was detected while preparing dual problem, primal status is feasible if all variables are fixed
3285  * and unknown else */
3286  if ( sdpi->allfixed )
3287  return TRUE;
3288  else
3289  return FALSE;
3290  }
3291  else if ( sdpi->allfixed )
3292  {
3293  /* all variables are fixed and dual problem is feasible, primal problem is feasible as well */
3294  return TRUE;
3295  }
3296  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3297  return TRUE; /* primal is always feasible */
3298 
3299  return SCIPsdpiSolverIsPrimalFeasible(sdpi->sdpisolver);
3300 }
3301 
3304  SCIP_SDPI* sdpi
3305  )
3306 {
3307  assert( sdpi != NULL );
3308  CHECK_IF_SOLVED_BOOL(sdpi);
3309 
3310  if ( sdpi->infeasible )
3311  {
3312  /* infeasibility was detected while preparing dual problem */
3313  return FALSE;
3314  }
3315  else if ( sdpi->allfixed )
3316  {
3317  /* all variables are fixed and dual problem is feasible */
3318  return FALSE;
3319  }
3320  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3321  return FALSE;
3322 
3323  return SCIPsdpiSolverIsDualUnbounded(sdpi->sdpisolver);
3324 }
3325 
3328  SCIP_SDPI* sdpi
3329  )
3330 {
3331  assert( sdpi != NULL );
3332  CHECK_IF_SOLVED_BOOL(sdpi);
3333 
3334  if ( sdpi->infeasible )
3335  {
3336  /* infeasibility was detected while preparing dual problem */
3337  return TRUE;
3338  }
3339  else if ( sdpi->allfixed )
3340  {
3341  /* all variables are fixed and dual problem is feasible */
3342  return FALSE;
3343  }
3344  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_OPTIMAL )
3345  return FALSE;
3346  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_INFEASIBLE )
3347  return TRUE;
3348 
3349  return SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver);
3350 }
3351 
3354  SCIP_SDPI* sdpi
3355  )
3356 {
3357  assert( sdpi != NULL );
3358  CHECK_IF_SOLVED_BOOL(sdpi);
3359 
3360  if ( sdpi->infeasible )
3361  {
3362  /* infeasibility was detected while preparing dual problem */
3363  return FALSE;
3364  }
3365  else if ( sdpi->allfixed )
3366  {
3367  /* all variables are fixed and dual problem is feasible */
3368  return TRUE;
3369  }
3370  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_OPTIMAL )
3371  return TRUE;
3372  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_INFEASIBLE )
3373  return FALSE;
3374 
3375  return SCIPsdpiSolverIsDualFeasible(sdpi->sdpisolver);
3376 }
3377 
3380  SCIP_SDPI* sdpi
3381  )
3382 {
3383  assert( sdpi != NULL );
3384  CHECK_IF_SOLVED_BOOL(sdpi);
3385 
3386  if ( sdpi->infeasible )
3387  {
3388  /* infeasibility was detected while preparing dual problem - this counts as converged */
3389  return TRUE;
3390  }
3391  else if ( sdpi->allfixed )
3392  {
3393  /* all variables are fixed and dual problem is feasible - this counts as converged */
3394  return TRUE;
3395  }
3396  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3397  return TRUE;
3398 
3399  return SCIPsdpiSolverIsConverged(sdpi->sdpisolver);
3400 }
3401 
3404  SCIP_SDPI* sdpi
3405  )
3406 {
3407  assert( sdpi != NULL );
3408  CHECK_IF_SOLVED_BOOL(sdpi);
3409 
3410  if ( sdpi->infeasible )
3411  {
3412  /* infeasibility was detected while preparing dual problem - objective limit was not reached */
3413  return FALSE;
3414  }
3415  else if ( sdpi->allfixed )
3416  {
3417  /* all variables are fixed and dual problem is feasible - objective limit was not reached */
3418  return FALSE;
3419  }
3420  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3421  return FALSE;
3422 
3423  return SCIPsdpiSolverIsObjlimExc(sdpi->sdpisolver);
3424 }
3425 
3428  SCIP_SDPI* sdpi
3429  )
3430 {
3431  assert( sdpi != NULL );
3432  CHECK_IF_SOLVED_BOOL(sdpi);
3433 
3434  if ( sdpi->infeasible )
3435  {
3436  /* infeasibility was detected while preparing problem - iteration limit was not reached */
3437  return FALSE;
3438  }
3439  else if ( sdpi->allfixed )
3440  {
3441  /* all variables are fixed and problem is feasible - iteration limit was not reached */
3442  return FALSE;
3443  }
3444  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3445  return FALSE;
3446 
3447  return SCIPsdpiSolverIsIterlimExc(sdpi->sdpisolver);
3448 }
3449 
3452  SCIP_SDPI* sdpi
3453  )
3454 {
3455  assert( sdpi != NULL );
3456 
3457  if ( sdpi->infeasible )
3458  {
3459  /* infeasibility was detected while preparing problem - time limit was not reached */
3460  return FALSE;
3461  }
3462  else if ( sdpi->allfixed )
3463  {
3464  /* all variables are fixed and problem is feasible - time limit was not reached */
3465  return FALSE;
3466  }
3467  else if ( ! sdpi->solved )
3468  {
3469  SCIPdebugMessage("Problem was not solved, time limit not exceeded.\n");
3470  return FALSE;
3471  }
3472  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3473  return FALSE;
3474 
3475  return SCIPsdpiSolverIsTimelimExc(sdpi->sdpisolver);
3476 }
3477 
3490  SCIP_SDPI* sdpi
3491  )
3492 {
3493  assert( sdpi != NULL );
3494 
3495  if ( ! sdpi->solved )
3496  {
3497  SCIPdebugMessage("Problem wasn't solved yet.\n");
3498  return -1;
3499  }
3500  else if ( sdpi->infeasible )
3501  {
3502  SCIPdebugMessage("Infeasibility was detected while preparing problem, no internal status available.\n");
3503  return 0;
3504  }
3505  else if ( sdpi->allfixed )
3506  {
3507  SCIPdebugMessage("All variables are fixed, no internal status available.\n");
3508  return 0;
3509  }
3510  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3511  {
3512  SCIPdebugMessage("Solved one variable SDP, no internal status available.\n");
3513  return 0;
3514  }
3515 
3516  return SCIPsdpiSolverGetInternalStatus(sdpi->sdpisolver);
3517 }
3518 
3521  SCIP_SDPI* sdpi
3522  )
3523 {
3524  assert( sdpi != NULL );
3525  CHECK_IF_SOLVED_BOOL(sdpi);
3526 
3527  if ( sdpi->infeasible )
3528  {
3529  /* infeasibility was detected while preparing problem */
3530  return FALSE;
3531  }
3532  else if ( sdpi->allfixed )
3533  {
3534  /* all variables are fixed and problem is feasible */
3535  return TRUE;
3536  }
3537  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_OPTIMAL )
3538  return TRUE;
3539  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_INFEASIBLE )
3540  return FALSE;
3541 
3542  return SCIPsdpiSolverIsOptimal(sdpi->sdpisolver);
3543 }
3544 
3549  SCIP_SDPI* sdpi
3550  )
3551 {
3552  assert( sdpi != NULL );
3553 
3554  if ( sdpi->infeasible )
3555  {
3556  /* infeasibility was detected while preparing problem - this is acceptable */
3557  return TRUE;
3558  }
3559  else if ( sdpi->allfixed )
3560  {
3561  /* all variables are fixed and problem is feasible - this is acceptable */
3562  return TRUE;
3563  }
3564  else if ( ! sdpi->solved )
3565  {
3566  SCIPdebugMessage("Problem not solved succesfully, this is not acceptable in a B&B context.\n");
3567  return FALSE;
3568  }
3569  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3570  return TRUE;
3571 
3572  return SCIPsdpiSolverIsAcceptable(sdpi->sdpisolver);
3573 }
3574 
3576 SCIP_RETCODE SCIPsdpiGetObjval(
3577  SCIP_SDPI* sdpi,
3578  SCIP_Real* objval
3579  )
3580 {
3581  assert( sdpi != NULL );
3582  assert( objval != NULL );
3583 
3584  CHECK_IF_SOLVED(sdpi);
3585 
3586  if ( sdpi->infeasible )
3587  *objval = SCIPsdpiInfinity(sdpi); /* we are minimizing */
3588  else if ( sdpi->allfixed )
3589  {
3590  int v;
3591 
3592  /* As all variables were fixed during preprocessing, we have to compute it ourselves here */
3593  *objval = 0;
3594 
3595  for (v = 0; v < sdpi->nvars; v++)
3596  *objval += sdpi->sdpilb[v] * sdpi->obj[v];
3597  }
3598  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3599  {
3600  assert( sdpi->onevarsdpobjval != SCIP_INVALID );
3601  *objval = sdpi->onevarsdpobjval;
3602  }
3603  else
3604  {
3605  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, objval) );
3606  }
3607 
3608  return SCIP_OKAY;
3609 }
3610 
3615  SCIP_SDPI* sdpi,
3616  SCIP_Real* objlb
3617  )
3618 {
3619  assert( sdpi != NULL );
3620  assert( objlb != NULL );
3621 
3622  /* if we could successfully solve the problem, the best bound is the optimal objective */
3623  if ( sdpi->solved )
3624  {
3625  if ( sdpi->infeasible )
3626  *objlb = SCIPsdpiInfinity(sdpi); /* we are minimizing */
3627  else if ( sdpi->allfixed )
3628  {
3629  int v;
3630 
3631  /* As all variables were fixed during preprocessing, we have to compute bound ourselves here. */
3632  *objlb = 0;
3633 
3634  for (v = 0; v < sdpi->nvars; v++)
3635  *objlb += sdpi->sdpilb[v] * sdpi->obj[v];
3636  }
3637  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3638  {
3639  assert( sdpi->onevarsdpobjval != SCIP_INVALID );
3640  *objlb = sdpi->onevarsdpobjval;
3641  }
3642  else
3643  {
3644  SCIP_CALL( SCIPsdpiSolverGetObjval(sdpi->sdpisolver, objlb) );
3645  }
3646 
3647  return SCIP_OKAY;
3648  }
3649 
3650  /* if we could not solve it, but tried the penalty formulation, we take the best bound computed by the penalty approach */
3651  if ( sdpi->penalty )
3652  {
3653  *objlb = sdpi->bestbound;
3654  return SCIP_OKAY;
3655  }
3656 
3657  /* if we could not solve it and did not use the penalty formulation (e.g. because the time limit was reached), we have no information */
3658  *objlb = -SCIPsdpiInfinity(sdpi);
3659 
3660  return SCIP_OKAY;
3661 }
3662 
3666 SCIP_RETCODE SCIPsdpiGetSol(
3667  SCIP_SDPI* sdpi,
3668  SCIP_Real* objval,
3669  SCIP_Real* dualsol,
3670  int* dualsollength
3672  )
3673 {
3674  assert( sdpi != NULL );
3675  assert( dualsollength != NULL );
3676  assert( *dualsollength == 0 || dualsol != NULL );
3677  CHECK_IF_SOLVED(sdpi);
3678 
3679  if ( sdpi->infeasible )
3680  {
3681  SCIPdebugMessage("Infeasibility was detected while preparing problem, no solution available.\n");
3682  *objval = SCIPsdpiInfinity(sdpi); /* we are minimizing */
3683  }
3684  else if ( sdpi->allfixed )
3685  {
3686  if ( objval != NULL )
3687  {
3688  SCIP_CALL( SCIPsdpiGetObjval(sdpi, objval) );
3689  }
3690 
3691  if ( *dualsollength > 0 )
3692  {
3693  int v;
3694 
3695  assert( dualsol != NULL );
3696  if ( *dualsollength < sdpi->nvars )
3697  {
3698  SCIPdebugMessage("The given array in SCIPsdpiGetSol only had length %d, but %d was needed", *dualsollength, sdpi->nvars);
3699  *dualsollength = sdpi->nvars;
3700 
3701  return SCIP_OKAY;
3702  }
3703 
3704  /* we give the fixed values as the solution */
3705  for (v = 0; v < sdpi->nvars; v++)
3706  dualsol[v] = sdpi->sdpilb[v];
3707  }
3708  }
3709  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3710  {
3711  if ( objval != NULL )
3712  {
3713  SCIP_CALL( SCIPsdpiGetObjval(sdpi, objval) );
3714  }
3715 
3716  if ( *dualsollength > 0 )
3717  {
3718  int v;
3719 
3720  assert( dualsol != NULL );
3721  if ( *dualsollength < sdpi->nvars )
3722  {
3723  SCIPdebugMessage("The given array in SCIPsdpiGetSol only had length %d, but %d was needed", *dualsollength, sdpi->nvars);
3724  *dualsollength = sdpi->nvars;
3725 
3726  return SCIP_OKAY;
3727  }
3728 
3729  /* we give the fixed values as the solution */
3730  for (v = 0; v < sdpi->nvars; v++)
3731  dualsol[v] = sdpi->sdpilb[v];
3732 
3733  /* fill in value for one variable */
3734  assert( 0 <= sdpi->onevarsdpidx && sdpi->onevarsdpidx < sdpi->nvars );
3735  dualsol[sdpi->onevarsdpidx] = sdpi->onevarsdpoptval;
3736  }
3737  }
3738  else
3739  {
3740  SCIP_CALL( SCIPsdpiSolverGetSol(sdpi->sdpisolver, objval, dualsol, dualsollength) );
3741  }
3742 
3743  return SCIP_OKAY;
3744 }
3745 
3748  SCIP_SDPI* sdpi,
3749  int nblocks,
3750  int* startXnblocknonz
3752  )
3753 {
3754  assert( sdpi != NULL );
3755  assert( nblocks >= 0 );
3756  assert( startXnblocknonz != NULL );
3757 
3758  if ( sdpi->infeasible )
3759  {
3760  SCIPdebugMessage("Infeasibility was detected while preparing problem, no preoptimal solution available.\n");
3761  startXnblocknonz[0] = -1;
3762  }
3763  else if ( sdpi->allfixed )
3764  {
3765  SCIPdebugMessage("All variables are fixed, no solution available.\n");
3766  startXnblocknonz[0] = -1;
3767  }
3768  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3769  {
3770  SCIPdebugMessage("One variable SDP solved, no solution available.\n");
3771  startXnblocknonz[0] = -1;
3772  }
3773  else
3774  {
3775  SCIP_CALL( SCIPsdpiSolverGetPreoptimalPrimalNonzeros(sdpi->sdpisolver, nblocks, startXnblocknonz) );
3776  }
3777 
3778  return SCIP_OKAY;
3779 }
3780 
3789  SCIP_SDPI* sdpi,
3790  SCIP_Bool* success,
3791  SCIP_Real* dualsol,
3792  int* dualsollength,
3794  int nblocks,
3795  int* startXnblocknonz,
3797  int** startXrow,
3798  int** startXcol,
3799  SCIP_Real** startXval
3800  )
3801 {
3802  assert( sdpi != NULL );
3803  assert( success != NULL );
3804  assert( dualsol != NULL );
3805  assert( dualsollength != NULL );
3806  assert( *dualsollength >= 0 );
3807  assert( startXnblocknonz != NULL || nblocks == -1 );
3808  assert( startXrow != NULL || nblocks == -1 );
3809  assert( startXcol != NULL || nblocks == -1 );
3810  assert( startXval != NULL || nblocks == -1 );
3811 
3812  if ( sdpi->infeasible )
3813  {
3814  *success = FALSE;
3815  SCIPdebugMessage("Infeasibility was detected while preparing problem, no preoptimal solution available.\n");
3816  assert( startXnblocknonz != NULL );
3817  startXnblocknonz[0] = -1;
3818  }
3819  else if ( sdpi->allfixed )
3820  {
3821  int v;
3822 
3823  assert( dualsol != NULL );
3824 
3825  *success = FALSE;
3826 
3827  if ( *dualsollength < sdpi->nvars )
3828  {
3829  SCIPdebugMessage("The given array in SCIPsdpiGetPreoptimalSol only had length %d, but %d was needed", *dualsollength, sdpi->nvars);
3830  *dualsollength = sdpi->nvars;
3831 
3832  return SCIP_OKAY;
3833  }
3834 
3835  /* we give the fixed values as the solution */
3836  for (v = 0; v < sdpi->nvars; v++)
3837  dualsol[v] = sdpi->sdpilb[v];
3838 
3839  if ( nblocks > -1 )
3840  {
3841  SCIPdebugMessage("No primal solution available, as problem was solved during preprocessing\n");
3842  assert( startXnblocknonz != NULL );
3843  startXnblocknonz[0] = -1;
3844  }
3845 
3846  return SCIP_OKAY;
3847  }
3848  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3849  {
3850  int v;
3851 
3852  assert( dualsol != NULL );
3853 
3854  *success = FALSE;
3855 
3856  if ( *dualsollength < sdpi->nvars )
3857  {
3858  SCIPdebugMessage("The given array in SCIPsdpiGetPreoptimalSol only had length %d, but %d was needed", *dualsollength, sdpi->nvars);
3859  *dualsollength = sdpi->nvars;
3860 
3861  return SCIP_OKAY;
3862  }
3863 
3864  /* we give the fixed values as the solution */
3865  for (v = 0; v < sdpi->nvars; v++)
3866  dualsol[v] = sdpi->sdpilb[v];
3867 
3868  /* fill in value for one variable */
3869  assert( 0 <= sdpi->onevarsdpidx && sdpi->onevarsdpidx < sdpi->nvars );
3870  dualsol[sdpi->onevarsdpidx] = sdpi->onevarsdpoptval;
3871 
3872  if ( nblocks > -1 )
3873  {
3874  SCIPdebugMessage("No primal solution available, since one variable SDP was solved.\n");
3875  assert( startXnblocknonz != NULL );
3876  startXnblocknonz[0] = -1;
3877  }
3878 
3879  return SCIP_OKAY;
3880  }
3881  else
3882  {
3883  SCIP_CALL( SCIPsdpiSolverGetPreoptimalSol(sdpi->sdpisolver, success, dualsol, dualsollength, nblocks, startXnblocknonz,
3884  startXrow, startXcol, startXval) );
3885  }
3886 
3887  return SCIP_OKAY;
3888 }
3889 
3896  SCIP_SDPI* sdpi,
3897  SCIP_Real* lbvars,
3898  SCIP_Real* ubvars,
3899  int* arraylength
3902  )
3903 {
3904  assert( sdpi != NULL );
3905  assert( lbvars != NULL );
3906  assert( ubvars != NULL );
3907  assert( arraylength != NULL );
3908  assert( *arraylength >= 0 );
3909 
3910  CHECK_IF_SOLVED(sdpi);
3911 
3912  if ( sdpi->infeasible )
3913  {
3914  SCIPdebugMessage("Infeasibility was detected while preparing problem, no primal variables available.\n");
3915  *arraylength = -1;
3916  }
3917  else if ( sdpi->allfixed )
3918  {
3919  SCIPdebugMessage("All variables fixed during preprocessing, no primal variables available.\n");
3920  *arraylength = -1;
3921  }
3922  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_OPTIMAL )
3923  {
3924  int i;
3925 
3926  /* check if the arrays are long enough */
3927  if ( *arraylength < sdpi->nvars )
3928  {
3929  *arraylength = sdpi->nvars;
3930  SCIPdebugMessage("Insufficient length of array in SCIPsdpiGetPrimalBoundVars (gave %d, needed %d)\n", *arraylength, sdpi->nvars);
3931  return SCIP_OKAY;
3932  }
3933 
3934  /* determine primal variables */
3935  for (i = 0; i < sdpi->nvars; i++)
3936  {
3937  ubvars[i] = 0.0; /* upper variables are always 0.0 */
3938  lbvars[i] = 0.0; /* most lower bound variables are 0.0 */
3939 
3940  /* if the variable was being optimized */
3941  if ( sdpi->onevarsdpidx == i )
3942  {
3943  /* if optimal value is equal to the lower bound */
3944  if ( REALABS(sdpi->onevarsdpoptval - sdpi->sdpilb[i]) < sdpi->feastol )
3945  {
3946  /* the primal variable is equal to the objective */
3947  lbvars[i] = sdpi->obj[i];
3948  }
3949  }
3950  else
3951  assert( isFixed(sdpi, i) );
3952  }
3953  }
3954  else if ( sdpi->solvedonevarsdp == SCIP_ONEVAR_INFEASIBLE )
3955  {
3956  SCIPdebugMessage("Problem is infeasible, no primal variables available.\n");
3957  *arraylength = -1;
3958  }
3959  /* If the dual is infeasible, there is no feasible solution; If the primal is infeasible, the dual is unbounded or
3960  * infeasible. In both cases we should not return the solution (rather a ray). */
3961  else if ( SCIPsdpiSolverIsDualInfeasible(sdpi->sdpisolver) || SCIPsdpiSolverIsPrimalInfeasible(sdpi->sdpisolver) )
3962  {
3963  SCIPdebugMessage("Problem infeasible.\n");
3964  *arraylength = -1;
3965  }
3966  else
3967  {
3968  SCIP_CALL( SCIPsdpiSolverGetPrimalBoundVars(sdpi->sdpisolver, lbvars, ubvars, arraylength) );
3969  }
3970 
3971  return SCIP_OKAY;
3972 }
3973 
3976  SCIP_SDPI* sdpi,
3977  int nblocks,
3978  int* startXnblocknonz
3979  )
3980 {
3981  assert( sdpi != NULL );
3982 
3983  if ( sdpi->infeasible )
3984  {
3985  SCIPdebugMessage("Infeasibility was detected while preparing problem, no primal solution available.\n");
3986  }
3987  else if ( sdpi->allfixed )
3988  {
3989  SCIPdebugMessage("All variables fixed during preprocessing, no primal solution available.\n");
3990  }
3991  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
3992  {
3993  SCIPdebugMessage("Solved one variable SDP, no primal solution available.\n");
3994  }
3995  else
3996  {
3997  SCIP_CALL( SCIPsdpiSolverGetPrimalNonzeros(sdpi->sdpisolver, nblocks, startXnblocknonz) );
3998  }
3999 
4000  return SCIP_OKAY;
4001 }
4002 
4010  SCIP_SDPI* sdpi,
4011  int nblocks,
4012  int* startXnblocknonz,
4014  int** startXrow,
4015  int** startXcol,
4016  SCIP_Real** startXval
4017  )
4018 {/* TODO: should also set startXnblocknonz[0] = -1 in case the problem was solved in presolving */
4019  assert( sdpi != NULL );
4020 
4021  if ( sdpi->infeasible )
4022  {
4023  SCIPdebugMessage("Infeasibility was detected while preparing problem, no primal solution available.\n");
4024  }
4025  else if ( sdpi->allfixed )
4026  {
4027  SCIPdebugMessage("All variables fixed during preprocessing, no primal solution available.\n");
4028  }
4029  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
4030  {
4031  SCIPdebugMessage("Solved one variable SDP, no primal solution available.\n");
4032  }
4033  else
4034  {
4035  SCIP_CALL( SCIPsdpiSolverGetPrimalMatrix(sdpi->sdpisolver, nblocks, startXnblocknonz, startXrow, startXcol, startXval) );
4036  }
4037 
4038  return SCIP_OKAY;
4039 }
4040 
4043  SCIP_SDPI* sdpi
4044  )
4045 {
4046  assert( sdpi != NULL );
4047 
4048  return SCIPsdpiSolverGetMaxPrimalEntry(sdpi->sdpisolver);
4049 }
4050 
4052 SCIP_RETCODE SCIPsdpiGetTime(
4053  SCIP_SDPI* sdpi,
4054  SCIP_Real* opttime
4055  )
4056 {
4057  assert( sdpi != NULL );
4058  assert( opttime != NULL );
4059 
4060  *opttime = sdpi->opttime;
4061 
4062  return SCIP_OKAY;
4063 }
4064 
4067  SCIP_SDPI* sdpi,
4068  int* iterations
4069  )
4070 {
4071  assert( sdpi != NULL );
4072  assert( iterations != NULL );
4073 
4074  *iterations = sdpi->niterations;
4075 
4076  return SCIP_OKAY;
4077 }
4078 
4080 SCIP_RETCODE SCIPsdpiGetSdpCalls(
4081  SCIP_SDPI* sdpi,
4082  int* calls
4083  )
4084 {
4085  assert( sdpi != NULL );
4086  assert( calls != NULL );
4087 
4088  *calls = sdpi->nsdpcalls;
4089 
4090  return SCIP_OKAY;
4091 }
4092 
4095  SCIP_SDPI* sdpi,
4096  SCIP_SDPSOLVERSETTING* usedsetting
4097  )
4098 {
4099  assert( sdpi != NULL );
4100  assert( usedsetting != NULL );
4101 
4102  if ( ! sdpi->solved )
4103  {
4104  SCIPdebugMessage("Problem was not solved successfully.\n");
4105  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4106  }
4107  else if ( sdpi->infeasible && ! sdpi->penalty ) /* if we solved the penalty formulation, we may also set infeasible if it is infeasible for the original problem */
4108  {
4109  SCIPdebugMessage("Infeasibility was detected while preparing the problem, no settings used.\n");
4110  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4111  }
4112  else if ( sdpi->allfixed )
4113  {
4114  SCIPdebugMessage("All varialbes fixed during preprocessing, no settings used.\n");
4115  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4116  }
4117  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
4118  {
4119  SCIPdebugMessage("Solved one variable SDP, no settings used.\n");
4120  *usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4121  }
4122  else if ( sdpi->penalty )
4123  {
4124  *usedsetting = SCIP_SDPSOLVERSETTING_PENALTY;
4125  }
4126  else
4127  {
4128  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, usedsetting) );
4129  }
4130 
4131  return SCIP_OKAY;
4132 }
4133 
4136  SCIP_SDPI* sdpi,
4137  SCIP_SDPSLATERSETTING* slatersetting
4138  )
4139 {
4140  SCIP_SDPSOLVERSETTING usedsetting;
4141 
4142  assert( sdpi != NULL );
4143  assert( slatersetting != NULL );
4144 
4145  if ( ! sdpi->solved )
4146  {
4147  SCIPdebugMessage("Problem was not solved successfully.\n");
4148  if ( sdpi->bestbound > -SCIPsdpiSolverInfinity(sdpi->sdpisolver) )
4149  {
4150  SCIPdebugMessage("But we could at least compute a lower bound.\n");
4151  if ( sdpi->dualslater == SCIP_SDPSLATER_INF)
4152  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDINFEASIBLE;
4153  else
4154  {
4155  switch( sdpi->primalslater )/*lint --e{788}*/
4156  {
4157  case SCIP_SDPSLATER_NOINFO:
4158  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
4159  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
4160  else
4161  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4162  break;
4163  case SCIP_SDPSLATER_NOT:
4164  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
4165  break;
4166  case SCIP_SDPSLATER_HOLDS:
4167  switch( sdpi->dualslater )/*lint --e{788}*/
4168  {
4169  case SCIP_SDPSLATER_NOINFO:
4170  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4171  break;
4172  case SCIP_SDPSLATER_NOT:
4173  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDNOSLATER;
4174  break;
4175  case SCIP_SDPSLATER_HOLDS:
4176  *slatersetting = SCIP_SDPSLATERSETTING_BOUNDEDWSLATER;
4177  break;
4178  default:
4179  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4180  break;
4181  }
4182  break;
4183  default:
4184  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4185  break;
4186  }
4187  }
4188  }
4189  else
4190  {
4191  if ( sdpi->dualslater == SCIP_SDPSLATER_INF)
4193  else
4194  {
4195  switch( sdpi->primalslater )/*lint --e{788}*/
4196  {
4197  case SCIP_SDPSLATER_NOINFO:
4198  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
4199  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
4200  else
4201  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4202  break;
4203  case SCIP_SDPSLATER_NOT:
4204  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
4205  break;
4206  case SCIP_SDPSLATER_HOLDS:
4207  switch( sdpi->dualslater )/*lint --e{788}*/
4208  {
4209  case SCIP_SDPSLATER_NOINFO:
4210  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4211  break;
4212  case SCIP_SDPSLATER_NOT:
4213  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDNOSLATER;
4214  break;
4215  case SCIP_SDPSLATER_HOLDS:
4216  *slatersetting = SCIP_SDPSLATERSETTING_UNSOLVEDWSLATER;
4217  break;
4218  default:
4219  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4220  break;
4221  }
4222  break;
4223  default:
4224  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4225  break;
4226  }
4227  }
4228  }
4229  return SCIP_OKAY;
4230  }
4231  else if ( sdpi->infeasible && ( ! sdpi->penalty ) ) /* if we solved the penalty formulation, we may also set infeasible if it is infeasible for the original problem */
4232  {
4233  SCIPdebugMessage("Infeasibility was detected while preparing problem, no settings used.\n");
4234  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4235  return SCIP_OKAY;
4236  }
4237  else if ( sdpi->allfixed )
4238  {
4239  SCIPdebugMessage("All varialbes fixed during preprocessing, no settings used.\n");
4240  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4241  return SCIP_OKAY;
4242  }
4243  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
4244  {
4245  SCIPdebugMessage("Solved one variable SDP, no settings used.\n");
4246  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4247  return SCIP_OKAY;
4248  }
4249  else if ( sdpi->penalty )
4250  {
4251  switch( sdpi->primalslater )/*lint --e{788}*/
4252  {
4253  case SCIP_SDPSLATER_NOINFO:
4254  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
4255  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
4256  else if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
4257  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
4258  else
4259  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4260  break;
4261  case SCIP_SDPSLATER_NOT:
4262  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
4263  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
4264  else
4265  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
4266  break;
4267  case SCIP_SDPSLATER_HOLDS:
4268  switch( sdpi->dualslater )/*lint --e{788}*/
4269  {
4270  case SCIP_SDPSLATER_NOINFO:
4271  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4272  break;
4273  case SCIP_SDPSLATER_NOT:
4274  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYNOSLATER;
4275  break;
4276  case SCIP_SDPSLATER_HOLDS:
4277  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYWSLATER;
4278  break;
4279  case SCIP_SDPSLATER_INF:
4280  *slatersetting = SCIP_SDPSLATERSETTING_PENALTYINFEASIBLE;
4281  break;
4282  default:
4283  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4284  break;
4285  }
4286  break;
4287  default:
4288  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4289  break;
4290  }
4291  return SCIP_OKAY;
4292  }
4293 
4294  switch( sdpi->primalslater )/*lint --e{788}*/
4295  {
4296  case SCIP_SDPSLATER_NOINFO:
4297  if ( sdpi->dualslater == SCIP_SDPSLATER_NOT )
4298  {
4299  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4300  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
4301  switch( usedsetting )/*lint --e{788}*/
4302  {
4304  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
4305  break;
4308  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
4309  break;
4310  default:
4311  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4312  break;
4313  }
4314  }
4315  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
4316  {
4317  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4318  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
4319  switch( usedsetting )/*lint --e{788}*/
4320  {
4322  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
4323  break;
4327  break;
4328  default:
4329  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4330  break;
4331  }
4332  }
4333  else
4334  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4335  break;
4336  case SCIP_SDPSLATER_NOT:
4337  if ( sdpi->dualslater == SCIP_SDPSLATER_INF )
4338  {
4339  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4340  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
4341  switch( usedsetting )/*lint --e{788}*/
4342  {
4344  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
4345  break;
4349  break;
4350  default:
4351  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4352  break;
4353  }
4354  }
4355  else
4356  {
4357  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4358  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
4359  switch( usedsetting )/*lint --e{788}*/
4360  {
4362  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
4363  break;
4366  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
4367  break;
4368  default:
4369  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4370  break;
4371  }
4372  }
4373  break;
4374  case SCIP_SDPSLATER_HOLDS:
4375  switch( sdpi->dualslater )/*lint --e{788}*/
4376  {
4377  case SCIP_SDPSLATER_NOINFO:
4378  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4379  break;
4380  case SCIP_SDPSLATER_NOT:
4381  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4382  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
4383  switch( usedsetting )/*lint --e{788}*/
4384  {
4386  *slatersetting = SCIP_SDPSLATERSETTING_STABLENOSLATER;
4387  break;
4390  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLENOSLATER;
4391  break;
4392  default:
4393  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4394  break;
4395  }
4396  break;
4397  case SCIP_SDPSLATER_INF:
4398  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4399  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
4400  switch( usedsetting )/*lint --e{788}*/
4401  {
4403  *slatersetting = SCIP_SDPSLATERSETTING_STABLEINFEASIBLE;
4404  break;
4408  break;
4409  default:
4410  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4411  break;
4412  }
4413  break;
4414  case SCIP_SDPSLATER_HOLDS:
4415  usedsetting = SCIP_SDPSOLVERSETTING_UNSOLVED;
4416  SCIP_CALL( SCIPsdpiSolverSettingsUsed(sdpi->sdpisolver, &usedsetting) );
4417  switch( usedsetting )/*lint --e{788}*/
4418  {
4420  *slatersetting = SCIP_SDPSLATERSETTING_STABLEWSLATER;
4421  break;
4424  *slatersetting = SCIP_SDPSLATERSETTING_UNSTABLEWSLATER;
4425  break;
4426  default:
4427  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4428  break;
4429  }
4430  break;
4431  default:
4432  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4433  break;
4434  }
4435  break;
4436  default:
4437  *slatersetting = SCIP_SDPSLATERSETTING_NOINFO;
4438  break;
4439  }
4440 
4441  return SCIP_OKAY;
4442 }
4443 
4445 SCIP_RETCODE SCIPsdpiSlater(
4446  SCIP_SDPI* sdpi,
4447  SCIP_SDPSLATER* primalslater,
4448  SCIP_SDPSLATER* dualslater
4449  )
4450 {
4451  assert( sdpi != NULL );
4452  assert( primalslater != NULL );
4453  assert( dualslater != NULL );
4454 
4455  if ( sdpi->infeasible )
4456  {
4457  *primalslater = SCIP_SDPSLATER_NOINFO;
4458  *dualslater = sdpi->dualslater;
4459  return SCIP_OKAY;
4460  }
4461  else if ( sdpi->allfixed )
4462  {
4463  *primalslater = SCIP_SDPSLATER_NOINFO;
4464  *dualslater = SCIP_SDPSLATER_NOINFO;
4465  return SCIP_OKAY;
4466  }
4467  else if ( sdpi->solvedonevarsdp > SCIP_ONEVAR_UNSOLVED )
4468  {
4469  *primalslater = SCIP_SDPSLATER_NOINFO;
4470  *dualslater = SCIP_SDPSLATER_NOINFO;
4471  return SCIP_OKAY;
4472  }
4473 
4474  *primalslater = sdpi->primalslater;
4475  *dualslater = sdpi->dualslater;
4476 
4477  return SCIP_OKAY;
4478 }
4479 
4482  SCIP_SDPI* sdpi,
4483  int* ninfeasible,
4484  int* nallfixed,
4485  int* nonevarsdp
4486  )
4487 {
4488  assert( sdpi != NULL );
4489  assert( ninfeasible != NULL );
4490  assert( nallfixed != NULL );
4491  assert( nonevarsdp != NULL );
4492 
4493  *ninfeasible = sdpi->ninfeasible;
4494  *nallfixed = sdpi->nallfixed;
4495  *nonevarsdp = sdpi->nonevarsdp;
4496 
4497  return SCIP_OKAY;
4498 }
4499 
4505 /*
4506  * Numerical Methods
4507  */
4508 
4514  SCIP_SDPI* sdpi
4515  )
4516 {
4517  assert( sdpi != NULL );
4518 
4519  return SCIPsdpiSolverInfinity(sdpi->sdpisolver);
4520 }
4521 
4524  SCIP_SDPI* sdpi,
4525  SCIP_Real val
4526  )
4527 {
4528  assert( sdpi != NULL );
4529 
4530  return ((val <= -SCIPsdpiInfinity(sdpi)) || (val >= SCIPsdpiInfinity(sdpi)));
4531 }
4532 
4534 SCIP_RETCODE SCIPsdpiGetRealpar(
4535  SCIP_SDPI* sdpi,
4536  SCIP_SDPPARAM type,
4537  SCIP_Real* dval
4538  )
4539 {
4540  assert( sdpi != NULL );
4541  assert( sdpi->sdpisolver != NULL );
4542  assert( dval != NULL );
4543 
4544  switch( type )/*lint --e{788}*/
4545  {
4546  case SCIP_SDPPAR_EPSILON:
4547  *dval = sdpi->epsilon;
4548  break;
4549  case SCIP_SDPPAR_GAPTOL:
4550  *dval = sdpi->gaptol;
4551  break;
4552  case SCIP_SDPPAR_FEASTOL:
4553  *dval = sdpi->feastol;
4554  break;
4556  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4557  break;
4558  case SCIP_SDPPAR_OBJLIMIT:
4559  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4560  break;
4562  *dval = sdpi->penaltyparam;
4563  break;
4565  *dval = sdpi->maxpenaltyparam;
4566  break;
4568  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4569  break;
4571  SCIP_CALL_PARAM( SCIPsdpiSolverGetRealpar(sdpi->sdpisolver, type, dval) );
4572  break;
4574  *dval = sdpi->peninfeasadjust;
4575  break;
4576  default:
4577  return SCIP_PARAMETERUNKNOWN;
4578  }
4579 
4580  return SCIP_OKAY;
4581 }
4582 
4584 SCIP_RETCODE SCIPsdpiSetRealpar(
4585  SCIP_SDPI* sdpi,
4586  SCIP_SDPPARAM type,
4587  SCIP_Real dval
4588  )
4589 {
4590  assert( sdpi != NULL );
4591 
4592  switch( type )/*lint --e{788}*/
4593  {
4594  case SCIP_SDPPAR_EPSILON:
4595  sdpi->epsilon = dval;
4596  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4597  break;
4598  case SCIP_SDPPAR_GAPTOL:
4599  sdpi->gaptol = dval;
4600  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4601  break;
4602  case SCIP_SDPPAR_FEASTOL:
4603  sdpi->feastol = dval;
4604  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4605  break;
4607  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4608  break;
4609  case SCIP_SDPPAR_OBJLIMIT:
4610  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4611  break;
4613  sdpi->penaltyparam = dval;
4614  SCIP_CALL_PARAM_IGNORE_UNKNOWN( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4615  break;
4617  sdpi->maxpenaltyparam = dval;
4618  break;
4620  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4621  break;
4623  SCIP_CALL_PARAM( SCIPsdpiSolverSetRealpar(sdpi->sdpisolver, type, dval) );
4624  break;
4626  sdpi->peninfeasadjust = dval;
4627  break;
4628  default:
4629  return SCIP_PARAMETERUNKNOWN;
4630  }
4631 
4632  return SCIP_OKAY;
4633 }
4634 
4636 SCIP_RETCODE SCIPsdpiGetIntpar(
4637  SCIP_SDPI* sdpi,
4638  SCIP_SDPPARAM type,
4639  int* ival
4640  )
4641 {
4642  assert( sdpi != NULL );
4643  assert( sdpi->sdpisolver != NULL );
4644  assert( ival != NULL );
4645 
4646  switch( type )/*lint --e{788}*/
4647  {
4648  case SCIP_SDPPAR_SDPINFO:
4649  case SCIP_SDPPAR_NTHREADS:
4652  case SCIP_SDPPAR_SCALEOBJ:
4653  SCIP_CALL_PARAM( SCIPsdpiSolverGetIntpar(sdpi->sdpisolver, type, ival) );
4654  break;
4656  *ival = sdpi->slatercheck;
4657  break;
4659  *ival = sdpi->npenaltyincr;
4660  break;
4661  default:
4662  return SCIP_PARAMETERUNKNOWN;
4663  }
4664 
4665  return SCIP_OKAY;
4666 }
4667 
4669 SCIP_RETCODE SCIPsdpiSetIntpar(
4670  SCIP_SDPI* sdpi,
4671  SCIP_SDPPARAM type,
4672  int ival
4673  )
4674 {
4675  assert( sdpi != NULL );
4676  assert( sdpi->sdpisolver != NULL );
4677 
4678  switch( type )/*lint --e{788}*/
4679  {
4680  case SCIP_SDPPAR_SDPINFO:
4683  case SCIP_SDPPAR_SCALEOBJ:
4684  assert( ival == 0 || ival == 1 ); /* this is a boolean parameter */
4685  SCIP_CALL_PARAM( SCIPsdpiSolverSetIntpar(sdpi->sdpisolver, type, ival) );
4686  break;
4687  case SCIP_SDPPAR_NTHREADS:
4688  SCIP_CALL_PARAM( SCIPsdpiSolverSetIntpar(sdpi->sdpisolver, type, ival) );
4689  break;
4691  sdpi->slatercheck = ival;
4692  break;
4694  sdpi->npenaltyincr = ival;
4695  break;
4696  default:
4697  return SCIP_PARAMETERUNKNOWN;
4698  }
4699 
4700  return SCIP_OKAY;
4701 }
4702 
4705  SCIP_SDPI* sdpi,
4706  SCIP_Real maxguess
4707  )
4708 {
4709  return SCIPsdpiSolverComputeLambdastar(sdpi->sdpisolver, maxguess);
4710 }
4711 
4714  SCIP_SDPI* sdpi,
4715  SCIP_Real maxcoeff,
4716  SCIP_Real* penaltyparam
4717  )
4718 {
4719  SCIP_CALL( SCIPsdpiSolverComputePenaltyparam(sdpi->sdpisolver, maxcoeff, penaltyparam) );
4720 
4721  sdpi->penaltyparam = *penaltyparam;
4722 
4723  return SCIP_OKAY;
4724 }
4725 
4728  SCIP_SDPI* sdpi,
4729  SCIP_Real penaltyparam,
4730  SCIP_Real* maxpenaltyparam
4731  )
4732 {
4733  SCIP_CALL( SCIPsdpiSolverComputeMaxPenaltyparam(sdpi->sdpisolver, penaltyparam, maxpenaltyparam) );
4734 
4735  sdpi->maxpenaltyparam = *maxpenaltyparam;
4736 
4737  /* if the initial penalty parameter is smaller than the maximum one, we decrease the initial correspondingly */
4738  /* if the maximum penalty parameter is smaller than the initial penalty paramater, we decrease the initial one correspondingly */
4739  if ( sdpi->penaltyparam > *maxpenaltyparam )
4740  {
4741  SCIPdebugMessage("Decreasing penaltyparameter of %g to maximum penalty paramater of %g.\n", sdpi->penaltyparam, *maxpenaltyparam);
4742  sdpi->penaltyparam = *maxpenaltyparam;
4743  }
4744 
4745  return SCIP_OKAY;
4746 }
4747 
4750  SCIP_SDPI* sdpi,
4751  int clocktype
4752  )
4753 {
4754  assert( sdpi != NULL );
4755  assert( clocktype == 1 || clocktype == 2 );
4756  assert( sdpi->usedsdpitime != NULL );
4757 
4758  SDPIclockSetType(sdpi->usedsdpitime, (SDPI_CLOCKTYPE) clocktype);
4759 }
4760 
4766 /*
4767  * File Interface Methods
4768  */
4769 
4774 SCIP_RETCODE SCIPsdpiReadSDP(
4775  SCIP_SDPI* sdpi,
4776  const char* fname
4777  )
4778 {
4779  assert( sdpi != NULL );
4780  assert( fname != NULL );
4781 
4782  SCIPerrorMessage("Not implemented yet.\n");
4783 
4784  return SCIP_NOTIMPLEMENTED;
4785 }
4786 
4788 SCIP_RETCODE SCIPsdpiWriteSDP(
4789  SCIP_SDPI* sdpi,
4790  const char* fname
4791  )
4792 {
4793  assert( sdpi != NULL );
4794  assert( fname != NULL );
4795 
4796  SCIPerrorMessage("Not implemented yet.\n");
4797 
4798  return SCIP_NOTIMPLEMENTED;
4799 }
4800 
SCIP_RETCODE SCIPsdpiFree(SCIP_SDPI **sdpi)
Definition: sdpi.c:1594
SCIP_Bool SCIPsdpiIsDualUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:3303
#define DEFAULT_SDPSOLVERGAPTOL
Definition: sdpi.c:197
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetPrimalBoundVars(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
SCIP_RETCODE SCIPsdpiDelLPRows(SCIP_SDPI *sdpi, int firstrow, int lastrow)
Definition: sdpi.c:2120
SCIP_EXPORT SCIP_Real SCIPsdpiSolverInfinity(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetTime(SCIP_SDPI *sdpi, SCIP_Real *opttime)
Definition: sdpi.c:4052
SCIP_Onevar_Status
Definition: sdpi.c:205
SCIP_EXPORT int SCIPsdpiSolverGetInternalStatus(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiChgLPLhRhSides(SCIP_SDPI *sdpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: sdpi.c:2358
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int *ival)
SCIP_RETCODE SCIPsolveOneVarSDP(BMS_BUFMEM *bufmem, SCIP_Real obj, SCIP_Real lb, SCIP_Real ub, int blocksize, int sdpconstnnonz, int *sdpconstrow, int *sdpconstcol, SCIP_Real *sdpconstval, int sdpnnonz, int *sdprow, int *sdpcol, SCIP_Real *sdpval, SCIP_Real infinity, SCIP_Real feastol, SCIP_Real *objval, SCIP_Real *optval)
SCIP_RETCODE SCIPsdpiGetSdpCalls(SCIP_SDPI *sdpi, int *calls)
Definition: sdpi.c:4080
SCIP_Bool SCIPsdpiDoesWarmstartNeedPrimal(void)
Definition: sdpi.c:1478
#define BMS_CALL(x)
Definition: sdpi.c:122
SCIP_EXPORT SCIP_Real SCIPsdpiSolverGetMaxPrimalEntry(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetTime(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *opttime)
SCIP_RETCODE SCIPsdpiGetSolFeasibility(SCIP_SDPI *sdpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: sdpi.c:3174
SCIP_RETCODE SCIPsdpiWriteSDP(SCIP_SDPI *sdpi, const char *fname)
Definition: sdpi.c:4788
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real *dval)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverResetCounter(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverSettingsUsed(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPSOLVERSETTING *usedsetting)
SCIP_RETCODE SCIPsdpiGetLPNNonz(SCIP_SDPI *sdpi, int *nnonz)
Definition: sdpi.c:2481
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetPreoptimalSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *success, SCIP_Real *dualsol, int *dualsollength, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
static SCIP_RETCODE checkFixedFeasibilitySdp(SCIP_SDPI *sdpi, SCIP_Real *sdpilb, SCIP_Real *sdpiub)
Definition: sdpi.c:971
SCIP_RETCODE SCIPsdpiGetPrimalMatrix(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
Definition: sdpi.c:4009
enum SCIP_SDPSolverSetting SCIP_SDPSOLVERSETTING
Definition: type_sdpi.h:83
void SCIPsdpiClockSetType(SCIP_SDPI *sdpi, int clocktype)
Definition: sdpi.c:4749
SCIP_Bool SCIPsdpiIsOptimal(SCIP_SDPI *sdpi)
Definition: sdpi.c:3520
SCIP_RETCODE SCIPsdpiGetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int *ival)
Definition: sdpi.c:4636
enum SDPI_ClockType SDPI_CLOCKTYPE
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsObjlimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiGetSDPNNonz(SCIP_SDPI *sdpi, int *nnonz)
Definition: sdpi.c:2453
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsConverged(SCIP_SDPISOLVER *sdpisolver)
#define MIN_GAPTOL
Definition: sdpi.c:196
SCIP_Bool SCIPsdpiIsInfinity(SCIP_SDPI *sdpi, SCIP_Real val)
Definition: sdpi.c:4523
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverSetRealpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, SCIP_Real dval)
const char * SCIPsdpiGetSolverName(void)
Definition: sdpi.c:1441
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverLoadAndSolveWithPenalty(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Bool withobj, SCIP_Bool rbound, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit, SDPI_CLOCK *usedsdpitime, SCIP_Bool *feasorig, SCIP_Bool *penaltybound)
enum SCIP_Onevar_Status SCIP_ONEVAR_STATUS
Definition: sdpi.c:211
SCIP_RETCODE SCIPsdpiGetNSDPBlocks(SCIP_SDPI *sdpi, int *nsdpblocks)
Definition: sdpi.c:2425
SCIP_RETCODE SCIPsdpiGetSol(SCIP_SDPI *sdpi, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
Definition: sdpi.c:3666
interface methods for specific SDP-solvers
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsTimelimExc(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiIsPrimalInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:3250
#define DEFAULT_FEASTOL
Definition: sdpi.c:198
SCIP_RETCODE SCIPsdpiSolve(SCIP_SDPI *sdpi, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Bool enforceslatercheck, SCIP_Real timelimit)
Definition: sdpi.c:2607
SCIP_Bool SCIPsdpiFeasibilityKnown(SCIP_SDPI *sdpi)
Definition: sdpi.c:3160
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:1836
SCIP_RETCODE SCIPsdpiComputeLambdastar(SCIP_SDPI *sdpi, SCIP_Real maxguess)
Definition: sdpi.c:4704
SCIP_RETCODE SCIPsdpiGetPrimalNonzeros(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz)
Definition: sdpi.c:3975
SCIP_RETCODE SCIPsdpiGetIterations(SCIP_SDPI *sdpi, int *iterations)
Definition: sdpi.c:4066
SCIP_RETCODE SCIPsdpiSettingsUsed(SCIP_SDPI *sdpi, SCIP_SDPSOLVERSETTING *usedsetting)
Definition: sdpi.c:4094
SCIP_RETCODE SCIPsdpiSlaterSettings(SCIP_SDPI *sdpi, SCIP_SDPSLATERSETTING *slatersetting)
Definition: sdpi.c:4135
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetSolFeasibility(SCIP_SDPISOLVER *sdpisolver, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsPrimalInfeasible(SCIP_SDPISOLVER *sdpisolver)
static SCIP_RETCODE checkSlaterCondition(SCIP_SDPI *sdpi, SCIP_Real timelimit, SCIP_Real *sdpilb, SCIP_Real *sdpiub, int *sdpconstnblocknonz, int sdpconstnnonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int **indchanges, int *nremovedinds, int nactivelpcons, SCIP_Real *sdpilplhs, SCIP_Real *sdpilprhs, int sdpilpnnonz, int *sdpilprow, int *sdpilpcol, SCIP_Real *sdpilpval, int *blockindchanges, int nremovedblocks, SCIP_Bool rootnodefailed)
Definition: sdpi.c:1073
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetSol(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
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:643
SCIP_Bool SCIPsdpiIsAcceptable(SCIP_SDPI *sdpi)
Definition: sdpi.c:3548
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsDualFeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiIsIterlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3427
SCIP_Bool SCIPsdpiIsTimelimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3451
SCIP_Bool SCIPsdpiIsDualInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:3327
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:2467
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetSdpCalls(SCIP_SDPISOLVER *sdpisolver, int *calls)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverCreate(SCIP_SDPISOLVER **sdpisolver, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem)
enum SCIP_SDPSlaterSetting SCIP_SDPSLATERSETTING
Definition: type_sdpi.h:105
SCIP_RETCODE SCIPsdpiClone(SCIP_SDPI *oldsdpi, SCIP_SDPI *newsdpi)
Definition: sdpi.c:1677
void SDPIclockFree(SDPI_CLOCK **clck)
Definition: sdpiclock.c:111
SCIP_RETCODE SCIPsdpiChgBounds(SCIP_SDPI *sdpi, int nvars, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: sdpi.c:2323
SCIP_RETCODE SCIPsdpiDelLPRowset(SCIP_SDPI *sdpi, int *dstat)
Definition: sdpi.c:2215
SCIP_RETCODE SCIPsdpiGetLowerObjbound(SCIP_SDPI *sdpi, SCIP_Real *objlb)
Definition: sdpi.c:3614
SCIP_Bool SCIPsdpiIsObjlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:3403
#define SCIP_CALL_PARAM_IGNORE_UNKNOWN(x)
Definition: sdpi.c:181
SCIP_RETCODE SCIPsdpiGetObj(SCIP_SDPI *sdpi, int firstvar, int lastvar, SCIP_Real *vals)
Definition: sdpi.c:2495
SCIP_RETCODE SDPIclockCreate(SDPI_CLOCK **clck)
Definition: sdpiclock.c:96
SCIP_EXPORT int SCIPsdpiSolverGetDefaultSdpiSolverNpenaltyIncreases(void)
void * SCIPsdpiGetSolverPointer(SCIP_SDPI *sdpi)
Definition: sdpi.c:1462
void SDPIclockStop(SDPI_CLOCK *clck)
Definition: sdpiclock.c:192
int SCIPsdpiGetInternalStatus(SCIP_SDPI *sdpi)
Definition: sdpi.c:3489
static SCIP_RETCODE ensureLPDataMemory(SCIP_SDPI *sdpi, int nlpcons, int nlpnonz)
Definition: sdpi.c:398
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverSetIntpar(SCIP_SDPISOLVER *sdpisolver, SCIP_SDPPARAM type, int ival)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverFeasibilityKnown(SCIP_SDPISOLVER *sdpisolver)
void SDPIclockStart(SDPI_CLOCK *clck)
Definition: sdpiclock.c:134
static SCIP_RETCODE ensureSDPDataMemory(SCIP_SDPI *sdpi, int nsdpblocks, int *sdpnblockvars, int **sdpnblockvarnonz, int *sdpconstnblocknonz, int sdpnnonz)
Definition: sdpi.c:440
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:2038
SCIP_EXPORT const char * SCIPsdpiSolverGetSolverName(void)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetPrimalMatrix(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
SCIP_RETCODE SCIPsdpiGetNVars(SCIP_SDPI *sdpi, int *nvars)
Definition: sdpi.c:2439
const char * SCIPsdpiGetSolverDesc(void)
Definition: sdpi.c:1449
SCIP_RETCODE SCIPsdpiComputePenaltyparam(SCIP_SDPI *sdpi, SCIP_Real maxcoeff, SCIP_Real *penaltyparam)
Definition: sdpi.c:4713
SCIP_RETCODE SCIPsdpiSetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int ival)
Definition: sdpi.c:4669
SCIP_Bool SCIPsdpiIsPrimalUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:3220
SCIP_Real SCIPsdpiInfinity(SCIP_SDPI *sdpi)
Definition: sdpi.c:4513
#define CHECK_IF_SOLVED_BOOL(sdpi)
Definition: sdpi.c:144
SCIP_RETCODE SCIPsdpiGetRhSides(SCIP_SDPI *sdpi, int firstrow, int lastrow, SCIP_Real *rhss)
Definition: sdpi.c:2568
SCIP_RETCODE SCIPsdpiCreate(SCIP_SDPI **sdpi, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem)
Definition: sdpi.c:1496
#define DUPLICATE_ARRAY_NULL(blkmem, target, source, size)
Definition: sdpi.c:155
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsDualInfeasible(SCIP_SDPISOLVER *sdpisolver)
adds the main functionality to fix/unfix/(multi-)aggregate variables by merging two three-tuple-array...
SCIP_EXPORT const char * SCIPsdpiSolverGetSolverDesc(void)
void SDPIclockSetType(SDPI_CLOCK *clck, SDPI_CLOCKTYPE clocktype)
Definition: sdpiclock.c:121
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverComputeMaxPenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real penaltyparam, SCIP_Real *maxpenaltyparam)
SCIP_RETCODE SCIPsdpiGetObjval(SCIP_SDPI *sdpi, SCIP_Real *objval)
Definition: sdpi.c:3576
SCIP_EXPORT void * SCIPsdpiSolverGetSolverPointer(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsAcceptable(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverIncreaseCounter(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsOptimal(SCIP_SDPISOLVER *sdpisolver)
int SCIPsdpiGetDefaultSdpiSolverNpenaltyIncreases(void)
Definition: sdpi.c:1470
SCIP_Bool SCIPsdpiIsConverged(SCIP_SDPI *sdpi)
Definition: sdpi.c:3379
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverWasSolved(SCIP_SDPISOLVER *sdpisolver)
static SCIP_RETCODE prepareLPData(SCIP_SDPI *sdpi, SCIP_Real *sdpilb, SCIP_Real *sdpiub, int *nsdpilpcons, SCIP_Real *sdpilplhs, SCIP_Real *sdpilprhs, int *sdpilpnnonz, int *sdpilprow, int *sdpilpcol, SCIP_Real *sdpilpval, SCIP_Bool *fixingsfound)
Definition: sdpi.c:778
#define DEFAULT_MAXPENALTYPARAM
Definition: sdpi.c:201
SCIP_RETCODE SCIPsdpiGetStatistics(SCIP_SDPI *sdpi, int *ninfeasible, int *nallfixed, int *nonevarsdp)
Definition: sdpi.c:4481
SCIP_Bool SCIPsdpiWasSolved(SCIP_SDPI *sdpi)
Definition: sdpi.c:3137
SCIP_RETCODE SCIPsdpiReadSDP(SCIP_SDPI *sdpi, const char *fname)
Definition: sdpi.c:4774
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverDoesWarmstartNeedPrimal(void)
SCIP_RETCODE SCIPsdpiComputeMaxPenaltyparam(SCIP_SDPI *sdpi, SCIP_Real penaltyparam, SCIP_Real *maxpenaltyparam)
Definition: sdpi.c:4727
SCIP_RETCODE SCIPsdpiClear(SCIP_SDPI *sdpi)
Definition: sdpi.c:2258
SCIP_RETCODE SCIPsdpiGetBounds(SCIP_SDPI *sdpi, int firstvar, int lastvar, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: sdpi.c:2517
SCIP_RETCODE SCIPsdpiChgObj(SCIP_SDPI *sdpi, int nvars, const int *ind, const SCIP_Real *obj)
Definition: sdpi.c:2293
static SCIP_RETCODE ensureBoundDataMemory(SCIP_SDPI *sdpi, int nvars)
Definition: sdpi.c:372
SCIP_RETCODE SCIPsdpiGetPreoptimalSol(SCIP_SDPI *sdpi, SCIP_Bool *success, SCIP_Real *dualsol, int *dualsollength, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
Definition: sdpi.c:3788
#define DEFAULT_NPENALTYINCR
Definition: sdpi.c:202
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetObjval(SCIP_SDPISOLVER *sdpisolver, SCIP_Real *objval)
#define DEFAULT_PENALTYPARAM
Definition: sdpi.c:200
SCIP_Bool SCIPsdpiIsDualFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:3353
struct SCIP_SDPi SCIP_SDPI
Definition: type_sdpi.h:117
Solve SDP with one variable.
SCIP_Bool SCIPsdpiIsPrimalFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:3275
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverComputePenaltyparam(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxcoeff, SCIP_Real *penaltyparam)
SCIP_RETCODE SCIPsdpiSetRealpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, SCIP_Real dval)
Definition: sdpi.c:4584
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverLoadAndSolve(SCIP_SDPISOLVER *sdpisolver, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int **indchanges, int *nremovedinds, int *blockindchanges, int nremovedblocks, int nlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval, SCIP_Real *starty, int *startZnblocknonz, int **startZrow, int **startZcol, SCIP_Real **startZval, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval, SCIP_SDPSOLVERSETTING startsettings, SCIP_Real timelimit, SDPI_CLOCK *usedsdpitime)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetPrimalNonzeros(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz)
enum SCIP_SDPSlater SCIP_SDPSLATER
Definition: type_sdpi.h:115
SCIP_Real SCIPsdpiGetMaxPrimalEntry(SCIP_SDPI *sdpi)
Definition: sdpi.c:4042
SCIP_MESSAGEHDLR * SCIPsdpiGetMessagehdlr(SCIP_SDPI *sdpi)
Definition: sdpi.c:2403
SCIP_RETCODE SCIPsdpVarfixerMergeArraysIntoNew(BMS_BLKMEM *blkmem, SCIP_Real epsilon, int *firstrow, int *firstcol, SCIP_Real *firstval, int firstlength, int *secondrow, int *secondcol, SCIP_Real *secondval, int secondlength, int *targetrow, int *targetcol, SCIP_Real *targetval, int *targetlength)
Definition: SdpVarfixer.c:252
interface methods for eigenvector computation and matrix multiplication using openblas ...
methods for clocks and timing
struct SCIP_SDPiSolver SCIP_SDPISOLVER
Definition: sdpisolver.h:71
SCIP_RETCODE SCIPsdpiGetRealpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, SCIP_Real *dval)
Definition: sdpi.c:4534
SCIP_RETCODE SCIPsdpiGetPreoptimalPrimalNonzeros(SCIP_SDPI *sdpi, int nblocks, int *startXnblocknonz)
Definition: sdpi.c:3747
static SCIP_RETCODE compConstMatAfterFixings(const SCIP_SDPI *sdpi, const SCIP_Real *sdpilb, const SCIP_Real *sdpiub, int *sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval)
Definition: sdpi.c:566
#define CHECK_IF_SOLVED(sdpi)
Definition: sdpi.c:133
#define DEFAULT_EPSILON
Definition: sdpi.c:199
SCIP_RETCODE SCIPlapackComputeIthEigenvalue(BMS_BUFMEM *bufmem, SCIP_Bool geteigenvectors, int n, SCIP_Real *A, int i, SCIP_Real *eigenvalue, SCIP_Real *eigenvector)
enum SCIP_SDPParam SCIP_SDPPARAM
Definition: type_sdpi.h:72
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverFree(SCIP_SDPISOLVER **sdpisolver)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetPreoptimalPrimalNonzeros(SCIP_SDPISOLVER *sdpisolver, int nblocks, int *startXnblocknonz)
SCIP_RETCODE SCIPsdpiGetNLPRows(SCIP_SDPI *sdpi, int *nlprows)
Definition: sdpi.c:2411
SCIP_RETCODE SCIPsdpiGetLhSides(SCIP_SDPI *sdpi, int firstrow, int lastrow, SCIP_Real *lhss)
Definition: sdpi.c:2546
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverGetIterations(SCIP_SDPISOLVER *sdpisolver, int *iterations)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsInfinity(SCIP_SDPISOLVER *sdpisolver, SCIP_Real val)
SCIP_RETCODE SCIPsdpiGetPrimalBoundVars(SCIP_SDPI *sdpi, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
Definition: sdpi.c:3895
static SCIP_Bool isFixed(const SCIP_SDPI *sdpi, int v)
Definition: sdpi.c:312
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsPrimalFeasible(SCIP_SDPISOLVER *sdpisolver)
SCIP_EXPORT SCIP_RETCODE SCIPsdpiSolverComputeLambdastar(SCIP_SDPISOLVER *sdpisolver, SCIP_Real maxguess)
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsDualUnbounded(SCIP_SDPISOLVER *sdpisolver)
SCIP_Bool SCIPsdpiSolvedOrig(SCIP_SDPI *sdpi)
Definition: sdpi.c:3147
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsPrimalUnbounded(SCIP_SDPISOLVER *sdpisolver)
SCIP_RETCODE SCIPsdpiSlater(SCIP_SDPI *sdpi, SCIP_SDPSLATER *primalslater, SCIP_SDPSLATER *dualslater)
Definition: sdpi.c:4445
#define SCIP_CALL_PARAM(x)
Definition: sdpi.c:165
static int calcGrowSize(int initsize, int num)
Definition: sdpi.c:337
SCIP_EXPORT SCIP_Bool SCIPsdpiSolverIsIterlimExc(SCIP_SDPISOLVER *sdpisolver)