SCIP-SDP  3.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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-2017 Discrete Optimization, TU Darmstadt */
9 /* */
10 /* */
11 /* This program is free software; you can redistribute it and/or */
12 /* modify it under the terms of the GNU Lesser General Public License */
13 /* as published by the Free Software Foundation; either version 3 */
14 /* of the License, or (at your option) any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU Lesser General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with this program; if not, write to the Free Software */
23 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
24 /* */
25 /* */
26 /* Based on SCIP - Solving Constraint Integer Programs */
27 /* Copyright (C) 2002-2017 Zuse Institute Berlin */
28 /* SCIP is distributed under the terms of the SCIP Academic Licence, */
29 /* see file COPYING in the SCIP distribution. */
30 /* */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32 
39 /*#define SCIP_DEBUG*/
40 /*#define SCIP_MORE_DEBUG*/
41 
42 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
43 
44 #include <assert.h>
45 #include <string.h> /* for strcmp */
46 
47 #include "scipsdp/reader_cbf.h"
48 #include "scipsdp/SdpVarmapper.h"
49 #include "scipsdp/cons_sdp.h"
50 #include "scip/cons_linear.h"
51 
52 
53 #define READER_NAME "cbfreader"
54 #define READER_DESC "file reader and writer for MISDPs in cbf format"
55 #define READER_EXTENSION "cbf"
56 
57 #define CBF_VERSION_NR 1
58 #define CBF_CHECK_NONNEG TRUE
61  /* TODO: currently doesn't work for ranged rows (which are not created by sdpa
62  * reader) */
63 
64 /* Use CBF_NAME_FORMAT instead of %s when parsing lines, to avoid buffer overflow. */
65 #define MACRO_STR_EXPAND(tok) #tok
66 #define MACRO_STR(tok) MACRO_STR_EXPAND(tok)
67 #define CBF_NAME_FORMAT "%" MACRO_STR(CBF_MAX_NAME) "s"
68 #define CBF_MAX_LINE 512 /* Last 3 chars reserved for '\r\n\0' */
69 #define CBF_MAX_NAME 512
70 
73 
74 struct CBF_Data
75 {
76  int firstnegorthvar;
78  int firstfreevar;
80  int nvars;
82  SCIP_VAR** createdvars;
83  int firstleqcons;
85  int firsteqcons;
87  int nconss;
89  SCIP_CONS** createdconss;
90  int nsdpblocks;
91  int* sdpblocksizes;
92  int* sdpnblocknonz;
93  int* sdpnblockvars;
94  int** nvarnonz;
95  SCIP_VAR*** sdpblockvars;
96  int** sdprow;
97  int** sdpcol;
98  SCIP_Real** sdpval;
99  int*** rowpointer;
100  int*** colpointer;
101  SCIP_Real*** valpointer;
102  int* sdpconstnblocknonz;
104  int** sdpconstrow;
105  int** sdpconstcol;
106  SCIP_Real** sdpconstval;
107 };
108 
109 typedef struct CBF_Data CBF_DATA;
110 
112 /*
113  * Local methods
114  */
115 
117 static
118 SCIP_RETCODE CBFfgets(
119  SCIP_FILE* pFile, /* file to read from */
120  long long int * linecount /* current linecount */
121  )
122 {
123  assert( pFile != NULL );
124  assert( linecount != NULL );
125 
126  /* Find first non-commentary line */
127  while( SCIPfgets(CBF_LINE_BUFFER, (int) sizeof(CBF_LINE_BUFFER), pFile) != NULL )
128  {
129  ++(*linecount);
130 
131  if (CBF_LINE_BUFFER[0] != '#')
132  return SCIP_OKAY;
133  }
134 
135  return SCIP_READERROR;
136 }
137 
139 static
140 SCIP_RETCODE CBFreadObjsense(
141  SCIP* scip, /* SCIP data structure */
142  SCIP_FILE* pfile, /* file to read from */
143  long long int * linecount /* current linecount */
144  )
145 {
146  assert( scip != NULL );
147  assert( pfile != NULL );
148  assert( linecount != NULL );
149 
150  SCIP_CALL( CBFfgets(pfile, linecount) );
151 
152  if ( sscanf(CBF_LINE_BUFFER, CBF_NAME_FORMAT, CBF_NAME_BUFFER) == 1 )
153  {
154  if (strcmp(CBF_NAME_BUFFER, "MIN") == 0)
155  {
156  SCIP_CALL( SCIPsetObjsense(scip, SCIP_OBJSENSE_MINIMIZE) );
157  }
158  else if (strcmp(CBF_NAME_BUFFER, "MAX") == 0)
159  {
160  SCIP_CALL( SCIPsetObjsense(scip, SCIP_OBJSENSE_MAXIMIZE) );
161  }
162  else
163  {
164  SCIPerrorMessage("OBJSENSE should be either MIN or MAX.\n");
165  SCIPABORT();
166  }
167  }
168  else
169  {
170  return SCIP_READERROR;
171  }
172 
173  return SCIP_OKAY;
174 }
175 
177 static
178 SCIP_RETCODE CBFreadVar(
179  SCIP* scip, /* SCIP data structure */
180  SCIP_FILE* pfile, /* file to read from */
181  long long int * linecount, /* current linecount */
182  CBF_DATA* data /* data pointer to save the results in */
183  )
184 {
185  int nvartypes;
186  int nvartypevars;
187  int nposorthvars;
188  int nnegorthvars;
189  int t;
190  int v;
191  SCIP_VAR* var;
192  char varname[SCIP_MAXSTRLEN];
193 #ifndef NDEBUG
194  int nfreevars;
195  int snprintfreturn;
196 #endif
197 
198  assert( scip != NULL );
199  assert( pfile != NULL );
200  assert( linecount != NULL );
201  assert( data != NULL );
202 
203  SCIP_CALL( CBFfgets(pfile, linecount) );
204 
205  if ( sscanf(CBF_LINE_BUFFER, "%i %i", &(data->nvars), &nvartypes) != 2 )
206  return SCIP_READERROR;
207  else
208  {
209  assert( data->nvars >= 0 );
210  assert( data->nvars == 0 || ((1 <= nvartypes) && (nvartypes <= 3)) );
211  /* create variables */
212  SCIP_CALL( SCIPallocBufferArray(scip, &(data->createdvars), data->nvars) );
213  for (v = 0; v < data->nvars; v++)
214  {
215 #ifndef NDEBUG
216  snprintfreturn = SCIPsnprintf(varname, SCIP_MAXSTRLEN, "x_%d", v);
217  assert( snprintfreturn < SCIP_MAXSTRLEN);
218 #else
219  (void)SCIPsnprintf(varname, SCIP_MAXSTRLEN, "x_%d", v);
220 #endif
221 
222  SCIP_CALL( SCIPcreateVar(scip, &var, varname, -SCIPinfinity(scip), SCIPinfinity(scip), 0.0,
223  SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL));/*lint !e732*//*lint !e747*/
224 
225  SCIP_CALL( SCIPaddVar(scip, var) );
226  data->createdvars[v] = var;/*lint !e732*//*lint !e747*/
227 
228  /* release variable for the reader. */
229  SCIP_CALL( SCIPreleaseVar(scip, &var) );
230  }
231  }
232  nposorthvars = 0;
233  nnegorthvars = 0;
234 #ifndef NDEBUG
235  nfreevars = 0;
236 #endif
237 
238  for (t = 0; t < nvartypes; t++)
239  {
240  SCIP_CALL( CBFfgets(pfile, linecount) );
241 
242  if ( sscanf(CBF_LINE_BUFFER, CBF_NAME_FORMAT" %i", CBF_NAME_BUFFER, &nvartypevars) == 2 )
243  {
244  if (strcmp(CBF_NAME_BUFFER, "L+") == 0)
245  {
246  if ( nvartypevars >= 0 )
247  nposorthvars = nvartypevars;
248  else
249  {
250  SCIPerrorMessage("Number of non-negative variables %d should be non-negative!\n", nvartypevars);
251  SCIPABORT();
252  }
253  }
254  else if (strcmp(CBF_NAME_BUFFER, "L-") == 0)
255  {
256  if ( nvartypevars >= 0 )
257  nnegorthvars = nvartypevars;
258  else
259  {
260  SCIPerrorMessage("Number of non-positive variables %d should be non-negative!\n", nvartypevars);
261  SCIPABORT();
262  }
263  }
264 #ifndef NDEBUG
265  else if (strcmp(CBF_NAME_BUFFER, "F") == 0)
266  {
267  if ( nvartypevars >= 0 )
268  nfreevars = nvartypevars;
269  else
270  {
271  SCIPerrorMessage("Number of free variables %d should be non-negative!\n", nvartypevars);
272  SCIPABORT();
273  }
274  }
275 #endif
276  else if (strcmp(CBF_NAME_BUFFER, "F") != 0)
277  {
278  SCIPerrorMessage("CBF-Reader of SCIP-SDP currently only supports non-negative, non-positive and free variables!\n");
279  SCIPABORT();
280  }
281  }
282  else
283  return SCIP_READERROR;
284  }
285 
286  /* set lower bound for non-negative variables */
287  data->firstnegorthvar = nposorthvars;
288  for (v = 0; v < nposorthvars; v++)
289  {
290  SCIP_CALL( SCIPchgVarLbGlobal(scip, data->createdvars[v], 0.0) );
291  }
292 
293  /* set upper bound for non-positive variables */
294  data->firstfreevar = data->firstnegorthvar + nnegorthvars;
295  for (v = data->firstnegorthvar; v < data->firstfreevar; v++)
296  {
297  SCIP_CALL( SCIPchgVarUbGlobal(scip, data->createdvars[v], 0.0) );
298  }
299 
300  assert( data->firstfreevar + nfreevars == data->nvars );
301 
302  return SCIP_OKAY;
303 }
304 
306 static
307 SCIP_RETCODE CBFreadCon(
308  SCIP* scip, /* SCIP data structure */
309  SCIP_FILE* pfile, /* file to read from */
310  long long int * linecount, /* current linecount */
311  CBF_DATA* data /* data pointer to save the results in */
312  )
313 {
314  int nconstypes;
315  int nconstypeconss;
316  int ngeqconss;
317  int nleqconss;
318  int t;
319  int c;
320  SCIP_CONS* cons;
321  char consname[SCIP_MAXSTRLEN];
322 #ifndef NDEBUG
323  int neqconss;
324  int snprintfreturn;
325 #endif
326 
327  assert( scip != NULL );
328  assert( pfile != NULL );
329  assert( linecount != NULL );
330  assert( data != NULL );
331 
332  SCIP_CALL( CBFfgets(pfile, linecount) );
333 
334  if ( sscanf(CBF_LINE_BUFFER, "%i %i", &(data->nconss), &nconstypes) != 2 )
335  return SCIP_READERROR;
336  else
337  {
338  assert( data->nconss >= 0 );
339  assert( data->nconss == 0 || ((1 <= nconstypes) && (nconstypes <= 3)) );
340  /* create variables */
341  SCIP_CALL( SCIPallocBufferArray(scip, &(data->createdconss), data->nconss) );
342  for (c = 0; c < data->nconss; c++)
343  {
344 #ifndef NDEBUG
345  snprintfreturn = SCIPsnprintf(consname, SCIP_MAXSTRLEN, "LP_%d", c);
346  assert( snprintfreturn < SCIP_MAXSTRLEN);
347 #else
348  (void)SCIPsnprintf(consname, SCIP_MAXSTRLEN, "linear_%d", c);
349 #endif
350 
351  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, 0, NULL, NULL, -SCIPinfinity(scip), SCIPinfinity(scip),
352  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE));
353 
354  SCIP_CALL( SCIPaddCons(scip, cons) );
355  data->createdconss[c] = cons;/*lint !e732*//*lint !e747*/
356 
357  /* release variable for the reader. */
358  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
359  }
360  }
361 
362  ngeqconss = 0;
363  nleqconss = 0;
364 #ifndef NDEBUG
365  neqconss = 0;
366 #endif
367 
368  for (t = 0; t < nconstypes; t++)
369  {
370  SCIP_CALL( CBFfgets(pfile, linecount) );
371 
372  if ( sscanf(CBF_LINE_BUFFER, CBF_NAME_FORMAT" %i", CBF_NAME_BUFFER, &nconstypeconss) == 2 )
373  {
374  if (strcmp(CBF_NAME_BUFFER, "L+") == 0)
375  {
376  if ( nconstypeconss >= 0 )
377  ngeqconss = nconstypeconss;
378  else
379  {
380  SCIPerrorMessage("Number of greater or equal constraints %d should be non-negative!\n", nconstypeconss);
381  SCIPABORT();
382  }
383  }
384  else if (strcmp(CBF_NAME_BUFFER, "L-") == 0)
385  {
386  if ( nconstypeconss >= 0 )
387  nleqconss = nconstypeconss;
388  else
389  {
390  SCIPerrorMessage("Number of less or equal constraints %d should be non-negative!\n", nconstypeconss);
391  SCIPABORT();
392  }
393  }
394 #ifndef NDEBUG
395  else if (strcmp(CBF_NAME_BUFFER, "L=") == 0)
396  {
397  if ( nconstypeconss >= 0 )
398  neqconss = nconstypeconss;
399  else
400  {
401  SCIPerrorMessage("Number of equality constraints %d should be non-negative!\n", nconstypeconss);
402  SCIPABORT();
403  }
404  }
405 #endif
406  else if (strcmp(CBF_NAME_BUFFER, "L=") != 0)
407  {
408  SCIPerrorMessage("CBF-Reader of SCIP-SDP currently only supports linear greater or equal, less or equal and"
409  "equality constraints!\n");
410  SCIPABORT();
411  }
412  }
413  else
414  return SCIP_READERROR;
415  }
416 
417  /* set left-hand side for greater or equal constraints */
418  data->firstleqcons = ngeqconss;
419  for (c = 0; c < ngeqconss; c++)
420  {
421  SCIP_CALL( SCIPchgLhsLinear(scip, data->createdconss[c], 0.0) );
422  }
423 
424  /* set right-hand side for less or equal constraints */
425  data->firsteqcons = data->firstleqcons + nleqconss;
426  for (c = data->firstleqcons; c < data->firsteqcons; c++)
427  {
428  SCIP_CALL( SCIPchgRhsLinear(scip, data->createdconss[c], 0.0) );
429  }
430 
431  assert( data->firsteqcons + neqconss == data->nconss );
432 
433  return SCIP_OKAY;
434 }
435 
437 static
438 SCIP_RETCODE CBFreadInt(
439  SCIP* scip, /* SCIP data structure */
440  SCIP_FILE* pfile, /* file to read from */
441  long long int * linecount, /* current linecount */
442  CBF_DATA* data /* data pointer to save the results in */
443  )
444 { /*lint --e{818}*/
445  int nintvars;
446  int i;
447  int v;
448  SCIP_Bool infeasible;
449 
450  assert( scip != NULL );
451  assert( pfile != NULL );
452  assert( linecount != NULL );
453  assert( data != NULL );
454 
455  SCIP_CALL( CBFfgets(pfile, linecount) );
456 
457  if ( sscanf(CBF_LINE_BUFFER, "%i", &nintvars) == 1 )
458  {
459  if ( nintvars >= 0 )
460  {
461  for (i = 0; i < nintvars; i++)
462  {
463  SCIP_CALL( CBFfgets(pfile, linecount) );
464  if ( sscanf(CBF_LINE_BUFFER, "%i", &v) == 1 )
465  {
466  SCIP_CALL( SCIPchgVarType(scip, data->createdvars[v], SCIP_VARTYPE_INTEGER, &infeasible) );
467 
468  if ( infeasible )
469  {
470  SCIPinfoMessage(scip, NULL, "Infeasibility detected because of integrality of variable %s\n",
471  SCIPvarGetName(data->createdvars[v]));
472  }
473  }
474  else
475  {
476  SCIPerrorMessage("Number of integrality constraints %d should be non-negative!\n", nintvars);
477  SCIPABORT();
478  }
479  }
480  }
481  else
482  {
483  SCIPerrorMessage("Number of integrality constraints %d should be non-negative!\n", nintvars);
484  SCIPABORT();
485  }
486  }
487  else
488  return SCIP_READERROR;
489 
490  return SCIP_OKAY;
491 }
492 
494 static
495 SCIP_RETCODE CBFreadPsdcon(
496  SCIP* scip, /* SCIP data structure */
497  SCIP_FILE* pfile, /* file to read from */
498  long long int * linecount, /* current linecount */
499  CBF_DATA* data /* data pointer to save the results in */
500  )
501 {
502  int b;
503 
504  assert( scip != NULL );
505  assert( pfile != NULL );
506  assert( linecount != NULL );
507  assert( data != NULL );
508 
509  SCIP_CALL( CBFfgets(pfile, linecount) );
510 
511  if ( sscanf(CBF_LINE_BUFFER, "%i", &(data->nsdpblocks)) == 1 )
512  {
513  if ( data->nsdpblocks >= 0 )
514  {
515  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpblocksizes), data->nsdpblocks) );
516 
517  for (b = 0; b < data->nsdpblocks; b++)
518  {
519  SCIP_CALL( CBFfgets(pfile, linecount) );
520  if ( sscanf(CBF_LINE_BUFFER, "%i", &(data->sdpblocksizes[b])) == 1 )
521  {
522  if ( data->sdpblocksizes[b] <= 0 )
523  {
524  SCIPerrorMessage("Size %d of SDP-block %d should be positive!\n", data->sdpblocksizes[b], b);
525  SCIPABORT();
526  }
527  }
528  else
529  return SCIP_READERROR;
530  }
531  }
532  else
533  {
534  SCIPerrorMessage("Number of SDP-blocks %d should be non-negative!\n", data->nsdpblocks);
535  SCIPABORT();
536  }
537  }
538  else
539  return SCIP_READERROR;
540 
541  return SCIP_OKAY;
542 }
543 
545 static
546 SCIP_RETCODE CBFreadObjacoord(
547  SCIP* scip, /* SCIP data structure */
548  SCIP_FILE* pfile, /* file to read from */
549  long long int * linecount, /* current linecount */
550  CBF_DATA* data /* data pointer to save the results in */
551  )
552 { /*lint --e{818}*/
553  int nobjcoefs;
554  int i;
555  int v;
556  SCIP_Real val;
557 
558  assert( scip != NULL );
559  assert( pfile != NULL );
560  assert( linecount != NULL );
561  assert( data != NULL );
562 
563  SCIP_CALL( CBFfgets(pfile, linecount) );
564 
565  if ( sscanf(CBF_LINE_BUFFER, "%i", &nobjcoefs) == 1 )
566  {
567  if ( nobjcoefs >= 0 )
568  {
569  for (i = 0; i < nobjcoefs; i++)
570  {
571  SCIP_CALL( CBFfgets(pfile, linecount) );
572  if ( sscanf(CBF_LINE_BUFFER, "%i %lf", &v, &val) == 2 )
573  {
574  if ( v < 0 || v >= data->nvars )
575  {
576  SCIPerrorMessage("Given objective coefficient for variable %d which does not exist!\n", v);
577  SCIPABORT();
578  }
579 
580  if ( SCIPisZero(scip, val) )
581  {
582  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Ignored objective coefficient of variable %d; value"
583  "%f is smaller than epsilon = %f.\n", v, val, SCIPepsilon(scip));
584  }
585  else
586  {
587  SCIP_CALL( SCIPchgVarObj(scip, data->createdvars[v], val) );
588  }
589  }
590  else
591  return SCIP_READERROR;
592  }
593  }
594  else
595  {
596  SCIPerrorMessage("Number of objective coefficients %d should be non-negative!\n", nobjcoefs);
597  SCIPABORT();
598  }
599  }
600  else
601  return SCIP_READERROR;
602 
603  return SCIP_OKAY;
604 }
605 
607 static
608 SCIP_RETCODE CBFreadAcoord(
609  SCIP* scip, /* SCIP data structure */
610  SCIP_FILE* pfile, /* file to read from */
611  long long int * linecount, /* current linecount */
612  CBF_DATA* data /* data pointer to save the results in */
613  )
614 { /*lint --e{818}*/
615  int ncoefs;
616  int c;
617  int i;
618  int v;
619  SCIP_Real val;
620 
621  assert( scip != NULL );
622  assert( pfile != NULL );
623  assert( linecount != NULL );
624  assert( data != NULL );
625 
626  SCIP_CALL( CBFfgets(pfile, linecount) );
627 
628  if ( sscanf(CBF_LINE_BUFFER, "%i", &ncoefs) == 1 )
629  {
630  if ( ncoefs >= 0 )
631  {
632  for (i = 0; i < ncoefs; i++)
633  {
634  SCIP_CALL( CBFfgets(pfile, linecount) );
635  if ( sscanf(CBF_LINE_BUFFER, "%i %i %lf", &c, &v, &val) == 3 )
636  {
637  if ( c < 0 || c >= data->nconss )
638  {
639  SCIPerrorMessage("Given linear coefficient for constraint %d which does not exist!\n", c);
640  SCIPABORT();
641  }
642  if ( v < 0 || v >= data->nvars )
643  {
644  SCIPerrorMessage("Given linear coefficient for variable %d which does not exist!\n", v);
645  SCIPABORT();
646  }
647  if ( SCIPisZero(scip, val) )
648  {
649  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Ignored linear coefficient of constraint %d, variable "
650  "%d; value %.9f is smaller than epsilon = %f.\n", c, v, val, SCIPepsilon(scip));
651  }
652  else
653  {
654  SCIP_CALL( SCIPaddCoefLinear(scip, data->createdconss[c], data->createdvars[v], val) );/*lint !e732*//*lint !e747*/
655  }
656  }
657  else
658  return SCIP_READERROR;
659  }
660  }
661  else
662  {
663  SCIPerrorMessage("Number of linear coefficients %d should be non-negative!\n", ncoefs);
664  SCIPABORT();
665  }
666  }
667  else
668  return SCIP_READERROR;
669 
670  return SCIP_OKAY;
671 }
672 
674 static
675 SCIP_RETCODE CBFreadBcoord(
676  SCIP* scip, /* SCIP data structure */
677  SCIP_FILE* pfile, /* file to read from */
678  long long int * linecount, /* current linecount */
679  CBF_DATA* data /* data pointer to save the results in */
680  )
681 { /*lint --e{818}*/
682  int nsides;
683  int c;
684  int i;
685  SCIP_Real val;
686 
687  assert( scip != NULL );
688  assert( pfile != NULL );
689  assert( linecount != NULL );
690  assert( data != NULL );
691 
692  SCIP_CALL( CBFfgets(pfile, linecount) );
693 
694  if ( sscanf(CBF_LINE_BUFFER, "%i", &nsides) == 1 )
695  {
696  if ( nsides >= 0 )
697  {
698  for (i = 0; i < nsides; i++)
699  {
700  SCIP_CALL( CBFfgets(pfile, linecount) );
701  if ( sscanf(CBF_LINE_BUFFER, "%i %lf", &c, &val) == 2 )
702  {
703  if ( c < 0 || c >= data->nconss )
704  {
705  SCIPerrorMessage("Given constant part for constraint %d which does not exist!\n", c);
706  SCIPABORT();
707  }
708  if ( SCIPisZero(scip, val) )
709  {
710  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Ignored constant part of constraint %d; value %.9f is "
711  "smaller than epsilon = %f.\n", c, val, SCIPepsilon(scip));
712  }
713  else
714  {
715  if ( c < data->firstleqcons )
716  {
717  /* greater or equal constraint -> left-hand side (minus since we have Ax + b >= 0) */
718  SCIP_CALL( SCIPchgLhsLinear(scip, data->createdconss[c], -val) );
719  }
720  else if ( c < data->firsteqcons )
721  {
722  /* less or equal constraint -> right-hand side (minus since we have Ax + b <= 0) */
723  SCIP_CALL( SCIPchgRhsLinear(scip, data->createdconss[c], -val) );
724  }
725  else
726  {
727  /* equality constraint -> left- and right-hand side (minus since we have Ax + b = 0) */
728  SCIP_CALL( SCIPchgLhsLinear(scip, data->createdconss[c], -val) );
729  SCIP_CALL( SCIPchgRhsLinear(scip, data->createdconss[c], -val) );
730  }
731  }
732  }
733  else
734  return SCIP_READERROR;
735  }
736  }
737  else
738  {
739  SCIPerrorMessage("Number of left- and right-hand sides %d should be non-negative!\n", nsides);
740  SCIPABORT();
741  }
742  }
743  else
744  return SCIP_READERROR;
745 
746  return SCIP_OKAY;
747 }
748 
750 static
751 SCIP_RETCODE CBFreadHcoord(
752  SCIP* scip, /* SCIP data structure */
753  SCIP_FILE* pfile, /* file to read from */
754  long long int * linecount, /* current linecount */
755  CBF_DATA* data /* data pointer to save the results in */
756  )
757 {
758  int nnonz;
759  int i;
760  int b;
761  int v;
762  int row;
763  int col;
764  SCIP_Real val;
765  int** sdpvar;
766  int firstindforvar;
767  int nextindaftervar;
768  SCIP_Bool varused;
769 
770  assert( scip != NULL );
771  assert( pfile != NULL );
772  assert( linecount != NULL );
773  assert( data != NULL );
774 
775  /* initialize sdpnblocknonz with 0 */
776  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpnblocknonz), data->nsdpblocks) );
777  for (b = 0; b < data->nsdpblocks; b++)
778  data->sdpnblocknonz[b] = 0;
779 
780  SCIP_CALL( CBFfgets(pfile, linecount) );
781 
782  if ( sscanf(CBF_LINE_BUFFER, "%i", &nnonz) == 1 )
783  {
784  if ( nnonz >= 0 )
785  {
786  /* allocate memory (nnonz for each block, since we do not yet no the distribution) */
787  SCIP_CALL( SCIPallocBufferArray(scip, &sdpvar, data->nsdpblocks) );
788  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdprow), data->nsdpblocks) );
789  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpcol), data->nsdpblocks) );
790  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpval), data->nsdpblocks) );
791  for (b = 0; b < data->nsdpblocks; b++)
792  {
793  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpvar[b]), nnonz) );
794  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdprow[b]), nnonz) );
795  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpcol[b]), nnonz) );
796  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpval[b]), nnonz) );
797  }
798 
799  for (i = 0; i < nnonz; i++)
800  {
801  SCIP_CALL( CBFfgets(pfile, linecount) );
802  if ( sscanf(CBF_LINE_BUFFER, "%i %i %i %i %lf", &b, &v, &row, &col, &val) == 5 )
803  {
804  if ( b < 0 || b >= data->nsdpblocks )
805  {
806  SCIPerrorMessage("Given SDP-coefficient for SDP-constraint %d which does not exist!\n", b);
807  SCIPABORT();
808  }
809  if ( v < 0 || v >= data->nvars )
810  {
811  SCIPerrorMessage("Given SDP-coefficient for variable %d which does not exist!\n", v);
812  SCIPABORT();
813  }
814  if ( row < 0 || row >= data->sdpblocksizes[b] )
815  {
816  SCIPerrorMessage("Row index %d of given SDP coefficient is negative or larger than blocksize %d!\n",
817  row, data->sdpblocksizes[b]);
818  SCIPABORT();
819  }
820  if ( col < 0 || col >= data->sdpblocksizes[b] )
821  {
822  SCIPerrorMessage("Column index %d of given SDP coefficient is negative or larger than blocksize %d!\n",
823  col, data->sdpblocksizes[b]);
824  SCIPABORT();
825  }
826  if ( SCIPisZero(scip, val) )
827  {
828  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Ignored SDP-coefficient of SDP-constraint %d, variable "
829  "%d, row %d, col %d; value %.9f is smaller than epsilon = %f.\n", b, v, row, col, val, SCIPepsilon(scip));
830  }
831  else
832  {
833  sdpvar[b][data->sdpnblocknonz[b]] = v;
834  data->sdprow[b][data->sdpnblocknonz[b]] = row;
835  data->sdpcol[b][data->sdpnblocknonz[b]] = col;
836  data->sdpval[b][data->sdpnblocknonz[b]] = val;
837  data->sdpnblocknonz[b]++;
838  }
839  }
840  else
841  return SCIP_READERROR;
842  }
843 
844  /* construct pointer arrays */
845  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpnblockvars), data->nsdpblocks) );
846  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpblockvars), data->nsdpblocks) );
847  SCIP_CALL( SCIPallocBufferArray(scip, &(data->nvarnonz), data->nsdpblocks) );
848  SCIP_CALL( SCIPallocBufferArray(scip, &(data->rowpointer), data->nsdpblocks) );
849  SCIP_CALL( SCIPallocBufferArray(scip, &(data->colpointer), data->nsdpblocks) );
850  SCIP_CALL( SCIPallocBufferArray(scip, &(data->valpointer), data->nsdpblocks) );
851  for (b = 0; b < data->nsdpblocks; b++)
852  {
853  /* sort the nonzeroes by non-decreasing variable indices */
854  SCIPsortIntIntIntReal(sdpvar[b], data->sdprow[b], data->sdpcol[b], data->sdpval[b], data->sdpnblocknonz[b]);
855 
856  /* create the pointer arrays and insert used variables into vars-array */
857  nextindaftervar = 0;
858  data->sdpnblockvars[b] = 0;
859  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpblockvars[b]), data->nvars) );
860  SCIP_CALL( SCIPallocBufferArray(scip, &(data->nvarnonz[b]), data->nvars) );
861  SCIP_CALL( SCIPallocBufferArray(scip, &(data->rowpointer[b]), data->nvars) );
862  SCIP_CALL( SCIPallocBufferArray(scip, &(data->colpointer[b]), data->nvars) );
863  SCIP_CALL( SCIPallocBufferArray(scip, &(data->valpointer[b]), data->nvars) );
864 
865  for (v = 0; v < data->nvars; v++)
866  {
867  varused = FALSE;
868  firstindforvar = nextindaftervar; /* this variable starts where the last one ended */
869  data->nvarnonz[b][data->sdpnblockvars[b]] = 0;
870  while (nextindaftervar < data->sdpnblocknonz[b] && sdpvar[b][nextindaftervar] == v) /* get the first index that doesn't belong to this variable */
871  {
872  nextindaftervar++;
873  varused = TRUE;
874  data->nvarnonz[b][data->sdpnblockvars[b]]++;
875  }
876  if (varused)
877  {
878  data->sdpblockvars[b][data->sdpnblockvars[b]] = data->createdvars[v];/*lint !e732*//*lint !e747*/ /* if the variable is used, add it to the vars array */
879  data->rowpointer[b][data->sdpnblockvars[b]] = &(data->sdprow[b][firstindforvar]); /* save a pointer to the first nonzero belonging to this variable */
880  data->colpointer[b][data->sdpnblockvars[b]] = &(data->sdpcol[b][firstindforvar]);
881  data->valpointer[b][data->sdpnblockvars[b]] = &(data->sdpval[b][firstindforvar]);
882  data->sdpnblockvars[b]++;
883  }
884  }
885 
886  assert (nextindaftervar == data->sdpnblocknonz[b]);
887 #ifdef SCIP_DISABLED_CODE
888  /* resize arrays and free sdpvar array which is no longer needed */
889  SCIP_CALL( SCIPreallocBufferArray(scip, &(data->rowpointer[b]), data->sdpnblocknonz[b]) );
890  SCIP_CALL( SCIPreallocBufferArray(scip, &(data->colpointer[b]), data->sdpnblocknonz[b]) );
891  SCIP_CALL( SCIPreallocBufferArray(scip, &(data->valpointer[b]), data->sdpnblocknonz[b]) );
892 #endif
893  SCIPfreeBufferArray(scip, &(sdpvar[b]));
894  }
895 
896  /* free SDP-var array which is no longer needed */
897  SCIPfreeBufferArray(scip, &sdpvar);
898  }
899  else
900  {
901  SCIPerrorMessage("Number of nonzero coefficients of SDP-constraints %d should be non-negative!\n", nnonz);
902  SCIPABORT();
903  }
904  }
905  else
906  return SCIP_READERROR;
907 
908  return SCIP_OKAY;
909 }
910 
912 static
913 SCIP_RETCODE CBFreadDcoord(
914  SCIP* scip, /* SCIP data structure */
915  SCIP_FILE* pfile, /* file to read from */
916  long long int * linecount, /* current linecount */
917  CBF_DATA* data /* data pointer to save the results in */
918  )
919 {
920  int constnnonz;
921  int b;
922  int i;
923  int row;
924  int col;
925  SCIP_Real val;
926 
927  assert( scip != NULL );
928  assert( pfile != NULL );
929  assert( linecount != NULL );
930  assert( data != NULL );
931 
932  /* initialize sdpconstnblocknonz with 0 */
933  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpconstnblocknonz), data->nsdpblocks) );
934  for (b = 0; b < data->nsdpblocks; b++)
935  data->sdpconstnblocknonz[b] = 0;
936 
937  SCIP_CALL( CBFfgets(pfile, linecount) );
938 
939  if ( sscanf(CBF_LINE_BUFFER, "%i", &constnnonz) == 1 )
940  {
941  if ( constnnonz >= 0 )
942  {
943  /* allocate memory (constnnonz for each block, since we do not yet no the distribution) */
944  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpconstrow), data->nsdpblocks) );
945  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpconstcol), data->nsdpblocks) );
946  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpconstval), data->nsdpblocks) );
947  for (b = 0; b < data->nsdpblocks; b++)
948  {
949  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpconstrow[b]), constnnonz) );
950  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpconstcol[b]), constnnonz) );
951  SCIP_CALL( SCIPallocBufferArray(scip, &(data->sdpconstval[b]), constnnonz) );
952  }
953 
954  for (i = 0; i < constnnonz; i++)
955  {
956  SCIP_CALL( CBFfgets(pfile, linecount) );
957  if ( sscanf(CBF_LINE_BUFFER, "%i %i %i %lf", &b, &row, &col, &val) == 4 )
958  {
959  if ( b < 0 || b >= data->nsdpblocks )
960  {
961  SCIPerrorMessage("Given constant entry for SDP-constraint %d which does not exist!\n", b);
962  SCIPABORT();
963  }
964  if ( row < 0 || row >= data->sdpblocksizes[b] )
965  {
966  SCIPerrorMessage("Row index %d of given constant SDP-entry is negative or larger than blocksize %d!\n",
967  row, data->sdpblocksizes[b]);
968  SCIPABORT();
969  }
970  if ( col < 0 || col >= data->sdpblocksizes[b] )
971  {
972  SCIPerrorMessage("Column index %d of given constant SDP-entry is negative or larger than blocksize %d!\n",
973  col, data->sdpblocksizes[b]);
974  SCIPABORT();
975  }
976  if ( SCIPisZero(scip, val) )
977  {
978  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Ignored constant entry of SDP-constraint %d, row %d,"
979  " col %d; value %.9f is smaller than epsilon = %f.\n", b, row, col, val, SCIPepsilon(scip));
980  }
981  else
982  {
983  data->sdpconstrow[b][data->sdpconstnblocknonz[b]] = row;
984  data->sdpconstcol[b][data->sdpconstnblocknonz[b]] = col;
985  data->sdpconstval[b][data->sdpconstnblocknonz[b]] = -val;
986  data->sdpconstnblocknonz[b]++;
987  }
988  }
989  else
990  return SCIP_READERROR;
991  }
992 #ifdef SCIP_DISABLED_CODE
993  for (b = 0; b < data->nsdpblocks; b++)
994  {
995  /* resize arrays */
996  SCIP_CALL( SCIPreallocBufferArray(scip, &(data->sdpconstrow[b]), data->sdpconstnblocknonz[b]) );
997  SCIP_CALL( SCIPreallocBufferArray(scip, &(data->sdpconstcol[b]), data->sdpconstnblocknonz[b]) );
998  SCIP_CALL( SCIPreallocBufferArray(scip, &(data->sdpconstval[b]), data->sdpconstnblocknonz[b]) );
999  }
1000 #endif
1001  }
1002  else
1003  {
1004  SCIPerrorMessage("Number of constant entries of SDP-constraints %d should be non-negative!\n", constnnonz);
1005  SCIPABORT();
1006  }
1007  }
1008  else
1009  return SCIP_READERROR;
1010 
1011  return SCIP_OKAY;
1012 }
1013 
1015 static
1016 SCIP_RETCODE CBFfreeData(
1017  SCIP* scip, /* SCIP data structure */
1018  CBF_DATA* data /* data pointer to save the results in */
1019  )
1020 {
1021  int b;
1022 
1023  assert( scip != NULL );
1024  assert( data != NULL );
1025 
1026  for (b = 0; b < data->nsdpblocks; b++)
1027  {
1028  SCIPfreeBufferArrayNull(scip, &(data->sdpconstval[b]));
1029  SCIPfreeBufferArrayNull(scip, &(data->sdpconstcol[b]));
1030  SCIPfreeBufferArrayNull(scip, &(data->sdpconstrow[b]));
1031  SCIPfreeBufferArrayNull(scip, &(data->valpointer[b]));
1032  SCIPfreeBufferArrayNull(scip, &(data->colpointer[b]));
1033  SCIPfreeBufferArrayNull(scip, &(data->rowpointer[b]));
1034  SCIPfreeBufferArrayNull(scip, &(data->sdpval[b]));
1035  SCIPfreeBufferArrayNull(scip, &(data->sdpcol[b]));
1036  SCIPfreeBufferArrayNull(scip, &(data->sdprow[b]));
1037  SCIPfreeBufferArrayNull(scip, &(data->sdpblockvars[b]));
1038  SCIPfreeBufferArrayNull(scip, &(data->nvarnonz[b]));
1039  }
1040  SCIPfreeBufferArrayNull(scip, &data->sdpconstval);
1041  SCIPfreeBufferArrayNull(scip, &data->sdpconstcol);
1042  SCIPfreeBufferArrayNull(scip, &data->sdpconstrow);
1043  SCIPfreeBufferArrayNull(scip, &data->sdpconstnblocknonz);
1044  SCIPfreeBufferArrayNull(scip, &data->valpointer);
1045  SCIPfreeBufferArrayNull(scip, &data->colpointer);
1046  SCIPfreeBufferArrayNull(scip, &data->rowpointer);
1047  SCIPfreeBufferArrayNull(scip, &data->sdpval);
1048  SCIPfreeBufferArrayNull(scip, &data->sdpcol);
1049  SCIPfreeBufferArrayNull(scip, &data->sdprow);
1050  SCIPfreeBufferArrayNull(scip, &data->sdpblockvars);
1051  SCIPfreeBufferArrayNull(scip, &data->nvarnonz);
1052  SCIPfreeBufferArrayNull(scip, &data->sdpnblockvars);
1053  SCIPfreeBufferArrayNull(scip, &data->sdpnblocknonz);
1054  SCIPfreeBufferArrayNull(scip, &data->sdpblocksizes);
1055  SCIPfreeBufferArrayNull(scip, &data->createdconss);
1056  SCIPfreeBufferArrayNull(scip, &data->createdvars);
1057 
1058  return SCIP_OKAY;
1059 }
1060 
1061 
1062 /*
1063  * Callback methods of reader
1064  */
1065 
1066 
1068 static
1069 SCIP_DECL_READERCOPY(readerCopyCbf)
1070 { /*lint --e{715,818}*/
1071  assert(scip != NULL);
1072 
1073  SCIP_CALL( SCIPincludeReaderCbf(scip) );
1074 
1075  return SCIP_OKAY;
1076 }
1077 
1079 static
1080 SCIP_DECL_READERREAD(readerReadCbf)
1081 { /*lint --e{715,818}*/
1082  SCIP_FILE* scipfile;
1083  long long int linecount;
1084  SCIP_Bool versionread;
1085  SCIP_Bool objread;
1086  CBF_DATA* data;
1087  int b;
1088 
1089  *result = SCIP_DIDNOTRUN;
1090  linecount = 0;
1091  versionread = FALSE;
1092  objread = FALSE;
1093 
1094  SCIPdebugMsg(scip, "Reading file %s\n", filename);
1095 
1096  scipfile = SCIPfopen(filename, "r");
1097 
1098  if ( ! scipfile )
1099  return SCIP_READERROR;
1100 
1101  SCIP_CALL( SCIPallocBuffer(scip, &data) );
1102  data->nsdpblocks = 0;
1103 
1104  /* create empty problem */
1105  SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
1106 
1107  while( CBFfgets(scipfile, &linecount) == SCIP_OKAY )
1108  {
1109  /* Parse keyword on non-empty lines */
1110  if ( sscanf(CBF_LINE_BUFFER, CBF_NAME_FORMAT, CBF_NAME_BUFFER) == 1 )
1111  {
1112  /* first line should be version number */
1113  if ( ! versionread )
1114  {
1115  if (strcmp(CBF_NAME_BUFFER, "VER") == 0)
1116  {
1117  int ver;
1118 
1119  SCIP_CALL( CBFfgets(scipfile, &linecount) );
1120 
1121  if ( sscanf(CBF_LINE_BUFFER, "%i", &ver) == 1 )
1122  {
1123  SCIPdebugMsg(scip, "file version %d\n", ver);
1124  if ( ver != CBF_VERSION_NR )
1125  {
1126  SCIPerrorMessage("Only version number %d is supported!\n", CBF_VERSION_NR);
1127  SCIPABORT();
1128  }
1129  else
1130  versionread = TRUE;
1131  }
1132  else
1133  return SCIP_READERROR;
1134  }
1135  else
1136  {
1137  SCIPerrorMessage("First keyword should be VER.\n");
1138  SCIPABORT();
1139  }
1140  }
1141  else
1142  {
1143  if ( strcmp(CBF_NAME_BUFFER, "OBJSENSE") == 0 )
1144  {
1145  SCIPdebugMsg(scip, "Reading OBJSENSE\n");
1146  SCIP_CALL( CBFreadObjsense(scip, scipfile, &linecount) );
1147  objread = TRUE;
1148  }
1149  else if (strcmp(CBF_NAME_BUFFER, "VAR") == 0)
1150  {
1151  SCIPdebugMsg(scip, "Reading VAR\n");
1152  SCIP_CALL( CBFreadVar(scip, scipfile, &linecount, data) );
1153  }
1154  else if (strcmp(CBF_NAME_BUFFER, "CON") == 0)
1155  {
1156  SCIPdebugMsg(scip, "Reading CON\n");
1157  SCIP_CALL( CBFreadCon(scip, scipfile, &linecount, data) );
1158  }
1159  else if (strcmp(CBF_NAME_BUFFER, "INT") == 0)
1160  {
1161  SCIPdebugMsg(scip, "Reading INT\n");
1162  SCIP_CALL( CBFreadInt(scip, scipfile, &linecount, data) );
1163  }
1164  else if (strcmp(CBF_NAME_BUFFER, "PSDCON") == 0)
1165  {
1166  SCIPdebugMsg(scip, "Reading PSDCON\n");
1167  SCIP_CALL( CBFreadPsdcon(scip, scipfile, &linecount, data) );
1168  }
1169  else if (strcmp(CBF_NAME_BUFFER, "PSDVAR") == 0)
1170  {
1171  /* TODO: automatically transform to dual form by introducing a new variable for all elements in the upper
1172  * triangular part and an SDP-constraint enforcing positive semidefiniteness of the PSD-variable
1173  */
1174  SCIPerrorMessage("SDPs in primal form currently not supported, please use PSDCON!\n");
1175  SCIPABORT();
1176  }
1177  else if (strcmp(CBF_NAME_BUFFER, "OBJFCOORD") == 0)
1178  {
1179  SCIPerrorMessage("SDPs in primal form currently not supported, please use PSDCON!\n");
1180  SCIPABORT();
1181  }
1182  else if (strcmp(CBF_NAME_BUFFER, "OBJACOORD") == 0)
1183  {
1184  SCIPdebugMsg(scip, "Reading OBJACOORD\n");
1185  SCIP_CALL( CBFreadObjacoord(scip, scipfile, &linecount, data) );
1186  }
1187  else if (strcmp(CBF_NAME_BUFFER, "OBJBCOORD") == 0)
1188  {
1189  SCIPerrorMessage("constant part in objective value not supported by SCIP!\n");
1190  SCIPABORT();
1191  }
1192  else if (strcmp(CBF_NAME_BUFFER, "FCOORD") == 0)
1193  {
1194  SCIPerrorMessage("SDPs in primal form currently not supported, please use PSDCON!\n");
1195  SCIPABORT();
1196  }
1197  else if (strcmp(CBF_NAME_BUFFER, "ACOORD") == 0)
1198  {
1199  SCIPdebugMsg(scip, "Reading ACOORD\n");
1200  SCIP_CALL( CBFreadAcoord(scip, scipfile, &linecount, data) );
1201  }
1202  else if (strcmp(CBF_NAME_BUFFER, "BCOORD") == 0)
1203  {
1204  SCIPdebugMsg(scip, "Reading BCOORD\n");
1205  SCIP_CALL( CBFreadBcoord(scip, scipfile, &linecount, data) );
1206  }
1207  else if (strcmp(CBF_NAME_BUFFER, "HCOORD") == 0)
1208  {
1209  SCIPdebugMsg(scip, "Reading HCOORD\n");
1210  SCIP_CALL( CBFreadHcoord(scip, scipfile, &linecount, data) );
1211  }
1212  else if (strcmp(CBF_NAME_BUFFER, "DCOORD") == 0)
1213  {
1214  SCIPdebugMsg(scip, "Reading DCOORD\n");
1215  SCIP_CALL( CBFreadDcoord(scip, scipfile, &linecount, data) );
1216  }
1217  else
1218  {
1219  SCIPerrorMessage("Keyword %s not recognized!\n", CBF_NAME_BUFFER);
1220  SCIPABORT();
1221  }
1222  }
1223  }
1224  }
1225 
1226  if ( !objread )
1227  {
1228  SCIPerrorMessage("Keyword OBJSENSE is missing!\n");
1229  SCIPABORT();
1230  }
1231 
1232  /* close the file (and make sure SCIPfclose returns 0) */
1233  if ( SCIPfclose(scipfile) )
1234  return SCIP_READERROR;
1235 
1236 #ifdef SCIP_MORE_DEBUG
1237  for (b = 0; b < SCIPgetNConss(scip); b++)
1238  {
1239  SCIP_CALL( SCIPprintCons(scip, SCIPgetConss(scip)[b], NULL) );
1240  }
1241 #endif
1242 
1243  /* create SDP-constraints */
1244  for (b = 0; b < data->nsdpblocks; b++)
1245  {
1246  SCIP_CONS* sdpcons;
1247  char sdpconname[SCIP_MAXSTRLEN];
1248 #ifndef NDEBUG
1249  int snprintfreturn;
1250 #endif
1251 
1252  assert( data->sdpblocksizes[b] > 0 );
1253  assert( ((data->sdpnblockvars[b] > 0) && data->sdpnblocknonz[b] > 0) || (data->sdpconstnblocknonz[b] > 0) );
1254 
1255 #ifndef NDEBUG
1256  snprintfreturn = SCIPsnprintf(sdpconname, SCIP_MAXSTRLEN, "SDP_%d", b);
1257  assert( snprintfreturn < SCIP_MAXSTRLEN);
1258 #else
1259  (void) SCIPsnprintf(sdpconname, SCIP_MAXSTRLEN, "SDP_%d", b);
1260 #endif
1261  SCIP_CALL( SCIPcreateConsSdp(scip, &sdpcons, sdpconname, data->sdpnblockvars[b], data->sdpnblocknonz[b],
1262  data->sdpblocksizes[b], data->nvarnonz[b], data->colpointer[b], data->rowpointer[b], data->valpointer[b],
1263  data->sdpblockvars[b], data->sdpconstnblocknonz[b], data->sdpconstcol[b], data->sdpconstrow[b],
1264  data->sdpconstval[b]) );
1265 
1266 #ifdef SCIP_MORE_DEBUG
1267 SCIP_CALL( SCIPprintCons(scip, sdpcons, NULL) );
1268 #endif
1269 
1270  SCIP_CALL( SCIPaddCons(scip, sdpcons) );
1271 
1272  SCIP_CALL( SCIPreleaseCons(scip, &sdpcons) );
1273  }
1274 
1275  SCIP_CALL( CBFfreeData(scip, data) );
1276  SCIPfreeBufferNull(scip, &data);
1277 
1278  *result = SCIP_SUCCESS;
1279 
1280  return SCIP_OKAY;
1281 }
1282 
1283 
1285 static
1286 SCIP_DECL_READERWRITE(readerWriteCbf)
1287 { /*lint --e{715,818}*/
1288  SdpVarmapper* varmapper;
1289  SCIP_VAR** linvars;
1290  SCIP_Real* linvals;
1291  SCIP_VAR** sdpvars;
1292  int nsdpconss;
1293  int sdpnvars;
1294  int sdpnnonz;
1295  int totalsdpnnonz;
1296  int sdpblocksize;
1297  int sdparraylength;
1298  int* sdpnvarnonz;
1299  int** sdpcol;
1300  int** sdprow;
1301  SCIP_Real** sdpval;
1302  int totalsdpconstnnonz;
1303  int sdpconstnnonz;
1304  int* sdpconstcol;
1305  int* sdpconstrow;
1306  SCIP_Real* sdpconstval;
1307  int c;
1308  int i;
1309  int v;
1310  int consind;
1311  int neqconss;
1312  int nleqconss;
1313  int ngeqconss;
1314  int nobjnonz;
1315  int nnonz;
1316  int nbnonz;
1317 #ifdef CBF_CHECK_NONNEG
1318  SCIP_Bool* consdisabled;
1319  int nposorth;
1320  SCIP_Bool* posorth;
1321  int nnegorth;
1322  SCIP_Bool* negorth;
1323 #endif
1324 
1325  assert( scip != NULL );
1326 
1327  SCIPdebugMsg(scip, "Writing problem in CBF format to %s\n", file);
1328  *result = SCIP_DIDNOTRUN;
1329 
1330  if ( transformed )
1331  {
1332  SCIPerrorMessage("CBF reader currently only supports writing original problems!\n");
1333  SCIPABORT(); /*lint --e{527}*/
1334  }
1335 
1336  for (c = 0; c < nconss; c++)
1337  {
1338  if ( (strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0)
1339  && (strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") != 0 ) )
1340  {
1341  SCIPerrorMessage("CBF reader currently only supports linear and SDP constraints!\n");
1342  SCIPABORT(); /*lint --e{527}*/
1343  }
1344  }
1345 
1346 #ifndef NDEBUG
1347  for (v = 0; v < nvars; v++)
1348  {
1349  assert( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_ORIGINAL );
1350  }
1351 #endif
1352 
1353  /* write version number */
1354  SCIPinfoMessage(scip, file, "VER\n%d\n\n", CBF_VERSION_NR);
1355 
1356  /* write objective sense */
1357  SCIPinfoMessage(scip, file, "OBJSENSE\n%s\n\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "MIN" : "MAX");
1358 
1359 #ifdef CBF_CHECK_NONNEG
1360  /* check for constraints with only a single non-zero and lhs/rhs zero, in that case disable the constraint
1361  * and force variable to be in positive or negative orthant
1362  */
1363  SCIP_CALL( SCIPallocBufferArray(scip, &consdisabled, nconss) );
1364  SCIP_CALL( SCIPallocBufferArray(scip, &posorth, nvars) );
1365  SCIP_CALL( SCIPallocBufferArray(scip, &negorth, nvars) );
1366 
1367  for (v = 0; v < nvars; v++)
1368  {
1369  posorth[v] = FALSE;
1370  negorth[v] = FALSE;
1371  }
1372  nposorth = 0;
1373  nnegorth = 0;
1374 
1375  for (c = 0; c < nconss; c++)
1376  {
1377  consdisabled[c] = 0;
1378 
1379  /* only check linear constraints */
1380  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1381  continue;
1382 
1383  /* only check constraints with exactly one nonzero */
1384  if ( SCIPgetNVarsLinear(scip, conss[c]) != 1 )
1385  continue;
1386 
1387  /* the nonzero should be a true nonzero */
1388  assert( ! SCIPisZero(scip, SCIPgetValsLinear(scip, conss[c])[0]) );
1389 
1390  /* the variable should not be fixed */
1391  assert( SCIPisLT(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c])) );
1392 
1393  if ( SCIPgetValsLinear(scip, conss[c])[0] > 0.0 )
1394  {
1395  if ( SCIPisZero(scip, SCIPgetLhsLinear(scip, conss[c])) )
1396  {
1397  consdisabled[c] = 1;
1398  posorth[v] = TRUE;
1399  nposorth++;
1400 
1401  if ( ! SCIPisInfinity(scip, SCIPgetRhsLinear(scip, conss[c])) )
1402  {
1403  SCIPerrorMessage("Detection of non-negativity constraints currently not supported for ranged rows!\n");
1404  SCIPABORT(); /*lint --e{527}*/
1405  }
1406  }
1407  else if ( SCIPisZero(scip, SCIPgetRhsLinear(scip, conss[c])) )
1408  {
1409  consdisabled[c] = 1;
1410  negorth[v] = TRUE;
1411  nnegorth++;
1412  }
1413  }
1414  else
1415  {
1416  if ( SCIPisZero(scip, SCIPgetLhsLinear(scip, conss[c])) )
1417  {
1418  consdisabled[c] = 1;
1419  negorth[v] = TRUE;
1420  nnegorth++;
1421  }
1422  else if ( SCIPisZero(scip, SCIPgetRhsLinear(scip, conss[c])) )
1423  {
1424  consdisabled[c] = 1;
1425  posorth[v] = TRUE;
1426  nposorth++;
1427  }
1428  }
1429  }
1430 
1431  assert( (0 <= nposorth) && (0 <= nnegorth) && (nposorth + nnegorth <= nvars) );
1432 
1433  /* prepare varmapper that maps SCIP variables to indices for CBF format (3/4 is the load factor java uses) */
1434  SCIP_CALL( SCIPsdpVarmapperCreate(scip, &(varmapper), (int) ceil(1.33 * nvars)) );
1435  /* in this case we first need to add all variables in the positive orthant, then all in the negative orthant
1436  * and finally the free variables, since they will be input and counted in CBF this way
1437  */
1438  for (v = 0; v < nvars; v++)
1439  {
1440  if ( posorth[v] )
1441  {
1442  SCIP_CALL( SCIPsdpVarmapperAddVars(scip, varmapper, 1, &(vars[v])) );
1443  }
1444  }
1445  for (v = 0; v < nvars; v++)
1446  {
1447  if ( negorth[v] )
1448  {
1449  SCIP_CALL( SCIPsdpVarmapperAddVars(scip, varmapper, 1, &(vars[v])) );
1450  }
1451  }
1452  for (v = 0; v < nvars; v++)
1453  {
1454  if ( ( ! posorth[v] ) && ( ! negorth[v] ) )
1455  {
1456  SCIP_CALL( SCIPsdpVarmapperAddVars(scip, varmapper, 1, &(vars[v])) );
1457  }
1458  }
1459 
1460  /* write variables */
1461  if ( (nposorth == 0) && (nnegorth == 0) )
1462  SCIPinfoMessage(scip, file, "VAR\n%d 1\nF %d\n\n", nvars, nvars);
1463  else if ( (nposorth > 0) && (nnegorth == 0) && (nposorth < nvars) )
1464  SCIPinfoMessage(scip, file, "VAR\n%d 2\nL+ %d\nF %d\n\n", nvars, nposorth, nvars - nposorth);
1465  else if ( (nposorth == 0) && (nnegorth > 0) && (nnegorth < nvars) )
1466  SCIPinfoMessage(scip, file, "VAR\n%d 2\nL- %d\nF %d\n\n", nvars, nposorth, nvars - nnegorth);
1467  else if ( nposorth + nnegorth < nvars )
1468  SCIPinfoMessage(scip, file, "VAR\n%d 3\nL+ %d\nL- %d\nF %d\n\n", nvars, nposorth, nnegorth, nvars - nposorth - nnegorth);/*lint !e834*/
1469  else if ( (nposorth > 0) && (nnegorth == 0) )
1470  SCIPinfoMessage(scip, file, "VAR\n%d 1\nL+ %d\n\n", nvars, nposorth);
1471  else if ( (nposorth == 0) && (nnegorth > 0) )
1472  SCIPinfoMessage(scip, file, "VAR\n%d 1\nL- %d\n\n", nvars, nnegorth);
1473  else
1474  SCIPinfoMessage(scip, file, "VAR\n%d 2\nL+ %d\nL- %d\n\n", nvars, nposorth, nnegorth);
1475 
1476 #else
1477  /* prepare varmapper that maps SCIP variables to indices for CBF format (3/4 is the load factor java uses) */
1478  SCIP_CALL( SCIPsdpVarmapperCreate(scip, &(varmapper), (int) ceil(1.33 * nvars)) );
1479  SCIP_CALL( SCIPsdpVarmapperAddVars(scip, varmapper, nvars, vars) );
1480 
1481  /* write variables */
1482  SCIPinfoMessage(scip, file, "VAR\n%d 1\nF %d\n\n", nvars, nvars);
1483 #endif
1484 
1485  /* write integrality constraints */
1486  if ( nbinvars + nintvars > 0 )
1487  {
1488  SCIPinfoMessage(scip, file, "INT\n%d\n", nbinvars + nintvars);
1489 
1490  for (v = 0; v < nbinvars + nintvars; v++)
1491  {
1492  assert( SCIPvarIsIntegral(vars[v]) );
1493  SCIPinfoMessage(scip, file, "%d\n", SCIPsdpVarmapperGetSdpIndex(varmapper, vars[v]));
1494  }
1495 
1496  SCIPinfoMessage(scip, file, "\n");
1497  }
1498 
1499  /* count number of equality/geq/leq constraints */
1500  neqconss = 0;
1501  ngeqconss = 0;
1502  nleqconss = 0;
1503  for (c = 0; c < nconss; c++)
1504  {
1505  /* only count linear constraints */
1506  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1507  continue;
1508 
1509 #ifdef CBF_CHECK_NONNEG
1510  if ( consdisabled[c] )
1511  continue;
1512 #endif
1513 
1514  if ( ( ! SCIPisInfinity(scip, -1 * SCIPgetLhsLinear(scip, conss[c]))) &&
1515  ( ! SCIPisInfinity(scip, SCIPgetRhsLinear(scip, conss[c])) ) &&
1516  SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c])) )
1517  neqconss++;
1518  else
1519  {
1520  if ( ! SCIPisInfinity(scip, -1 * SCIPgetLhsLinear(scip, conss[c])) )
1521  ngeqconss++;
1522  if ( ! SCIPisInfinity(scip, SCIPgetRhsLinear(scip, conss[c])) )
1523  nleqconss++;
1524  }
1525  }
1526 
1527  /* write constraints */
1528  if ( neqconss + ngeqconss + nleqconss > 0 )
1529  {
1530  if ( ((neqconss > 0) && (ngeqconss == 0) && (nleqconss == 0))
1531  || ((neqconss == 0) && (ngeqconss > 0) && (nleqconss == 0))
1532  || ((neqconss == 0) && (ngeqconss == 0) && (nleqconss > 0)) )
1533  SCIPinfoMessage(scip, file, "CON\n%d 1\n", neqconss + ngeqconss + nleqconss);
1534  else if ( ((neqconss > 0) && (ngeqconss > 0) && (nleqconss == 0))
1535  || ((neqconss > 0) && (ngeqconss == 0) && (nleqconss > 0))
1536  || ((neqconss == 0) && (ngeqconss > 0) && (nleqconss > 0)) )
1537  SCIPinfoMessage(scip, file, "CON\n%d 2\n", neqconss + ngeqconss + nleqconss);
1538  else
1539  {
1540  assert( (neqconss > 0) && (ngeqconss > 0) && (nleqconss > 0) );
1541  SCIPinfoMessage(scip, file, "CON\n%d 3\n", neqconss + ngeqconss + nleqconss);
1542  }
1543 
1544  if ( ngeqconss > 0 )
1545  SCIPinfoMessage(scip, file, "L+ %d", ngeqconss);
1546  if ( nleqconss > 0 )
1547  SCIPinfoMessage(scip, file, "L- %d", nleqconss);
1548  if ( neqconss > 0 )
1549  SCIPinfoMessage(scip, file, "L= %d", neqconss);
1550 
1551  SCIPinfoMessage(scip, file, "\n\n");
1552  }
1553 
1554  /* count number of SDP constraints (conshdlrGetNConss doesn't seem to work before transformation) */
1555  nsdpconss = 0;
1556  for (c = 0; c < nconss; c++)
1557  {
1558  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") == 0 )
1559  nsdpconss++;
1560  }
1561 
1562  /* write SDP constraints */
1563  SCIPinfoMessage(scip, file, "PSDCON\n%d\n", nsdpconss);
1564 
1565  for (c = 0; c < nconss; c++)
1566  {
1567  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") != 0 )
1568  continue;
1569 
1570  SCIPinfoMessage(scip, file, "%d\n", SCIPconsSdpGetBlocksize(scip, conss[c]));
1571  }
1572 
1573  SCIPinfoMessage(scip, file, "\n");
1574 
1575  /* count number of nonzero objective coefficients */
1576  nobjnonz = 0;
1577  for (v = 0; v < nvars; v++)
1578  {
1579  if ( ! SCIPisZero(scip, SCIPvarGetObj(vars[v])) )
1580  nobjnonz++;
1581  }
1582 
1583  /* write objective */
1584  SCIPinfoMessage(scip, file, "OBJACOORD\n%d\n", nobjnonz);
1585 
1586  for (v = 0; v < nvars; v++)
1587  {
1588  if ( ! SCIPisZero(scip, SCIPvarGetObj(vars[v])) )
1589  {
1590  SCIPinfoMessage(scip, file, "%d %.9f\n", SCIPsdpVarmapperGetSdpIndex(varmapper, vars[v]), SCIPvarGetObj(vars[v]));
1591  }
1592  }
1593 
1594  SCIPinfoMessage(scip, file, "\n");
1595 
1596  if ( neqconss + ngeqconss + nleqconss > 0 )
1597  {
1598  /* count number of nonzero coefficients in linear constraints */
1599  nnonz = 0;
1600  nbnonz = 0;
1601 
1602  /* first iterate over all greater or equal constraints */
1603  for (c = 0; c < nconss; c++)
1604  {
1605  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1606  continue;
1607 
1608  if ( SCIPisInfinity(scip, -1 * SCIPgetLhsLinear(scip, conss[c]))
1609  || SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c])) )
1610  continue;
1611 #ifdef CBF_CHECK_NONNEG
1612  if ( consdisabled[c] )
1613  continue;
1614 #endif
1615 
1616  nnonz += SCIPgetNVarsLinear(scip, conss[c]);
1617  nbnonz += ( ! SCIPisZero(scip, SCIPgetLhsLinear(scip, conss[c])));
1618  }
1619  /* iterate over all less or equal constraints */
1620  for (c = 0; c < nconss; c++)
1621  {
1622  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1623  continue;
1624 
1625  if ( SCIPisInfinity(scip, SCIPgetRhsLinear(scip, conss[c]))
1626  || SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c])) )
1627  continue;
1628 #ifdef CBF_CHECK_NONNEG
1629  if ( consdisabled[c] )
1630  continue;
1631 #endif
1632 
1633  nnonz += SCIPgetNVarsLinear(scip, conss[c]);
1634  nbnonz += ( ! SCIPisZero(scip, SCIPgetRhsLinear(scip, conss[c])));
1635  }
1636  /* finally iterate over all equality constraints */
1637  for (c = 0; c < nconss; c++)
1638  {
1639  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1640  continue;
1641 
1642  if ( SCIPisInfinity(scip, -1 * SCIPgetLhsLinear(scip, conss[c]))
1643  || SCIPisInfinity(scip, SCIPgetRhsLinear(scip, conss[c]))
1644  || ( ! SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c]))) )
1645  continue;
1646 #ifdef CBF_CHECK_NONNEG
1647  if ( consdisabled[c] )
1648  continue;
1649 #endif
1650 
1651  nnonz += SCIPgetNVarsLinear(scip, conss[c]);
1652  nbnonz += ( ! SCIPisZero(scip, SCIPgetLhsLinear(scip, conss[c])));
1653  }
1654 
1655  /* write linear nonzero coefficients */
1656  SCIPinfoMessage(scip, file, "ACOORD\n%d\n", nnonz);
1657  consind = 0;
1658 
1659  /* first iterate over all greater or equal constraints */
1660  for (c = 0; c < nconss; c++)
1661  {
1662  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1663  continue;
1664 
1665  if ( SCIPisInfinity(scip, -1 * SCIPgetLhsLinear(scip, conss[c]))
1666  || SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c])) )
1667  continue;
1668 #ifdef CBF_CHECK_NONNEG
1669  if ( consdisabled[c] )
1670  continue;
1671 #endif
1672 
1673  linvars = SCIPgetVarsLinear(scip, conss[c]);
1674  linvals = SCIPgetValsLinear(scip, conss[c]);
1675 
1676  for (v = 0; v < SCIPgetNVarsLinear(scip, conss[c]); v++)
1677  {
1678  SCIPinfoMessage(scip, file, "%d %d %.9f\n", consind, SCIPsdpVarmapperGetSdpIndex(varmapper, linvars[v]), linvals[v]);
1679  }
1680  consind++;
1681  }
1682  /* iterate over all less or equal constraints */
1683  for (c = 0; c < nconss; c++)
1684  {
1685  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1686  continue;
1687 
1688  if ( SCIPisInfinity(scip, SCIPgetRhsLinear(scip, conss[c]))
1689  || SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c])) )
1690  continue;
1691 #ifdef CBF_CHECK_NONNEG
1692  if ( consdisabled[c] )
1693  continue;
1694 #endif
1695 
1696  linvars = SCIPgetVarsLinear(scip, conss[c]);
1697  linvals = SCIPgetValsLinear(scip, conss[c]);
1698 
1699  for (v = 0; v < SCIPgetNVarsLinear(scip, conss[c]); v++)
1700  {
1701  SCIPinfoMessage(scip, file, "%d %d %.9f\n", consind, SCIPsdpVarmapperGetSdpIndex(varmapper, linvars[v]), linvals[v]);
1702  }
1703  consind++;
1704  }
1705  /* finally iterate over all equality constraints */
1706  for (c = 0; c < nconss; c++)
1707  {
1708  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1709  continue;
1710 
1711  if ( SCIPisInfinity(scip, -1 * SCIPgetLhsLinear(scip, conss[c]))
1712  || SCIPisInfinity(scip, SCIPgetRhsLinear(scip, conss[c]))
1713  || ( ! SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c]))) )
1714  continue;
1715 #ifdef CBF_CHECK_NONNEG
1716  if ( consdisabled[c] )
1717  continue;
1718 #endif
1719 
1720  linvars = SCIPgetVarsLinear(scip, conss[c]);
1721  linvals = SCIPgetValsLinear(scip, conss[c]);
1722 
1723  for (v = 0; v < SCIPgetNVarsLinear(scip, conss[c]); v++)
1724  {
1725  SCIPinfoMessage(scip, file, "%d %d %.9f\n", consind, SCIPsdpVarmapperGetSdpIndex(varmapper, linvars[v]), linvals[v]);
1726  }
1727  consind++;
1728  }
1729 
1730  SCIPinfoMessage(scip, file, "\n");
1731 
1732  /* write constant part of linear constraints */
1733  SCIPinfoMessage(scip, file, "BCOORD\n%d\n", nbnonz);
1734  consind = 0;
1735 
1736  /* first iterate over all greater or equal constraints */
1737  for (c = 0; c < nconss; c++)
1738  {
1739  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1740  continue;
1741 
1742  if ( SCIPisInfinity(scip, -1 * SCIPgetLhsLinear(scip, conss[c]))
1743  || SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c])) )
1744  continue;
1745 #ifdef CBF_CHECK_NONNEG
1746  if ( consdisabled[c] )
1747  continue;
1748 #endif
1749 
1750  /* write the entry; *(-1) because we have Ax - lhs >= 0 */
1751  if ( ! SCIPisZero(scip, SCIPgetLhsLinear(scip, conss[c])) )
1752  {
1753  SCIPinfoMessage(scip, file, "%d %.9f\n", consind, -1 * SCIPgetLhsLinear(scip, conss[c]));
1754  }
1755  consind++; /* counting the constraint numbers is independent of whether the lhs is nonzero */
1756  }
1757  /* iterate over all less or equal constraints */
1758  for (c = 0; c < nconss; c++)
1759  {
1760  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1761  continue;
1762 
1763  if ( SCIPisInfinity(scip, SCIPgetRhsLinear(scip, conss[c]))
1764  || SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c])) )
1765  continue;
1766 #ifdef CBF_CHECK_NONNEG
1767  if ( consdisabled[c] )
1768  continue;
1769 #endif
1770 
1771  /* write the entry; *(-1) because we have Ax - rhs <= 0 */
1772  if ( ! SCIPisZero(scip, SCIPgetRhsLinear(scip, conss[c])) )
1773  {
1774  SCIPinfoMessage(scip, file, "%d %.9f\n", consind, -1 * SCIPgetRhsLinear(scip, conss[c]));
1775  }
1776  consind++; /* counting the constraint numbers is independent of whether the rhs is nonzero */
1777  }
1778  /* finally iterate over all equality constraints */
1779  for (c = 0; c < nconss; c++)
1780  {
1781  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "linear") != 0 )
1782  continue;
1783 
1784  if ( SCIPisInfinity(scip, -1 * SCIPgetLhsLinear(scip, conss[c]))
1785  || SCIPisInfinity(scip, SCIPgetRhsLinear(scip, conss[c]))
1786  || ( ! SCIPisEQ(scip, SCIPgetLhsLinear(scip, conss[c]), SCIPgetRhsLinear(scip, conss[c]))) )
1787  continue;
1788 #ifdef CBF_CHECK_NONNEG
1789  if ( consdisabled[c] )
1790  continue;
1791 #endif
1792 
1793  /* write the entry; *(-1) because we have Ax - lhs = 0 */
1794  if ( ! SCIPisZero(scip, SCIPgetLhsLinear(scip, conss[c])) )
1795  {
1796  SCIPinfoMessage(scip, file, "%d %.9f\n", consind, -1 * SCIPgetLhsLinear(scip, conss[c]));
1797  }
1798  consind++;/* counting the constraint numbers is independent of whether the lhs is nonzero */
1799  }
1800  SCIPinfoMessage(scip, file, "\n");
1801  }
1802 
1803  /*count SDP nonzeros */
1804  totalsdpnnonz = 0;
1805  totalsdpconstnnonz = 0;
1806  for (c = 0; c < nconss; c++)
1807  {
1808  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])),"SDP") != 0 )
1809  continue;
1810 
1811  SCIP_CALL( SCIPconsSdpGetNNonz(scip, conss[c], &sdpnnonz, &sdpconstnnonz) );
1812  totalsdpnnonz += sdpnnonz;
1813  totalsdpconstnnonz += sdpconstnnonz;
1814  }
1815 
1816  /* allocate memory for SDPdata */
1817  SCIP_CALL( SCIPallocBufferArray(scip, &sdpnvarnonz, nvars) );
1818  SCIP_CALL( SCIPallocBufferArray(scip, &sdpcol, totalsdpnnonz) );
1819  SCIP_CALL( SCIPallocBufferArray(scip, &sdprow, totalsdpnnonz) );
1820  SCIP_CALL( SCIPallocBufferArray(scip, &sdpval, totalsdpnnonz) );
1821  SCIP_CALL( SCIPallocBufferArray(scip, &sdpvars, nvars) );
1822  SCIP_CALL( SCIPallocBufferArray(scip, &sdpconstcol, totalsdpconstnnonz) );
1823  SCIP_CALL( SCIPallocBufferArray(scip, &sdpconstrow, totalsdpconstnnonz) );
1824  SCIP_CALL( SCIPallocBufferArray(scip, &sdpconstval, totalsdpconstnnonz) );
1825 
1826  sdparraylength = totalsdpnnonz;
1827  sdpconstnnonz = totalsdpconstnnonz;
1828 
1829  /* write SDP nonzeros */
1830  SCIPinfoMessage(scip, file, "HCOORD\n%d\n", totalsdpnnonz);
1831  consind = 0;
1832  for (c = 0; c < nconss; c++)
1833  {
1834  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])),"SDP") != 0 )
1835  continue;
1836 
1837  /* initialization for SDPconsSDPGetData-call */
1838  sdparraylength = totalsdpnnonz;
1839  sdpconstnnonz = totalsdpconstnnonz;
1840 
1841  SCIP_CALL( SCIPconsSdpGetData(scip, conss[c], &sdpnvars, &sdpnnonz, &sdpblocksize, &sdparraylength, sdpnvarnonz,
1842  sdpcol, sdprow, sdpval, sdpvars, &sdpconstnnonz, sdpconstcol, sdpconstrow, sdpconstval) );
1843 
1844  assert( sdpconstnnonz <= totalsdpconstnnonz );
1845  assert( sdparraylength <= totalsdpnnonz);
1846 
1847  for (v = 0; v < sdpnvars; v++)
1848  {
1849  for (i = 0; i < sdpnvarnonz[v]; i++)
1850  {
1851  SCIPinfoMessage(scip, file, "%d %d %d %d %.9f\n", consind, SCIPsdpVarmapperGetSdpIndex(varmapper, sdpvars[v]),
1852  sdprow[v][i], sdpcol[v][i], sdpval[v][i]);
1853  }
1854  }
1855  consind++;
1856  }
1857  SCIPinfoMessage(scip, file, "\n");
1858 
1859  /* write nonzeros of constant part of SDP constraint */
1860  SCIPinfoMessage(scip, file, "DCOORD\n%d\n", totalsdpconstnnonz);
1861  consind = 0;
1862  for (c = 0; c < nconss; c++)
1863  {
1864  if ( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])), "SDP") != 0 )
1865  continue;
1866 
1867  /* initialization for SDPconsSDPGetData-call */
1868  sdparraylength = totalsdpnnonz;
1869  sdpconstnnonz = totalsdpconstnnonz;
1870 
1871  SCIP_CALL( SCIPconsSdpGetData(scip, conss[c], &sdpnvars, &sdpnnonz, &sdpblocksize, &sdparraylength, sdpnvarnonz,
1872  sdpcol, sdprow, sdpval, sdpvars, &sdpconstnnonz, sdpconstcol, sdpconstrow, sdpconstval) );
1873 
1874  assert( sdpconstnnonz <= totalsdpconstnnonz );
1875  assert( sdparraylength <= totalsdpnnonz);
1876 
1877  for (i = 0; i < sdpconstnnonz; i++)
1878  {
1879  SCIPinfoMessage(scip, file, "%d %d %d %.9f\n", consind, sdpconstrow[i], sdpconstcol[i], -1* sdpconstval[i]);
1880  }
1881  consind++;
1882  }
1883 
1884  SCIPfreeBufferArray(scip, &sdpconstval);
1885  SCIPfreeBufferArray(scip, &sdpconstrow);
1886  SCIPfreeBufferArray(scip, &sdpconstcol);
1887  SCIPfreeBufferArray(scip, &sdpvars);
1888  SCIPfreeBufferArray(scip, &sdpval);
1889  SCIPfreeBufferArray(scip, &sdprow);
1890  SCIPfreeBufferArray(scip, &sdpcol);
1891  SCIPfreeBufferArray(scip, &sdpnvarnonz);
1892  SCIP_CALL( SCIPsdpVarmapperFree(scip, &varmapper) );
1893 #ifdef CBF_CHECK_NONNEG
1894  SCIPfreeBufferArray(scip, &negorth);
1895  SCIPfreeBufferArray(scip, &posorth);
1896  SCIPfreeBufferArray(scip, &consdisabled);
1897 #endif
1898 
1899  *result = SCIP_SUCCESS;
1900 
1901  return SCIP_OKAY;
1902 }
1903 
1904 
1905 /*
1906  * reader specific interface methods
1907  */
1908 
1910 SCIP_RETCODE SCIPincludeReaderCbf(
1911  SCIP* scip
1912  )
1913 {
1914  SCIP_READERDATA* readerdata;
1915  SCIP_READER* reader;
1916 
1917  /* create reader data */
1918  readerdata = NULL;
1919 
1920  /* include reader */
1921  SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, readerdata) );
1922 
1923  assert(reader != NULL);
1924 
1925  /* set non fundamental callbacks via setter functions */
1926  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyCbf) );
1927  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadCbf) );
1928  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteCbf) );
1929 
1930  return SCIP_OKAY;
1931 }
static SCIP_RETCODE CBFreadCon(SCIP *scip, SCIP_FILE *pfile, long long int *linecount, CBF_DATA *data)
Definition: reader_cbf.c:309
static SCIP_RETCODE CBFreadDcoord(SCIP *scip, SCIP_FILE *pfile, long long int *linecount, CBF_DATA *data)
Definition: reader_cbf.c:915
SCIP_RETCODE SCIPsdpVarmapperAddVars(SCIP *scip, SdpVarmapper *varmapper, int nvars, SCIP_VAR **vars)
Definition: SdpVarmapper.c:108
char CBF_LINE_BUFFER[CBF_MAX_LINE]
Definition: reader_cbf.c:73
#define CBF_MAX_NAME
Definition: reader_cbf.c:71
static SCIP_RETCODE CBFreadHcoord(SCIP *scip, SCIP_FILE *pfile, long long int *linecount, CBF_DATA *data)
Definition: reader_cbf.c:753
file reader for mixed-integer semidefinite programs in CBF format
static SCIP_RETCODE CBFfgets(SCIP_FILE *pFile, long long int *linecount)
Definition: reader_cbf.c:120
#define READER_DESC
Definition: reader_cbf.c:54
static SCIP_DECL_READERCOPY(readerCopyCbf)
Definition: reader_cbf.c:1071
static SCIP_RETCODE CBFreadAcoord(SCIP *scip, SCIP_FILE *pfile, long long int *linecount, CBF_DATA *data)
Definition: reader_cbf.c:610
static SCIP_RETCODE CBFfreeData(SCIP *scip, CBF_DATA *data)
Definition: reader_cbf.c:1018
char CBF_NAME_BUFFER[CBF_MAX_NAME]
Definition: reader_cbf.c:74
SCIP_RETCODE SCIPsdpVarmapperCreate(SCIP *scip, SdpVarmapper **varmapper, int size)
Definition: SdpVarmapper.c:53
struct Sdpvarmapper SdpVarmapper
Definition: SdpVarmapper.h:48
#define CBF_VERSION_NR
Definition: reader_cbf.c:57
int SCIPsdpVarmapperGetSdpIndex(SdpVarmapper *varmapper, SCIP_VAR *var)
Definition: SdpVarmapper.c:225
#define READER_EXTENSION
Definition: reader_cbf.c:55
Constraint handler for SDP-constraints.
SCIP_RETCODE SCIPincludeReaderCbf(SCIP *scip)
Definition: reader_cbf.c:1912
maps SCIP variables to SDP indices (the SCIP variables are given SDP indices in the order in which th...
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)
Definition: cons_sdp.c:3001
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)
Definition: cons_sdp.c:2513
static SCIP_RETCODE CBFreadPsdcon(SCIP *scip, SCIP_FILE *pfile, long long int *linecount, CBF_DATA *data)
Definition: reader_cbf.c:497
static SCIP_RETCODE CBFreadVar(SCIP *scip, SCIP_FILE *pfile, long long int *linecount, CBF_DATA *data)
Definition: reader_cbf.c:180
#define CBF_MAX_LINE
Definition: reader_cbf.c:70
#define READER_NAME
Definition: reader_cbf.c:53
static SCIP_DECL_READERREAD(readerReadCbf)
Definition: reader_cbf.c:1082
struct CBF_Data CBF_DATA
Definition: reader_cbf.c:111
int SCIPconsSdpGetBlocksize(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sdp.c:2634
SCIP_RETCODE SCIPsdpVarmapperFree(SCIP *scip, SdpVarmapper **varmapper)
Definition: SdpVarmapper.c:80
static SCIP_RETCODE CBFreadObjacoord(SCIP *scip, SCIP_FILE *pfile, long long int *linecount, CBF_DATA *data)
Definition: reader_cbf.c:548
static SCIP_RETCODE CBFreadBcoord(SCIP *scip, SCIP_FILE *pfile, long long int *linecount, CBF_DATA *data)
Definition: reader_cbf.c:677
SCIP_RETCODE SCIPconsSdpGetNNonz(SCIP *scip, SCIP_CONS *cons, int *nnonz, int *constnnonz)
Definition: cons_sdp.c:2609
static SCIP_RETCODE CBFreadInt(SCIP *scip, SCIP_FILE *pfile, long long int *linecount, CBF_DATA *data)
Definition: reader_cbf.c:440
static SCIP_RETCODE CBFreadObjsense(SCIP *scip, SCIP_FILE *pfile, long long int *linecount)
Definition: reader_cbf.c:142
#define CBF_NAME_FORMAT
Definition: reader_cbf.c:69
static SCIP_DECL_READERWRITE(readerWriteCbf)
Definition: reader_cbf.c:1288