SCIP-SDP  4.0.0
reader_cbf.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 
70 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
71 
72 #include <assert.h>
73 #include <string.h> /* for strcmp */
74 
75 #include "scipsdp/reader_cbf.h"
76 #include "scipsdp/cons_sdp.h"
77 #include "scip/cons_linear.h"
78 
79 
80 #define READER_NAME "cbfreader"
81 #define READER_DESC "file reader and writer for MISDPs in cbf format"
82 #define READER_EXTENSION "cbf"
83 
84 #define CBF_VERSION_NR 3
85 #define CBF_CHECK_NONNEG TRUE
88  /* TODO: currently doesn't work for ranged rows (which are not created by sdpa
89  * reader) */
90 
91 /* lengths of strings */
92 #define CBF_MAX_LINE 512 /* Last 3 chars reserved for '\r\n\0' */
93 #define CBF_MAX_NAME 512
94 
95 /* used macros for reading names */
96 #define MACRO_STR_EXPAND(tok) #tok
97 #define MACRO_STR(tok) MACRO_STR_EXPAND(tok)
98 #define CBF_NAME_FORMAT "%" MACRO_STR(CBF_MAX_NAME) "s"
99 
100 struct CBF_Data
101 {
102  int npsdvars;
103  int* psdvarsizes;
104  SCIP_Bool* psdvarrank1;
105  SCIP_VAR**** createdpsdvars;
106  SCIP_Bool noorigsdpcons;
107  SCIP_Bool* sdpblockrank1;
108  int nsdpblocksrank1;
110  int nvars;
111  SCIP_VAR** createdvars;
112  int nconss;
113  SCIP_CONS** createdconss;
115  int nsdpblocks;
116  int* sdpblocksizes;
117  int* sdpnblocknonz;
118  int* sdpnblockvars;
119  int** nvarnonz;
120  SCIP_VAR*** sdpblockvars;
121  int** sdprow;
122  int** sdpcol;
123  SCIP_Real** sdpval;
124  int nnonz;
125  int*** rowpointer;
126  int*** colpointer;
127  SCIP_Real*** valpointer;
128  int* sdpconstnblocknonz;
130  int** sdpconstrow;
131  int** sdpconstcol;
132  SCIP_Real** sdpconstval;
133  int constnnonz;
134  char* linebuffer;
135  char* namebuffer;
136 };
137 
138 typedef struct CBF_Data CBF_DATA;
139 
141 /*
142  * Local methods
143  */
145 static
146 SCIP_RETCODE CBFfreeData(
147  SCIP* scip,
148  SCIP_FILE* file,
149  CBF_DATA* data
150  )
151 {
152  int b = 0;
153  int i;
154  int t;
155  int ncbfsdpblocks;
156 
157  assert( scip != NULL );
158  assert( data != NULL );
159 
160  /* we only allocated memory for the const blocks if there were any nonzeros */
161  if ( data->constnnonz > 0 )
162  {
163  for (b = 0; b < data->nsdpblocks; b++)
164  {
165  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpconstval[b]), data->constnnonz);
166  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpconstcol[b]), data->constnnonz);
167  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpconstrow[b]), data->constnnonz);
168  }
169  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpconstval, data->nsdpblocks);
170  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpconstcol, data->nsdpblocks);
171  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpconstrow, data->nsdpblocks);
172  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpconstnblocknonz, data->nsdpblocks);
173  }
174 
175  /* we only allocated memory for the sdpblocks if there were any nonzeros */
176  if ( data->nnonz > 0 )
177  {
178  /* get number of sdp blocks specified by PSDCON (without auxiliary sdp blocks for reformulating matrix variables
179  * using scalar variables), save number of nonzeros needed for the auxiliary sdp blocks in nauxnonz */
180  if ( data->npsdvars > 0 )
181  ncbfsdpblocks = data->nsdpblocks - data->npsdvars;
182  else
183  ncbfsdpblocks = data->nsdpblocks;
184 
185  if ( data->noorigsdpcons )
186  {
187  /* no SDP constraints specified in the CBF file! */
188  assert( ncbfsdpblocks == 0 );
189 
190  for (b = 0; b < data->nsdpblocks; b++)
191  {
192  SCIPfreeBlockMemoryArrayNull(scip, &(data->valpointer[b]), data->sdpnblocknonz[b]);
193  SCIPfreeBlockMemoryArrayNull(scip, &(data->colpointer[b]), data->sdpnblocknonz[b]);
194  SCIPfreeBlockMemoryArrayNull(scip, &(data->rowpointer[b]), data->sdpnblocknonz[b]);
195  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpval[b]), data->sdpnblocknonz[b]);
196  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpcol[b]), data->sdpnblocknonz[b]);
197  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdprow[b]), data->sdpnblocknonz[b]);
198  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpblockvars[b]), data->sdpnblocknonz[b]);
199  SCIPfreeBlockMemoryArrayNull(scip, &(data->nvarnonz[b]), data->sdpnblocknonz[b]);
200  }
201 
202  SCIPfreeBlockMemoryArrayNull(scip, &data->valpointer, data->nsdpblocks);
203  SCIPfreeBlockMemoryArrayNull(scip, &data->colpointer, data->nsdpblocks);
204  SCIPfreeBlockMemoryArrayNull(scip, &data->rowpointer, data->nsdpblocks);
205  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpval, data->nsdpblocks);
206  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpcol, data->nsdpblocks);
207  SCIPfreeBlockMemoryArrayNull(scip, &data->sdprow, data->nsdpblocks);
208  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblockvars, data->nsdpblocks);
209  SCIPfreeBlockMemoryArrayNull(scip, &data->nvarnonz, data->nsdpblocks);
210  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpnblockvars, data->nsdpblocks);
211  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpnblocknonz, data->nsdpblocks);
212  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblockrank1, data->nsdpblocks);
213  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblocksizes, data->nsdpblocks);
214  }
215  else
216  {
217  /* some SDP constraints specified in the CBF file! */
218  assert( ncbfsdpblocks > 0 );
219 
220  for (b = 0; b < ncbfsdpblocks; b++)
221  {
222  if ( data->sdpnblockvars != NULL )
223  {
224  SCIPfreeBlockMemoryArrayNull(scip, &(data->valpointer[b]), data->nvars);
225  SCIPfreeBlockMemoryArrayNull(scip, &(data->colpointer[b]), data->nvars);
226  SCIPfreeBlockMemoryArrayNull(scip, &(data->rowpointer[b]), data->nvars);
227  SCIPfreeBlockMemoryArrayNull(scip, &(data->nvarnonz[b]), data->nvars);
228  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpblockvars[b]), data->nvars);
229  }
230  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpval[b]), data->nnonz);
231  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpcol[b]), data->nnonz);
232  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdprow[b]), data->nnonz);
233  }
234 
235  if ( data->npsdvars > 0 )
236  {
237  for (b = ncbfsdpblocks; b < data->nsdpblocks; b++)
238  {
239  if ( data->sdpnblockvars != NULL )
240  {
241  SCIPfreeBlockMemoryArrayNull(scip, &(data->valpointer[b]), data->sdpnblocknonz[b]);
242  SCIPfreeBlockMemoryArrayNull(scip, &(data->colpointer[b]), data->sdpnblocknonz[b]);
243  SCIPfreeBlockMemoryArrayNull(scip, &(data->rowpointer[b]), data->sdpnblocknonz[b]);
244  SCIPfreeBlockMemoryArrayNull(scip, &(data->nvarnonz[b]), data->sdpnblocknonz[b]);
245  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpblockvars[b]), data->sdpnblocknonz[b]);
246  }
247  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpval[b]), data->nnonz);
248  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdpcol[b]), data->nnonz);
249  SCIPfreeBlockMemoryArrayNull(scip, &(data->sdprow[b]), data->nnonz);
250  }
251  }
252 
253  if ( data->sdpnblockvars != NULL )
254  {
255  SCIPfreeBlockMemoryArrayNull(scip, &data->valpointer, data->nsdpblocks);
256  SCIPfreeBlockMemoryArrayNull(scip, &data->colpointer, data->nsdpblocks);
257  SCIPfreeBlockMemoryArrayNull(scip, &data->rowpointer, data->nsdpblocks);
258  SCIPfreeBlockMemoryArrayNull(scip, &data->nvarnonz, data->nsdpblocks);
259  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblockvars, data->nsdpblocks);
260  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpnblockvars, data->nsdpblocks);
261  }
262  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpval, data->nsdpblocks);
263  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpcol, data->nsdpblocks);
264  SCIPfreeBlockMemoryArrayNull(scip, &data->sdprow, data->nsdpblocks);
265  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpnblocknonz, data->nsdpblocks);
266  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblockrank1, data->nsdpblocks);
267  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblocksizes, data->nsdpblocks);
268  }
269  }
270  else if ( data->nsdpblocks > 0 )
271  {
272  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblockrank1, data->nsdpblocks);
273  SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblocksizes, data->nsdpblocks);
274  }
275 
276  if (data->nconss > 0)
277  {
278  SCIPfreeBlockMemoryArrayNull(scip, &data->createdconss, data->nconss);
279  }
280 
281  if (data->nvars > 0)
282  SCIPfreeBlockMemoryArrayNull(scip, &data->createdvars, data->nvars);
283 
284  if ( data->npsdvars > 0 && data->psdvarsizes != NULL )
285  {
286  assert( data->createdpsdvars != NULL );
287  assert( data->psdvarrank1 != NULL );
288 
289  for (t = 0; t < data->npsdvars; t++)
290  {
291  if ( data->psdvarsizes[t] > 0 )
292  {
293  for (i = 0; i < data->psdvarsizes[t]; ++i)
294  SCIPfreeBlockMemoryArrayNull(scip, &(data->createdpsdvars[t][i]), i+1);
295  SCIPfreeBlockMemoryArrayNull(scip, &(data->createdpsdvars[t]), data->psdvarsizes[t]);
296  }
297  }
298 
299  SCIPfreeBlockMemoryArrayNull(scip, &(data->psdvarrank1), data->npsdvars);
300  SCIPfreeBlockMemoryArrayNull(scip, &(data->psdvarsizes), data->npsdvars);
301  SCIPfreeBlockMemoryArrayNull(scip, &(data->createdpsdvars), data->npsdvars);
302  }
303 
304  SCIPfreeBlockMemoryArrayNull(scip, &data->namebuffer, CBF_MAX_NAME);
305  SCIPfreeBlockMemoryArrayNull(scip, &data->linebuffer, CBF_MAX_LINE);
306 
307  SCIPfreeBufferNull(scip, &data);
308  assert( data == NULL );
309 
310  /* close the file (and make sure SCIPfclose returns 0) */
311  if ( SCIPfclose(file) )
312  return SCIP_READERROR;
313 
314  return SCIP_OKAY;
315 }
316 
318 static
319 SCIP_RETCODE CBFfgets(
320  SCIP* scip,
321  CBF_DATA* data,
322  SCIP_FILE* pFile,
323  SCIP_Longint* linecount,
324  SCIP_Bool printerror
325  )
326 {
327  assert( data != NULL );
328  assert( pFile != NULL );
329  assert( linecount != NULL );
330 
331  /* Find first non-commentary line */
332  while ( SCIPfgets(data->linebuffer, CBF_MAX_LINE, pFile) != NULL )
333  {
334  ++(*linecount);
335 
336  if ( data->linebuffer[0] != '#' )
337  return SCIP_OKAY;
338  }
339 
340  if ( printerror )
341  {
342  SCIPerrorMessage("Could not read content of line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
343  SCIP_CALL( CBFfreeData(scip, pFile, data) );
344  }
345  return SCIP_READERROR;
346 }
347 
349 static
350 SCIP_RETCODE CBFreadObjsense(
351  SCIP* scip,
352  CBF_DATA* data,
353  SCIP_FILE* pfile,
354  SCIP_Longint* linecount
355  )
356 {
357  assert( scip != NULL );
358  assert( data != NULL );
359  assert( pfile != NULL );
360  assert( linecount != NULL );
361 
362  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
363 
364  if ( sscanf(data->linebuffer, CBF_NAME_FORMAT, data->namebuffer) != 1 )
365  {
366  SCIPerrorMessage("Could not read OBJSENSE in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
367  SCIP_CALL( CBFfreeData(scip, pfile, data) );
368  return SCIP_READERROR;
369  }
370 
371  if ( strcmp(data->namebuffer, "MIN") == 0 )
372  {
373  SCIP_CALL( SCIPsetObjsense(scip, SCIP_OBJSENSE_MINIMIZE) );
374  }
375  else if ( strcmp(data->namebuffer, "MAX") == 0 )
376  {
377  SCIP_CALL( SCIPsetObjsense(scip, SCIP_OBJSENSE_MAXIMIZE) );
378  }
379  else
380  {
381  SCIPerrorMessage("OBJSENSE in line %" SCIP_LONGINT_FORMAT " should be either MIN or MAX.\n", *linecount);
382  SCIP_CALL( CBFfreeData(scip, pfile, data) );
383  return SCIP_READERROR; /*lint !e527*/
384  }
385 
386  return SCIP_OKAY;
387 }
388 
390 static
391 SCIP_RETCODE CBFreadVar(
392  SCIP* scip,
393  CBF_DATA* data,
394  SCIP_FILE* pfile,
395  SCIP_Longint* linecount
396  )
397 {
398  char varname[SCIP_MAXSTRLEN];
399  SCIP_VAR* var;
400  int nvartypevars;
401  int nvartypes;
402  int cnt = 0;
403  int t;
404  int v;
405 #ifndef NDEBUG
406  int snprintfreturn;
407 #endif
408 
409  assert( scip != NULL );
410  assert( data != NULL );
411  assert( pfile != NULL );
412  assert( linecount != NULL );
413 
414  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
415 
416  if ( sscanf(data->linebuffer, "%i %i", &(data->nvars), &nvartypes) != 2 )
417  {
418  SCIPerrorMessage("Could not read number of scalar variables and conic domains in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
419  SCIP_CALL( CBFfreeData(scip, pfile, data) );
420  return SCIP_READERROR;
421  }
422 
423  if ( data->nvars < 0 )
424  {
425  SCIPerrorMessage("Number of scalar variables %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", data->nvars, *linecount);
426  SCIP_CALL( CBFfreeData(scip, pfile, data) );
427  return SCIP_READERROR; /*lint !e527*/
428  }
429 
430  if ( nvartypes < 0 )
431  {
432  SCIPerrorMessage("Number of conic variable domains %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", nvartypes, *linecount);
433  SCIP_CALL( CBFfreeData(scip, pfile, data) );
434  return SCIP_READERROR; /*lint !e527*/
435  }
436 
437  assert( data->nvars >= 0 && nvartypes >= 0 );
438  assert( data->nvars > 0 || nvartypes == 0 );
439  assert( data->nvars == 0 || nvartypes > 0 );
440 
441  /* if no scalar variables exist, then exit */
442  if ( data->nvars == 0 )
443  return SCIP_OKAY;
444 
445  /* loop through different variable types */
446  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->createdvars), data->nvars) );
447  for (t = 0; t < nvartypes; t++)
448  {
449  SCIP_Real lb;
450  SCIP_Real ub;
451 
452  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
453 
454  if ( sscanf(data->linebuffer, CBF_NAME_FORMAT" %i", data->namebuffer, &nvartypevars) != 2 )
455  {
456  SCIPerrorMessage("Could not read conic domain and number of corresponding scalar variables in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
457  SCIP_CALL( CBFfreeData(scip, pfile, data) );
458  return SCIP_READERROR;
459  }
460 
461  if ( nvartypevars <= 0 )
462  {
463  SCIPerrorMessage("Number of scalar variables %d in line %" SCIP_LONGINT_FORMAT " should be positive!\n", nvartypevars, *linecount);
464  SCIP_CALL( CBFfreeData(scip, pfile, data) );
465  return SCIP_READERROR; /*lint !e527*/
466  }
467 
468  lb = -SCIPinfinity(scip);
469  ub = SCIPinfinity(scip);
470 
471  if ( strcmp(data->namebuffer, "L+") == 0 )
472  {
473  lb = 0.0;
474  }
475  else if ( strcmp(data->namebuffer, "L-") == 0 )
476  {
477  ub = 0.0;
478  }
479  else if ( strcmp(data->namebuffer, "F") != 0 )
480  {
481  SCIPerrorMessage("CBF-Reader of SCIP-SDP currently only supports non-negative, non-positive and free variables!\n");
482  SCIP_CALL( CBFfreeData(scip, pfile, data) );
483  return SCIP_READERROR; /*lint !e527*/
484  }
485 
486  /* create corresponding variables */
487  for (v = 0; v < nvartypevars; v++)
488  {
489 #ifndef NDEBUG
490  snprintfreturn = SCIPsnprintf(varname, SCIP_MAXSTRLEN, "x_%d", cnt);
491  assert( snprintfreturn < SCIP_MAXSTRLEN);
492 #else
493  (void)SCIPsnprintf(varname, SCIP_MAXSTRLEN, "x_%d", cnt);
494 #endif
495 
496  SCIP_CALL( SCIPcreateVar(scip, &var, varname, lb, ub, 0.0, SCIP_VARTYPE_CONTINUOUS,
497  TRUE, FALSE, NULL, NULL, NULL, NULL, NULL));/*lint !e732*//*lint !e747*/
498 
499  SCIP_CALL( SCIPaddVar(scip, var) );
500  data->createdvars[cnt++] = var;/*lint !e732*//*lint !e747*/
501 
502  /* release variable for the reader */
503  SCIP_CALL( SCIPreleaseVar(scip, &var) );
504  }
505  }
506 
507  if ( cnt != data->nvars )
508  {
509  SCIPerrorMessage("Total number of scalar variables for different cone types not equal to total number of scalar variables!\n");
510  SCIP_CALL( CBFfreeData(scip, pfile, data) );
511  return SCIP_READERROR; /*lint !e527*/
512  }
513 
514  return SCIP_OKAY;
515 }
516 
518 static
519 SCIP_RETCODE CBFreadPsdVar(
520  SCIP* scip,
521  CBF_DATA* data,
522  SCIP_FILE* pfile,
523  SCIP_Longint* linecount
524  )
525 { /*lint --e{818}*/
526  char varname[SCIP_MAXSTRLEN];
527  SCIP_VAR* var;
528  int i;
529  int j;
530  int t;
531 #ifndef NDEBUG
532  int snprintfreturn;
533 #endif
534 
535  assert( scip != NULL );
536  assert( data != NULL );
537  assert( pfile != NULL );
538  assert( linecount != NULL );
539 
540  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
541 
542  if ( sscanf(data->linebuffer, "%i", &(data->npsdvars)) != 1 )
543  {
544  SCIPerrorMessage("Could not read number of psd variables in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
545  SCIP_CALL( CBFfreeData(scip, pfile, data) );
546  return SCIP_READERROR;
547  }
548 
549  if ( data->npsdvars < 0 )
550  {
551  SCIPerrorMessage("Number of psd variables %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", data->npsdvars, *linecount);
552  SCIP_CALL( CBFfreeData(scip, pfile, data) );
553  return SCIP_READERROR; /*lint !e527*/
554  }
555 
556  /* if no psd variables exist, then exit */
557  if ( data->npsdvars == 0 )
558  return SCIP_OKAY;
559 
560  /* PSDVAR need to be in front of PSDCON! */
561  if ( data->nsdpblocks > -1 )
562  {
563  SCIPerrorMessage("Need to have 'PSDVAR' section before 'PSDCON' section!\n");
564  SCIP_CALL( CBFfreeData(scip, pfile, data) );
565  return SCIP_READERROR; /*lint !e527*/
566  }
567 
568  assert( data->npsdvars > 0 );
569 
570  /* loop through different psd variables */
571  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->createdpsdvars), data->npsdvars) );
572  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->psdvarsizes), data->npsdvars) );
573  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->psdvarrank1), data->npsdvars) );
574 
575  for (t = 0; t < data->npsdvars; t++)
576  {
577  SCIP_Real lb;
578  SCIP_Real ub;
579  int sizepsdvar;
580  int cnt = 0;
581 
582  /* initialize psdvarsizes with -1 to simplify freeing memory */
583  data->psdvarsizes[t] = -1;
584 
585  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
586 
587  if ( sscanf(data->linebuffer, "%i", &sizepsdvar) != 1 )
588  {
589  SCIPerrorMessage("Could not read the size of psd variable %d in line %" SCIP_LONGINT_FORMAT ".\n", t, *linecount);
590  SCIP_CALL( CBFfreeData(scip, pfile, data) );
591  return SCIP_READERROR;
592  }
593 
594  if ( sizepsdvar <= 0 )
595  {
596  SCIPerrorMessage("Size %d of psd variable %d in line %" SCIP_LONGINT_FORMAT " should be positive!\n", sizepsdvar, t, *linecount);
597  SCIP_CALL( CBFfreeData(scip, pfile, data) );
598  return SCIP_READERROR; /*lint !e527*/
599  }
600 
601  /* for each psd variable of size n_i create 1/2*n_i*(n_i+1) scalar variables */
602  data->psdvarsizes[t] = sizepsdvar;
603 
604  /* initialize rank-1 information for each psd variable with FALSE, will eventually be changed when reading PSDVARRANK1 */
605  data->psdvarrank1[t] = FALSE;
606 
607  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->createdpsdvars[t]), sizepsdvar) );
608 
609  lb = -SCIPinfinity(scip);
610  ub = SCIPinfinity(scip);
611 
612  for (i = 0; i < sizepsdvar; ++i)
613  {
614  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->createdpsdvars[t][i]), i+1) );
615  for (j = 0; j <= i; ++j)
616  {
617 #ifndef NDEBUG
618  snprintfreturn = SCIPsnprintf(varname, SCIP_MAXSTRLEN, "y_%d%d%d", t, i, j);
619  assert( snprintfreturn < SCIP_MAXSTRLEN);
620 #else
621  (void)SCIPsnprintf(varname, SCIP_MAXSTRLEN, "y_%d%d%d", t, i, j);
622 #endif
623 
624  SCIP_CALL( SCIPcreateVar(scip, &var, varname, lb, ub, 0.0, SCIP_VARTYPE_CONTINUOUS,
625  TRUE, FALSE, NULL, NULL, NULL, NULL, NULL));/*lint !e732*//*lint !e747*/
626 
627  SCIP_CALL( SCIPaddVar(scip, var) );
628  data->createdpsdvars[t][i][j] = var;/*lint !e732*//*lint !e747*/
629  ++cnt;
630 
631  /* release variable for the reader */
632  SCIP_CALL( SCIPreleaseVar(scip, &var) );
633  }
634  }
635  assert( cnt == sizepsdvar * (sizepsdvar + 1) / 2 );
636  }
637 
638  return SCIP_OKAY;
639 }
640 
642 static
643 SCIP_RETCODE CBFreadPsdVarRank1(
644  SCIP* scip,
645  CBF_DATA* data,
646  SCIP_FILE* pfile,
647  SCIP_Longint* linecount
648  )
649 { /*lint --e{818}*/
650  int nrank1psdvars;
651  int i;
652  int v;
653 
654  assert( scip != NULL );
655  assert( data != NULL );
656  assert( pfile != NULL );
657  assert( linecount != NULL );
658 
659  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
660 
661  if ( sscanf(data->linebuffer, "%i", &(nrank1psdvars)) != 1 )
662  {
663  SCIPerrorMessage("Could not read number of psd variables with a rank-1 constraint in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
664  SCIP_CALL( CBFfreeData(scip, pfile, data) );
665  return SCIP_READERROR;
666  }
667 
668  if ( nrank1psdvars == 0 )
669  return SCIP_OKAY;
670 
671  /* PSDVAR need to be in front of PSDVARRANK1! */
672  if ( data->npsdvars < 0 )
673  {
674  SCIPerrorMessage("Need to have 'PSDVAR' section before 'PSDVARRANK1' section!\n");
675  SCIP_CALL( CBFfreeData(scip, pfile, data) );
676  return SCIP_READERROR; /*lint !e527*/
677  }
678 
679  if ( nrank1psdvars < 0 )
680  {
681  SCIPerrorMessage("Number of psd variables with a rank-1 constraint %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", nrank1psdvars, *linecount);
682  SCIP_CALL( CBFfreeData(scip, pfile, data) );
683  return SCIP_READERROR; /*lint !e527*/
684  }
685 
686  assert( data->npsdvars >= 0 );
687  assert( nrank1psdvars >= 0 );
688  assert( data->nsdpblocksrank1 >= 0 );
689 
690  data->nsdpblocksrank1 += nrank1psdvars;
691 
692  for (i = 0; i < nrank1psdvars; i++)
693  {
694  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
695 
696  if ( sscanf(data->linebuffer, "%i", &v) != 1 )
697  {
698  SCIPerrorMessage("Could not read index of psd variable with a rank-1 constraint in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
699  SCIP_CALL( CBFfreeData(scip, pfile, data) );
700  return SCIP_READERROR;
701  }
702 
703  if ( v < 0 || v >= data->npsdvars )
704  {
705  SCIPerrorMessage("Given rank-1 constraint in line %" SCIP_LONGINT_FORMAT " for matrix variable %d which does not exist!\n", *linecount, v);
706  SCIP_CALL( CBFfreeData(scip, pfile, data) );
707  return SCIP_READERROR; /*lint !e527*/
708  }
709 
710  data->psdvarrank1[v] = TRUE;
711  }
712 
713  return SCIP_OKAY;
714 }
715 
717 static
718 SCIP_RETCODE CBFreadCon(
719  SCIP* scip,
720  CBF_DATA* data,
721  SCIP_FILE* pfile,
722  SCIP_Longint* linecount
723  )
724 {
725  char consname[SCIP_MAXSTRLEN];
726  SCIP_CONS* cons;
727  int nconstypes;
728  int nconstypeconss;
729  int t;
730  int c;
731  int cnt = 0;
732 #ifndef NDEBUG
733  int snprintfreturn;
734 #endif
735 
736  assert( scip != NULL );
737  assert( data != NULL );
738  assert( pfile != NULL );
739  assert( linecount != NULL );
740 
741  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
742 
743  if ( sscanf(data->linebuffer, "%i %i", &(data->nconss), &nconstypes) != 2 )
744  {
745  SCIPerrorMessage("Could not read number of scalar constraints and conic domains in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
746  SCIP_CALL( CBFfreeData(scip, pfile, data) );
747  return SCIP_READERROR;
748  }
749 
750  if ( data->nconss < 0 )
751  {
752  SCIPerrorMessage("Number of scalar constraints %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", data->nconss, *linecount);
753  SCIP_CALL( CBFfreeData(scip, pfile, data) );
754  return SCIP_READERROR; /*lint !e527*/
755  }
756 
757  if ( nconstypes < 0 )
758  {
759  SCIPerrorMessage("Number of conic constraint domains %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", nconstypes, *linecount);
760  SCIP_CALL( CBFfreeData(scip, pfile, data) );
761  return SCIP_READERROR; /*lint !e527*/
762  }
763  assert( data->nconss >= 0 && nconstypes >= 0 );
764  assert( data->nconss > 0 || nconstypes == 0 );
765  assert( data->nconss == 0 || nconstypes > 0 );
766 
767  /* if no scalar constraints exist, then exit */
768  if ( data->nconss == 0 )
769  return SCIP_OKAY;
770 
771  /* loop through different constraint types */
772  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->createdconss), data->nconss) );
773  for (t = 0; t < nconstypes; t++)
774  {
775  SCIP_Real lhs;
776  SCIP_Real rhs;
777 
778  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
779 
780  if ( sscanf(data->linebuffer, CBF_NAME_FORMAT" %i", data->namebuffer, &nconstypeconss) != 2 )
781  {
782  SCIPerrorMessage("Could not read conic domain and number of corresponding scalar constraints in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
783  SCIP_CALL( CBFfreeData(scip, pfile, data) );
784  return SCIP_READERROR;
785  }
786 
787  if ( nconstypeconss <= 0 )
788  {
789  SCIPerrorMessage("Number of constraints %d in line %" SCIP_LONGINT_FORMAT " should be positive!\n", nconstypeconss, *linecount);
790  SCIP_CALL( CBFfreeData(scip, pfile, data) );
791  return SCIP_READERROR; /*lint !e527*/
792  }
793 
794  lhs = -SCIPinfinity(scip);
795  rhs = SCIPinfinity(scip);
796 
797  if ( strcmp(data->namebuffer, "L+") == 0 )
798  {
799  lhs = 0.0;
800  }
801  else if ( strcmp(data->namebuffer, "L-") == 0 )
802  {
803  rhs = 0.0;
804  }
805  else if ( strcmp(data->namebuffer, "L=") == 0 )
806  {
807  lhs = 0.0;
808  rhs = 0.0;
809  }
810  else
811  {
812  SCIPerrorMessage("CBF-Reader of SCIP-SDP currently only supports linear greater or equal, less or equal and"
813  " equality constraints!\n");
814  SCIP_CALL( CBFfreeData(scip, pfile, data) );
815  return SCIP_READERROR; /*lint !e527*/
816  }
817 
818  /* create corresponding constraints */
819  for (c = 0; c < nconstypeconss; c++)
820  {
821 #ifndef NDEBUG
822  snprintfreturn = SCIPsnprintf(consname, SCIP_MAXSTRLEN, "LP_%d", cnt);
823  assert( snprintfreturn < SCIP_MAXSTRLEN);
824 #else
825  (void)SCIPsnprintf(consname, SCIP_MAXSTRLEN, "linear_%d", cnt);
826 #endif
827 
828  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, 0, NULL, NULL, lhs, rhs,
829  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE));
830 
831  SCIP_CALL( SCIPaddCons(scip, cons) );
832  data->createdconss[cnt++] = cons;
833 
834  /* release constraint for the reader. */
835  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
836  }
837  }
838 
839  if ( cnt != data->nconss )
840  {
841  SCIPerrorMessage("Total number of constraints for different cone types not equal to total number of constraints!\n");
842  SCIP_CALL( CBFfreeData(scip, pfile, data) );
843  return SCIP_READERROR; /*lint !e527*/
844  }
845 
846  return SCIP_OKAY;
847 }
848 
850 static
851 SCIP_RETCODE CBFreadInt(
852  SCIP* scip,
853  CBF_DATA* data,
854  SCIP_FILE* pfile,
855  SCIP_Longint* linecount
856  )
857 { /*lint --e{818}*/
858  int nintvars;
859  int i;
860  int v;
861  SCIP_Bool infeasible;
862 
863  assert( scip != NULL );
864  assert( data != NULL );
865  assert( pfile != NULL );
866  assert( linecount != NULL );
867 
868  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
869 
870  if ( sscanf(data->linebuffer, "%i", &nintvars) != 1 )
871  {
872  SCIPerrorMessage("Could not read number of integer variables in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
873  SCIP_CALL( CBFfreeData(scip, pfile, data) );
874  return SCIP_READERROR;
875  }
876 
877  if ( nintvars == 0 )
878  return SCIP_OKAY;
879 
880  if ( nintvars < 0 )
881  {
882  SCIPerrorMessage("Number of integrality constraints %d in line %" SCIP_LONGINT_FORMAT " should be non-negative.\n", nintvars, *linecount);
883  SCIP_CALL( CBFfreeData(scip, pfile, data) );
884  return SCIP_READERROR; /*lint !e527*/
885  }
886 
887  if ( data->createdvars == NULL )
888  {
889  SCIPerrorMessage("Need to have 'VAR' section before 'INT' section!\n");
890  SCIP_CALL( CBFfreeData(scip, pfile, data) );
891  return SCIP_READERROR; /*lint !e527*/
892  }
893  assert( data->nvars >= 0 );
894 
895  for (i = 0; i < nintvars; i++)
896  {
897  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
898 
899  if ( sscanf(data->linebuffer, "%i", &v) != 1 )
900  {
901  SCIPerrorMessage("Could not read variable index in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
902  SCIP_CALL( CBFfreeData(scip, pfile, data) );
903  return SCIP_READERROR; /*lint !e527*/
904  }
905 
906  if ( v < 0 || v >= data->nvars )
907  {
908  SCIPerrorMessage("Given integrality contraint in line %" SCIP_LONGINT_FORMAT " for variable %d which does not exist!\n", *linecount, v);
909  SCIP_CALL( CBFfreeData(scip, pfile, data) );
910  return SCIP_READERROR; /*lint !e527*/
911  }
912 
913  SCIP_CALL( SCIPchgVarType(scip, data->createdvars[v], SCIP_VARTYPE_INTEGER, &infeasible) );
914 
915  if ( infeasible )
916  {
917  SCIPerrorMessage("Infeasibility detected because of integrality of variable %s!\n", SCIPvarGetName(data->createdvars[v]));
918  SCIP_CALL( CBFfreeData(scip, pfile, data) );
919  return SCIP_READERROR; /*lint !e527*/
920  }
921  }
922 
923  return SCIP_OKAY;
924 }
925 
927 static
928 SCIP_RETCODE CBFreadPsdCon(
929  SCIP* scip,
930  CBF_DATA* data,
931  SCIP_FILE* pfile,
932  SCIP_Longint* linecount
933  )
934 {
935  int b;
936  int ncbfsdpblocks;
937 
938  assert( scip != NULL );
939  assert( data != NULL );
940  assert( pfile != NULL );
941  assert( linecount != NULL );
942 
943  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
944 
945  if ( sscanf(data->linebuffer, "%i", &ncbfsdpblocks) != 1 )
946  {
947  SCIPerrorMessage("Could not read number of psd constraints in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
948  SCIP_CALL( CBFfreeData(scip, pfile, data) );
949  return SCIP_READERROR;
950  }
951 
952  if ( ncbfsdpblocks < 0 )
953  {
954  SCIPerrorMessage("Number of SDP-blocks %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", ncbfsdpblocks, *linecount);
955  SCIP_CALL( CBFfreeData(scip, pfile, data) );
956  return SCIP_READERROR; /*lint !e527*/
957  }
958 
959  /* if no psd constraints are specified, then exit */
960  if ( ncbfsdpblocks == 0 )
961  {
962  data->noorigsdpcons = TRUE;
963  data->nsdpblocks = 0;
964  return SCIP_OKAY;
965  }
966  assert( ncbfsdpblocks > 0 );
967 
968  /* increase number of sdp blocks by number of psd variables that need to be transformed into a psd constraint
969  * with scalar variables */
970  if ( data->npsdvars > 0 )
971  data->nsdpblocks = ncbfsdpblocks + data->npsdvars;
972  else
973  data->nsdpblocks = ncbfsdpblocks;
974 
975  assert( data->nsdpblocks > 0 );
976 
977  data->noorigsdpcons = FALSE;
978  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblocksizes), data->nsdpblocks) );
979  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblockrank1), data->nsdpblocks) );
980 
981  for (b = 0; b < ncbfsdpblocks; b++)
982  {
983  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
984  if ( sscanf(data->linebuffer, "%i", &(data->sdpblocksizes[b])) != 1 )
985  {
986  SCIPerrorMessage("Could not read size of psd constraint %d in line %" SCIP_LONGINT_FORMAT ".\n", b, *linecount);
987  SCIP_CALL( CBFfreeData(scip, pfile, data) );
988  return SCIP_READERROR;
989  }
990 
991  if ( data->sdpblocksizes[b] <= 0 )
992  {
993  SCIPerrorMessage("Size %d of SDP-block %d in line %" SCIP_LONGINT_FORMAT " should be positive!\n", data->sdpblocksizes[b], b, *linecount);
994  SCIP_CALL( CBFfreeData(scip, pfile, data) );
995  return SCIP_READERROR; /*lint !e527*/
996  }
997 
998  /* initialize rank-1 information to FALSE, will eventually be changed in PSDCONRANK1 */
999  data->sdpblockrank1[b] = FALSE;
1000  }
1001 
1002  for (b = 0; b < data->npsdvars; b++)
1003  {
1004  /* read rank-1 information and size for psd variables (if existing, recall PSDVAR needs to be in front of
1005  PSDCON) */
1006  data->sdpblocksizes[ncbfsdpblocks + b] = data->psdvarsizes[b];
1007  data->sdpblockrank1[ncbfsdpblocks + b] = data->psdvarrank1[b];
1008  }
1009 
1010  return SCIP_OKAY;
1011 }
1012 
1014 static
1015 SCIP_RETCODE CBFreadPsdConRank1(
1016  SCIP* scip,
1017  CBF_DATA* data,
1018  SCIP_FILE* pfile,
1019  SCIP_Longint* linecount
1020  )
1021 {
1022  int c;
1023  int i;
1024  int nrank1sdpblocks;
1025  int ncbfsdpblocks;
1026 
1027  assert( scip != NULL );
1028  assert( data != NULL );
1029  assert( pfile != NULL );
1030  assert( linecount != NULL );
1031 
1032  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1033 
1034  if ( sscanf(data->linebuffer, "%i", &(nrank1sdpblocks)) != 1 )
1035  {
1036  SCIPerrorMessage("Could not read number of psd constraints with a rank-1 constraint in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1037  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1038  return SCIP_READERROR;
1039  }
1040 
1041  if ( nrank1sdpblocks == 0 )
1042  return SCIP_OKAY;
1043 
1044  /* PSDCON need to be in front of PSDCONRANK1! */
1045  if ( data->nsdpblocks < 0 )
1046  {
1047  SCIPerrorMessage("Need to have 'PSDCON' section before 'PSDCONRANK1' section!\n");
1048  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1049  return SCIP_READERROR; /*lint !e527*/
1050  }
1051 
1052  if ( nrank1sdpblocks < 0 )
1053  {
1054  SCIPerrorMessage("Number of psd constraints with a rank-1 constraint %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", nrank1sdpblocks, *linecount);
1055  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1056  return SCIP_READERROR; /*lint !e527*/
1057  }
1058 
1059  assert( data->nsdpblocks >= 0 );
1060  assert( nrank1sdpblocks >= 0 );
1061  assert( data->nsdpblocksrank1 >= 0 );
1062 
1063  data->nsdpblocksrank1 += nrank1sdpblocks;
1064 
1065  if ( data->npsdvars > 0 )
1066  ncbfsdpblocks = data->nsdpblocks - data->npsdvars;
1067  else
1068  ncbfsdpblocks = data->nsdpblocks;
1069 
1070  for (i = 0; i < nrank1sdpblocks; i++)
1071  {
1072  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1073  if ( sscanf(data->linebuffer, "%i", &c) != 1 )
1074  {
1075  SCIPerrorMessage("Could not read index of psd constraint with a rank-1 constraint in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1076  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1077  return SCIP_READERROR;
1078  }
1079 
1080  if ( c < 0 || c >= ncbfsdpblocks )
1081  {
1082  SCIPerrorMessage("Given rank-1 constraint in line %" SCIP_LONGINT_FORMAT " for sdp constraint %d which does not exist!\n", *linecount, c);
1083  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1084  return SCIP_READERROR; /*lint !e527*/
1085  }
1086 
1087  data->sdpblockrank1[c] = TRUE;
1088  }
1089 
1090  return SCIP_OKAY;
1091 }
1092 
1094 static
1095 SCIP_RETCODE CBFreadObjFcoord(
1096  SCIP* scip,
1097  CBF_DATA* data,
1098  SCIP_FILE* pfile,
1099  SCIP_Longint* linecount
1100  )
1101 { /*lint --e{818}*/
1102  SCIP_Real val;
1103  int nobjcoefs;
1104  int nzerocoef = 0;
1105  int i;
1106  int v;
1107  int row;
1108  int col;
1109 
1110  assert( scip != NULL );
1111  assert( data != NULL );
1112  assert( pfile != NULL );
1113  assert( linecount != NULL );
1114 
1115  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1116 
1117  if ( sscanf(data->linebuffer, "%i", &nobjcoefs) != 1 )
1118  {
1119  SCIPerrorMessage("Could not read number of objective coefficients for matrix variables in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1120  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1121  return SCIP_READERROR;
1122  }
1123 
1124  if ( nobjcoefs < 0 )
1125  {
1126  SCIPerrorMessage("Number of objective coefficients for matrix variables %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", nobjcoefs, *linecount);
1127  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1128  return SCIP_READERROR; /*lint !e527*/
1129  }
1130 
1131  if ( nobjcoefs == 0 )
1132  return SCIP_OKAY;
1133 
1134  if ( data->createdpsdvars == NULL )
1135  {
1136  SCIPerrorMessage("Need to have 'PSDVAR' section before 'OBJFCOORD' section!\n");
1137  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1138  return SCIP_READERROR; /*lint !e527*/
1139  }
1140  assert( data->npsdvars >= 0 );
1141 
1142  for (i = 0; i < nobjcoefs; i++)
1143  {
1144  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1145 
1146  if ( sscanf(data->linebuffer, "%i %i %i %lf", &v, &row, &col, &val) != 4 )
1147  {
1148  SCIPerrorMessage("Could not read entry of OBJFCOORD in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1149  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1150  return SCIP_READERROR;
1151  }
1152 
1153  if ( v < 0 || v >= data->npsdvars )
1154  {
1155  SCIPerrorMessage("Given objective coefficient in line %" SCIP_LONGINT_FORMAT " for matrix variable %d which does not exist!\n", *linecount, v);
1156  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1157  return SCIP_READERROR; /*lint !e527*/
1158  }
1159 
1160  if ( row < 0 || row >= data->psdvarsizes[v] )
1161  {
1162  SCIPerrorMessage("Row index %d of given coefficient in line %" SCIP_LONGINT_FORMAT " for matrix variable %d in objective function is negative or larger than varsize %d!\n",
1163  row, *linecount, v, data->psdvarsizes[v]);
1164  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1165  return SCIP_READERROR; /*lint !e527*/
1166  }
1167 
1168  if ( col < 0 || col >= data->psdvarsizes[v] )
1169  {
1170  SCIPerrorMessage("Column index %d of given coefficient in line %" SCIP_LONGINT_FORMAT " for matrix variable %d in objective function is negative or larger than varsize %d!\n",
1171  col, *linecount, v, data->psdvarsizes[v]);
1172  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1173  return SCIP_READERROR; /*lint !e527*/
1174  }
1175 
1176  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
1177  {
1178  SCIPerrorMessage("Given objective coefficient in line %" SCIP_LONGINT_FORMAT " for matrix variable %d is infinity, which is not allowed.\n",
1179  *linecount, v);
1180  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1181  return SCIP_READERROR;
1182  }
1183 
1184  if ( SCIPisZero(scip, val) )
1185  {
1186  ++nzerocoef;
1187  }
1188  else
1189  {
1190  /* make sure matrix is in lower triangular form */
1191  if ( row < col )
1192  {
1193  SCIP_CALL( SCIPchgVarObj(scip, data->createdpsdvars[v][col][row], 2*val) );
1194  }
1195  else if ( row == col )
1196  {
1197  SCIP_CALL( SCIPchgVarObj(scip, data->createdpsdvars[v][col][row], val) );
1198  }
1199  else
1200  {
1201  SCIP_CALL( SCIPchgVarObj(scip, data->createdpsdvars[v][row][col], 2*val) );
1202  }
1203  }
1204  }
1205 
1206  if ( nzerocoef > 0 )
1207  {
1208  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
1209  "OBJFCOORD: Found %d coefficients with absolute value less than epsilon = %g.\n", nzerocoef, SCIPepsilon(scip));
1210  }
1211 
1212  return SCIP_OKAY;
1213 }
1214 
1216 static
1217 SCIP_RETCODE CBFreadObjAcoord(
1218  SCIP* scip,
1219  CBF_DATA* data,
1220  SCIP_FILE* pfile,
1221  SCIP_Longint* linecount
1222  )
1223 { /*lint --e{818}*/
1224  SCIP_Real val;
1225  int nobjcoefs;
1226  int nzerocoef = 0;
1227  int i;
1228  int v;
1229 
1230  assert( scip != NULL );
1231  assert( data != NULL );
1232  assert( pfile != NULL );
1233  assert( linecount != NULL );
1234 
1235  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1236 
1237  if ( sscanf(data->linebuffer, "%i", &nobjcoefs) != 1 )
1238  {
1239  SCIPerrorMessage("Could not read number of objective coefficients for scalar variables in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1240  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1241  return SCIP_READERROR;
1242  }
1243 
1244  if ( nobjcoefs < 0 )
1245  {
1246  SCIPerrorMessage("Number of objective coefficients for scalar variables %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", nobjcoefs, *linecount);
1247  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1248  return SCIP_READERROR; /*lint !e527*/
1249  }
1250 
1251  if ( nobjcoefs == 0 )
1252  return SCIP_OKAY;
1253 
1254  if ( data->createdvars == NULL )
1255  {
1256  SCIPerrorMessage("Need to have 'VAR' section before 'OBJACOORD' section!\n");
1257  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1258  return SCIP_READERROR; /*lint !e527*/
1259  }
1260  assert( data->nvars >= 0 );
1261 
1262  for (i = 0; i < nobjcoefs; i++)
1263  {
1264  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1265  if ( sscanf(data->linebuffer, "%i %lf", &v, &val) != 2 )
1266  {
1267  SCIPerrorMessage("Could not read entry of OBJACOORD in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1268  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1269  return SCIP_READERROR;
1270  }
1271 
1272  if ( v < 0 || v >= data->nvars )
1273  {
1274  SCIPerrorMessage("Given objective coefficient in line %" SCIP_LONGINT_FORMAT " for scalar variable %d which does not exist!\n", *linecount, v);
1275  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1276  return SCIP_READERROR; /*lint !e527*/
1277  }
1278 
1279  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
1280  {
1281  SCIPerrorMessage("Given objective coefficient in line %" SCIP_LONGINT_FORMAT " for scalar variable %d is infinity, which is not allowed.\n",
1282  *linecount, v);
1283  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1284  return SCIP_READERROR;
1285  }
1286 
1287  if ( SCIPisZero(scip, val) )
1288  {
1289  ++nzerocoef;
1290  }
1291  else
1292  {
1293  SCIP_CALL( SCIPchgVarObj(scip, data->createdvars[v], val) );
1294  }
1295  }
1296 
1297  if ( nzerocoef > 0 )
1298  {
1299  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
1300  "OBJACOORD: Found %d coefficients with absolute value less than epsilon = %g.\n", nzerocoef, SCIPepsilon(scip));
1301  }
1302 
1303  return SCIP_OKAY;
1304 }
1305 
1307 static
1308 SCIP_RETCODE CBFreadFcoord(
1309  SCIP* scip,
1310  CBF_DATA* data,
1311  SCIP_FILE* pfile,
1312  SCIP_Longint* linecount
1313  )
1314 { /*lint --e{818}*/
1315  SCIP_Real val;
1316  int nzerocoef = 0;
1317  int ncoefs;
1318  int c;
1319  int i;
1320  int v;
1321  int row;
1322  int col;
1323 
1324  assert( scip != NULL );
1325  assert( data != NULL );
1326  assert( pfile != NULL );
1327  assert( linecount != NULL );
1328 
1329  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1330 
1331  if ( sscanf(data->linebuffer, "%i", &ncoefs) != 1 )
1332  {
1333  SCIPerrorMessage("Could not read number of coefficients for psd variables in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1334  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1335  return SCIP_READERROR;
1336  }
1337 
1338  if ( ncoefs < 0 )
1339  {
1340  SCIPerrorMessage("Number of matrix variable coefficients %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", ncoefs, *linecount);
1341  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1342  return SCIP_READERROR; /*lint !e527*/
1343  }
1344 
1345  if ( ncoefs == 0 )
1346  return SCIP_OKAY;
1347 
1348  if ( data->createdpsdvars == NULL )
1349  {
1350  SCIPerrorMessage("Need to have 'PSDVAR' section before 'FCOORD' section!\n");
1351  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1352  return SCIP_READERROR; /*lint !e527*/
1353  }
1354  assert( data->npsdvars >= 0 );
1355 
1356  if ( data->createdconss == NULL )
1357  {
1358  SCIPerrorMessage("Need to have 'CON' section before 'FCOORD' section!\n");
1359  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1360  return SCIP_READERROR; /*lint !e527*/
1361  }
1362  assert( data->nconss >= 0 );
1363 
1364  for (i = 0; i < ncoefs; i++)
1365  {
1366  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1367 
1368  if ( sscanf(data->linebuffer, "%i %i %i %i %lf", &c, &v, &row, &col, &val) != 5 )
1369  {
1370  SCIPerrorMessage("Could not read entry of FCOORD in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1371  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1372  return SCIP_READERROR;
1373  }
1374 
1375  if ( c < 0 || c >= data->nconss )
1376  {
1377  SCIPerrorMessage("Given matrix variable coefficient in line %" SCIP_LONGINT_FORMAT " for constraint %d which does not exist!\n", *linecount, c);
1378  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1379  return SCIP_READERROR; /*lint !e527*/
1380  }
1381 
1382  if ( v < 0 || v >= data->npsdvars )
1383  {
1384  SCIPerrorMessage("Given coefficient in line %" SCIP_LONGINT_FORMAT " for matrix variable %d which does not exist!\n", *linecount, v);
1385  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1386  return SCIP_READERROR; /*lint !e527*/
1387  }
1388 
1389  if ( row < 0 || row >= data->psdvarsizes[v] )
1390  {
1391  SCIPerrorMessage("Row index %d of given coefficient in line %" SCIP_LONGINT_FORMAT " for matrix variable %d in scalar constraint %d is negative or larger than varsize %d!\n",
1392  row, *linecount, v, c, data->psdvarsizes[v]);
1393  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1394  return SCIP_READERROR; /*lint !e527*/
1395  }
1396 
1397  if ( col < 0 || col >= data->psdvarsizes[v] )
1398  {
1399  SCIPerrorMessage("Column index %d of given coefficient in line %" SCIP_LONGINT_FORMAT " for matrix variable %d in scalar constraint %d is negative or larger than varsize %d!\n",
1400  col, *linecount, v, c, data->psdvarsizes[v]);
1401  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1402  return SCIP_READERROR; /*lint !e527*/
1403  }
1404 
1405  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
1406  {
1407  SCIPerrorMessage("Given coefficient in line %" SCIP_LONGINT_FORMAT " for matrix variable %d is infinity, which is not allowed.\n",
1408  *linecount, v);
1409  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1410  return SCIP_READERROR;
1411  }
1412 
1413  if ( SCIPisZero(scip, val) )
1414  {
1415  ++nzerocoef;
1416  }
1417  else
1418  {
1419  /* make sure matrix is in lower triangular form */
1420  if ( row < col )
1421  {
1422  SCIP_CALL( SCIPaddCoefLinear(scip, data->createdconss[c], data->createdpsdvars[v][col][row], 2*val) );/*lint !e732*//*lint !e747*/
1423  }
1424  else if ( row == col )
1425  SCIP_CALL( SCIPaddCoefLinear(scip, data->createdconss[c], data->createdpsdvars[v][row][col], val) );/*lint !e732*//*lint !e747*/
1426  else
1427  {
1428  SCIP_CALL( SCIPaddCoefLinear(scip, data->createdconss[c], data->createdpsdvars[v][row][col], 2*val) );/*lint !e732*//*lint !e747*/
1429  }
1430  }
1431  }
1432 
1433  if ( nzerocoef > 0 )
1434  {
1435  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
1436  "FCOORD: Found %d coefficients with absolute value less than epsilon = %g.\n", nzerocoef, SCIPepsilon(scip));
1437  }
1438 
1439  return SCIP_OKAY;
1440 }
1441 
1443 static
1444 SCIP_RETCODE CBFreadAcoord(
1445  SCIP* scip,
1446  CBF_DATA* data,
1447  SCIP_FILE* pfile,
1448  SCIP_Longint* linecount
1449  )
1450 { /*lint --e{818}*/
1451  SCIP_Real val;
1452  int nzerocoef = 0;
1453  int ncoefs;
1454  int c;
1455  int i;
1456  int v;
1457 
1458  assert( scip != NULL );
1459  assert( data != NULL );
1460  assert( pfile != NULL );
1461  assert( linecount != NULL );
1462 
1463  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1464 
1465  if ( sscanf(data->linebuffer, "%i", &ncoefs) != 1 )
1466  {
1467  SCIPerrorMessage("Could not read number of linear coefficients in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1468  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1469  return SCIP_READERROR;
1470  }
1471 
1472  if ( ncoefs < 0 )
1473  {
1474  SCIPerrorMessage("Number of linear coefficients %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", ncoefs, *linecount);
1475  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1476  return SCIP_READERROR; /*lint !e527*/
1477  }
1478 
1479  if ( ncoefs == 0 )
1480  return SCIP_OKAY;
1481 
1482  if ( data->createdvars == NULL )
1483  {
1484  SCIPerrorMessage("Need to have 'VAR' section before 'ACOORD' section!\n");
1485  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1486  return SCIP_READERROR; /*lint !e527*/
1487  }
1488  assert( data->nvars >= 0 );
1489 
1490  if ( data->createdconss == NULL )
1491  {
1492  SCIPerrorMessage("Need to have 'CON' section before 'ACOORD' section!\n");
1493  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1494  return SCIP_READERROR; /*lint !e527*/
1495  }
1496  assert( data->nconss >= 0 );
1497 
1498  for (i = 0; i < ncoefs; i++)
1499  {
1500  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1501  if ( sscanf(data->linebuffer, "%i %i %lf", &c, &v, &val) != 3 )
1502  {
1503  SCIPerrorMessage("Could not read entry of ACOORD in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1504  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1505  return SCIP_READERROR;
1506  }
1507 
1508  if ( c < 0 || c >= data->nconss )
1509  {
1510  SCIPerrorMessage("Given linear coefficient in line %" SCIP_LONGINT_FORMAT " for constraint %d which does not exist!\n", *linecount, c);
1511  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1512  return SCIP_READERROR; /*lint !e527*/
1513  }
1514 
1515  if ( v < 0 || v >= data->nvars )
1516  {
1517  SCIPerrorMessage("Given linear coefficient in line %" SCIP_LONGINT_FORMAT " for variable %d which does not exist!\n", *linecount, v);
1518  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1519  return SCIP_READERROR; /*lint !e527*/
1520  }
1521 
1522  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
1523  {
1524  SCIPerrorMessage("Given linear coefficient in line %" SCIP_LONGINT_FORMAT " for variable %d is infinity, which is not allowed.\n",
1525  *linecount, v);
1526  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1527  return SCIP_READERROR;
1528  }
1529 
1530  if ( SCIPisZero(scip, val) )
1531  {
1532  ++nzerocoef;
1533  }
1534  else
1535  {
1536  SCIP_CALL( SCIPaddCoefLinear(scip, data->createdconss[c], data->createdvars[v], val) );/*lint !e732*//*lint !e747*/
1537  }
1538  }
1539 
1540  if ( nzerocoef > 0 )
1541  {
1542  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
1543  "ACOORD: Found %d coefficients with absolute value less than epsilon = %g.\n", nzerocoef, SCIPepsilon(scip));
1544  }
1545 
1546  return SCIP_OKAY;
1547 }
1548 
1550 static
1551 SCIP_RETCODE CBFreadBcoord(
1552  SCIP* scip,
1553  CBF_DATA* data,
1554  SCIP_FILE* pfile,
1555  SCIP_Longint* linecount
1556  )
1557 { /*lint --e{818}*/
1558  SCIP_Real val;
1559  int nzerocoef = 0;
1560  int nsides;
1561  int c;
1562  int i;
1563 
1564  assert( scip != NULL );
1565  assert( data != NULL );
1566  assert( pfile != NULL );
1567  assert( linecount != NULL );
1568 
1569  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1570 
1571  if ( sscanf(data->linebuffer, "%i", &nsides) != 1 )
1572  {
1573  SCIPerrorMessage("Could not read number of constant parts in scalar constraints in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1574  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1575  return SCIP_READERROR;
1576  }
1577 
1578  if ( nsides < 0 )
1579  {
1580  SCIPerrorMessage("Number of constant parts %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", nsides, *linecount);
1581  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1582  return SCIP_READERROR; /*lint !e527*/
1583  }
1584 
1585  if ( nsides == 0 )
1586  return SCIP_OKAY;
1587 
1588  if ( data->createdconss == NULL )
1589  {
1590  SCIPerrorMessage("Need to have 'CON' section before 'BCOORD' section!\n");
1591  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1592  return SCIP_READERROR; /*lint !e527*/
1593  }
1594  assert( data->nconss >= 0 );
1595 
1596  for (i = 0; i < nsides; i++)
1597  {
1598  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1599 
1600  if ( sscanf(data->linebuffer, "%i %lf", &c, &val) != 2 )
1601  {
1602  SCIPerrorMessage("Could not read entry of BCOORD in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1603  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1604  return SCIP_READERROR;
1605  }
1606 
1607  if ( c < 0 || c >= data->nconss )
1608  {
1609  SCIPerrorMessage("Given constant part in line %" SCIP_LONGINT_FORMAT " for scalar constraint %d which does not exist!\n", *linecount, c);
1610  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1611  return SCIP_READERROR; /*lint !e527*/
1612  }
1613 
1614  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
1615  {
1616  SCIPerrorMessage("Given constant part in line %" SCIP_LONGINT_FORMAT " of scalar constraint %d is infinity, which is not allowed.\n",
1617  *linecount, c);
1618  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1619  return SCIP_READERROR; /*lint !e527*/
1620  }
1621 
1622  if ( SCIPisZero(scip, val) )
1623  {
1624  ++nzerocoef;
1625  }
1626  else
1627  {
1628  /* check type */
1629  if ( ! SCIPisInfinity(scip, -SCIPgetLhsLinear(scip, data->createdconss[c])) )
1630  {
1631  /* greater or equal constraint -> left-hand side (minus since we have Ax + b >= 0) */
1632  SCIP_CALL( SCIPchgLhsLinear(scip, data->createdconss[c], -val) );
1633  }
1634 
1635  if ( ! SCIPisInfinity(scip, SCIPgetRhsLinear(scip, data->createdconss[c]) ) )
1636  {
1637  /* less or equal constraint -> right-hand side (minus since we have Ax + b <= 0) */
1638  SCIP_CALL( SCIPchgRhsLinear(scip, data->createdconss[c], -val) );
1639  }
1640  }
1641  }
1642 
1643  if ( nzerocoef > 0 )
1644  {
1645  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
1646  "BCOORD: Found %d coefficients with absolute value less than epsilon = %g.\n", nzerocoef, SCIPepsilon(scip));
1647  }
1648 
1649  return SCIP_OKAY;
1650 }
1651 
1653 static
1654 SCIP_RETCODE CBFreadHcoord(
1655  SCIP* scip,
1656  CBF_DATA* data,
1657  SCIP_FILE* pfile,
1658  SCIP_Longint* linecount
1659  )
1660 {
1661  SCIP_Real val;
1662  int** sdpvar;
1663  int nnonz;
1664  int i;
1665  int b;
1666  int v;
1667  int row;
1668  int col;
1669  int firstindforvar;
1670  int nextindaftervar;
1671  int nzerocoef = 0;
1672  int ncbfsdpblocks;
1673  int nauxnonz = 0; /* number of nonzeros in each auxiliary sdp block for reformulating matrix variables using
1674  * scalar variables */
1675 
1676  assert( scip != NULL );
1677  assert( data != NULL );
1678  assert( pfile != NULL );
1679  assert( linecount != NULL );
1680 
1681  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1682 
1683  if ( sscanf(data->linebuffer, "%i", &nnonz) != 1 )
1684  {
1685  SCIPerrorMessage("Could not read number of nonzero coefficients of SDP-constraints in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1686  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1687  return SCIP_READERROR;
1688  }
1689 
1690  if ( nnonz < 0 )
1691  {
1692  SCIPerrorMessage("Number of nonzero coefficients of SDP-constraints %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", nnonz, *linecount);
1693  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1694  return SCIP_READERROR; /*lint !e527*/
1695  }
1696 
1697  if ( nnonz == 0 )
1698  return SCIP_OKAY;
1699 
1700  if ( data->nsdpblocks < 0 )
1701  {
1702  SCIPerrorMessage("Need to have 'PSDCON' section before 'HCOORD' section!\n");
1703  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1704  return SCIP_READERROR; /*lint !e527*/
1705  }
1706  assert( data->nsdpblocks >= 0 );
1707 
1708  if ( data->nvars < 0 )
1709  {
1710  SCIPerrorMessage("Need to have 'VAR' section before 'HCOORD' section!\n");
1711  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1712  return SCIP_READERROR; /*lint !e527*/
1713  }
1714  assert( data->nvars >= 0 );
1715 
1716  /* get number of sdp blocks specified by PSDCON (without auxiliary sdp blocks for reformulating matrix variables
1717  * using scalar variables), save number of nonzeros needed for the auxiliary sdp blocks in nauxnonz */
1718  if ( data->npsdvars > 0 )
1719  {
1720  ncbfsdpblocks = data->nsdpblocks - data->npsdvars;
1721  for (i = 0; i < data->npsdvars; i++)
1722  nauxnonz += data->psdvarsizes[i] * (data->psdvarsizes[i] + 1) / 2;
1723  }
1724  else
1725  {
1726  ncbfsdpblocks = data->nsdpblocks;
1727  nauxnonz = 0;
1728  }
1729  assert( ncbfsdpblocks >= 0 );
1730 
1731  /* initialize sdpnblocknonz with 0 */
1732  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpnblocknonz), data->nsdpblocks) );
1733  for (b = 0; b < data->nsdpblocks; b++)
1734  data->sdpnblocknonz[b] = 0;
1735 
1736  data->nnonz = nnonz + nauxnonz;
1737 
1738  /* allocate memory (nnonz for each block, since we do not yet know the distribution) */
1739  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &sdpvar, data->nsdpblocks) );
1740  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdprow), data->nsdpblocks) );
1741  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpcol), data->nsdpblocks) );
1742  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpval), data->nsdpblocks) );
1743 
1744  for (b = 0; b < data->nsdpblocks; b++)
1745  {
1746  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(sdpvar[b]), data->nnonz) );
1747  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdprow[b]), data->nnonz) );
1748  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpcol[b]), data->nnonz) );
1749  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpval[b]), data->nnonz) );
1750  }
1751 
1752  for (i = 0; i < nnonz; i++)
1753  {
1754  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1755 
1756  if ( sscanf(data->linebuffer, "%i %i %i %i %lf", &b, &v, &row, &col, &val) != 5 )
1757  {
1758  SCIPerrorMessage("Could not read entry of HCOORD in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1759  goto TERMINATE;
1760  }
1761 
1762  if ( b < 0 || b >= ncbfsdpblocks )
1763  {
1764  SCIPerrorMessage("Given SDP-coefficient in line %" SCIP_LONGINT_FORMAT " for SDP-constraint %d which does not exist!\n", *linecount, b);
1765  goto TERMINATE;
1766  }
1767 
1768  if ( v < 0 || v >= data->nvars )
1769  {
1770  SCIPerrorMessage("Given SDP-coefficient in line %" SCIP_LONGINT_FORMAT " for variable %d which does not exist!\n", *linecount, v);
1771  goto TERMINATE;
1772  }
1773 
1774  if ( row < 0 || row >= data->sdpblocksizes[b] )
1775  {
1776  SCIPerrorMessage("Row index %d of given SDP coefficient in line %" SCIP_LONGINT_FORMAT " is negative or larger than blocksize %d!\n",
1777  row, *linecount, data->sdpblocksizes[b]);
1778  goto TERMINATE;
1779  }
1780 
1781  if ( col < 0 || col >= data->sdpblocksizes[b] )
1782  {
1783  SCIPerrorMessage("Column index %d of given SDP coefficient in line %" SCIP_LONGINT_FORMAT " is negative or larger than blocksize %d!\n",
1784  col, *linecount, data->sdpblocksizes[b]);
1785  goto TERMINATE;
1786  }
1787 
1788  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
1789  {
1790  SCIPerrorMessage("Given SDP-coefficient in line %" SCIP_LONGINT_FORMAT " for variable %d is infinity, which is not allowed.\n",
1791  *linecount, v);
1792  goto TERMINATE;
1793  }
1794 
1795  if ( SCIPisZero(scip, val) )
1796  {
1797  ++nzerocoef;
1798  }
1799  else
1800  {
1801  sdpvar[b][data->sdpnblocknonz[b]] = v;
1802 
1803  /* make sure matrix is in lower triangular form */
1804  if ( col > row )
1805  {
1806  data->sdprow[b][data->sdpnblocknonz[b]] = col;
1807  data->sdpcol[b][data->sdpnblocknonz[b]] = row;
1808  }
1809  else
1810  {
1811  data->sdprow[b][data->sdpnblocknonz[b]] = row;
1812  data->sdpcol[b][data->sdpnblocknonz[b]] = col;
1813  }
1814 
1815  data->sdpval[b][data->sdpnblocknonz[b]] = val;
1816  data->sdpnblocknonz[b]++;
1817  }
1818  }
1819 
1820  /* construct entries for auxiliary sdp blocks (reformulation of psdvars) */
1821  if ( data->npsdvars > 0 )
1822  {
1823  val = 1.0;
1824  for (v = 0; v < data->npsdvars; v++)
1825  {
1826  b = ncbfsdpblocks + v;
1827  for (row = 0; row < data->psdvarsizes[v]; row++)
1828  {
1829  for (col = 0; col <= row; col++)
1830  {
1831  sdpvar[b][data->sdpnblocknonz[b]] = data->nvars + 1;
1832  data->sdprow[b][data->sdpnblocknonz[b]] = row;
1833  data->sdpcol[b][data->sdpnblocknonz[b]] = col;
1834  data->sdpval[b][data->sdpnblocknonz[b]] = val;
1835  data->sdpnblocknonz[b]++;
1836  }
1837  }
1838  assert( data->sdpnblocknonz[b] == data->psdvarsizes[v] * (data->psdvarsizes[v] + 1) / 2 );
1839  assert( b == data->nsdpblocks - 1 );
1840  }
1841  }
1842 
1843  /* construct pointer arrays */
1844  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpnblockvars), data->nsdpblocks) );
1845  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblockvars), data->nsdpblocks) );
1846  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->nvarnonz), data->nsdpblocks) );
1847  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->rowpointer), data->nsdpblocks) );
1848  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->colpointer), data->nsdpblocks) );
1849  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->valpointer), data->nsdpblocks) );
1850 
1851  /* sdp blocks as specified in cbf file in HCOORD */
1852  for (b = 0; b < ncbfsdpblocks; b++)
1853  {
1854  /* sort the nonzeroes by non-decreasing variable indices */
1855  SCIPsortIntIntIntReal(sdpvar[b], data->sdprow[b], data->sdpcol[b], data->sdpval[b], data->sdpnblocknonz[b]);
1856 
1857  /* create the pointer arrays and insert used variables into vars-array */
1858  nextindaftervar = 0;
1859  data->sdpnblockvars[b] = 0;
1860  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblockvars[b]), data->nvars) );
1861  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->nvarnonz[b]), data->nvars) );
1862  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->rowpointer[b]), data->nvars) );
1863  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->colpointer[b]), data->nvars) );
1864  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->valpointer[b]), data->nvars) );
1865 
1866  for (v = 0; v < data->nvars; v++)
1867  {
1868  SCIP_Bool varused = FALSE;
1869 
1870  firstindforvar = nextindaftervar; /* this variable starts where the last one ended */
1871  data->nvarnonz[b][data->sdpnblockvars[b]] = 0;
1872 
1873  while (nextindaftervar < data->sdpnblocknonz[b] && sdpvar[b][nextindaftervar] == v) /* get the first index that doesn't belong to this variable */
1874  {
1875  nextindaftervar++;
1876  varused = TRUE;
1877  data->nvarnonz[b][data->sdpnblockvars[b]]++;
1878  }
1879 
1880  if ( varused )
1881  {
1882  data->sdpblockvars[b][data->sdpnblockvars[b]] = data->createdvars[v];/*lint !e732*//*lint !e747*/ /* if the variable is used, add it to the vars array */
1883  data->rowpointer[b][data->sdpnblockvars[b]] = &(data->sdprow[b][firstindforvar]); /* save a pointer to the first nonzero belonging to this variable */
1884  data->colpointer[b][data->sdpnblockvars[b]] = &(data->sdpcol[b][firstindforvar]);
1885  data->valpointer[b][data->sdpnblockvars[b]] = &(data->sdpval[b][firstindforvar]);
1886  data->sdpnblockvars[b]++;
1887  }
1888  }
1889 
1890  assert( nextindaftervar == data->sdpnblocknonz[b] );
1891  }
1892 
1893  /* auxiliary sdp blocks (reformulation of psd variables) */
1894  if ( data->npsdvars > 0 )
1895  {
1896  assert( data->nsdpblocks == ncbfsdpblocks + data->npsdvars );
1897  for (v = 0; v < data->npsdvars; v++)
1898  {
1899  int varidx = 0;
1900 
1901  /* create the pointer arrays and insert used variables into vars-array */
1902  b = ncbfsdpblocks + v;
1903 
1904  data->sdpnblockvars[b] = data->sdpnblocknonz[b];
1905 
1906  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblockvars[b]), data->sdpnblocknonz[b]) );
1907  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->nvarnonz[b]), data->sdpnblocknonz[b]) );
1908  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->rowpointer[b]), data->sdpnblocknonz[b]) );
1909  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->colpointer[b]), data->sdpnblocknonz[b]) );
1910  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->valpointer[b]), data->sdpnblocknonz[b]) );
1911 
1912  for (row = 0; row < data->psdvarsizes[v]; row++)
1913  {
1914  for (col = 0; col <= row; col++)
1915  {
1916  data->nvarnonz[b][varidx] = 1;
1917  data->sdpblockvars[b][varidx] = data->createdpsdvars[v][row][col];
1918  data->rowpointer[b][varidx] = &(data->sdprow[b][varidx]);
1919  data->colpointer[b][varidx] = &(data->sdpcol[b][varidx]);
1920  data->valpointer[b][varidx] = &(data->sdpval[b][varidx]);
1921  varidx++;
1922  }
1923  }
1924  assert( varidx == data->sdpnblocknonz[b] );
1925  }
1926  }
1927  /* free SDP-var array which is no longer needed */
1928  for (b = 0; b < data->nsdpblocks; b++)
1929  SCIPfreeBlockMemoryArray(scip, &(sdpvar[b]), data->nnonz);
1930 
1931  SCIPfreeBlockMemoryArray(scip, &sdpvar, data->nsdpblocks);
1932 
1933  if ( nzerocoef > 0 )
1934  {
1935  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
1936  "HCOORD: Found %d coefficients with absolute value less than epsilon = %g.\n", nzerocoef, SCIPepsilon(scip));
1937  }
1938 
1939  return SCIP_OKAY;
1940 
1941  TERMINATE:
1942  /* free SDP-var array which is no longer needed */
1943  for (b = 0; b < data->nsdpblocks; b++)
1944  SCIPfreeBlockMemoryArray(scip, &(sdpvar[b]), data->nnonz);
1945 
1946  SCIPfreeBlockMemoryArray(scip, &sdpvar, data->nsdpblocks);
1947 
1948  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1949  return SCIP_READERROR;
1950 }
1951 
1953 static
1954 SCIP_RETCODE CBFreadDcoord(
1955  SCIP* scip,
1956  CBF_DATA* data,
1957  SCIP_FILE* pfile,
1958  SCIP_Longint* linecount
1959  )
1960 {
1961  SCIP_Real val;
1962  int nzerocoef = 0;
1963  int constnnonz;
1964  int b;
1965  int i;
1966  int row;
1967  int col;
1968 
1969  assert( scip != NULL );
1970  assert( data != NULL );
1971  assert( pfile != NULL );
1972  assert( linecount != NULL );
1973 
1974  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
1975 
1976  if ( sscanf(data->linebuffer, "%i", &constnnonz) != 1 )
1977  {
1978  SCIPerrorMessage("Could not read number of constant entries of SDP-constraints in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
1979  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1980  return SCIP_READERROR;
1981  }
1982 
1983  if ( constnnonz < 0 )
1984  {
1985  SCIPerrorMessage("Number of constant entries of SDP-constraints %d in line %" SCIP_LONGINT_FORMAT " should be non-negative!\n", constnnonz, *linecount);
1986  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1987  return SCIP_READERROR; /*lint !e527*/
1988  }
1989 
1990  if ( constnnonz == 0 )
1991  return SCIP_OKAY;
1992 
1993  if ( data->nsdpblocks < 0 )
1994  {
1995  SCIPerrorMessage("Need to have 'PSDCON' section before 'DCOORD' section!\n");
1996  SCIP_CALL( CBFfreeData(scip, pfile, data) );
1997  return SCIP_READERROR; /*lint !e527*/
1998  }
1999 
2000  /* if ( data->nvars < 0 ) */
2001  /* { */
2002  /* SCIPerrorMessage("Need to have 'VAR' section before 'DCOORD' section!\n"); */
2003  /* SCIPABORT(); */
2004  /* return SCIP_READERROR; /\*lint !e527*\/ */
2005  /* } */
2006 
2007  data->constnnonz = constnnonz;
2008  assert( constnnonz > 0 );
2009 
2010  /* initialize sdpconstnblocknonz with 0 */
2011  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstnblocknonz), data->nsdpblocks) );
2012  for (b = 0; b < data->nsdpblocks; b++)
2013  data->sdpconstnblocknonz[b] = 0;
2014 
2015  /* allocate memory (constnnonz for each block, since we do not yet know the distribution) */
2016  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstrow), data->nsdpblocks) );
2017  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstcol), data->nsdpblocks) );
2018  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstval), data->nsdpblocks) );
2019 
2020  for (b = 0; b < data->nsdpblocks; b++)
2021  {
2022  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstrow[b]), constnnonz) );
2023  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstcol[b]), constnnonz) );
2024  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpconstval[b]), constnnonz) );
2025  }
2026 
2027  for (i = 0; i < constnnonz; i++)
2028  {
2029  SCIP_CALL( CBFfgets(scip, data, pfile, linecount, TRUE) );
2030  if ( sscanf(data->linebuffer, "%i %i %i %lf", &b, &row, &col, &val) != 4 )
2031  {
2032  SCIPerrorMessage("Could not read entry of DCOORD in line %" SCIP_LONGINT_FORMAT ".\n", *linecount);
2033  SCIP_CALL( CBFfreeData(scip, pfile, data) );
2034  return SCIP_READERROR;
2035  }
2036 
2037  if ( b < 0 || b >= data->nsdpblocks )
2038  {
2039  SCIPerrorMessage("Given constant entry in line %" SCIP_LONGINT_FORMAT " for SDP-constraint %d which does not exist!\n", *linecount, b);
2040  SCIP_CALL( CBFfreeData(scip, pfile, data) );
2041  return SCIP_READERROR; /*lint !e527*/
2042  }
2043 
2044  if ( row < 0 || row >= data->sdpblocksizes[b] )
2045  {
2046  SCIPerrorMessage("Row index %d of given constant SDP-entry in line %" SCIP_LONGINT_FORMAT " is negative or larger than blocksize %d!\n",
2047  row, *linecount, data->sdpblocksizes[b]);
2048  SCIP_CALL( CBFfreeData(scip, pfile, data) );
2049  return SCIP_READERROR; /*lint !e527*/
2050  }
2051 
2052  if ( col < 0 || col >= data->sdpblocksizes[b] )
2053  {
2054  SCIPerrorMessage("Column index %d of given constant SDP-entry in line %" SCIP_LONGINT_FORMAT " is negative or larger than blocksize %d!\n",
2055  col, *linecount, data->sdpblocksizes[b]);
2056  SCIP_CALL( CBFfreeData(scip, pfile, data) );
2057  return SCIP_READERROR; /*lint !e527*/
2058  }
2059 
2060  if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
2061  {
2062  SCIPerrorMessage("Given constant entry in line %" SCIP_LONGINT_FORMAT " for SDP constraint %d is infinity, which is not allowed.\n",
2063  *linecount, b);
2064  SCIP_CALL( CBFfreeData(scip, pfile, data) );
2065  return SCIP_READERROR; /*lint !e527*/
2066  }
2067 
2068  if ( SCIPisZero(scip, val) )
2069  {
2070  ++nzerocoef;
2071  }
2072  else
2073  {
2074  /* make sure matrix is in lower triangular form */
2075  if ( col > row )
2076  {
2077  data->sdpconstrow[b][data->sdpconstnblocknonz[b]] = col;
2078  data->sdpconstcol[b][data->sdpconstnblocknonz[b]] = row;
2079  }
2080  else
2081  {
2082  data->sdpconstrow[b][data->sdpconstnblocknonz[b]] = row;
2083  data->sdpconstcol[b][data->sdpconstnblocknonz[b]] = col;
2084  }
2085  data->sdpconstval[b][data->sdpconstnblocknonz[b]] = -val;
2086  data->sdpconstnblocknonz[b]++;
2087  }
2088  }
2089 
2090  if ( nzerocoef > 0 )
2091  {
2092  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
2093  "DCOORD: Found %d coefficients with absolute value less than epsilon = %g.\n", nzerocoef, SCIPepsilon(scip));
2094  }
2095 
2096  return SCIP_OKAY;
2097 }
2098 
2099 
2100 /*
2101  * Callback methods of reader
2102  */
2103 
2104 
2106 static
2107 SCIP_DECL_READERCOPY(readerCopyCbf)
2108 { /*lint --e{715,818}*/
2109  assert(scip != NULL);
2110 
2111  SCIP_CALL( SCIPincludeReaderCbf(scip) );
2112 
2113  return SCIP_OKAY;
2114 }
2115 
2117 static
2118 SCIP_DECL_READERREAD(readerReadCbf)
2119 { /*lint --e{715,818}*/
2120  SCIP_FILE* scipfile;
2121  SCIP_Longint linecount = 0;
2122  SCIP_Bool versionread = FALSE;
2123  SCIP_Bool objread = FALSE;
2124  CBF_DATA* data;
2125  int b;
2126 
2127  assert( result != NULL );
2128 
2129  *result = SCIP_DIDNOTRUN;
2130 
2131  SCIPdebugMsg(scip, "Reading file %s ...\n", filename);
2132 
2133  scipfile = SCIPfopen(filename, "r");
2134 
2135  if ( ! scipfile )
2136  return SCIP_READERROR;
2137 
2138  SCIP_CALL( SCIPallocBuffer(scip, &data) );
2139  data->nsdpblocks = -1;
2140  data->nsdpblocksrank1 = 0;
2141  data->nconss = -1;
2142  data->nvars = -1;
2143  data->npsdvars = -1;
2144  data->constnnonz = 0;
2145  data->nnonz = 0;
2146  data->noorigsdpcons= FALSE;
2147 
2148  data->createdvars = NULL;
2149  data->createdconss = NULL;
2150  data->createdpsdvars = NULL;
2151  data->psdvarsizes = NULL;
2152  data->psdvarrank1 = NULL;
2153  data->sdpblockrank1 = NULL;
2154  data->sdpblocksizes = NULL;
2155  data->sdpnblocknonz = NULL;
2156  data->sdpnblockvars = NULL;
2157  data->nvarnonz = NULL;
2158  data->sdpblockvars = NULL;
2159  data->sdprow = NULL;
2160  data->sdpcol = NULL;
2161  data->sdpval = NULL;
2162  data->rowpointer = NULL;
2163  data->colpointer = NULL;
2164  data->valpointer = NULL;
2165  data->sdpconstnblocknonz = NULL;
2166  data->sdpconstrow = NULL;
2167  data->sdpconstcol = NULL;
2168  data->sdpconstval = NULL;
2169 
2170  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &data->linebuffer, CBF_MAX_LINE) );
2171  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &data->namebuffer, CBF_MAX_NAME) );
2172 
2173  /* create empty problem */
2174  SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
2175 
2176  while( CBFfgets(scip, data, scipfile, &linecount, FALSE) == SCIP_OKAY )
2177  {
2178  /* Parse keyword on non-empty lines */
2179  if ( sscanf(data->linebuffer, CBF_NAME_FORMAT, data->namebuffer) == 1 )
2180  {
2181  /* first line should be version number */
2182  if ( ! versionread )
2183  {
2184  if ( strcmp(data->namebuffer, "VER") == 0 )
2185  {
2186  int ver;
2187 
2188  SCIP_CALL( CBFfgets(scip, data, scipfile, &linecount, TRUE) );
2189 
2190  if ( sscanf(data->linebuffer, "%i", &ver) == 1 )
2191  {
2192  SCIPdebugMsg(scip, "file version %d.\n", ver);
2193  if ( ver < 1 )
2194  {
2195  SCIPerrorMessage("Strange version number %d; need at least version 1.\n", ver);
2196  SCIP_CALL( CBFfreeData(scip, scipfile, data) );
2197  return SCIP_READERROR; /*lint !e527*/
2198  }
2199  else if ( ver > CBF_VERSION_NR )
2200  {
2201  SCIPerrorMessage("Version %d too new; only supported up to version %d.\n", ver, CBF_VERSION_NR);
2202  SCIP_CALL( CBFfreeData(scip, scipfile, data) );
2203  return SCIP_READERROR; /*lint !e527*/
2204  }
2205  else
2206  versionread = TRUE;
2207  }
2208  else
2209  {
2210  SCIPerrorMessage("Could not read version number in line %" SCIP_LONGINT_FORMAT ".\n", linecount);
2211  SCIP_CALL( CBFfreeData(scip, scipfile, data) );
2212  return SCIP_READERROR;
2213  }
2214  }
2215  else
2216  {
2217  SCIPerrorMessage("First keyword should be VER.\n");
2218  SCIP_CALL( CBFfreeData(scip, scipfile, data) );
2219  return SCIP_READERROR; /*lint !e527*/
2220  }
2221  }
2222  else
2223  {
2224  if ( strcmp(data->namebuffer, "OBJSENSE") == 0 )
2225  {
2226  SCIPdebugMsg(scip, "Reading OBJSENSE\n");
2227  SCIP_CALL( CBFreadObjsense(scip, data, scipfile, &linecount) );
2228  objread = TRUE;
2229  }
2230  else if ( strcmp(data->namebuffer, "VAR") == 0 )
2231  {
2232  SCIPdebugMsg(scip, "Reading VAR\n");
2233  SCIP_CALL( CBFreadVar(scip, data, scipfile, &linecount) );
2234  }
2235  else if ( strcmp(data->namebuffer, "CON") == 0 )
2236  {
2237  SCIPdebugMsg(scip, "Reading CON\n");
2238  SCIP_CALL( CBFreadCon(scip, data, scipfile, &linecount) );
2239  }
2240  else if ( strcmp(data->namebuffer, "INT") == 0 )
2241  {
2242  SCIPdebugMsg(scip, "Reading INT\n");
2243  SCIP_CALL( CBFreadInt(scip, data, scipfile, &linecount) );
2244  }
2245  else if ( strcmp(data->namebuffer, "PSDCON") == 0 )
2246  {
2247  SCIPdebugMsg(scip, "Reading PSDCON\n");
2248  SCIP_CALL( CBFreadPsdCon(scip, data, scipfile, &linecount) );
2249  }
2250  else if ( strcmp(data->namebuffer, "PSDVAR") == 0 )
2251  {
2252  SCIPdebugMsg(scip, "Reading PSDVAR\n");
2253  SCIP_CALL( CBFreadPsdVar(scip, data, scipfile, &linecount) );
2254  }
2255  else if ( strcmp(data->namebuffer, "PSDCONRANK1") == 0 )
2256  {
2257  SCIPdebugMsg(scip, "Reading PSDCONRANK1\n");
2258  SCIP_CALL( CBFreadPsdConRank1(scip, data, scipfile, &linecount) );
2259  }
2260  else if ( strcmp(data->namebuffer, "PSDVARRANK1") == 0 )
2261  {
2262  SCIPdebugMsg(scip, "Reading PSDVARRANK1\n");
2263  SCIP_CALL( CBFreadPsdVarRank1(scip, data, scipfile, &linecount) );
2264  }
2265  else if ( strcmp(data->namebuffer, "OBJFCOORD") == 0 )
2266  {
2267  SCIPdebugMsg(scip, "Reading OBJFCOORD\n");
2268  SCIP_CALL( CBFreadObjFcoord(scip, data, scipfile, &linecount) );
2269  }
2270  else if ( strcmp(data->namebuffer, "OBJACOORD") == 0 )
2271  {
2272  SCIPdebugMsg(scip, "Reading OBJACOORD\n");
2273  SCIP_CALL( CBFreadObjAcoord(scip, data, scipfile, &linecount) );
2274  }
2275  else if ( strcmp(data->namebuffer, "OBJBCOORD") == 0 )
2276  {
2277  SCIPerrorMessage("constant part in objective value not supported by SCIP!\n");
2278  SCIP_CALL( CBFfreeData(scip, scipfile, data) );
2279  return SCIP_READERROR; /*lint !e527*/
2280  }
2281  else if ( strcmp(data->namebuffer, "FCOORD") == 0 )
2282  {
2283  SCIPdebugMsg(scip, "Reading FCOORD\n");
2284  SCIP_CALL( CBFreadFcoord(scip, data, scipfile, &linecount) );
2285  }
2286  else if ( strcmp(data->namebuffer, "ACOORD") == 0 )
2287  {
2288  SCIPdebugMsg(scip, "Reading ACOORD\n");
2289  SCIP_CALL( CBFreadAcoord(scip, data, scipfile, &linecount) );
2290  }
2291  else if ( strcmp(data->namebuffer, "BCOORD") == 0 )
2292  {
2293  SCIPdebugMsg(scip, "Reading BCOORD\n");
2294  SCIP_CALL( CBFreadBcoord(scip, data, scipfile, &linecount) );
2295  }
2296  else if ( strcmp(data->namebuffer, "HCOORD") == 0 )
2297  {
2298  SCIPdebugMsg(scip, "Reading HCOORD\n");
2299  SCIP_CALL( CBFreadHcoord(scip, data, scipfile, &linecount) );
2300  }
2301  else if ( strcmp(data->namebuffer, "DCOORD") == 0 )
2302  {
2303  SCIPdebugMsg(scip, "Reading DCOORD\n");
2304  SCIP_CALL( CBFreadDcoord(scip, data, scipfile, &linecount) );
2305  }
2306  else
2307  {
2308  SCIPerrorMessage("Keyword %s in line %" SCIP_LONGINT_FORMAT " not recognized!\n", data->namebuffer, linecount);
2309  SCIP_CALL( CBFfreeData(scip, scipfile, data) );
2310  return SCIP_READERROR; /*lint !e527*/
2311  }
2312  }
2313  }
2314  }
2315 
2316  /* If there were no sections PSDCON or PSDVAR, then set data->npsdvars and data->nsdpblocks to 0 */
2317  if ( data->nsdpblocks < 0 )
2318  data->nsdpblocks = 0;
2319 
2320  if ( data->npsdvars < 0 )
2321  data->npsdvars = 0;
2322 
2323  /* Psd vars are created using scalar vars and a corresponding psd constraint that gets created in the function
2324  * CBFreadPsdCon. If there are no psd cons in the original problem, then the psd constraint for the reformulation of the
2325  * original psd vars needs to be created at this point! */
2326  if ( data->npsdvars > data->nsdpblocks )
2327  {
2328  int nauxvars;
2329  int varidx;
2330  int row;
2331  int col;
2332  int val;
2333 
2334  assert( data->nsdpblocks == 0 );
2335  assert( data->createdpsdvars != NULL );
2336  assert( data->psdvarrank1 != NULL );
2337  assert( data->npsdvars > 0 );
2338 
2339  data->noorigsdpcons = TRUE;
2340 
2341  data->nsdpblocks = data->npsdvars;
2342  data->nnonz = 0;
2343 
2344  /* allocate memory for auxiliary sdp blocks */
2345  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblocksizes), data->nsdpblocks) );
2346  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblockrank1), data->nsdpblocks) );
2347  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpnblocknonz), data->nsdpblocks) );
2348  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpnblockvars), data->nsdpblocks) );
2349  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->nvarnonz), data->nsdpblocks) );
2350  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblockvars), data->nsdpblocks) );
2351  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdprow), data->nsdpblocks) );
2352  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpcol), data->nsdpblocks) );
2353  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpval), data->nsdpblocks) );
2354  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->rowpointer), data->nsdpblocks) );
2355  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->colpointer), data->nsdpblocks) );
2356  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->valpointer), data->nsdpblocks) );
2357 
2358  for (b = 0; b < data->nsdpblocks; b++)
2359  {
2360  nauxvars = data->psdvarsizes[b] * (data->psdvarsizes[b] + 1) / 2;
2361  data->nnonz += nauxvars;
2362  varidx = 0;
2363 
2364  data->sdpblocksizes[b] = data->psdvarsizes[b];
2365  data->sdpblockrank1[b] = data->psdvarrank1[b];
2366  data->sdpnblocknonz[b] = nauxvars;
2367  data->sdpnblockvars[b] = nauxvars;
2368 
2369  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->nvarnonz[b]), nauxvars) );
2370  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpblockvars[b]), nauxvars) );
2371  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdprow[b]), nauxvars) );
2372  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpcol[b]), nauxvars) );
2373  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->sdpval[b]), nauxvars) );
2374  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->rowpointer[b]), nauxvars) );
2375  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->colpointer[b]), nauxvars) );
2376  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->valpointer[b]), nauxvars) );
2377 
2378  val = 1;
2379  for (row = 0; row < data->psdvarsizes[b]; row++)
2380  {
2381  for (col = 0; col <= row; col++)
2382  {
2383  data->sdprow[b][varidx] = row;
2384  data->sdpcol[b][varidx] = col;
2385  data->sdpval[b][varidx] = val;
2386 
2387  data->nvarnonz[b][varidx] = 1;
2388  data->sdpblockvars[b][varidx] = data->createdpsdvars[b][row][col];
2389  data->rowpointer[b][varidx] = &(data->sdprow[b][varidx]);
2390  data->colpointer[b][varidx] = &(data->sdpcol[b][varidx]);
2391  data->valpointer[b][varidx] = &(data->sdpval[b][varidx]);
2392  varidx++;
2393  }
2394  }
2395  assert( varidx == nauxvars );
2396  }
2397  }
2398 
2399  assert( data->npsdvars == data->nsdpblocks || ! data->noorigsdpcons );
2400 
2401  if ( ! objread )
2402  {
2403  SCIPerrorMessage("Keyword OBJSENSE is missing!\n");
2404  SCIP_CALL( CBFfreeData(scip, scipfile, data) );
2405  return SCIP_READERROR; /*lint !e527*/
2406  }
2407 
2408 #ifdef SCIP_MORE_DEBUG
2409  for (b = 0; b < SCIPgetNConss(scip); b++)
2410  {
2411  SCIP_CALL( SCIPprintCons(scip, SCIPgetConss(scip)[b], NULL) );
2412  SCIPinfoMessage(scip, NULL, "\n");
2413  }
2414 #endif
2415 
2416  /* check if any nonzeros were specified in HCOORD */
2417  if ( data->sdpnblocknonz == NULL && data->nsdpblocks > 0 )
2418  {
2419  SCIPerrorMessage("No nonconstant nonzeros have been specified for any SDP block, please remove all SDP blocks!\n");
2420  SCIP_CALL( CBFfreeData(scip, scipfile, data) );
2421  return SCIP_READERROR; /*lint !e527*/
2422  }
2423 
2424  /* create SDP-constraints */
2425  for (b = 0; b < data->nsdpblocks; b++)
2426  {
2427  SCIP_CONS* sdpcons;
2428  char sdpconname[SCIP_MAXSTRLEN];
2429 #ifndef NDEBUG
2430  int snprintfreturn;
2431 #endif
2432 
2433  /* check if nonzeros were only specified in DCOORD */
2434  if ( data->sdpnblockvars[b] == 0 || data->sdpnblocknonz[b] == 0 )
2435  {
2436  SCIPerrorMessage("SDP block %d has no nonzeros or only constant nonzeros, please remove this SDP block!\n", b);
2437  SCIP_CALL( CBFfreeData(scip, scipfile, data) );
2438  return SCIP_READERROR; /*lint !e527*/
2439  }
2440 
2441  assert( data->sdpblocksizes[b] > 0 );
2442  assert( (data->sdpnblockvars[b] > 0 && data->sdpnblocknonz[b] > 0) || (data->sdpconstnblocknonz[b] > 0) );
2443 
2444 #ifndef NDEBUG
2445  snprintfreturn = SCIPsnprintf(sdpconname, SCIP_MAXSTRLEN, "SDP_%d", b);
2446  assert( snprintfreturn < SCIP_MAXSTRLEN);
2447 #else
2448  (void) SCIPsnprintf(sdpconname, SCIP_MAXSTRLEN, "SDP_%d", b);
2449 #endif
2450 
2451  /* special treatment of case without constant PSD blocks */
2452  if ( data->sdpconstnblocknonz == NULL )
2453  {
2454  if ( ! data->sdpblockrank1[b] )
2455  {
2456  SCIP_CALL( SCIPcreateConsSdp(scip, &sdpcons, sdpconname, data->sdpnblockvars[b], data->sdpnblocknonz[b],
2457  data->sdpblocksizes[b], data->nvarnonz[b], data->colpointer[b], data->rowpointer[b], data->valpointer[b],
2458  data->sdpblockvars[b], 0, NULL, NULL, NULL, TRUE) );
2459  }
2460  else
2461  {
2462  SCIP_CALL( SCIPcreateConsSdpRank1(scip, &sdpcons, sdpconname, data->sdpnblockvars[b], data->sdpnblocknonz[b],
2463  data->sdpblocksizes[b], data->nvarnonz[b], data->colpointer[b], data->rowpointer[b], data->valpointer[b],
2464  data->sdpblockvars[b], 0, NULL, NULL, NULL, TRUE) );
2465  }
2466  }
2467  else
2468  {
2469  if ( ! data->sdpblockrank1[b] )
2470  {
2471  SCIP_CALL( SCIPcreateConsSdp(scip, &sdpcons, sdpconname, data->sdpnblockvars[b], data->sdpnblocknonz[b],
2472  data->sdpblocksizes[b], data->nvarnonz[b], data->colpointer[b], data->rowpointer[b], data->valpointer[b],
2473  data->sdpblockvars[b], data->sdpconstnblocknonz[b], data->sdpconstcol[b], data->sdpconstrow[b],
2474  data->sdpconstval[b], TRUE) );
2475  }
2476  else
2477  {
2478  SCIP_CALL( SCIPcreateConsSdpRank1(scip, &sdpcons, sdpconname, data->sdpnblockvars[b], data->sdpnblocknonz[b],
2479  data->sdpblocksizes[b], data->nvarnonz[b], data->colpointer[b], data->rowpointer[b], data->valpointer[b],
2480  data->sdpblockvars[b], data->sdpconstnblocknonz[b], data->sdpconstcol[b], data->sdpconstrow[b],
2481  data->sdpconstval[b], TRUE) );
2482  }
2483  }
2484 
2485 #ifdef SCIP_MORE_DEBUG
2486  SCIP_CALL( SCIPprintCons(scip, sdpcons, NULL) );
2487 #endif
2488 
2489  SCIP_CALL( SCIPaddCons(scip, sdpcons) );
2490 
2491  SCIP_CALL( SCIPreleaseCons(scip, &sdpcons) );
2492  }
2493 
2494  SCIP_CALL( CBFfreeData(scip, scipfile, data) );
2495 
2496  *result = SCIP_SUCCESS;
2497 
2498  return SCIP_OKAY;
2499 }
2500 
2501 
2503 static
2504 SCIP_DECL_READERWRITE(readerWriteCbf)
2505 { /*lint --e{715,818}*/
2506  SCIP_VAR** linvars;
2507  SCIP_Real* linvals;
2508  SCIP_VAR** sdpvars;
2509  SCIP_Real** sdpval;
2510  SCIP_Real* sdpconstval;
2511  int** sdpcol;
2512  int** sdprow;
2513  int* sdpconstcol;
2514  int* sdpconstrow;
2515  int* sdpnvarnonz;
2516  int* varsenses;
2517  int* consssenses;
2518  int nsdpconss;
2519  int sdpnvars;
2520  int sdpnnonz;
2521  int totalsdpnnonz;
2522  int sdpblocksize;
2523  int sdparraylength;
2524  int totalsdpconstnnonz;
2525  int sdpconstnnonz;
2526  int nobjnonz;
2527  int nnonz;
2528  int nbnonz;
2529  int nsenses;
2530  int nconsssenses;
2531  int lastsense;
2532  int consind;
2533  int c;
2534  int i;
2535  int v;
2536  int nrank1sdpblocks;
2537 
2538  assert( scip != NULL );
2539  assert( result != NULL );
2540 
2541  SCIPdebugMsg(scip, "Writing problem in CBF format to file.\n");
2542  *result = SCIP_DIDNOTRUN;
2543 
2544  if ( transformed )
2545  {
2546  SCIPerrorMessage("CBF reader currently only supports writing original problems!\n");
2547  return SCIP_READERROR; /*lint !e527*/
2548  }
2549 
2550  for (c = 0; c < nconss; c++)
2551  {
2552  if ( (strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0)
2553  && (strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") != 0 )
2554  && (strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") != 0 ) )
2555  {
2556  SCIPerrorMessage("CBF reader currently only supports linear and SDP constraints!\n");
2557  return SCIP_READERROR; /*lint !e527*/
2558  }
2559  }
2560 
2561 #ifndef NDEBUG
2562  for (v = 0; v < nvars; v++)
2563  {
2564  assert( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_ORIGINAL );
2565  }
2566 #endif
2567 
2568  /* write version number */
2569  SCIPinfoMessage(scip, file, "VER\n%d\n\n", CBF_VERSION_NR);
2570 
2571  /* write objective sense */
2572  SCIPinfoMessage(scip, file, "OBJSENSE\n%s\n\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "MIN" : "MAX");
2573 
2574  /* collect different variable senses */
2575  SCIP_CALL( SCIPallocBufferArray(scip, &varsenses, nvars) );
2576  for (v = 0; v < nvars; v++)
2577  {
2578  SCIP_Real lb;
2579  SCIP_Real ub;
2580 
2581  lb = SCIPvarGetLbOriginal(vars[v]);
2582  ub = SCIPvarGetUbOriginal(vars[v]);
2583 
2584  varsenses[v] = 0;
2585  if ( SCIPisZero(scip, lb) )
2586  varsenses[v] = 1;
2587  else
2588  {
2589  if ( ! SCIPisInfinity(scip, -lb) )
2590  {
2591  SCIPerrorMessage("Can only handle variables with lower bound 0 or minus infinity.\n");
2592  SCIPfreeBufferArray(scip, &varsenses);
2593  return SCIP_READERROR; /*lint !e527*/
2594  }
2595  }
2596 
2597  if ( SCIPisZero(scip, ub) )
2598  varsenses[v] = -1;
2599  else
2600  {
2601  if ( ! SCIPisInfinity(scip, ub) )
2602  {
2603  SCIPerrorMessage("Can only handle variables with upper bound 0 or infinity.\n");
2604  SCIPfreeBufferArray(scip, &varsenses);
2605  return SCIP_READERROR; /*lint !e527*/
2606  }
2607  }
2608  }
2609 
2610  /* now determine senses of constraints - possibly disable constraints */
2611  SCIP_CALL( SCIPallocBufferArray(scip, &consssenses, nconss) );
2612  for (c = 0; c < nconss; c++)
2613  {
2614  SCIP_Real lhs;
2615  SCIP_Real rhs;
2616 
2617  consssenses[c] = 2;
2618 
2619  /* only count linear constraints */
2620  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
2621  continue;
2622 
2623  lhs = SCIPgetLhsLinear(scip, conss[c]);
2624  rhs = SCIPgetRhsLinear(scip, conss[c]);
2625 
2626 #ifdef CBF_CHECK_NONNEG
2627  /* check if there are constraints that would determine senses of variables */
2628  if ( SCIPgetNVarsLinear(scip, conss[c]) == 1 && ! SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c])) )
2629  {
2630  /* the nonzero should be a true nonzero */
2631  assert( ! SCIPisZero(scip, SCIPgetValsLinear(scip, conss[c])[0]) );
2632  assert( SCIPgetVarsLinear(scip, conss[c]) != NULL );
2633 
2634  v = SCIPvarGetProbindex(SCIPgetVarsLinear(scip, conss[c])[0]);
2635  assert( 0 <= v && v < nvars );
2636 
2637  if ( SCIPgetValsLinear(scip, conss[c])[0] > 0.0 )
2638  {
2639  if ( SCIPisZero(scip, lhs) )
2640  {
2641  varsenses[v] = 1;
2642  continue;
2643  }
2644  else if ( SCIPisZero(scip, rhs) )
2645  {
2646  varsenses[v] = -1;
2647  continue;
2648  }
2649  }
2650  else
2651  {
2652  if ( SCIPisZero(scip, lhs) )
2653  {
2654  varsenses[v] = -1;
2655  continue;
2656  }
2657  else if ( SCIPisZero(scip, rhs) )
2658  {
2659  varsenses[v] = 1;
2660  continue;
2661  }
2662  }
2663  }
2664 #endif
2665 
2666  if ( SCIPisEQ(scip, lhs, rhs) )
2667  {
2668  assert( ! SCIPisInfinity(scip, -lhs) );
2669  assert( ! SCIPisInfinity(scip, rhs) );
2670  consssenses[c] = 0;
2671  }
2672  else
2673  {
2674  if ( ! SCIPisInfinity(scip, -lhs) && ! SCIPisInfinity(scip, rhs) )
2675  {
2676  SCIPerrorMessage("Cannot handle ranged rows.\n");
2677  SCIPfreeBufferArray(scip, &varsenses);
2678  SCIPfreeBufferArray(scip, &consssenses);
2679  return SCIP_READERROR; /*lint !e527*/
2680  }
2681 
2682  if ( ! SCIPisInfinity(scip, -lhs) )
2683  consssenses[c] = 1;
2684  else if ( ! SCIPisInfinity(scip, rhs) )
2685  consssenses[c] = -1;
2686  }
2687  }
2688 
2689  /* compute different varsenses */
2690  nsenses = 0;
2691  lastsense = 2;
2692  for (v = 0; v < nvars; v++)
2693  {
2694  if ( varsenses[v] != lastsense )
2695  {
2696  ++nsenses;
2697  lastsense = varsenses[v];
2698  }
2699  }
2700 
2701  /* write variable senses */
2702  SCIPinfoMessage(scip, file, "VAR\n%d %d\n", nvars, nsenses);
2703  lastsense = varsenses[0];
2704  nsenses = 1;
2705  for (v = 1; v < nvars; v++)
2706  {
2707  if ( varsenses[v] != lastsense )
2708  {
2709  if ( lastsense == 0 )
2710  SCIPinfoMessage(scip, file, "F %d\n", nsenses);
2711  else if ( lastsense == -1 )
2712  SCIPinfoMessage(scip, file, "L- %d\n", nsenses);
2713  else
2714  {
2715  assert( lastsense == 1 );
2716  SCIPinfoMessage(scip, file, "L+ %d\n", nsenses);
2717  }
2718  nsenses = 0;
2719  lastsense = varsenses[v];
2720  }
2721  ++nsenses;
2722  }
2723  if ( lastsense == 0 )
2724  SCIPinfoMessage(scip, file, "F %d\n\n", nsenses);
2725  else if ( lastsense == -1 )
2726  SCIPinfoMessage(scip, file, "L- %d\n\n", nsenses);
2727  else
2728  {
2729  assert( lastsense == 1 );
2730  SCIPinfoMessage(scip, file, "L+ %d\n\n", nsenses);
2731  }
2732 
2733  /* write integrality constraints */
2734  if ( nbinvars + nintvars > 0 )
2735  {
2736  SCIPinfoMessage(scip, file, "INT\n%d\n", nbinvars + nintvars);
2737 
2738  for (v = 0; v < nbinvars + nintvars; v++)
2739  {
2740  assert( SCIPvarIsIntegral(vars[v]) );
2741  SCIPinfoMessage(scip, file, "%d\n", v);
2742  }
2743  SCIPinfoMessage(scip, file, "\n");
2744  }
2745 
2746  /* compute different consssenses */
2747  nsenses = 0;
2748  lastsense = 3;
2749  i = 0;
2750  for (c = 0; c < nconss; c++)
2751  {
2752  if ( consssenses[c] == 2 )
2753  continue;
2754 
2755  ++i;
2756  if ( consssenses[c] != lastsense )
2757  {
2758  ++nsenses;
2759  lastsense = consssenses[c];
2760  }
2761  }
2762 
2763  assert( nsenses == 0 || i > 0 );
2764  assert( nsenses > 0 || i == 0 );
2765 
2766  /* write constraint senses if there are any linear constraints */
2767  if ( nsenses > 0 )
2768  {
2769  SCIPinfoMessage(scip, file, "CON\n%d %d\n", i, nsenses);
2770  nconsssenses = nsenses;
2771  c = 0;
2772  while (c < nconss && consssenses[c] == 2)
2773  ++c;
2774  if ( c < nconss )
2775  {
2776  lastsense = consssenses[c];
2777  nsenses = 1;
2778  ++c;
2779  for (; c < nconss; ++c)
2780  {
2781  if ( consssenses[c] == 2 )
2782  continue;
2783 
2784  if ( consssenses[c] != lastsense )
2785  {
2786  if ( lastsense == 0 )
2787  SCIPinfoMessage(scip, file, "L= %d\n", nsenses);
2788  else if ( lastsense == -1 )
2789  SCIPinfoMessage(scip, file, "L- %d\n", nsenses);
2790  else
2791  {
2792  assert( lastsense == 1 );
2793  SCIPinfoMessage(scip, file, "L+ %d\n", nsenses);
2794  }
2795  nsenses = 0;
2796  lastsense = consssenses[c];
2797  }
2798  ++nsenses;
2799  }
2800  }
2801  if ( lastsense == 0 )
2802  SCIPinfoMessage(scip, file, "L= %d\n\n", nsenses);
2803  else if ( lastsense == -1 )
2804  SCIPinfoMessage(scip, file, "L- %d\n\n", nsenses);
2805  else
2806  {
2807  assert( lastsense == 1 );
2808  SCIPinfoMessage(scip, file, "L+ %d\n\n", nsenses);
2809  }
2810  }
2811  else
2812  {
2813  nconsssenses = 0;
2814  }
2815 
2816  /* count number of SDP constraints (conshdlrGetNConss doesn't seem to work before transformation) */
2817  nsdpconss = 0;
2818  for (c = 0; c < nconss; c++)
2819  {
2820  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") == 0 || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") == 0 )
2821  ++nsdpconss;
2822  }
2823 
2824  /* write SDP constraints if there are any */
2825  if ( nsdpconss > 0 )
2826  {
2827  SCIPinfoMessage(scip, file, "PSDCON\n%d\n", nsdpconss);
2828 
2829  for (c = 0; c < nconss; c++)
2830  {
2831  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") != 0 && strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") != 0 )
2832  continue;
2833 
2834  SCIPinfoMessage(scip, file, "%d\n", SCIPconsSdpGetBlocksize(scip, conss[c]));
2835  }
2836 
2837  SCIPinfoMessage(scip, file, "\n");
2838  }
2839 
2840  /* count number of rank-1 SDP constraints */
2841  nrank1sdpblocks = 0;
2842  for (c = 0; c < nconss; c++)
2843  {
2844  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") == 0 )
2845  ++nrank1sdpblocks;
2846  }
2847 
2848  /* write rank-1 SDP constraints (if existing) */
2849  if ( nrank1sdpblocks > 0 )
2850  {
2851  SCIPinfoMessage(scip, file, "PSDCONRANK1\n%d\n", nrank1sdpblocks);
2852  consind = 0;
2853 
2854  for (c = 0; c < nconss; c++)
2855  {
2856  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") != 0 )
2857  continue;
2858 
2859  assert( SCIPconsSdpShouldBeRankOne(conss[c]) );
2860  SCIPinfoMessage(scip, file, "%d\n", consind);
2861  consind++;
2862  }
2863 
2864  SCIPinfoMessage(scip, file, "\n");
2865  }
2866 
2867  /* count number of nonzero objective coefficients */
2868  nobjnonz = 0;
2869  for (v = 0; v < nvars; v++)
2870  {
2871  if ( ! SCIPisZero(scip, SCIPvarGetObj(vars[v])) )
2872  ++nobjnonz;
2873  }
2874 
2875  /* write objective */
2876  SCIPinfoMessage(scip, file, "OBJACOORD\n%d\n", nobjnonz);
2877 
2878  for (v = 0; v < nvars; v++)
2879  {
2880  SCIP_Real obj;
2881 
2882  obj = SCIPvarGetObj(vars[v]);
2883  if ( ! SCIPisZero(scip, obj) )
2884  {
2885  SCIPinfoMessage(scip, file, "%d %.15g\n", v, obj);
2886  }
2887  }
2888  SCIPinfoMessage(scip, file, "\n");
2889 
2890  /* write coefficients of linear constraints */
2891  if ( nconsssenses > 0 )
2892  {
2893  /* count number of nonzero coefficients in linear constraints */
2894  nnonz = 0;
2895  nbnonz = 0;
2896  for (c = 0; c < nconss; c++)
2897  {
2898  if ( consssenses[c] == -1 )
2899  {
2900  assert( ! SCIPisInfinity(scip, SCIPgetRhsLinear(scip, conss[c])) );
2901  nnonz += SCIPgetNVarsLinear(scip, conss[c]);
2902  if ( ! SCIPisZero(scip, SCIPgetRhsLinear(scip, conss[c])) )
2903  ++nbnonz;
2904  }
2905  else if ( consssenses[c] == 1 )
2906  {
2907  assert( ! SCIPisInfinity(scip, -SCIPgetLhsLinear(scip, conss[c])) );
2908  nnonz += SCIPgetNVarsLinear(scip, conss[c]);
2909  if ( ! SCIPisZero(scip, SCIPgetLhsLinear(scip, conss[c])) )
2910  ++nbnonz;
2911  }
2912  else if ( consssenses[c] == 0 )
2913  {
2914  assert( SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c])) );
2915  nnonz += SCIPgetNVarsLinear(scip, conss[c]);
2916  if ( ! SCIPisZero(scip, SCIPgetLhsLinear(scip, conss[c])) )
2917  ++nbnonz;
2918  }
2919  }
2920 
2921  /* write linear nonzero coefficients */
2922  SCIPinfoMessage(scip, file, "ACOORD\n%d\n", nnonz);
2923  consind = 0;
2924  for (c = 0; c < nconss; c++)
2925  {
2926  if ( consssenses[c] == -1 || consssenses[c] == 0 || consssenses[c] == 1 )
2927  {
2928  assert( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") == 0 );
2929 
2930  linvars = SCIPgetVarsLinear(scip, conss[c]);
2931  linvals = SCIPgetValsLinear(scip, conss[c]);
2932 
2933  for (v = 0; v < SCIPgetNVarsLinear(scip, conss[c]); v++)
2934  {
2935  i = SCIPvarGetProbindex(linvars[v]);
2936  assert( 0 <= i && i < nvars );
2937  SCIPinfoMessage(scip, file, "%d %d %.15g\n", consind, i, linvals[v]);
2938  }
2939  ++consind;
2940  }
2941  }
2942  SCIPinfoMessage(scip, file, "\n");
2943 
2944  /* write constant part of linear constraints */
2945  SCIPinfoMessage(scip, file, "BCOORD\n%d\n", nbnonz);
2946  consind = 0;
2947  for (c = 0; c < nconss; c++)
2948  {
2949  SCIP_Real val;
2950  if ( consssenses[c] == -1 )
2951  {
2952  val = SCIPgetRhsLinear(scip, conss[c]);
2953  if ( ! SCIPisZero(scip, val) )
2954  SCIPinfoMessage(scip, file, "%d %.15g\n", consind, -val);
2955  consind++;
2956  }
2957  else if ( consssenses[c] == 1 )
2958  {
2959  val = SCIPgetLhsLinear(scip, conss[c]);
2960  if ( ! SCIPisZero(scip, val) )
2961  SCIPinfoMessage(scip, file, "%d %.15g\n", consind, -val);
2962  consind++;
2963  }
2964  else if ( consssenses[c] == 0 )
2965  {
2966  val = SCIPgetLhsLinear(scip, conss[c]);
2967  if ( ! SCIPisZero(scip, val) )
2968  SCIPinfoMessage(scip, file, "%d %.15g\n", consind, -val);
2969  consind++;
2970  }
2971  }
2972  SCIPinfoMessage(scip, file, "\n");
2973  }
2974 
2975  /* count SDP nonzeros */
2976  totalsdpnnonz = 0;
2977  totalsdpconstnnonz = 0;
2978  for (c = 0; c < nconss; c++)
2979  {
2980  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])),"SDP") != 0 && strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])),"SDPrank1") != 0 )
2981  continue;
2982 
2983  SCIP_CALL( SCIPconsSdpGetNNonz(scip, conss[c], &sdpnnonz, &sdpconstnnonz) );
2984  totalsdpnnonz += sdpnnonz;
2985  totalsdpconstnnonz += sdpconstnnonz;
2986  }
2987 
2988  /* allocate memory for SDPdata */
2989  SCIP_CALL( SCIPallocBufferArray(scip, &sdpnvarnonz, nvars) );
2990  SCIP_CALL( SCIPallocBufferArray(scip, &sdpcol, totalsdpnnonz) );
2991  SCIP_CALL( SCIPallocBufferArray(scip, &sdprow, totalsdpnnonz) );
2992  SCIP_CALL( SCIPallocBufferArray(scip, &sdpval, totalsdpnnonz) );
2993  SCIP_CALL( SCIPallocBufferArray(scip, &sdpvars, nvars) );
2994  SCIP_CALL( SCIPallocBufferArray(scip, &sdpconstcol, totalsdpconstnnonz) );
2995  SCIP_CALL( SCIPallocBufferArray(scip, &sdpconstrow, totalsdpconstnnonz) );
2996  SCIP_CALL( SCIPallocBufferArray(scip, &sdpconstval, totalsdpconstnnonz) );
2997 
2998  sdparraylength = totalsdpnnonz;
2999  sdpconstnnonz = totalsdpconstnnonz;
3000 
3001  /* write SDP nonzeros */
3002  if ( totalsdpnnonz > 0 )
3003  {
3004  SCIPinfoMessage(scip, file, "HCOORD\n%d\n", totalsdpnnonz);
3005  consind = 0;
3006  for (c = 0; c < nconss; c++)
3007  {
3008  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") != 0 && strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") != 0 )
3009  continue;
3010 
3011  /* initialization for SDPconsSDPGetData-call */
3012  sdparraylength = totalsdpnnonz;
3013  sdpconstnnonz = totalsdpconstnnonz;
3014 
3015  SCIP_CALL( SCIPconsSdpGetData(scip, conss[c], &sdpnvars, &sdpnnonz, &sdpblocksize, &sdparraylength, sdpnvarnonz,
3016  sdpcol, sdprow, sdpval, sdpvars, &sdpconstnnonz, sdpconstcol, sdpconstrow, sdpconstval, NULL, NULL, NULL) );
3017 
3018  assert( sdpconstnnonz <= totalsdpconstnnonz );
3019  assert( sdparraylength <= totalsdpnnonz);
3020 
3021  for (v = 0; v < sdpnvars; v++)
3022  {
3023  for (i = 0; i < sdpnvarnonz[v]; i++)
3024  {
3025  int ind;
3026  ind = SCIPvarGetProbindex(sdpvars[v]);
3027  assert( 0 <= ind && ind < nvars );
3028  SCIPinfoMessage(scip, file, "%d %d %d %d %.15g\n", consind, ind, sdprow[v][i], sdpcol[v][i], sdpval[v][i]);
3029  }
3030  }
3031  consind++;
3032  }
3033  SCIPinfoMessage(scip, file, "\n");
3034  }
3035 
3036  /* write nonzeros of constant part of SDP constraint */
3037  if ( totalsdpnnonz > 0 )
3038  {
3039  SCIPinfoMessage(scip, file, "DCOORD\n%d\n", totalsdpconstnnonz);
3040  consind = 0;
3041  for (c = 0; c < nconss; c++)
3042  {
3043  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") != 0 && strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDPrank1") != 0 )
3044  continue;
3045 
3046  /* initialization for SDPconsSDPGetData-call */
3047  sdparraylength = totalsdpnnonz;
3048  sdpconstnnonz = totalsdpconstnnonz;
3049 
3050  SCIP_CALL( SCIPconsSdpGetData(scip, conss[c], &sdpnvars, &sdpnnonz, &sdpblocksize, &sdparraylength, sdpnvarnonz,
3051  sdpcol, sdprow, sdpval, sdpvars, &sdpconstnnonz, sdpconstcol, sdpconstrow, sdpconstval, NULL, NULL, NULL) );
3052 
3053  assert( sdpconstnnonz <= totalsdpconstnnonz );
3054  assert( sdparraylength <= totalsdpnnonz);
3055 
3056  for (i = 0; i < sdpconstnnonz; i++)
3057  {
3058  SCIPinfoMessage(scip, file, "%d %d %d %.15g\n", consind, sdpconstrow[i], sdpconstcol[i], -sdpconstval[i]);
3059  }
3060  consind++;
3061  }
3062  }
3063 
3064  SCIPfreeBufferArray(scip, &sdpconstval);
3065  SCIPfreeBufferArray(scip, &sdpconstrow);
3066  SCIPfreeBufferArray(scip, &sdpconstcol);
3067  SCIPfreeBufferArray(scip, &sdpvars);
3068  SCIPfreeBufferArray(scip, &sdpval);
3069  SCIPfreeBufferArray(scip, &sdprow);
3070  SCIPfreeBufferArray(scip, &sdpcol);
3071  SCIPfreeBufferArray(scip, &sdpnvarnonz);
3072  SCIPfreeBufferArray(scip, &consssenses);
3073  SCIPfreeBufferArray(scip, &varsenses);
3074 
3075  *result = SCIP_SUCCESS;
3076 
3077  return SCIP_OKAY;
3078 }
3079 
3080 
3081 /*
3082  * reader specific interface methods
3083  */
3084 
3086 SCIP_RETCODE SCIPincludeReaderCbf(
3087  SCIP* scip
3088  )
3089 {
3090  SCIP_READERDATA* readerdata = NULL;
3091  SCIP_READER* reader;
3092 
3093  /* include reader */
3094  SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, readerdata) );
3095 
3096  assert( reader != NULL );
3097 
3098  /* set non fundamental callbacks via setter functions */
3099  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyCbf) );
3100  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadCbf) );
3101  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteCbf) );
3102 
3103  return SCIP_OKAY;
3104 }
static SCIP_RETCODE CBFreadPsdConRank1(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:1017
static SCIP_RETCODE CBFreadBcoord(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:1553
static SCIP_RETCODE CBFreadPsdVar(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:521
static SCIP_RETCODE CBFreadAcoord(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:1446
static SCIP_RETCODE CBFreadObjFcoord(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:1097
static SCIP_RETCODE CBFreadObjsense(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:352
#define CBF_MAX_NAME
Definition: reader_cbf.c:95
static SCIP_RETCODE CBFreadVar(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:393
file reader for mixed-integer semidefinite programs in CBF format
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_RETCODE CBFreadFcoord(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:1310
#define READER_DESC
Definition: reader_cbf.c:81
static SCIP_DECL_READERCOPY(readerCopyCbf)
Definition: reader_cbf.c:2109
static SCIP_RETCODE CBFfreeData(SCIP *scip, SCIP_FILE *file, CBF_DATA *data)
Definition: reader_cbf.c:148
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
#define CBF_VERSION_NR
Definition: reader_cbf.c:84
static SCIP_RETCODE CBFreadObjAcoord(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:1219
#define READER_EXTENSION
Definition: reader_cbf.c:82
Constraint handler for SDP-constraints.
SCIP_RETCODE SCIPincludeReaderCbf(SCIP *scip)
Definition: reader_cbf.c:3088
static SCIP_RETCODE CBFreadPsdCon(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:930
static SCIP_RETCODE CBFreadPsdVarRank1(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:645
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 CBF_MAX_LINE
Definition: reader_cbf.c:94
static SCIP_RETCODE CBFreadHcoord(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:1656
#define READER_NAME
Definition: reader_cbf.c:80
static SCIP_DECL_READERREAD(readerReadCbf)
Definition: reader_cbf.c:2120
static SCIP_RETCODE CBFfgets(SCIP *scip, CBF_DATA *data, SCIP_FILE *pFile, SCIP_Longint *linecount, SCIP_Bool printerror)
Definition: reader_cbf.c:321
static SCIP_RETCODE CBFreadInt(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:853
static SCIP_RETCODE CBFreadDcoord(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:1956
int SCIPconsSdpGetBlocksize(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sdp.c:8149
SCIP_RETCODE SCIPconsSdpGetNNonz(SCIP *scip, SCIP_CONS *cons, int *nnonz, int *constnnonz)
Definition: cons_sdp.c:8090
static SCIP_RETCODE CBFreadCon(SCIP *scip, CBF_DATA *data, SCIP_FILE *pfile, SCIP_Longint *linecount)
Definition: reader_cbf.c:720
#define CBF_NAME_FORMAT
Definition: reader_cbf.c:100
static SCIP_DECL_READERWRITE(readerWriteCbf)
Definition: reader_cbf.c:2506