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