SCIP-SDP  4.0.0
reader_sdpa.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_MORE_DEBUG */
34 /* #define SCIP_DEBUG */
35 
46 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
47 
48 #include <assert.h>
49 #include <string.h> /* for strcmp */
50 #include <ctype.h> /* for isspace/isdigit */
51 
52 #include "scipsdp/reader_sdpa.h"
53 #include "scipsdp/cons_sdp.h"
54 #include "scip/cons_linear.h"
55 #include "scip/cons_indicator.h" /* for SCIPcreateConsIndicatorLinCons */
56 
57 #define READER_NAME "sdpareader"
58 #define READER_DESC "file reader and writer for MISDPs in sdpa format"
59 #define READER_EXTENSION "dat-s"
60 
61 #define SDPA_MIN_BUFFERLEN 65536 /* minimal size of buffer */
62 
63 
64 struct SDPA_Data
65 {
66  SCIP_Bool* sdpblockrank1;
67  int nsdpblocksrank1;
68  int nvars;
69  SCIP_VAR** createdvars;
70  int nlinconss;
71  SCIP_CONS** createdconss;
72  int nsdpblocks;
73  int* sdpblocksizes;
74  int* sdpnblocknonz;
75  int* sdpnblockvars;
76  int** nvarnonz;
77  SCIP_VAR*** sdpblockvars;
78  int** sdprow;
79  int** sdpcol;
80  SCIP_Real** sdpval;
81  int*** rowpointer;
82  int*** colpointer;
83  SCIP_Real*** valpointer;
84  int* sdpconstnblocknonz;
86  int** sdpconstrow;
87  int** sdpconstcol;
88  SCIP_Real** sdpconstval;
89  int nconsblocks;
90  int* sdpmemsize;
91  int* sdpconstmemsize;
92  int idxlinconsblock;
93  char* buffer;
94  int bufferlen;
95 };
96 
97 typedef struct SDPA_Data SDPA_DATA;
98 
99 /*
100  * Local methods
101  */
102 
104 static
105 SCIP_RETCODE readLine(
106  SCIP* scip,
107  SCIP_FILE* file,
108  char** buffer,
109  int* bufferlen,
110  SCIP_Bool* success
111  )
112 {
113  assert( scip != NULL );
114  assert( file != NULL );
115  assert( buffer != NULL );
116  assert( bufferlen != NULL );
117  assert( success != NULL );
118 
119  /* possibly allocate buffer space */
120  if ( *buffer == NULL )
121  {
122  assert( *bufferlen == 0 );
123  SCIP_CALL( SCIPallocBlockMemoryArray(scip, buffer, SDPA_MIN_BUFFERLEN) );
124  *bufferlen = SDPA_MIN_BUFFERLEN;
125  }
126  assert( *bufferlen >= 2 );
127 
128  /* mark position near end (-2 because *bufferlen possibly will be \0) */
129  (*buffer)[*bufferlen-2] = '\0';
130 
131  /* read line */
132  if ( SCIPfgets(*buffer, *bufferlen, file) == NULL )
133  {
134  *success = FALSE;
135  return SCIP_OKAY;
136  }
137 
138  /* while buffer is not large enough (this will happen rarely) */
139  while ( (*buffer)[*bufferlen-2] != '\0' )
140  {
141  int newsize;
142 
143  assert( (*buffer)[*bufferlen-1] == '\0' );
144 
145  /* increase size */
146  newsize = SCIPcalcMemGrowSize(scip, *bufferlen + 1);
147  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, buffer, *bufferlen, newsize) );
148  assert( newsize >= *bufferlen + 1 );
149 
150  /* mark position near end */
151  (*buffer)[newsize-2] = '\0';
152 
153  /* read next part into buffer following already read part; -1/+1, because \0 char at end can be used */
154  if ( SCIPfgets(*buffer + *bufferlen - 1, newsize - *bufferlen + 1, file) == NULL )
155  {
156  *success = FALSE;
157  return SCIP_OKAY;
158  }
159  *bufferlen = newsize;
160  }
161  *success = TRUE;
162 
163  return SCIP_OKAY;
164 }
165 
166 
168 static
169 SCIP_RETCODE readNextLine(
170  SCIP* scip,
171  SCIP_FILE* file,
172  char** buffer,
173  int* bufferlen,
174  SCIP_Longint* linecount,
175  SCIP_Bool* success
176  )
177 {
178  char* comment;
179 
180  assert( buffer != NULL );
181  assert( bufferlen != NULL );
182  assert( linecount != NULL );
183  assert( success != NULL );
184 
185  do
186  {
187  /* read next line */
188  SCIP_CALL( readLine(scip, file, buffer, bufferlen, success) );
189  if ( ! *success )
190  return SCIP_OKAY;
191  ++(*linecount);
192 
193  /* special treatment of integer and rank1 section, because they are inside a comment */
194  if ( strncmp(*buffer, "*INTEGER", 8) == 0 || strncmp(*buffer, "*RANK1", 5) == 0 )
195  return SCIP_OKAY;
196  }
197  while ( **buffer == '*' || **buffer == '"' || **buffer == '\n' ); /* repeat reading if the line is a comment line */
198  assert( *success );
199 
200  /* remove comments */
201  comment = strpbrk(*buffer, "*\"=");
202  if ( comment != NULL )
203  *comment = '\0';
204 
205  return SCIP_OKAY;
206 }
207 
208 
210 static
211 SCIP_RETCODE readNextLineStar(
212  SCIP* scip,
213  SCIP_FILE* file,
214  char** buffer,
215  int* bufferlen,
216  SCIP_Longint* linecount,
217  SCIP_Bool* success
218  )
219 {
220  assert( buffer != NULL );
221  assert( bufferlen != NULL );
222  assert( linecount != NULL );
223  assert( success != NULL );
224 
225  do
226  {
227  /* read next line */
228  SCIP_CALL( readLine(scip, file, buffer, bufferlen, success) );
229  if ( ! *success )
230  return SCIP_OKAY;
231  ++(*linecount);
232 
233  /* special treatment of integer and rank1 section, because they are inside a comment */
234  if ( strncmp(*buffer, "*INTEGER", 8) == 0 || strncmp(*buffer, "*RANK1", 5) == 0 )
235  return SCIP_OKAY;
236  }
237  while ( **buffer == '\n' ); /* repeat reading for empty lines */
238  assert( *success );
239 
240  return SCIP_OKAY;
241 }
242 
243 
245 static
246 SCIP_RETCODE readLineDoubles(
247  SCIP* scip,
248  SCIP_FILE* file,
249  char** buffer,
250  int* bufferlen,
251  SCIP_Longint* linecount,
252  int nvals,
253  SCIP_Real* values,
254  int* nread
255  )
256 {
257  SCIP_Real val;
258  SCIP_Bool success;
259  char* endptr;
260  char* str;
261  int cnt = 0;
262 
263  assert( nread != NULL );
264  *nread = 0;
265 
266  SCIP_CALL( readLine(scip, file, buffer, bufferlen, &success) );
267  if ( ! success )
268  return SCIP_OKAY;
269  ++(*linecount);
270 
271  str = *buffer;
272  while ( *str != '\0' )
273  {
274  /* skip whitespace */
275  while ( isspace(*str) )
276  ++str;
277 
278  /* if we reached a number */
279  if ( isdigit(*str) || *str == '-' || *str == '+' )
280  {
281  if ( cnt >= nvals )
282  {
283  SCIPwarningMessage(scip, "Warning: Already read %d values in line %" SCIP_LONGINT_FORMAT ", dropping following numbers in the same line.\n", cnt, *linecount);
284  break;
285  }
286 
287  /* read number itself */
288  val = strtod(str, &endptr);
289  if ( endptr == NULL )
290  {
291  SCIPerrorMessage("Could not read number in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
292  *nread = -1;
293  return SCIP_READERROR;
294  }
295 
296  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
297  {
298  SCIPerrorMessage("Given value in line %" SCIP_LONGINT_FORMAT " for variable %d is infinity, which is not allowed.\n",
299  *linecount, cnt+1);
300  *nread = -1;
301  return SCIP_READERROR;
302  }
303 
304  values[cnt++] = val;
305  /* advance string to after number */
306  str = endptr;
307  }
308  else if ( *str == '*' || *str == '\"' || *str == '=' )
309  {
310  /* stop or read next line if we reached a comment */
311  if ( cnt < nvals )
312  {
313  SCIP_CALL( readLine(scip, file, buffer, bufferlen, &success) );
314  if ( ! success )
315  return SCIP_OKAY;
316  ++(*linecount);
317  str = *buffer;
318  }
319  else
320  break;
321  }
322  else
323  {
324  if ( *str != '\0' )
325  {
326  SCIPerrorMessage("Found invalid symbol in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
327  *nread = -1;
328  return SCIP_READERROR;
329  }
330  }
331  }
332 
333  *nread = cnt;
334  return SCIP_OKAY;
335 }
336 
337 
339 static
340 SCIP_RETCODE readLineInts(
341  SCIP* scip,
342  SCIP_FILE* file,
343  char** buffer,
344  int* bufferlen,
345  SCIP_Longint* linecount,
346  int nvals,
347  int* values,
348  int* nread
349  )
350 {
351  SCIP_Bool success;
352  char* endptr;
353  char* str;
354  int cnt = 0;
355  int val;
356 
357  assert( nread != NULL );
358  *nread = 0;
359 
360  SCIP_CALL( readLine(scip, file, buffer, bufferlen, &success) );
361  if ( ! success )
362  return SCIP_OKAY;
363  ++(*linecount);
364 
365  str = *buffer;
366  while ( *str != '\0' )
367  {
368  /* skip whitespace */
369  while ( isspace(*str) )
370  ++str;
371 
372  /* if we reached a number */
373  if ( isdigit(*str) || *str == '-' || *str == '+' )
374  {
375  if ( cnt >= nvals )
376  {
377  SCIPwarningMessage(scip, "Warning: Already read %d values in line %" SCIP_LONGINT_FORMAT ", dropping following numbers in the same line.\n", cnt, *linecount);
378  break;
379  }
380 
381  /* read number itself */
382  val = (int) strtol(str, &endptr, 10);
383  if ( endptr == NULL )
384  {
385  SCIPerrorMessage("Could not read number in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
386  *nread = -1;
387  return SCIP_READERROR;
388  }
389  values[cnt++] = val;
390  /* advance string to after number */
391  str = endptr;
392  }
393  else if ( *str == '*' || *str == '\"' || *str == '=' )
394  {
395  /* stop or read next line if we reached a comment */
396  if ( cnt < nvals )
397  {
398  SCIP_CALL( readLine(scip, file, buffer, bufferlen, &success) );
399  if ( ! success )
400  return SCIP_OKAY;
401  ++(*linecount);
402  str = *buffer;
403  }
404  else
405  break;
406  }
407  else
408  {
409  if ( *str != '\0' )
410  {
411  SCIPerrorMessage("Found invalid symbol in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
412  *nread = -1;
413  return SCIP_READERROR;
414  }
415  }
416  }
417 
418  *nread = cnt;
419  return SCIP_OKAY;
420 }
421 
422 
424 static
425 SCIP_RETCODE SDPAfreeData(
426  SCIP* scip,
427  SCIP_FILE* file,
428  SDPA_DATA* data
429  )
430 {
431  int b = 0;
432 
433  assert( scip != NULL );
434  assert( data != NULL );
435 
436  SCIPfreeBlockMemoryArrayNull(scip, &data->buffer, data->bufferlen);
437  data->bufferlen = 0;
438 
439  if ( data->nsdpblocks > 0 )
440  {
441  assert( data->nvars > 0 );
442 
443  if ( data->sdprow != NULL )
444  {
445  for (b = 0; b < data->nsdpblocks; b++)
446  {
447  assert( data->sdpmemsize[b] > 0);
448  assert( data->sdpconstmemsize[b] > 0);
449 
450  SCIPfreeBlockMemoryArrayNull(scip, &(data->valpointer[b]), data->nvars);
451  SCIPfreeBlockMemoryArrayNull(scip, &(data->colpointer[b]), data->nvars);
452  SCIPfreeBlockMemoryArrayNull(scip, &(data->rowpointer[b]), data->nvars);
453  SCIPfreeBlockMemoryArrayNull(scip, &(data->nvarnonz[b]), data->nvars);
454  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpblockvars[b]), data->nvars);
455  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpconstval[b]), data->sdpconstmemsize[b]);
456  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpconstcol[b]), data->sdpconstmemsize[b]);
457  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpconstrow[b]), data->sdpconstmemsize[b]);
458  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpval[b]), data->sdpmemsize[b]);
459  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpcol[b]), data->sdpmemsize[b]);
460  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdprow[b]), data->sdpmemsize[b]);
461  }
462  }
463  SCIPfreeBlockMemoryArrayNull(scip, &data->valpointer, data->nsdpblocks);
464  SCIPfreeBlockMemoryArrayNull(scip, &data->colpointer, data->nsdpblocks);
465  SCIPfreeBlockMemoryArrayNull(scip, &data->rowpointer, data->nsdpblocks);
466  SCIPfreeBlockMemoryArrayNull(scip, &data->nvarnonz, data->nsdpblocks);
467  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblockvars, data->nsdpblocks);
468  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpnblockvars, data->nsdpblocks);
469  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpconstval, data->nsdpblocks);
470  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpconstcol, data->nsdpblocks);
471  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpconstrow, data->nsdpblocks);
472  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpval, data->nsdpblocks);
473  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpcol, data->nsdpblocks);
474  SCIPfreeBlockMemoryArrayNull(scip, &data->sdprow, data->nsdpblocks);
475  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpconstnblocknonz, data->nsdpblocks);
476  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpnblocknonz, data->nsdpblocks);
477  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpconstmemsize, data->nsdpblocks);
478  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpmemsize, data->nsdpblocks);
479  }
480 
481  SCIPfreeBlockMemoryArrayNull(scip, &data->createdconss, data->nlinconss);
482  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblockrank1, data->nsdpblocks);
483  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblocksizes, data->nsdpblocks);
484  SCIPfreeBlockMemoryArrayNull(scip, &data->createdvars, data->nvars);
485 
486  SCIPfreeBufferNull(scip, &data);
487 
488  /* close the file (and make sure SCIPfclose returns 0) */
489  if ( SCIPfclose(file) )
490  return SCIP_READERROR;
491 
492  return SCIP_OKAY;
493 }
494 
495 
497 static
498 SCIP_RETCODE SDPAreadNVars(
499  SCIP* scip,
500  SCIP_FILE* file,
501  SCIP_Longint* linecount,
502  SDPA_DATA* data
503  )
504 {
505  SCIP_VAR* var;
506  SCIP_Bool success;
507  char varname[SCIP_MAXSTRLEN];
508  int cnt = 0;
509  int v;
510 #ifndef NDEBUG
511  int snprintfreturn;
512 #endif
513 
514  assert( scip != NULL );
515  assert( file != NULL );
516  assert( linecount != NULL );
517  assert( data != NULL );
518 
519  SCIP_CALL( readNextLine(scip, file, &data->buffer, &data->bufferlen, linecount, &success) );
520  if ( ! success )
521  {
522  SCIPerrorMessage("Unexpected end of file in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
523  goto TERMINATE;
524  }
525 
526  if ( sscanf(data->buffer, "%i", &data->nvars) != 1 )
527  {
528  SCIPerrorMessage("Could not read number of scalar variables in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
529  goto TERMINATE;
530  }
531 
532  if ( data->nvars < 0 )
533  {
534  SCIPerrorMessage("Number of scalar variables %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n",
535  data->nvars, *linecount);
536  goto TERMINATE;
537  }
538 
539  assert( data->nvars >= 0 );
540 
541  /* loop through different variable types */
542  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->createdvars), data->nvars) );
543 
544  /* create corresponding variables */
545  for (v = 0; v < data->nvars; v++)
546  {
547 #ifndef NDEBUG
548  snprintfreturn = SCIPsnprintf(varname, SCIP_MAXSTRLEN, "x_%d", cnt);
549  assert( snprintfreturn < SCIP_MAXSTRLEN );
550 #else
551  (void)SCIPsnprintf(varname, SCIP_MAXSTRLEN, "x_%d", cnt);
552 #endif
553 
554  SCIP_CALL( SCIPcreateVar(scip, &var, varname, -SCIPinfinity(scip), SCIPinfinity(scip), 0.0, SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL,
555  NULL, NULL) );
556 
557  SCIP_CALL( SCIPaddVar(scip, var) );
558  data->createdvars[cnt++] = var; /*lint !e732*//*lint !e747*/
559 
560  /* release variable for the reader */
561  SCIP_CALL( SCIPreleaseVar(scip, &var) );
562  }
563 
564  return SCIP_OKAY;
565 
566  TERMINATE:
567  SCIP_CALL( SDPAfreeData(scip, file, data) );
568  return SCIP_READERROR;
569 }
570 
571 
573 static
574 SCIP_RETCODE SDPAreadNBlocks(
575  SCIP* scip,
576  SCIP_FILE* file,
577  SCIP_Longint* linecount,
578  SDPA_DATA* data
579  )
580 {
581  SCIP_Bool success;
582 
583  assert( scip != NULL );
584  assert( file != NULL );
585  assert( linecount != NULL );
586  assert( data != NULL );
587 
588  SCIP_CALL( readNextLine(scip, file, &data->buffer, &data->bufferlen, linecount, &success) );
589  if ( ! success )
590  {
591  SCIPerrorMessage("Unexpected end of file in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
592  goto TERMINATE;
593  }
594 
595  if ( sscanf(data->buffer, "%i", &data->nconsblocks) != 1 )
596  {
597  SCIPerrorMessage("Could not read number of SDP blocks in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
598  goto TERMINATE;
599  }
600 
601  if ( data->nconsblocks < 0 )
602  {
603  SCIPerrorMessage("Number of SDP blocks %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n",
604  data->nconsblocks, *linecount);
605  goto TERMINATE;
606  }
607 
608  assert( data->nconsblocks >= 0 );
609 
610  return SCIP_OKAY;
611 
612  TERMINATE:
613  SCIP_CALL( SDPAfreeData(scip, file, data) );
614  return SCIP_READERROR;
615 }
616 
617 
619 static
620 SCIP_RETCODE SDPAreadBlockSize(
621  SCIP* scip,
622  SCIP_FILE* file,
623  SCIP_Longint* linecount,
624  SDPA_DATA* data
625  )
626 {
627  SCIP_CONS* cons;
628  char consname[SCIP_MAXSTRLEN];
629  int* sdpblocksizes;
630  int* blocksizes;
631  int nsdpblocks = 0;
632  int nblocks;
633  int cnt = 0;
634  int b;
635  int c;
636  int i;
637 
638 #ifndef NDEBUG
639  int snprintfreturn;
640 #endif
641 
642  SCIP_CALL( SCIPallocBufferArray(scip, &blocksizes, data->nconsblocks) );
643  SCIP_CALL( SCIPallocBufferArray(scip, &sdpblocksizes, data->nconsblocks) );
644 
645  assert( scip != NULL );
646  assert( file != NULL );
647  assert( linecount != NULL );
648  assert( data != NULL );
649 
650  SCIP_CALL( readLineInts(scip, file, &data->buffer, &data->bufferlen, linecount, data->nconsblocks, blocksizes, &nblocks) );
651 
652  if ( nblocks == -1 )
653  goto TERMINATE;
654  else if ( data->nconsblocks != nblocks )
655  {
656  SCIPerrorMessage("Number of specified blocksizes %d in line %" SCIP_LONGINT_FORMAT
657  " does not match number of blocks %d.\n", nblocks, *linecount, data->nconsblocks);
658  goto TERMINATE;
659  }
660 
661  assert( nblocks == data->nconsblocks );
662 
663  for (i = 0; i < nblocks; i++)
664  {
665  /* if the entry is less than zero it describes the LP blocks */
666  if ( *(blocksizes + i) < 0 )
667  {
668  if ( data->idxlinconsblock == -1 )
669  data->idxlinconsblock = i;
670  else
671  {
672  SCIPerrorMessage("Only one LP block can be defined in line %" SCIP_LONGINT_FORMAT
673  " but at least two blocksizes are negative.\n", *linecount);
674  goto TERMINATE;
675  }
676  data->nlinconss = - *(blocksizes + i);
677  }
678  else
679  {
680  if ( *(blocksizes + i) == 0 )
681  {
682  SCIPerrorMessage("Encountered a block size of 0 in line %" SCIP_LONGINT_FORMAT " which is not valid.\n",
683  *linecount);
684  goto TERMINATE;
685  }
686  *(sdpblocksizes + nsdpblocks) = *(blocksizes + i);
687  ++nsdpblocks;
688  }
689  }
690 
691  assert( data->idxlinconsblock < 0 || data->nlinconss > 0 );
692  assert( data->idxlinconsblock >= 0 || data->nlinconss == 0 );
693 
694  if ( data->nlinconss < 0 )
695  {
696  SCIPerrorMessage("Number of linear constraints %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n",
697  data->nlinconss, *linecount);
698  goto TERMINATE;
699  }
700 
701  assert( data->nlinconss >= 0 );
702  assert( nsdpblocks >= 0 );
703 
704  data->nsdpblocks = nsdpblocks;
705 
706  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblocksizes), data->nsdpblocks) );
707  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblockrank1), data->nsdpblocks) );
708  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->createdconss), data->nlinconss) );
709 
710  for (b = 0; b < nsdpblocks; b++)
711  {
712  assert( sdpblocksizes[b] > 0 );
713 
714  data->sdpblocksizes[b] = *(sdpblocksizes + b);
715 
716  /* initialize rank-1 information to FALSE, will eventually be changed in SDPAreadRank1 */
717  data->sdpblockrank1[b] = FALSE;
718  }
719 
720  /* create corresponding constraints */
721  for (c = 0; c < data->nlinconss; c++)
722  {
723 #ifndef NDEBUG
724  snprintfreturn = SCIPsnprintf(consname, SCIP_MAXSTRLEN, "LP_%d", cnt);
725  assert( snprintfreturn < SCIP_MAXSTRLEN );
726 #else
727  (void)SCIPsnprintf(consname, SCIP_MAXSTRLEN, "linear_%d", cnt);
728 #endif
729  /* linear constraints are specified as 0 <= cons <= SCIPinfinity(scip) */
730  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, 0, NULL, NULL, 0.0, SCIPinfinity(scip), TRUE, TRUE, TRUE, TRUE, TRUE,
731  FALSE, FALSE, FALSE, FALSE, FALSE) );
732 
733  SCIP_CALL( SCIPaddCons(scip, cons) );
734  data->createdconss[cnt++] = cons;
735 
736  /* release constraint for the reader. */
737  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
738  }
739 
740  assert( cnt == data->nlinconss );
741 
742  SCIPfreeBufferArray(scip, &sdpblocksizes);
743  SCIPfreeBufferArray(scip, &blocksizes);
744 
745  return SCIP_OKAY;
746 
747  TERMINATE:
748  SCIPfreeBufferArray(scip, &sdpblocksizes);
749  SCIPfreeBufferArray(scip, &blocksizes);
750 
751  SCIP_CALL( SDPAfreeData(scip, file, data) );
752  return SCIP_READERROR;
753 }
754 
755 
757 static
758 SCIP_RETCODE SDPAreadObjVals(
759  SCIP* scip,
760  SCIP_FILE* file,
761  SCIP_Longint* linecount,
762  SDPA_DATA* data
763  )
764 { /*lint --e{818}*/
765  SCIP_Real* objvals;
766  int v;
767  int nreadvals;
768  int nzerocoef = 0;
769 
770  assert( scip != NULL );
771  assert( file != NULL );
772  assert( linecount != NULL );
773  assert( data != NULL );
774 
775  SCIP_CALL( SCIPallocBufferArray(scip, &objvals, data->nvars ) );
776 
777  if ( data->createdvars == NULL )
778  {
779  SCIPerrorMessage("Number of variables needs to be specified before objective values!\n");
780  goto TERMINATE;
781  }
782  assert( data->nvars >= 0 );
783 
784  SCIP_CALL( readLineDoubles(scip, file, &data->buffer, &data->bufferlen, linecount, data->nvars, objvals, &nreadvals) );
785 
786  if ( nreadvals == -1 )
787  goto TERMINATE;
788  else if ( nreadvals != data->nvars )
789  {
790  SCIPerrorMessage("Number of objective coefficients %i in line %" SCIP_LONGINT_FORMAT
791  " does not match the number of variables %d.\n", nreadvals, *linecount, data->nvars);
792  goto TERMINATE;
793  }
794 
795  assert( data->nvars == nreadvals );
796 
797  for (v = 0; v < data->nvars; v++)
798  {
799  if ( SCIPisZero(scip, *(objvals + v)) )
800  ++nzerocoef;
801  else
802  SCIP_CALL( SCIPchgVarObj(scip, data->createdvars[v], *(objvals + v)) );
803  }
804 
805  if ( nzerocoef > 0 )
806  {
807  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Found %d objective coefficients with absolute value less than epsilon = %g.\n",
808  nzerocoef, SCIPepsilon(scip));
809  }
810 
811  SCIPfreeBufferArray(scip, &objvals);
812 
813  return SCIP_OKAY;
814 
815  TERMINATE:
816  /* free memory */
817  SCIPfreeBufferArray(scip, &objvals);
818 
819  SCIP_CALL( SDPAfreeData(scip, file, data) );
820  return SCIP_READERROR;
821 }
822 
823 
825 static
826 SCIP_RETCODE SDPAreadBlocks(
827  SCIP* scip,
828  SCIP_FILE* file,
829  SCIP_Longint* linecount,
830  SDPA_DATA* data
831  )
832 {
833  SCIP_VAR* indvar = 0;
834  SCIP_Real** sdpval_local = NULL; /* array of all values of SDP nonzeros for each SDP block */
835  SCIP_Real** sdpconstval_local = NULL;
836  SCIP_Real val;
837  SCIP_Bool infeasible;
838  SCIP_Bool success;
839  int** sdprow_local = NULL; /* array of all row indices for each SDP block */
840  int** sdpcol_local = NULL; /* array of all column indices for each SDP block */
841  int** sdpconstrow_local = NULL; /* pointers to row-indices for each block */
842  int** sdpconstcol_local = NULL; /* pointers to column-indices for each block */
843  int** sdpvar = NULL;
844  int* nentriessdp = NULL;
845  int* nentriessdpconst = NULL;
846  int* nentrieslincon = NULL;
847  int firstindforvar;
848  int nextindaftervar;
849  int nzerocoef = 0;
850  int emptysdpblocks = 0;
851  int emptylinconsblocks = 0;
852  int nindcons = 0;
853  int blockidxoffset = 0;
854  int row;
855  int col;
856  int b; /* current block */
857  int v; /* current variable */
858  int c; /* current linear constraint */
859 
860  assert( scip != NULL );
861  assert( file != NULL );
862  assert( linecount != NULL );
863  assert( data != NULL );
864 
865  assert( data->nvars >= 0 );
866 
867  if ( data->nvars < 0 || data-> createdvars == NULL )
868  {
869  SCIPerrorMessage("Number of variables needs to be specified before entries of the blocks!\n");
870  goto TERMINATE;
871  }
872 
873  SCIP_CALL( SCIPallocBufferArray(scip, &nentrieslincon, data->nlinconss) );
874 
875  if ( data->nsdpblocks > 0 )
876  {
877  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpmemsize), data->nsdpblocks) );
878  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstmemsize), data->nsdpblocks) );
879 
880  SCIP_CALL( SCIPallocBufferArray(scip, &nentriessdp, data->nsdpblocks) );
881  SCIP_CALL( SCIPallocBufferArray(scip, &nentriessdpconst, data->nsdpblocks) );
882 
883  /* set initial memory size*/
884  for (b = 0; b < data->nsdpblocks; b++)
885  {
886  data->sdpmemsize[b] = 8;
887  data->sdpconstmemsize[b] = 8;
888  nentriessdpconst[b] = 0;
889  nentriessdp[b] = 0;
890  }
891 
892  for (c = 0; c < data->nlinconss; c++)
893  nentrieslincon[c] = 0;
894 
895  if ( data->nsdpblocks < 0 )
896  {
897  SCIPerrorMessage("Number of blocks needs to be specified before entries of the blocks!\n");
898  goto TERMINATE;
899  }
900 
901  if ( data->sdpblocksizes == NULL )
902  {
903  SCIPerrorMessage("Sizes of the SDP blocks need to be specified before entries of the blocks!\n");
904  goto TERMINATE;
905  }
906  assert( data->nlinconss >= 0 );
907 
908  /* initialize sdpnblocknonz with 0 */
909  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpnblocknonz), data->nsdpblocks) );
910  for (b = 0; b < data->nsdpblocks; b++)
911  data->sdpnblocknonz[b] = 0;
912 
913  /* allocate memory */
914  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpvar), data->nsdpblocks) );
915  SCIP_CALL( SCIPallocBufferArray(scip, &(sdprow_local), data->nsdpblocks) );
916  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpcol_local), data->nsdpblocks) );
917  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpval_local), data->nsdpblocks) );
918 
919  for (b = 0; b < data->nsdpblocks; b++)
920  {
921  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpvar[b]), data->sdpmemsize[b]) );
922  SCIP_CALL( SCIPallocBufferArray(scip, &(sdprow_local[b]), data->sdpmemsize[b]) );
923  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpcol_local[b]), data->sdpmemsize[b]) );
924  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpval_local[b]), data->sdpmemsize[b]) );
925  }
926 
927  /* initialize sdpconstnblocknonz with 0 */
928  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstnblocknonz), data->nsdpblocks) );
929  for (b = 0; b < data->nsdpblocks; b++)
930  data->sdpconstnblocknonz[b] = 0;
931 
932  /* allocate memory (constnnonz for each block, since we do not yet know the distribution) */
933  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpconstrow_local), data->nsdpblocks) );
934  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpconstcol_local), data->nsdpblocks) );
935  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpconstval_local), data->nsdpblocks) );
936 
937  for (b = 0; b < data->nsdpblocks; b++)
938  {
939  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpconstrow_local[b]), data->sdpconstmemsize[b]) );
940  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpconstcol_local[b]), data->sdpconstmemsize[b]) );
941  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpconstval_local[b]), data->sdpconstmemsize[b]) );
942  }
943  }
944 
945  /* read data */
946  SCIP_CALL( readNextLine(scip, file, &data->buffer, &data->bufferlen, linecount, &success) );
947  if ( ! success )
948  {
949  SCIPerrorMessage("Unexpected end of file in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
950  goto TERMINATE;
951  }
952 
953  while ( success )
954  {
955  if ( strncmp(data->buffer, "*INTEGER", 8) == 0 || strncmp(data->buffer, "*RANK1", 5) == 0 )
956  break;
957 
958  if ( sscanf(data->buffer, "%i %i %i %i %lf", &v, &b, &row, &col, &val) != 5 )
959  {
960  SCIPerrorMessage("Could not read block entry in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
961  goto TERMINATE;
962  }
963 
964  /* switch from SDPA counting (starting from 1) to SCIP counting (starting from 0) */
965  --v;
966  --b;
967  --row;
968  --col;
969 
970  /* reset LP block offset */
971  blockidxoffset = 0;
972 
973  /* check if this entry belongs to the LP block (FALSE) or to an SDP block (TRUE)*/
974  if ( b != data->idxlinconsblock )
975  {
976  /* check if the LP block was already read and adjust the counter as well as the offset for error messages */
977  if ( b > data->idxlinconsblock && data->idxlinconsblock >= 0 )
978  {
979  --b;
980  blockidxoffset = 1;
981  }
982 
983  if ( v < - 1 || v >= data->nvars )
984  {
985  SCIPerrorMessage("Given coefficient in line %" SCIP_LONGINT_FORMAT " for variable %d which does not exist!\n",
986  *linecount, v+1);
987  goto TERMINATE;
988  }
989 
990  if ( b < 0 || b >= data->nsdpblocks )
991  {
992  SCIPerrorMessage("Given coefficient in line %" SCIP_LONGINT_FORMAT " for SDP block %d which does not exist!\n",
993  *linecount, b + 1 + blockidxoffset);
994  goto TERMINATE;
995  }
996  assert( 0 <= b && b < data->nsdpblocks );
997 
998  if ( row < 0 || row >= data->sdpblocksizes[b] )
999  {
1000  SCIPerrorMessage("Row index %d of given coefficient in line %" SCIP_LONGINT_FORMAT " is negative or larger than blocksize %d!\n",
1001  row +1, *linecount, data->sdpblocksizes[b]);
1002  goto TERMINATE;
1003  }
1004 
1005  if ( col < 0 || col >= data->sdpblocksizes[b] )
1006  {
1007  SCIPerrorMessage("Column index %d of given coefficient in line %" SCIP_LONGINT_FORMAT " is negative or larger than blocksize %d!\n",
1008  col + 1, *linecount, data->sdpblocksizes[b]);
1009  goto TERMINATE;
1010  }
1011 
1012  /* check if this entry belongs to the constant part of the SDP block (v = -1) or not (v >= 0) */
1013  if ( v >= 0 )
1014  {
1015  if ( SCIPisZero(scip, val) )
1016  ++nzerocoef;
1017  else
1018  {
1019  /* for lint: */
1020  assert( nentriessdp != NULL );
1021  assert( sdpvar != NULL );
1022  assert( sdprow_local != NULL );
1023  assert( sdpcol_local != NULL );
1024  assert( sdpval_local != NULL );
1025 
1026  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
1027  {
1028  SCIPerrorMessage("Given coefficient in line %" SCIP_LONGINT_FORMAT " for variable %d is infinity, which is not allowed.\n",
1029  *linecount, v+1);
1030  goto TERMINATE;
1031  }
1032 
1033  nentriessdp[b]++;
1034 
1035  /* if the current memory is not sufficient reallocate*/
1036  if ( nentriessdp[b] >= data->sdpmemsize[b] )
1037  {
1038  int newsize = SCIPcalcMemGrowSize(scip, data->sdpmemsize[b] + 1);
1039  assert( newsize > data->sdpmemsize[b] );
1040  assert( newsize > nentriessdp[b] );
1041 
1042  SCIP_CALL( SCIPreallocBufferArray(scip, &(sdpvar[b]), newsize) );
1043  SCIP_CALL( SCIPreallocBufferArray(scip, &(sdprow_local[b]), newsize) );
1044  SCIP_CALL( SCIPreallocBufferArray(scip, &(sdpcol_local[b]), newsize) );
1045  SCIP_CALL( SCIPreallocBufferArray(scip, &(sdpval_local[b]), newsize) );
1046  data->sdpmemsize[b] = newsize;
1047  }
1048 
1049  sdpvar[b][data->sdpnblocknonz[b]] = v;
1050 
1051  /* make sure matrix is in lower triangular form */
1052  if ( col > row )
1053  {
1054  sdprow_local[b][data->sdpnblocknonz[b]] = col;
1055  sdpcol_local[b][data->sdpnblocknonz[b]] = row;
1056  }
1057  else
1058  {
1059  sdprow_local[b][data->sdpnblocknonz[b]] = row;
1060  sdpcol_local[b][data->sdpnblocknonz[b]] = col;
1061  }
1062 
1063  sdpval_local[b][data->sdpnblocknonz[b]] = val;
1064  data->sdpnblocknonz[b]++;
1065  }
1066  }
1067  else /* constant part of SDP block*/
1068  {
1069  assert( v == -1 );
1070 
1071  if ( SCIPisZero(scip, val) )
1072  ++nzerocoef;
1073  else
1074  {
1075  /* for lint: */
1076  assert( nentriessdpconst != NULL );
1077  assert( sdpconstrow_local != NULL );
1078  assert( sdpconstcol_local != NULL );
1079  assert( sdpconstval_local != NULL );
1080 
1081  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
1082  {
1083  SCIPerrorMessage("Given constant part in line %" SCIP_LONGINT_FORMAT " of block %d is infinity, which is not allowed.\n",
1084  *linecount, b+1);
1085  goto TERMINATE;
1086  }
1087 
1088  nentriessdpconst[b]++;
1089 
1090  /* if the current memory is not sufficient reallocate*/
1091  if ( nentriessdpconst[b] >= data->sdpconstmemsize[b] )
1092  {
1093  int newsize = SCIPcalcMemGrowSize(scip, data->sdpconstmemsize[b] + 1);
1094  assert( newsize > data->sdpconstmemsize[b] );
1095  assert( newsize > nentriessdpconst[b] );
1096 
1097  SCIP_CALL( SCIPreallocBufferArray(scip, &(sdpconstrow_local[b]), newsize) );
1098  SCIP_CALL( SCIPreallocBufferArray(scip, &(sdpconstcol_local[b]), newsize) );
1099  SCIP_CALL( SCIPreallocBufferArray(scip, &(sdpconstval_local[b]), newsize) );
1100 
1101  data->sdpconstmemsize[b] = newsize;
1102  }
1103 
1104  /* make sure matrix is in lower triangular form */
1105  if ( col > row )
1106  {
1107  sdpconstrow_local[b][data->sdpconstnblocknonz[b]] = col;
1108  sdpconstcol_local[b][data->sdpconstnblocknonz[b]] = row;
1109  }
1110  else
1111  {
1112  sdpconstrow_local[b][data->sdpconstnblocknonz[b]] = row;
1113  sdpconstcol_local[b][data->sdpconstnblocknonz[b]] = col;
1114  }
1115  sdpconstval_local[b][data->sdpconstnblocknonz[b]] = val;
1116  data->sdpconstnblocknonz[b]++;
1117  }
1118  }
1119  }
1120  else /* LP block */
1121  {
1122  /* indicator variables have a negative variable index */
1123  if ( v >= data->nvars )
1124  {
1125  SCIPerrorMessage("Given linear coefficient in line %" SCIP_LONGINT_FORMAT " for variable %d which does not exist!\n",
1126  *linecount, v + 1);
1127  goto TERMINATE;
1128  }
1129 
1130  /* linear constraints are specified on the diagonal of the LP block */
1131  if ( row != col )
1132  {
1133  SCIPerrorMessage("Given linear coefficient in line %" SCIP_LONGINT_FORMAT " is not located on the diagonal!\n",
1134  *linecount);
1135  goto TERMINATE;
1136  }
1137 
1138  assert( row == col );
1139 
1140  if ( row < 0 || row >= data->nlinconss )
1141  {
1142  SCIPerrorMessage("Given linear coefficient in line %" SCIP_LONGINT_FORMAT " for linear constraint %d which does not exist!\n",
1143  *linecount, row + 1);
1144  goto TERMINATE;
1145  }
1146 
1147  /* check if this entry belongs to the constant part of the LP block (v = -1) or not (v >= 0 || v < -1) the latter for indicator variables */
1148  if ( v >= 0 )
1149  {
1150  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
1151  {
1152  SCIPerrorMessage("Given linear coefficient in line %" SCIP_LONGINT_FORMAT " for variable %d is infinity, which is not allowed.\n",
1153  *linecount, v+1);
1154  goto TERMINATE;
1155  }
1156 
1157  if ( SCIPisZero(scip, val) )
1158  {
1159  ++nzerocoef;
1160  }
1161  else
1162  {
1163  SCIP_CALL( SCIPaddCoefLinear(scip, data->createdconss[row], data->createdvars[v],val) );/*lint !e732*//*lint !e747*/
1164  nentrieslincon[row]++;
1165  }
1166  }
1167  else /* constant part or indicator constraint*/
1168  {
1169  if ( v < -1 ) /* indicator constraint*/
1170  {
1171  SCIP_CONS* indcons;
1172  SCIP_VAR* slackvar = 0;
1173  char name[SCIP_MAXSTRLEN];
1174 #ifndef NDEBUG
1175  int snprintfreturn;
1176 #endif
1177  /* adjust variable index to be positive */
1178  v = -v - 2;
1179 
1180 #ifndef NDEBUG
1181  snprintfreturn = SCIPsnprintf(name, SCIP_MAXSTRLEN, "indslack_cons_indicator_%d", nindcons);
1182  assert( snprintfreturn < SCIP_MAXSTRLEN);
1183 #else
1184  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "indslack_cons_indicator_%d", nindcons);
1185 #endif
1186  /* create slack variable and add it to the constraint */
1187  SCIP_CALL( SCIPcreateVar(scip, &slackvar, name, 0.0, SCIPinfinity(scip), 0.0,
1188  SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, 0, 0, 0, 0, 0));
1189  SCIP_CALL( SCIPaddVar(scip, slackvar) );
1190 
1191  SCIP_CALL( SCIPaddCoefLinear(scip,data->createdconss[row] , slackvar, +1.0) );/*lint !e732*//*lint !e747*/
1192 
1193 #ifndef NDEBUG
1194  snprintfreturn = SCIPsnprintf(name, SCIP_MAXSTRLEN, "indlin_cons_indicator_%d", nindcons);
1195  assert( snprintfreturn < SCIP_MAXSTRLEN);
1196 #else
1197  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "indlin_cons_indicator_%d", nindcons);
1198 #endif
1199  /* change name of the corresponding linear constraint */
1200  SCIP_CALL( SCIPchgConsName(scip, data->createdconss[row], name) );
1201 
1202 #ifndef NDEBUG
1203  snprintfreturn = SCIPsnprintf(name, SCIP_MAXSTRLEN, "cons_indicator_%d", nindcons);
1204  assert( snprintfreturn < SCIP_MAXSTRLEN);
1205 #else
1206  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "cons_indicator_%d", nindcons);
1207 #endif
1208  indvar = data->createdvars[v];
1209  SCIP_CALL( SCIPchgVarLbGlobal(scip, indvar, 0.0) );
1210  SCIP_CALL( SCIPchgVarUbGlobal(scip, indvar, 1.0) );
1211  SCIP_CALL( SCIPchgVarType(scip, indvar, SCIP_VARTYPE_BINARY, &infeasible) );
1212  SCIP_CALL( SCIPcreateConsIndicatorLinCons( scip, &indcons, name, indvar,data->createdconss[row], slackvar,
1213  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1214  SCIP_CALL( SCIPaddCons(scip, indcons) );
1215 
1216  /* release both conss and the slackvar */
1217  SCIP_CALL( SCIPreleaseCons(scip, &indcons) );
1218  SCIP_CALL( SCIPreleaseVar(scip, &slackvar) );
1219 
1220  nindcons++;
1221  }
1222  else /* constant part */
1223  {
1224  assert( v == -1 );
1225 
1226  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val))
1227  {
1228  SCIPerrorMessage("Given constant part in line %" SCIP_LONGINT_FORMAT " of block %d is infinity, which is not allowed.\n",
1229  *linecount, b+1);
1230  goto TERMINATE;
1231  }
1232 
1233  if ( SCIPisZero(scip, val) )
1234  ++nzerocoef;
1235  else
1236  {
1237  assert( ! SCIPisInfinity(scip, - SCIPgetLhsLinear(scip, data->createdconss[row])) );
1238  assert( SCIPisInfinity(scip, SCIPgetRhsLinear(scip, data->createdconss[row])) );
1239 
1240  /* all linear constraints are greater or equal constraints */
1241  SCIP_CALL( SCIPchgLhsLinear(scip, data->createdconss[row], val) );
1242  }
1243  }
1244  }
1245  }
1246 
1247  SCIP_CALL( readNextLine(scip, file, &data->buffer, &data->bufferlen, linecount, &success) );
1248  }
1249 
1250  /* reset LP block offset */
1251  blockidxoffset = 0;
1252 
1253  for (b = 0; b < data->nsdpblocks; b++)
1254  {
1255  if ( nentriessdp[b] == 0 )
1256  {
1257  emptysdpblocks++;
1258 
1259  /* account for a possible LP block */
1260  if ( data->idxlinconsblock >= 0 && b >= data->idxlinconsblock )
1261  blockidxoffset = 1;
1262 
1263  SCIPerrorMessage("SDP block number %d does not contain any nonzero entries!\n", b + 1 + blockidxoffset);
1264  }
1265  }
1266 
1267  if ( emptysdpblocks > 0 )
1268  goto TERMINATE;
1269 
1270  for (c = 0; c < data->nlinconss; c++)
1271  {
1272  if ( nentrieslincon[c] == 0 )
1273  {
1274  SCIPerrorMessage("Linear constraint number %d does not contain nonzero entries!\n", c + 1);
1275  emptylinconsblocks++;
1276  }
1277  }
1278 
1279  if ( emptylinconsblocks > 0 )
1280  goto TERMINATE;
1281 
1282  if ( data->nsdpblocks > 0 )
1283  {
1284  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdprow), data->nsdpblocks) );
1285  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpcol), data->nsdpblocks) );
1286  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpval), data->nsdpblocks) );
1287 
1288  for (b = 0; b < data->nsdpblocks; b++)
1289  {
1290  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdprow[b]), data->sdpmemsize[b]) );
1291  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpcol[b]), data->sdpmemsize[b]) );
1292  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpval[b]), data->sdpmemsize[b]) );
1293  }
1294 
1295  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstrow), data->nsdpblocks) );
1296  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstcol), data->nsdpblocks) );
1297  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstval), data->nsdpblocks) );
1298 
1299  for (b = 0; b < data->nsdpblocks; b++)
1300  {
1301  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstrow[b]), data->sdpconstmemsize[b]) );
1302  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstcol[b]), data->sdpconstmemsize[b]) );
1303  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstval[b]), data->sdpconstmemsize[b]) );
1304  }
1305 
1306  /* write the read blocks from buffer memory to the data object */
1307  for (b = 0; b < data->nsdpblocks; b++)
1308  {
1309  int nonz;
1310 
1311  for (nonz = 0; nonz < data->sdpnblocknonz[b]; nonz++)
1312  {
1313  if ( sdpcol_local[b][nonz] > sdprow_local[b][nonz] )
1314  {
1315  data->sdprow[b][nonz] = sdpcol_local[b][nonz];
1316  data->sdpcol[b][nonz] = sdprow_local[b][nonz];
1317  }
1318  else
1319  {
1320  data->sdprow[b][nonz] = sdprow_local[b][nonz];
1321  data->sdpcol[b][nonz] = sdpcol_local[b][nonz];
1322  }
1323  data->sdpval[b][nonz] = sdpval_local[b][nonz];
1324  }
1325 
1326  for (nonz = 0; nonz < data->sdpconstnblocknonz[b]; nonz++)
1327  {
1328  if ( sdpconstcol_local[b][nonz] > sdpconstrow_local[b][nonz] )
1329  {
1330  data->sdpconstrow[b][nonz] = sdpconstcol_local[b][nonz];
1331  data->sdpconstcol[b][nonz] = sdpconstrow_local[b][nonz];
1332  }
1333  else
1334  {
1335  data->sdpconstrow[b][nonz] = sdpconstrow_local[b][nonz];
1336  data->sdpconstcol[b][nonz] = sdpconstcol_local[b][nonz];
1337  }
1338  data->sdpconstval[b][nonz] = sdpconstval_local[b][nonz];
1339  }
1340  }
1341 
1342  /* construct pointer arrays */
1343  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpnblockvars), data->nsdpblocks) );
1344  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblockvars), data->nsdpblocks) );
1345  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->nvarnonz), data->nsdpblocks) );
1346  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->rowpointer), data->nsdpblocks) );
1347  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->colpointer), data->nsdpblocks) );
1348  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->valpointer), data->nsdpblocks) );
1349 
1350  /* sdp blocks as specified in sdpa file */
1351  for (b = 0; b < data->nsdpblocks; b++)
1352  {
1353  /* sort the nonzeroes by non-decreasing variable indices */
1354  SCIPsortIntIntIntReal(sdpvar[b], data->sdprow[b], data->sdpcol[b], data->sdpval[b], data->sdpnblocknonz[b]);
1355 
1356  /* create the pointer arrays and insert used variables into vars-array */
1357  nextindaftervar = 0;
1358  data->sdpnblockvars[b] = 0;
1359  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblockvars[b]), data->nvars) );
1360  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->nvarnonz[b]), data->nvars) );
1361  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->rowpointer[b]), data->nvars) );
1362  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->colpointer[b]), data->nvars) );
1363  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->valpointer[b]), data->nvars) );
1364 
1365  for (v = 0; v < data->nvars; v++)
1366  {
1367  SCIP_Bool varused = FALSE;
1368 
1369  firstindforvar = nextindaftervar; /* this variable starts where the last one ended */
1370  data->nvarnonz[b][data->sdpnblockvars[b]] = 0;
1371 
1372  /* get the first index that doesn't belong to this variable */
1373  while ( nextindaftervar < data->sdpnblocknonz[b] && sdpvar[b][nextindaftervar] == v )
1374  {
1375  nextindaftervar++;
1376  varused = TRUE;
1377  data->nvarnonz[b][data->sdpnblockvars[b]]++;
1378  }
1379 
1380  if ( varused )
1381  {
1382  /* if the variable is used, add it to the vars array */
1383  data->sdpblockvars[b][data->sdpnblockvars[b]] = data->createdvars[v];
1384  /* save a pointer to the first nonzero belonging to this variable */
1385  data->rowpointer[b][data->sdpnblockvars[b]] = &(data->sdprow[b][firstindforvar]);
1386  data->colpointer[b][data->sdpnblockvars[b]] = &(data->sdpcol[b][firstindforvar]);
1387  data->valpointer[b][data->sdpnblockvars[b]] = &(data->sdpval[b][firstindforvar]);
1388  data->sdpnblockvars[b]++;
1389  }
1390  }
1391  assert( nextindaftervar == data->sdpnblocknonz[b] );
1392  }
1393 
1394  if ( nzerocoef > 0 )
1395  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
1396  "Found %d block coefficients with absolute value less than epsilon = %g.\n", nzerocoef, SCIPepsilon(scip));
1397 
1398  /* free buffer memory */
1399  for (b = 0; b < data->nsdpblocks; b++)
1400  {
1401  SCIPfreeBufferArray(scip, &(sdpconstval_local[b]));
1402  SCIPfreeBufferArray(scip, &(sdpconstcol_local[b]));
1403  SCIPfreeBufferArray(scip, &(sdpconstrow_local[b]));
1404  SCIPfreeBufferArray(scip, &(sdpval_local[b]));
1405  SCIPfreeBufferArray(scip, &(sdpcol_local[b]));
1406  SCIPfreeBufferArray(scip, &(sdprow_local[b]));
1407  SCIPfreeBufferArray(scip, &(sdpvar[b]));
1408  }
1409  SCIPfreeBufferArray(scip, &(sdpconstval_local));
1410  SCIPfreeBufferArray(scip, &(sdpconstcol_local));
1411  SCIPfreeBufferArray(scip, &(sdpconstrow_local));
1412  SCIPfreeBufferArray(scip, &(sdpval_local));
1413  SCIPfreeBufferArray(scip, &(sdpcol_local));
1414  SCIPfreeBufferArray(scip, &(sdprow_local));
1415  SCIPfreeBufferArray(scip, &sdpvar);
1416  SCIPfreeBufferArray(scip, &nentriessdpconst);
1417  SCIPfreeBufferArray(scip, &nentriessdp);
1418  }
1419 
1420  SCIPfreeBufferArray(scip, &nentrieslincon);
1421 
1422  return SCIP_OKAY;
1423 
1424  TERMINATE:
1425  /* free memory */
1426  if ( data->nsdpblocks > 0 )
1427  {
1428  if ( sdpvar != NULL )
1429  {
1430  /* free buffer memory */
1431  for (b = 0; b < data->nsdpblocks; b++)
1432  {
1433  SCIPfreeBufferArrayNull(scip, &(sdpconstval_local[b]));
1434  SCIPfreeBufferArrayNull(scip, &(sdpconstcol_local[b]));
1435  SCIPfreeBufferArrayNull(scip, &(sdpconstrow_local[b]));
1436  SCIPfreeBufferArrayNull(scip, &(sdpval_local[b]));
1437  SCIPfreeBufferArrayNull(scip, &(sdpcol_local[b]));
1438  SCIPfreeBufferArrayNull(scip, &(sdprow_local[b]));
1439  SCIPfreeBufferArrayNull(scip, &(sdpvar[b]));
1440  }
1441  }
1442  SCIPfreeBufferArrayNull(scip, &(sdpconstval_local));
1443  SCIPfreeBufferArrayNull(scip, &(sdpconstcol_local));
1444  SCIPfreeBufferArrayNull(scip, &(sdpconstrow_local));
1445  SCIPfreeBufferArrayNull(scip, &(sdpval_local));
1446  SCIPfreeBufferArrayNull(scip, &(sdpcol_local));
1447  SCIPfreeBufferArrayNull(scip, &(sdprow_local));
1448  SCIPfreeBufferArrayNull(scip, &sdpvar);
1449  SCIPfreeBufferArrayNull(scip, &nentriessdpconst);
1450  SCIPfreeBufferArrayNull(scip, &nentriessdp);
1451  }
1452  SCIPfreeBufferArrayNull(scip, &nentrieslincon);
1453 
1454  SCIP_CALL( SDPAfreeData(scip, file, data) );
1455  return SCIP_READERROR;
1456 }
1457 
1458 
1460 static
1461 SCIP_RETCODE SDPAreadInt(
1462  SCIP* scip,
1463  SCIP_FILE* file,
1464  SCIP_Longint* linecount,
1465  SDPA_DATA* data
1466  )
1467 { /*lint --e{818}*/
1468  SCIP_Bool success;
1469  int v;
1470 
1471  assert( scip != NULL );
1472  assert( file != NULL );
1473  assert( linecount != NULL );
1474  assert( data != NULL );
1475 
1476  if ( data->createdvars == NULL )
1477  {
1478  SCIPerrorMessage("Number of variables needs to be specified before integer section!\n");
1479  goto TERMINATE;
1480  }
1481 
1482  assert( data->nvars >= 0 );
1483 
1484  /* read to end of file */
1485  SCIP_CALL( readNextLineStar(scip, file, &data->buffer, &data->bufferlen, linecount, &success) );
1486  while ( success )
1487  {
1488  if ( strncmp(data->buffer, "*RANK1", 5) == 0 )
1489  break;
1490 
1491  /* check that line starts with '*' */
1492  if ( strncmp(data->buffer, "*", 1) != 0 )
1493  {
1494  SCIPerrorMessage("Expected '*' at the beginning of line %" SCIP_LONGINT_FORMAT " in the INT-section.\n",
1495  *linecount);
1496  goto TERMINATE;
1497  }
1498 
1499  if ( sscanf(data->buffer + 1, "%i", &v) != 1 ) /* move the index by one to ignore the first character of the line */
1500  {
1501  SCIPerrorMessage("Could not read variable index in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1502  goto TERMINATE;
1503  }
1504 
1505  if ( v < 1 || v > data->nvars )
1506  {
1507  SCIPerrorMessage("Given integrality in line %" SCIP_LONGINT_FORMAT " for variable %d which does not exist!\n",
1508  *linecount, v);
1509  goto TERMINATE;
1510  }
1511 
1512  --v;
1513 
1514  if ( SCIPvarGetType(data->createdvars[v]) != SCIP_VARTYPE_BINARY )
1515  {
1516  SCIP_Bool infeasible;
1517 
1518  SCIP_CALL( SCIPchgVarType(scip, data->createdvars[v], SCIP_VARTYPE_INTEGER, &infeasible) );
1519 
1520  if ( infeasible )
1521  {
1522  SCIPerrorMessage("Infeasibility detected because of integrality of variable %s!\n",
1523  SCIPvarGetName(data->createdvars[v]));
1524  goto TERMINATE;
1525  }
1526  }
1527 
1528  /* read next line */
1529  SCIP_CALL( readNextLineStar(scip, file, &data->buffer, &data->bufferlen, linecount, &success) );
1530  }
1531 
1532  return SCIP_OKAY;
1533 
1534  TERMINATE:
1535  SCIP_CALL( SDPAfreeData(scip, file, data) );
1536  return SCIP_READERROR;
1537 }
1538 
1539 
1541 static
1542 SCIP_RETCODE SDPAreadRank1(
1543  SCIP* scip,
1544  SCIP_FILE* file,
1545  SCIP_Longint* linecount,
1546  SDPA_DATA* data
1547  )
1548 { /*lint --e{818}*/
1549  SCIP_Bool success;
1550  int blockidxoffset = 0;
1551  int v;
1552 
1553  assert( scip != NULL );
1554  assert( file != NULL );
1555  assert( linecount != NULL );
1556  assert( data != NULL );
1557 
1558  if ( data->sdpblocksizes == NULL )
1559  {
1560  SCIPerrorMessage("SDP blocks need to be specified before rank-1 section!\n");
1561  goto TERMINATE;
1562  }
1563 
1564  assert( data->nvars >= 0 );
1565 
1566  /* read to end of file */
1567  SCIP_CALL( readNextLineStar(scip, file, &data->buffer, &data->bufferlen, linecount, &success) );
1568  while ( success )
1569  {
1570  char* ps;
1571 
1572  if ( strncmp(data->buffer, "*INTEGER", 8) == 0 )
1573  {
1574  SCIPerrorMessage("Integer section in line %" SCIP_LONGINT_FORMAT " needs to be in front of rank1 section.\n",
1575  *linecount);
1576  goto TERMINATE;
1577  }
1578 
1579  /* check that line starts with '*' */
1580  if ( strncmp(data->buffer, "*", 1) != 0 )
1581  {
1582  SCIPerrorMessage("Expected '*' at the beginning of line %" SCIP_LONGINT_FORMAT " in the RANK1-section.\n", *linecount);
1583  goto TERMINATE;
1584  }
1585 
1586  /* move the index by one to ignore the first character of the line */
1587  ps = data->buffer + 1;
1588  if ( sscanf(ps, "%i", &v) != 1 )
1589  {
1590  SCIPerrorMessage("Could not read SDP block index in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1591  goto TERMINATE;
1592  }
1593 
1594  /* switch from SDPA counting (starting from 1) to SCIP counting (starting from 0) */
1595  --v;
1596 
1597  /* reset LP block offset */
1598  blockidxoffset = 0;
1599 
1600  if ( v == data->idxlinconsblock )
1601  {
1602  SCIPerrorMessage("Given rank1 in line %" SCIP_LONGINT_FORMAT " for the LP block which is not valid.\n",
1603  *linecount);
1604  goto TERMINATE;
1605  }
1606 
1607  /* check if the LP block was already read and adjust the counter as well as the offset for error messages */
1608  if ( data->idxlinconsblock >= 0 && v > data->idxlinconsblock )
1609  {
1610  v -= 1;
1611  blockidxoffset = 1;
1612  }
1613 
1614  if ( v < 0 || v >= data->nsdpblocks )
1615  {
1616  SCIPerrorMessage("Given rank1 in line %" SCIP_LONGINT_FORMAT " for SDP block %d which does not exist!\n",
1617  *linecount, v + 1 + blockidxoffset);
1618  goto TERMINATE;
1619  }
1620 
1621  data->sdpblockrank1[v] = TRUE;
1622  ++data->nsdpblocksrank1;
1623 
1624  SCIP_CALL( readNextLineStar(scip, file, &data->buffer, &data->bufferlen, linecount, &success) );
1625  }
1626 
1627  return SCIP_OKAY;
1628 
1629  TERMINATE:
1630  SCIP_CALL( SDPAfreeData(scip, file, data) );
1631  return SCIP_READERROR;
1632 }
1633 
1634 
1635 /*
1636  * Callback methods of reader
1637  */
1638 
1639 
1641 static
1642 SCIP_DECL_READERCOPY(readerCopySdpa)
1643 { /*lint --e{715,818}*/
1644  assert( scip != NULL );
1645 
1646  SCIP_CALL( SCIPincludeReaderSdpa(scip) );
1647 
1648  return SCIP_OKAY;
1649 }
1650 
1651 
1653 static
1654 SCIP_DECL_READERREAD(readerReadSdpa)
1655 { /*lint --e{715,818}*/
1656  SCIP_FILE* file;
1657  SCIP_Longint linecount = 0;
1658  SDPA_DATA* data;
1659  int b;
1660 
1661  assert( result != NULL );
1662 
1663  *result = SCIP_DIDNOTRUN;
1664 
1665  SCIPdebugMsg(scip, "Reading file %s ...\n", filename);
1666 
1667  file = SCIPfopen(filename, "r");
1668 
1669  if ( ! file )
1670  return SCIP_READERROR;
1671 
1672  SCIP_CALL( SCIPallocBuffer(scip, &data) );
1673  data->nsdpblocks = -1;
1674  data->nsdpblocksrank1 = 0;
1675  data->nlinconss = 0;
1676  data->nvars = -1;
1677  data->nconsblocks = -1;
1678  data->idxlinconsblock = -1;
1679  data->bufferlen = 0;
1680  data->sdpblockrank1 = NULL;
1681  data->createdvars = NULL;
1682  data->createdconss = NULL;
1683  data->sdpblocksizes = NULL;
1684  data->sdpnblocknonz = NULL;
1685  data->sdpnblockvars = NULL;
1686  data->nvarnonz = NULL;
1687  data->sdpblockvars = NULL;
1688  data->sdprow = NULL;
1689  data->sdpcol = NULL;
1690  data->sdpval = NULL;
1691  data->rowpointer = NULL;
1692  data->colpointer = NULL;
1693  data->valpointer = NULL;
1694  data->sdpconstnblocknonz = NULL;
1695  data->sdpconstrow = NULL;
1696  data->sdpconstcol = NULL;
1697  data->sdpconstval = NULL;
1698  data->sdpmemsize = NULL;
1699  data->sdpconstmemsize = NULL;
1700  data->buffer = NULL;
1701 
1702  /* create empty problem */
1703  SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
1704 
1705  SCIP_CALL( SCIPsetObjsense(scip, SCIP_OBJSENSE_MINIMIZE) );
1706 
1707  /* read the file */
1708  SCIPdebugMsg(scip, "Reading number of variables\n");
1709  SCIP_CALL( SDPAreadNVars(scip, file, &linecount, data) );
1710 
1711  SCIPdebugMsg(scip, "Reading number of blocks\n");
1712  SCIP_CALL( SDPAreadNBlocks(scip, file, &linecount, data) );
1713 
1714  SCIPdebugMsg(scip, "Reading blocksizes\n");
1715  SCIP_CALL( SDPAreadBlockSize(scip, file, &linecount, data) );
1716 
1717  SCIPdebugMsg(scip, "Reading objective values\n");
1718  SCIP_CALL( SDPAreadObjVals(scip, file, &linecount, data) );
1719 
1720  SCIPdebugMsg(scip, "Reading block entries\n");
1721  SCIP_CALL( SDPAreadBlocks(scip, file, &linecount, data) );
1722 
1723  if ( strncmp(data->buffer, "*INTEGER", 8) == 0 )
1724  {
1725  SCIPdebugMsg(scip, "Reading integer section\n");
1726  SCIP_CALL( SDPAreadInt(scip, file, &linecount, data) );
1727  }
1728 
1729  if ( strncmp(data->buffer, "*RANK1", 5) == 0 )
1730  {
1731  SCIPdebugMsg(scip, "Reading rank1 section\n");
1732  SCIP_CALL( SDPAreadRank1(scip, file, &linecount, data) );
1733  }
1734 
1735 #ifdef SCIP_MORE_DEBUG
1736  for (b = 0; b < SCIPgetNConss(scip); b++)
1737  {
1738  SCIP_CALL( SCIPprintCons(scip, SCIPgetConss(scip)[b], NULL) );
1739  SCIPinfoMessage(scip, NULL, "\n");
1740  }
1741 #endif
1742 
1743  /* create SDP-constraints */
1744  for (b = 0; b < data->nsdpblocks; b++)
1745  {
1746  SCIP_CONS *sdpcons;
1747  char sdpconname[SCIP_MAXSTRLEN];
1748 #ifndef NDEBUG
1749  int snprintfreturn;
1750 #endif
1751  assert( data->sdpblocksizes[b] > 0 );
1752  assert( (data->sdpnblockvars[b] > 0 && data->sdpnblocknonz[b] > 0) || (data->sdpconstnblocknonz[b] > 0) );
1753 #ifndef NDEBUG
1754  snprintfreturn = SCIPsnprintf(sdpconname, SCIP_MAXSTRLEN, "SDP_%d", b);
1755  assert( snprintfreturn < SCIP_MAXSTRLEN );
1756 #else
1757  (void) SCIPsnprintf(sdpconname, SCIP_MAXSTRLEN, "SDP_%d", b);
1758 #endif
1759 
1760  /* special treatment of case without constant PSD blocks */
1761  if ( data->sdpconstnblocknonz == NULL )
1762  {
1763  if ( ! data->sdpblockrank1[b] )
1764  {
1765  SCIP_CALL( SCIPcreateConsSdp(scip, &sdpcons, sdpconname, data->sdpnblockvars[b], data->sdpnblocknonz[b],
1766  data->sdpblocksizes[b], data->nvarnonz[b], data->colpointer[b], data->rowpointer[b],
1767  data->valpointer[b], data->sdpblockvars[b], 0, NULL, NULL, NULL, TRUE) );
1768  }
1769  else
1770  {
1771  SCIP_CALL( SCIPcreateConsSdpRank1(scip, &sdpcons, sdpconname, data->sdpnblockvars[b], data->sdpnblocknonz[b],
1772  data->sdpblocksizes[b], data->nvarnonz[b], data->colpointer[b], data->rowpointer[b],
1773  data->valpointer[b], data->sdpblockvars[b], 0, NULL, NULL, NULL, TRUE) );
1774  }
1775  }
1776  else
1777  {
1778  if ( ! data->sdpblockrank1[b] )
1779  {
1780  SCIP_CALL( SCIPcreateConsSdp(scip, &sdpcons, sdpconname, data->sdpnblockvars[b],data->sdpnblocknonz[b],
1781  data->sdpblocksizes[b], data->nvarnonz[b], data->colpointer[b],data->rowpointer[b], data->valpointer[b],
1782  data->sdpblockvars[b], data->sdpconstnblocknonz[b],data->sdpconstcol[b], data->sdpconstrow[b],
1783  data->sdpconstval[b], TRUE) );
1784  }
1785  else
1786  {
1787  SCIP_CALL( SCIPcreateConsSdpRank1(scip, &sdpcons, sdpconname, data->sdpnblockvars[b], data->sdpnblocknonz[b],
1788  data->sdpblocksizes[b], data->nvarnonz[b], data->colpointer[b], data->rowpointer[b], data->valpointer[b],
1789  data->sdpblockvars[b], data->sdpconstnblocknonz[b], data->sdpconstcol[b], data->sdpconstrow[b],
1790  data->sdpconstval[b], TRUE) );
1791  }
1792  }
1793 #ifdef SCIP_MORE_DEBUG
1794  SCIP_CALL( SCIPprintCons(scip, sdpcons, NULL) );
1795 #endif
1796  SCIP_CALL( SCIPaddCons(scip, sdpcons) );
1797 
1798  SCIP_CALL( SCIPreleaseCons(scip, &sdpcons) );
1799  }
1800 
1801  /* free space */
1802  SCIP_CALL( SDPAfreeData(scip, file, data) );
1803 
1804  *result = SCIP_SUCCESS;
1805 
1806  return SCIP_OKAY;
1807 }
1808 
1809 
1811 static
1812 SCIP_DECL_READERWRITE(readerWriteSdpa)
1813 { /*lint --e{715,818}*/
1814  SCIP_VAR** linvars;
1815  SCIP_Real* linvals;
1816  SCIP_VAR** sdpvars;
1817  SCIP_Real** sdpval;
1818  SCIP_Real* sdpconstval;
1819  SCIP_Real val;
1820  SCIP_Real lhs;
1821  SCIP_Real rhs;
1822  int** sdpcol;
1823  int** sdprow;
1824  int* sdpconstcol;
1825  int* sdpconstrow;
1826  int* sdpnvarnonz;
1827  int* varsenses;
1828  int* consssenses;
1829  int nsdpconss = 0;
1830  int sdpnvars;
1831  int sdpnnonz;
1832  int totalsdpnnonz = 0;
1833  int sdpblocksize;
1834  int sdparraylength;
1835  int totalsdpconstnnonz = 0;
1836  int sdpconstnnonz;
1837  int consind = 0;
1838  int linconsind = 0;
1839  int nblocks;
1840  int conssign = 1;
1841  int nchangedconss = 0;
1842  int nvarbndslinconss = 0;
1843  int nlinconss = 0;
1844  int nrank1sdpblocks = 0;
1845  int objcoeff = 1;
1846  int c;
1847  int i;
1848  int v;
1849 
1850  assert( scip != NULL );
1851  assert( result != NULL );
1852  assert( nvars > 0 );
1853  assert( nconss >= 0 );
1854 
1855  SCIPdebugMsg(scip, "Writing problem in SDPA format to file.\n");
1856  *result = SCIP_DIDNOTRUN;
1857 
1858  if ( transformed )
1859  {
1860  SCIPerrorMessage("SDPA reader currently only supports writing original problems!\n");
1861  return SCIP_READERROR; /*lint !e527*/
1862  }
1863 
1864 #ifndef NDEBUG
1865  for (v = 0; v < nvars; v++)
1866  assert( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_ORIGINAL );
1867 #endif
1868 
1869  /* write number of variables */
1870  SCIPinfoMessage(scip, file, "%d\n", nvars);
1871 
1872  /* collect different variable senses */
1873  SCIP_CALL( SCIPallocBufferArray(scip, &varsenses, nvars) );
1874 
1875  for (v = 0; v < nvars; v++)
1876  {
1877  SCIP_Real lb;
1878  SCIP_Real ub;
1879 
1880  lb = SCIPvarGetLbOriginal(vars[v]);
1881  ub = SCIPvarGetUbOriginal(vars[v]);
1882 
1883  varsenses[v] = 0;
1884  if ( SCIPisZero(scip, lb) )
1885  {
1886  varsenses[v] = 1;
1887  nvarbndslinconss++;
1888  }
1889  else
1890  {
1891  if ( ! SCIPisInfinity(scip, -lb) )
1892  {
1893  SCIPerrorMessage("Can only handle variables with lower bound 0 or minus infinity.\n");
1894  SCIPfreeBufferArray(scip, &varsenses);
1895  return SCIP_READERROR; /*lint !e527*/
1896  }
1897  }
1898 
1899  if ( SCIPisZero(scip, ub) )
1900  {
1901  varsenses[v] = -1;
1902  nvarbndslinconss++;
1903  }
1904  else
1905  {
1906  if ( ! SCIPisInfinity(scip, ub) )
1907  {
1908  SCIPerrorMessage("Can only handle variables with upper bound 0 or infinity.\n");
1909  SCIPfreeBufferArray(scip, &varsenses);
1910  return SCIP_READERROR; /*lint !e527*/
1911  }
1912  }
1913  }
1914 
1915  /* collect different constraint senses */
1916  SCIP_CALL( SCIPallocBufferArray(scip, &consssenses, nconss) );
1917 
1918  /* check if all constraints are either linear or SDP*/
1919  for (c = 0; c < nconss; c++)
1920  {
1921  if ( (strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0)
1922  && (strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") != 0)
1923  && (strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") != 0))
1924  {
1925  SCIPerrorMessage("SDPA reader currently only supports linear, SDP and SDPrank1 constraints!\n");
1926  SCIPfreeBufferArray(scip, &consssenses);
1927  SCIPfreeBufferArray(scip, &varsenses);
1928  return SCIP_READERROR; /*lint !e527*/
1929  }
1930 
1931  /* count number of rank1 sdp blocks */
1932  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") == 0 )
1933  ++nrank1sdpblocks;
1934 
1935  /* only check linear constraints */
1936  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") == 0 )
1937  {
1938  lhs = SCIPgetLhsLinear(scip, conss[c]);
1939  rhs = SCIPgetRhsLinear(scip, conss[c]);
1940 
1941  if ( SCIPisEQ(scip, lhs, rhs) )
1942  {
1943  assert( ! SCIPisInfinity(scip, -lhs) && ! SCIPisInfinity(scip, rhs) );
1944  nlinconss += 2;
1945  consssenses[c] = 0;
1946  }
1947  else
1948  {
1949  if ( ! SCIPisInfinity(scip, -lhs) && ! SCIPisInfinity(scip, rhs) )
1950  {
1951  SCIPerrorMessage("Cannot handle ranged rows.\n");
1952  SCIPfreeBufferArray(scip, &consssenses);
1953  SCIPfreeBufferArray(scip, &varsenses);
1954  return SCIP_READERROR; /*lint !e527*/
1955  }
1956  else
1957  {
1958  assert( SCIPisInfinity(scip, -lhs) || SCIPisInfinity(scip, rhs) );
1959 
1960  if ( ! SCIPisInfinity(scip, -lhs) )
1961  consssenses[c] = 1;
1962  else if ( ! SCIPisInfinity(scip, rhs) )
1963  consssenses[c] = -1;
1964 
1965  nlinconss++;
1966  }
1967  }
1968  }
1969  else
1970  {
1971  assert( (strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") != 0)
1972  || (strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") != 0) );
1973 
1974  /* count number of SDP constraints (conshdlrGetNConss doesn't seem to work before transformation) */
1975  ++nsdpconss;
1976 
1977  /* count SDP nonzeros */
1978  SCIP_CALL( SCIPconsSdpGetNNonz(scip, conss[c], &sdpnnonz, &sdpconstnnonz) );
1979  totalsdpnnonz += sdpnnonz;
1980  totalsdpconstnnonz += sdpconstnnonz;
1981  }
1982  }
1983 
1984  nblocks = nsdpconss;
1985 
1986  if ( nblocks > 0 && totalsdpnnonz == 0 )
1987  {
1988  SCIPerrorMessage("There are %d SDP blocks but no nonzero coefficients. \n", nblocks);
1989  SCIPfreeBufferArray(scip, &consssenses);
1990  SCIPfreeBufferArray(scip, &varsenses);
1991  return SCIP_READERROR; /*lint !e527*/
1992  }
1993 
1994  if ( nvarbndslinconss + nlinconss > 0 )
1995  nblocks++;
1996 
1997  /* write number of blocks */
1998  SCIPinfoMessage(scip, file, "%d\n", nblocks);
1999 
2000  /* write sizes of the SDP blocks and number of linear constraints */
2001  for (c = 0; c < nconss; c++)
2002  {
2003  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") != 0 && strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") )
2004  continue;
2005 
2006  SCIPinfoMessage(scip, file, "%d ", SCIPconsSdpGetBlocksize(scip, conss[c]));
2007  }
2008 
2009  if ( nvarbndslinconss + nlinconss > 0 )
2010  SCIPinfoMessage(scip, file, "-%d \n", nvarbndslinconss + nlinconss);
2011  else
2012  SCIPinfoMessage(scip, file, "\n");
2013 
2014  /* write the objective values */
2015  /* If objsense = maximize, multiply objective values with -1 */
2016  if ( objsense == SCIP_OBJSENSE_MAXIMIZE )
2017  {
2018  objcoeff = -1;
2019  SCIPinfoMessage(scip, NULL, "WARNING: Transforming original maximization problem to a minimization problem by multiplying all objective coefficients by -1. \n");
2020  }
2021 
2022  for (v = 0; v < nvars; v++)
2023  {
2024  SCIP_Real obj;
2025 
2026  obj = SCIPvarGetObj(vars[v]);
2027 
2028  if ( ! SCIPisZero(scip, obj) )
2029  SCIPinfoMessage(scip, file, "%.15g ", obj * objcoeff);
2030  else
2031  SCIPinfoMessage(scip, file, "%.15g ", 0.0);
2032  }
2033  SCIPinfoMessage(scip, file, "\n");
2034 
2035  /* write variable bounds as linear constraints */
2036  if ( nvarbndslinconss > 0 )
2037  {
2038  for (c = 0; c < nvars; c++)
2039  {
2040  assert(varsenses[c] == 0 || varsenses[c] == -1 || varsenses[c] == 1 );
2041 
2042  if (varsenses[c] == 0 )
2043  continue;
2044 
2045  if ( varsenses[c] == -1 )
2046  {
2047  ++linconsind;
2048  SCIPinfoMessage(scip, file, "%d %d %d %d -1.0\n", c + 1, nsdpconss + 1, linconsind, linconsind);
2049  }
2050  else
2051  {
2052  ++linconsind;
2053  SCIPinfoMessage(scip, file, "%d %d %d %d 1.0\n", c + 1, nsdpconss + 1, linconsind, linconsind);
2054  }
2055  }
2056  }
2057 
2058  if ( nsdpconss > 0 )
2059  {
2060  /* allocate memory for SDPdata */
2061  SCIP_CALL( SCIPallocBufferArray(scip, &sdpnvarnonz, nvars) );
2062  SCIP_CALL( SCIPallocBufferArray(scip, &sdpcol, totalsdpnnonz) );
2063  SCIP_CALL( SCIPallocBufferArray(scip, &sdprow, totalsdpnnonz) );
2064  SCIP_CALL( SCIPallocBufferArray(scip, &sdpval, totalsdpnnonz) );
2065  SCIP_CALL( SCIPallocBufferArray(scip, &sdpvars, nvars) );
2066  SCIP_CALL( SCIPallocBufferArray(scip, &sdpconstcol, totalsdpconstnnonz) );
2067  SCIP_CALL( SCIPallocBufferArray(scip, &sdpconstrow, totalsdpconstnnonz) );
2068  SCIP_CALL( SCIPallocBufferArray(scip, &sdpconstval, totalsdpconstnnonz) );
2069 
2070  sdparraylength = totalsdpnnonz;
2071  sdpconstnnonz = totalsdpconstnnonz;
2072  }
2073 
2074  /* write SDP constraint blocks */
2075  for (c = 0; c < nconss; c++)
2076  {
2077  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") == 0
2078  || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") == 0 )
2079  {
2080  /* write SDP nonzeros */
2081  if ( totalsdpnnonz > 0 )
2082  {
2083  /* coefficient matrices */
2084 
2085  /* for lint: */
2086  assert( sdpnvarnonz != NULL );
2087  assert( sdpcol != NULL );
2088  assert( sdprow != NULL );
2089  assert( sdpval != NULL );
2090  assert( sdpvars != NULL );
2091  assert( sdpconstcol != NULL );
2092  assert( sdpconstrow != NULL );
2093  assert( sdpconstval != NULL );
2094 
2095  /* initialization for SDPconsSDPGetData-call */
2096  sdparraylength = totalsdpnnonz;
2097  sdpconstnnonz = totalsdpconstnnonz;
2098 
2099  SCIP_CALL( SCIPconsSdpGetData(scip, conss[c], &sdpnvars, &sdpnnonz, &sdpblocksize, &sdparraylength,
2100  sdpnvarnonz, sdprow, sdpcol, sdpval, sdpvars, &sdpconstnnonz, sdpconstrow, sdpconstcol,
2101  sdpconstval, NULL, NULL, NULL) );
2102 
2103  assert( sdpconstnnonz <= totalsdpconstnnonz );
2104  assert( sdparraylength <= totalsdpnnonz );
2105 
2106  for (v = 0; v < sdpnvars; v++)
2107  {
2108  for (i = 0; i < sdpnvarnonz[v]; i++)
2109  {
2110  int ind;
2111  ind = SCIPvarGetProbindex(sdpvars[v]);
2112  assert( 0 <= ind && ind < nvars );
2113  SCIPinfoMessage(scip, file, "%d %d %d %d %.15g\n", ind + 1, consind + 1, sdprow[v][i]+ 1, sdpcol[v][i] + 1,
2114  sdpval[v][i]);
2115  }
2116  }
2117 
2118  /* constant matrix */
2119 
2120  /* initialization for SDPconsSDPGetData-call */
2121  sdparraylength = totalsdpnnonz;
2122 
2123  assert( sdpconstnnonz <= totalsdpconstnnonz );
2124  assert( sdparraylength <= totalsdpnnonz );
2125 
2126  for (i = 0; i < sdpconstnnonz; i++)
2127  {
2128  SCIPinfoMessage(scip, file, "%d %d %d %d %.15g\n", 0, consind + 1, sdpconstrow[i] + 1, sdpconstcol[i] + 1,
2129  sdpconstval[i]);
2130  }
2131  consind++;
2132  }
2133  }
2134  else
2135  {
2136  assert( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") == 0 );
2137 
2138  linconsind++;
2139 
2140  lhs = SCIPgetLhsLinear(scip, conss[c]);
2141  rhs = SCIPgetRhsLinear(scip, conss[c]);
2142  conssign = 1;
2143 
2144  /* in case of unconstrained left side and constrained right side swap the inequality by multipling with -1 */
2145  if ( ! SCIPisInfinity(scip, rhs) && SCIPisInfinity(scip, -lhs) )
2146  {
2147  conssign = -1;
2148  nchangedconss++;
2149  }
2150 
2151  linvars = SCIPgetVarsLinear(scip, conss[c]);
2152  linvals = SCIPgetValsLinear(scip, conss[c]);
2153 
2154  if ( ! SCIPisEQ(scip, lhs, rhs) )
2155  {
2156  for (v = 0; v < SCIPgetNVarsLinear(scip, conss[c]); v++)
2157  {
2158  i = SCIPvarGetProbindex(linvars[v]);
2159  assert( 0 <= i && i < nvars );
2160  SCIPinfoMessage(scip, file, "%d %d %d %d %.15g\n", i + 1, nsdpconss + 1, linconsind, linconsind, linvals[v] * conssign);
2161  }
2162 
2163  /* write the constant part of the LP block */
2164  if ( conssign < 0 )
2165  val = SCIPgetRhsLinear(scip, conss[c]);
2166  else
2167  val = SCIPgetLhsLinear(scip, conss[c]);
2168 
2169  if ( ! SCIPisZero(scip, val) )
2170  SCIPinfoMessage(scip, file, "%d %d %d %d %.15g\n", 0, nsdpconss + 1, linconsind, linconsind, val * conssign);
2171  }
2172  else /* write linear constraint block */
2173  {
2174  for (v = 0; v < SCIPgetNVarsLinear(scip, conss[c]); v++)
2175  {
2176  i = SCIPvarGetProbindex(linvars[v]);
2177  assert( 0 <= i && i < nvars );
2178  SCIPinfoMessage(scip, file, "%d %d %d %d %.15g\n", i + 1, nsdpconss + 1, linconsind,linconsind, linvals[v] * conssign);
2179  }
2180 
2181  /* write the constant part of the LP block */
2182  if ( conssign < 0 )
2183  val = SCIPgetRhsLinear(scip, conss[c]);
2184  else
2185  val = SCIPgetLhsLinear(scip, conss[c]);
2186 
2187  if ( ! SCIPisZero(scip, val) )
2188  SCIPinfoMessage(scip, file, "%d %d %d %d %.15g\n", 0, nsdpconss + 1, linconsind, linconsind, val * conssign);
2189 
2190  ++linconsind;
2191 
2192  for (v = 0; v < SCIPgetNVarsLinear(scip, conss[c]); v++)
2193  {
2194  i = SCIPvarGetProbindex(linvars[v]);
2195  assert( 0 <= i && i < nvars );
2196  SCIPinfoMessage(scip, file, "%d %d %d %d %.15g\n", i + 1, nsdpconss + 1, linconsind,linconsind, linvals[v] * conssign*(-1));
2197  }
2198 
2199  /* write the constant part of the LP block */
2200  if ( conssign < 0 )
2201  val = SCIPgetRhsLinear(scip, conss[c]);
2202  else
2203  val = SCIPgetLhsLinear(scip, conss[c]);
2204 
2205  if ( ! SCIPisZero(scip, val) )
2206  SCIPinfoMessage(scip, file, "%d %d %d %d %.15g\n", 0, nsdpconss + 1, linconsind, linconsind, val * conssign*(-1));
2207  }
2208  }
2209  }
2210 
2211  if ( nchangedconss > 0 )
2212  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Changed the sign of %d constraints. \n", nchangedconss);
2213 
2214  /* write integrality constraints */
2215  if ( nbinvars + nintvars > 0 )
2216  {
2217  SCIPinfoMessage(scip, file, "*INTEGER\n");
2218  for (v = 0; v < nbinvars + nintvars; v++)
2219  {
2220  assert( SCIPvarIsIntegral(vars[v]) );
2221  SCIPinfoMessage(scip, file, "*%d\n", v + 1);
2222  }
2223  }
2224 
2225  /* write rank-1 SDP constraints (if existing) */
2226  if ( nrank1sdpblocks > 0 )
2227  {
2228  consind = 0;
2229  SCIPinfoMessage(scip, file, "*RANK1\n");
2230  for (c = 0; c < nconss; c++)
2231  {
2232  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") == 0 )
2233  continue;
2234 
2235  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") == 0
2236  || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") == 0 )
2237  consind++;
2238 
2239  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") == 0 )
2240  {
2241  assert( SCIPconsSdpShouldBeRankOne(conss[c]) );
2242  SCIPinfoMessage(scip, file, "*%d\n", consind);
2243  }
2244  }
2245  }
2246 
2247  if ( nsdpconss > 0 )
2248  {
2249  SCIPfreeBufferArray(scip, &sdpconstval);
2250  SCIPfreeBufferArray(scip, &sdpconstrow);
2251  SCIPfreeBufferArray(scip, &sdpconstcol);
2252  SCIPfreeBufferArray(scip, &sdpvars);
2253  SCIPfreeBufferArray(scip, &sdpval);
2254  SCIPfreeBufferArray(scip, &sdprow);
2255  SCIPfreeBufferArray(scip, &sdpcol);
2256  SCIPfreeBufferArray(scip, &sdpnvarnonz);
2257  }
2258  SCIPfreeBufferArray(scip, &consssenses);
2259  SCIPfreeBufferArray(scip, &varsenses);
2260 
2261  *result = SCIP_SUCCESS;
2262 
2263  return SCIP_OKAY;
2264 }
2265 
2266 
2267 /*
2268  * reader specific interface methods
2269  */
2270 
2273  SCIP* scip
2274  )
2275 {
2276  SCIP_READERDATA* readerdata = NULL;
2277  SCIP_READER* reader;
2278 
2279  /* include reader */
2280  SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, readerdata) );
2281 
2282  assert( reader != NULL );
2283 
2284  /* set non fundamental callbacks via setter functions */
2285  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopySdpa) );
2286  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadSdpa) );
2287  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteSdpa) );
2288 
2289  return SCIP_OKAY;
2290 }
static SCIP_RETCODE SDPAreadNBlocks(SCIP *scip, SCIP_FILE *file, SCIP_Longint *linecount, SDPA_DATA *data)
Definition: reader_sdpa.c:574
#define READER_NAME
Definition: reader_sdpa.c:57
file reader for mixed-integer semidefinite programs in SDPA format
static SCIP_RETCODE SDPAreadObjVals(SCIP *scip, SCIP_FILE *file, SCIP_Longint *linecount, SDPA_DATA *data)
Definition: reader_sdpa.c:758
#define SDPA_MIN_BUFFERLEN
Definition: reader_sdpa.c:61
#define READER_EXTENSION
Definition: reader_sdpa.c:59
static SCIP_DECL_READERREAD(readerReadSdpa)
Definition: reader_sdpa.c:1654
static SCIP_RETCODE SDPAfreeData(SCIP *scip, SCIP_FILE *file, SDPA_DATA *data)
Definition: reader_sdpa.c:425
struct SDPA_Data SDPA_DATA
Definition: reader_sdpa.c:97
static SCIP_RETCODE readNextLine(SCIP *scip, SCIP_FILE *file, char **buffer, int *bufferlen, SCIP_Longint *linecount, SCIP_Bool *success)
Definition: reader_sdpa.c:169
SCIP_RETCODE SCIPcreateConsSdpRank1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, int nnonz, int blocksize, int *nvarnonz, int **col, int **row, SCIP_Real **val, SCIP_VAR **vars, int constnnonz, int *constcol, int *constrow, SCIP_Real *constval, SCIP_Bool removeduplicates)
Definition: cons_sdp.c:8794
static SCIP_DECL_READERWRITE(readerWriteSdpa)
Definition: reader_sdpa.c:1812
SCIP_RETCODE SCIPcreateConsSdp(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, int nnonz, int blocksize, int *nvarnonz, int **col, int **row, SCIP_Real **val, SCIP_VAR **vars, int constnnonz, int *constcol, int *constrow, SCIP_Real *constval, SCIP_Bool removeduplicates)
Definition: cons_sdp.c:8567
static SCIP_RETCODE SDPAreadBlockSize(SCIP *scip, SCIP_FILE *file, SCIP_Longint *linecount, SDPA_DATA *data)
Definition: reader_sdpa.c:620
static SCIP_RETCODE SDPAreadBlocks(SCIP *scip, SCIP_FILE *file, SCIP_Longint *linecount, SDPA_DATA *data)
Definition: reader_sdpa.c:826
Constraint handler for SDP-constraints.
SCIP_RETCODE SCIPconsSdpGetData(SCIP *scip, SCIP_CONS *cons, int *nvars, int *nnonz, int *blocksize, int *arraylength, int *nvarnonz, int **col, int **row, SCIP_Real **val, SCIP_VAR **vars, int *constnnonz, int *constcol, int *constrow, SCIP_Real *constval, SCIP_Bool *rankone, int **maxevsubmat, SCIP_Bool *addedquadcons)
Definition: cons_sdp.c:7983
SCIP_Bool SCIPconsSdpShouldBeRankOne(SCIP_CONS *cons)
Definition: cons_sdp.c:8513
#define READER_DESC
Definition: reader_sdpa.c:58
static SCIP_RETCODE readLineInts(SCIP *scip, SCIP_FILE *file, char **buffer, int *bufferlen, SCIP_Longint *linecount, int nvals, int *values, int *nread)
Definition: reader_sdpa.c:340
static SCIP_DECL_READERCOPY(readerCopySdpa)
Definition: reader_sdpa.c:1642
static SCIP_RETCODE readLine(SCIP *scip, SCIP_FILE *file, char **buffer, int *bufferlen, SCIP_Bool *success)
Definition: reader_sdpa.c:105
int SCIPconsSdpGetBlocksize(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sdp.c:8149
static SCIP_RETCODE readLineDoubles(SCIP *scip, SCIP_FILE *file, char **buffer, int *bufferlen, SCIP_Longint *linecount, int nvals, SCIP_Real *values, int *nread)
Definition: reader_sdpa.c:246
static SCIP_RETCODE SDPAreadInt(SCIP *scip, SCIP_FILE *file, SCIP_Longint *linecount, SDPA_DATA *data)
Definition: reader_sdpa.c:1461
SCIP_RETCODE SCIPincludeReaderSdpa(SCIP *scip)
Definition: reader_sdpa.c:2272
static SCIP_RETCODE readNextLineStar(SCIP *scip, SCIP_FILE *file, char **buffer, int *bufferlen, SCIP_Longint *linecount, SCIP_Bool *success)
Definition: reader_sdpa.c:211
SCIP_RETCODE SCIPconsSdpGetNNonz(SCIP *scip, SCIP_CONS *cons, int *nnonz, int *constnnonz)
Definition: cons_sdp.c:8090
static SCIP_RETCODE SDPAreadRank1(SCIP *scip, SCIP_FILE *file, SCIP_Longint *linecount, SDPA_DATA *data)
Definition: reader_sdpa.c:1542
static SCIP_RETCODE SDPAreadNVars(SCIP *scip, SCIP_FILE *file, SCIP_Longint *linecount, SDPA_DATA *data)
Definition: reader_sdpa.c:498