1    	#include "soplex.h"
2    	#include "soplex_interface.h"
3    	#include <iostream>
4    	
5    	using namespace soplex;
6    	
7    	/** creates new SoPlex struct **/
8    	void* SoPlex_create()
9    	{
10   	   SoPlex* so = new SoPlex();
11   	   return so;
12   	}
13   	
14   	/** frees SoPlex struct **/
15   	void SoPlex_free(void* soplex)
16   	{
17   	   SoPlex* so = (SoPlex*)(soplex);
18   	   delete so;
19   	}
20   	
21   	/** clears the (floating point) LP **/
22   	void SoPlex_clearLPReal(void* soplex)
23   	{
24   	   SoPlex* so = (SoPlex*)(soplex);
25   	   so->clearLPReal();
26   	}
27   	
28   	/** returns number of rows **/
29   	int SoPlex_numRows(void* soplex)
30   	{
31   	   SoPlex* so = (SoPlex*)(soplex);
32   	   return so->numRows();
33   	}
34   	
35   	/** returns number of columns **/
36   	int SoPlex_numCols(void* soplex)
37   	{
38   	   SoPlex* so = (SoPlex*)(soplex);
39   	   return so->numCols();
40   	}
41   	
42   	/** enables rational solving mode **/
43   	void SoPlex_setRational(void* soplex)
44   	{
45   	#ifndef SOPLEX_WITH_BOOST
46   	   throw SPxException("Rational functions cannot be used when built without Boost.");
47   	#endif
48   	   /* coverity[unreachable] */
49   	   SoPlex* so = (SoPlex*)(soplex);
50   	   so->setIntParam(SoPlex::READMODE, SoPlex::READMODE_RATIONAL);
51   	   so->setIntParam(SoPlex::SOLVEMODE, SoPlex::SOLVEMODE_RATIONAL);
52   	   so->setIntParam(SoPlex::CHECKMODE, SoPlex::CHECKMODE_RATIONAL);
53   	   so->setIntParam(SoPlex::SYNCMODE, SoPlex::SYNCMODE_AUTO);
54   	   so->setRealParam(SoPlex::FEASTOL, 0.0);
55   	   so->setRealParam(SoPlex::OPTTOL, 0.0);
56   	}
57   	
58   	/** sets integer parameter value **/
59   	void SoPlex_setIntParam(void* soplex, int paramcode, int paramvalue)
60   	{
61   	   SoPlex* so = (SoPlex*)(soplex);
62   	   so->setIntParam((SoPlex::IntParam)paramcode, paramvalue);
63   	}
64   	
65   	/** returns value of integer parameter **/
66   	int SoPlex_getIntParam(void* soplex, int paramcode)
67   	{
68   	   SoPlex* so = (SoPlex*)(soplex);
69   	   return so->intParam((SoPlex::IntParam)paramcode);
70   	}
71   	
72   	/** adds a single (floating point) column **/
73   	void SoPlex_addColReal(
74   	   void* soplex,
75   	   double* colentries,
76   	   int colsize,
77   	   int nnonzeros,
78   	   double objval,
79   	   double lb,
80   	   double ub
81   	)
82   	{
83   	   SoPlex* so = (SoPlex*)(soplex);
84   	   DSVector col(nnonzeros);
85   	
86   	   /* add nonzero entries to column vector */
87   	   for(int i = 0; i < colsize; ++i)
88   	   {
89   	      if(colentries[i] != 0.0)
90   	         col.add(i, colentries[i]);
91   	   }
92   	
93   	   so->addColReal(LPCol(objval, col, ub, lb));
94   	}
95   	
96   	/** adds a single rational column **/
97   	void SoPlex_addColRational(
98   	   void* soplex,
99   	   long* colnums,
100  	   long* coldenoms,
101  	   int colsize,
102  	   int nnonzeros,
103  	   long objvalnum,
104  	   long objvaldenom,
105  	   long lbnum,
106  	   long lbdenom,
107  	   long ubnum,
108  	   long ubdenom
109  	)
110  	{
111  	#ifndef SOPLEX_WITH_BOOST
112  	   throw SPxException("Rational functions cannot be used when built without Boost.");
113  	#endif
114  	   /* coverity[unreachable] */
115  	   SoPlex* so = (SoPlex*)(soplex);
116  	   DSVectorRational col(nnonzeros);
117  	
118  	   /* get rational lower bound */
119  	   Rational lower(lbnum, lbdenom);
120  	
121  	   /* get rational upper bound */
122  	   Rational upper(ubnum, ubdenom);
123  	
124  	   /* get rational objective value */
125  	   Rational objval(objvalnum, objvaldenom);
126  	
127  	   /* add nonzero entries to column vector */
128  	   for(int i = 0; i < colsize; ++i)
129  	   {
130  	      if(colnums[i] != 0)
131  	      {
132  	         /* get rational nonzero entry */
133  	         Rational colentry(colnums[i], coldenoms[i]);
134  	         col.add(i, colentry);
135  	      }
136  	   }
137  	
138  	   so->addColRational(LPColRational(objval, col, upper, lower));
139  	}
140  	
141  	/** adds a single (floating point) row **/
142  	void SoPlex_addRowReal(
143  	   void* soplex,
144  	   double* rowentries,
145  	   int rowsize,
146  	   int nnonzeros,
147  	   double lb,
148  	   double ub
149  	)
150  	{
151  	   SoPlex* so = (SoPlex*)(soplex);
152  	   DSVector row(nnonzeros);
153  	
154  	   /* add nonzero entries to row vector */
155  	   for(int i = 0; i < rowsize; ++i)
156  	   {
157  	      if(rowentries[i] != 0.0)
158  	         row.add(i, rowentries[i]);
159  	   }
160  	
161  	   so->addRowReal(LPRow(lb, row, ub));
162  	}
163  	
164  	/** adds a single rational row **/
165  	void SoPlex_addRowRational(
166  	   void* soplex,
167  	   long* rownums,
168  	   long* rowdenoms,
169  	   int rowsize,
170  	   int nnonzeros,
171  	   long lbnum,
172  	   long lbdenom,
173  	   long ubnum,
174  	   long ubdenom
175  	)
176  	{
177  	#ifndef SOPLEX_WITH_BOOST
178  	   throw SPxException("Rational functions cannot be used when built without Boost.");
179  	#endif
180  	   /* coverity[unreachable] */
181  	   SoPlex* so = (SoPlex*)(soplex);
182  	   DSVectorRational row(nnonzeros);
183  	
184  	   /* get rational lower bound */
185  	   Rational lower(lbnum, lbdenom);
186  	
187  	   /* get rational upper bound */
188  	   Rational upper(ubnum, ubdenom);
189  	
190  	   /* add nonzero entries to row vector */
191  	   for(int i = 0; i < rowsize; ++i)
192  	   {
193  	      if(rownums[i] != 0)
194  	      {
195  	         /* get rational nonzero entry */
196  	         Rational rowentry(rownums[i], rowdenoms[i]);
197  	         row.add(i, rowentry);
198  	      }
199  	   }
200  	
201  	   so->addRowRational(LPRowRational(lower, row, upper));
202  	}
203  	
204  	/** gets primal solution **/
205  	void SoPlex_getPrimalReal(void* soplex, double* primal, int dim)
206  	{
207  	   SoPlex* so = (SoPlex*)(soplex);
208  	   so->getPrimalReal(primal, dim);
209  	}
210  	
211  	/** Returns rational primal solution in a char pointer.
212  	*   The caller needs to ensure the char array is freed.
213  	**/
214  	char* SoPlex_getPrimalRationalString(void* soplex, int dim)
215  	{
216  	#ifndef SOPLEX_WITH_BOOST
217  	   throw SPxException("Rational functions cannot be used when built without Boost.");
218  	#endif
219  	   /* coverity[unreachable] */
220  	   SoPlex* so = (SoPlex*)(soplex);
221  	   VectorRational primal(dim);
222  	   std::string primalstring;
223  	   char* rawstring;
224  	   long unsigned int stringlength;
225  	
226  	   so->getPrimalRational(primal);
227  	
228  	   for(int i = 0; i < dim; ++i)
229  	   {
230  	      primalstring.append(primal[i].str());
231  	      primalstring.append(" ");
232  	   }
233  	
234  	   stringlength = strlen(primalstring.c_str()) + 1;
235  	   rawstring = new char[stringlength];
236  	   strncpy(rawstring, primalstring.c_str(), stringlength);
237  	   return rawstring;
238  	}
239  	
240  	/** gets dual solution **/
241  	void SoPlex_getDualReal(void* soplex, double* dual, int dim)
242  	{
243  	   SoPlex* so = (SoPlex*)(soplex);
244  	   so->getDualReal(dual, dim);
245  	}
246  	
247  	/** optimizes the given LP **/
248  	int SoPlex_optimize(void* soplex)
249  	{
250  	   SoPlex* so = (SoPlex*)(soplex);
251  	   return so->optimize();
252  	}
253  	
254  	/** changes objective function vector to obj **/
255  	void SoPlex_changeObjReal(void* soplex, double* obj, int dim)
256  	{
257  	   SoPlex* so = (SoPlex*)(soplex);
258  	   Vector objective(dim, obj);
259  	   return so->changeObjReal(objective);
260  	}
261  	
262  	/** changes rational objective function vector to obj **/
263  	void SoPlex_changeObjRational(void* soplex, long* objnums, long* objdenoms, int dim)
264  	{
265  	#ifndef SOPLEX_WITH_BOOST
266  	   throw SPxException("Rational functions cannot be used when built without Boost.");
267  	#endif
268  	   /* coverity[unreachable] */
269  	   SoPlex* so = (SoPlex*)(soplex);
270  	   Rational* objrational = new Rational [dim];
271  	
272  	   /* create rational objective vector */
273  	   for(int i = 0; i < dim; ++i)
274  	   {
275  	      Rational objentry(objnums[i], objdenoms[i]);
276  	      objrational[i] = objentry;
277  	   }
278  	
279  	   VectorRational objective(dim, objrational);
280  	   return so->changeObjRational(objective);
281  	}
282  	
283  	/** changes left-hand side vector for constraints to lhs **/
284  	void SoPlex_changeLhsReal(void* soplex, double* lhs, int dim)
285  	{
286  	   SoPlex* so = (SoPlex*)(soplex);
287  	   Vector lhsvec(dim, lhs);
288  	   return so->changeLhsReal(lhsvec);
289  	}
290  	
291  	/** changes rational left-hand side vector for constraints to lhs **/
292  	void SoPlex_changeLhsRational(void* soplex, long* lhsnums, long* lhsdenoms, int dim)
293  	{
294  	#ifndef SOPLEX_WITH_BOOST
295  	   throw SPxException("Rational functions cannot be used when built without Boost.");
296  	#endif
297  	   /* coverity[unreachable] */
298  	   SoPlex* so = (SoPlex*)(soplex);
299  	   Rational* lhsrational = new Rational [dim];
300  	
301  	   /* create rational lhs vector */
302  	   for(int i = 0; i < dim; ++i)
303  	   {
304  	      Rational lhsentry(lhsnums[i], lhsdenoms[i]);
305  	      lhsrational[i] = lhsentry;
306  	   }
307  	
308  	   VectorRational lhs(dim, lhsrational);
309  	   return so->changeLhsRational(lhs);
310  	}
311  	
312  	/** changes right-hand side vector for constraints to rhs **/
313  	void SoPlex_changeRhsReal(void* soplex, double* rhs, int dim)
314  	{
315  	   SoPlex* so = (SoPlex*)(soplex);
316  	   Vector rhsvec(dim, rhs);
317  	   return so->changeRhsReal(rhsvec);
318  	}
319  	
320  	/** changes rational right-hand side vector for constraints to rhs **/
321  	void SoPlex_changeRhsRational(void* soplex, long* rhsnums, long* rhsdenoms, int dim)
322  	{
323  	#ifndef SOPLEX_WITH_BOOST
324  	   throw SPxException("Rational functions cannot be used when built without Boost.");
325  	#endif
326  	   /* coverity[unreachable] */
327  	   SoPlex* so = (SoPlex*)(soplex);
328  	   Rational* rhsrational = new Rational [dim];
329  	
330  	   /* create rational rhs vector */
331  	   for(int i = 0; i < dim; ++i)
332  	   {
333  	      Rational rhsentry(rhsnums[i], rhsdenoms[i]);
334  	      rhsrational[i] = rhsentry;
335  	   }
336  	
337  	   VectorRational rhs(dim, rhsrational);
338  	   return so->changeRhsRational(rhs);
339  	}
340  	
341  	/** write LP to file **/
342  	void SoPlex_writeFileReal(void* soplex, char* filename)
343  	{
344  	   SoPlex* so = (SoPlex*)(soplex);
345  	   so->writeFile(filename);
346  	}
347  	
348  	/** returns the objective value if a primal solution is available **/
349  	double SoPlex_objValueReal(void* soplex)
350  	{
351  	   SoPlex* so = (SoPlex*)(soplex);
352  	   return so->objValueReal();
353  	}
354  	
355  	/** Returns the rational objective value (as a string) if a primal solution is available.
356  	*   The caller needs to ensure the char array is freed.
357  	**/
358  	char* SoPlex_objValueRationalString(void* soplex)
359  	{
360  	#ifndef SOPLEX_WITH_BOOST
361  	   throw SPxException("Rational functions cannot be used when built without Boost.");
362  	#endif
363  	   /* coverity[unreachable] */
364  	   long unsigned int stringlength;
365  	   char* value;
366  	   std::string objstring;
367  	   SoPlex* so = (SoPlex*)(soplex);
368  	
369  	   stringlength = strlen(objstring.c_str()) + 1;
370  	   objstring = so->objValueRational().str();
371  	   value = new char[stringlength];
372  	   strncpy(value, objstring.c_str(), stringlength);
373  	   return value;
374  	}
375  	
376  	/** changes vectors of column bounds to lb and ub **/
377  	void SoPlex_changeBoundsReal(void* soplex, double* lb, double* ub, int dim)
378  	{
379  	   SoPlex* so = (SoPlex*)(soplex);
380  	   Vector lbvec(dim, lb);
381  	   Vector ubvec(dim, ub);
382  	   return so->changeBoundsReal(lbvec, ubvec);
383  	}
384  	
385  	/** changes bounds of a column to lb and ub **/
386  	void SoPlex_changeVarBoundsReal(void* soplex, int colidx, double lb, double ub)
387  	{
388  	   SoPlex* so = (SoPlex*)(soplex);
389  	   return so->changeBoundsReal(colidx, lb, ub);
390  	}
391  	
392  	/** changes rational bounds of a column to lbnum/lbdenom and ubnum/ubdenom **/
393  	void SoPlex_changeVarBoundsRational(
394  	   void* soplex,
395  	   int colidx,
396  	   long lbnum,
397  	   long lbdenom,
398  	   long ubnum,
399  	   long ubdenom
400  	)
401  	{
402  	#ifndef SOPLEX_WITH_BOOST
403  	   throw SPxException("Rational functions cannot be used when built without Boost.");
404  	#endif
405  	   /* coverity[unreachable] */
406  	   SoPlex* so = (SoPlex*)(soplex);
407  	
408  	   /* get rational lower bound */
409  	   Rational lower(lbnum, lbdenom);
410  	
411  	   /* get rational upper bound */
412  	   Rational upper(ubnum, ubdenom);
413  	
414  	   return so->changeBoundsRational(colidx, lower, upper);
415  	}
416  	
417  	/** changes upper bound of column to ub **/
418  	void SoPlex_changeVarUpperReal(void* soplex, int colidx, double ub)
419  	{
420  	   SoPlex* so = (SoPlex*)(soplex);
421  	   return so->changeLowerReal(colidx, ub);
422  	}
423  	
424  	/** changes upper bound vector of columns to ub **/
425  	void SoPlex_getUpperReal(void* soplex, double* ub, int dim)
426  	{
427  	   SoPlex* so = (SoPlex*)(soplex);
428  	   Vector ubvec(dim, ub);
429  	
430  	   so->getLowerReal(ubvec);
431  	
432  	   for(int i = 0; i < dim; ++i)
433  	      ub[i] = ubvec[i];
434  	}
435  	
436  	/** returns status of row
437  	 *  0 -> row is set to its upper bound
438  	 *  1 -> row is set to its lower bound
439  	 *  2 -> row is fixed to its identical bounds
440  	 *  4 -> row is basic
441  	 *  5 -> nothing known about basis status
442  	 **/
443  	int SoPlex_basisRowStatus(void* soplex, int rowidx)
444  	{
445  	   SoPlex* so = (SoPlex*)(soplex);
446  	
447  	   return so->basisRowStatus(rowidx);
448  	}
449  	
450  	/** returns status of column
451  	 *  0 -> column is set to its upper bound
452  	 *  1 -> column is set to its lower bound
453  	 *  2 -> column is fixed to its identical bounds
454  	 *  3 -> column is free and fixed to zero
455  	 *  4 -> column is basic
456  	 *  5 -> nothing known about basis status
457  	 **/
458  	int SoPlex_basisColStatus(void* soplex, int colidx)
459  	{
460  	   SoPlex* so = (SoPlex*)(soplex);
461  	
462  	   return so->basisColStatus(colidx);
463  	}
464  	
465  	/** get non-zero entries and indices of row i **/
466  	void SoPlex_getRowVectorReal(
467  	   void* soplex,
468  	   int i,
469  	   int* nnonzeros,
470  	   long* indices,
471  	   double* coefs
472  	)
473  	{
474  	   SoPlex* so = (SoPlex*)(soplex);
475  	   DSVector row;
476  	
477  	   so->getRowVectorReal(i, row);
478  	
479  	   *nnonzeros = row.size();
480  	
481  	   for(int j = 0; j < *nnonzeros; ++j)
482  	   {
483  	      coefs[j] = row.value(j);
484  	      indices[j] = row.index(j);
485  	   }
486  	}
487  	
488  	/** get non-zero entries and indices of rational row i **/
489  	void SoPlex_getRowVectorRational(
490  	   void* soplex,
491  	   int i,
492  	   int* nnonzeros,
493  	   long* indices,
494  	   long* coefsnum,
495  	   long* coefsdenom
496  	)
497  	{
498  	#ifndef SOPLEX_WITH_BOOST
499  	   throw SPxException("Rational functions cannot be used when built without Boost.");
500  	#endif
501  	   SoPlex* so = (SoPlex*)(soplex);
502  	   LPRowRational lprow;
503  	   SVectorRational row;
504  	
505  	   so->getRowRational(i, lprow);
506  	   row = lprow.rowVector();
507  	
508  	   *nnonzeros = row.size();
509  	
510  	   for(int j = 0; j < *nnonzeros; ++j)
511  	   {
512  	      coefsnum[j] = (long int) numerator(row.value(j));
513  	      coefsdenom[j] = (long int) denominator(row.value(j));
514  	      indices[j] = row.index(j);
515  	   }
516  	}
517  	
518  	/** get lower and upper bounds of row i **/
519  	void SoPlex_getRowBoundsReal(
520  	   void* soplex,
521  	   int i,
522  	   double* lb,
523  	   double* ub
524  	)
525  	{
526  	   SoPlex* so = (SoPlex*)(soplex);
527  	
528  	   *lb = so->lhsReal(i);
529  	   *ub = so->rhsReal(i);
530  	}
531  	
532  	/** get rational lower and upper bounds of row i **/
533  	void SoPlex_getRowBoundsRational(
534  	   void* soplex,
535  	   int i,
536  	   long* lbnum,
537  	   long* lbdenom,
538  	   long* ubnum,
539  	   long* ubdenom
540  	)
541  	{
542  	#ifndef SOPLEX_WITH_BOOST
543  	   throw SPxException("Rational functions cannot be used when built without Boost.");
544  	#endif
(1) Event unreachable: This code cannot be reached: "soplex::SoPlex *so = (sople...".
545  	   SoPlex* so = (SoPlex*)(soplex);
546  	
547  	   *lbnum = (long int) numerator(so->lhsRational(i));
548  	   *lbdenom = (long int) denominator(so->lhsRational(i));
549  	   *ubnum = (long int) numerator(so->rhsRational(i));
550  	   *ubdenom = (long int) denominator(so->rhsRational(i));
551  	}
552