1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the class library                   */
4    	/*       SoPlex --- the Sequential object-oriented simPlex.                  */
5    	/*                                                                           */
6    	/*    Copyright (C) 1996-2021 Konrad-Zuse-Zentrum                            */
7    	/*                            fuer Informationstechnik Berlin                */
8    	/*                                                                           */
9    	/*  SoPlex is distributed under the terms of the ZIB Academic Licence.       */
10   	/*                                                                           */
11   	/*  You should have received a copy of the ZIB Academic License              */
12   	/*  along with SoPlex; see the file COPYING. If not email to soplex@zib.de.  */
13   	/*                                                                           */
14   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15   	
16   	/**@file  soplex.hpp
17   	 * @brief General templated functions for SoPlex
18   	 */
19   	
20   	/// maximum length of lines in settings file
21   	#define SET_MAX_LINE_LEN 500
22   	
23   	/// default setting for LU refactorization interval
24   	#define DEFAULT_REFACTOR_INTERVAL 200
25   	
26   	#ifdef _MSC_VER
27   	#define strncasecmp _strnicmp
28   	#endif
29   	
30   	#ifndef _MSC_VER
31   	#include <strings.h>
32   	#endif
33   	
34   	namespace soplex
35   	{
36   	template <class R>
37   	typename SoPlexBase<R>::Settings::IntParam SoPlexBase<R>::Settings::intParam = IntParam();
38   	
39   	template <class R>
40   	typename SoPlexBase<R>::Settings::RealParam SoPlexBase<R>::Settings::realParam = RealParam();
41   	
42   	template <class R>
43   	typename SoPlexBase<R>::Settings::BoolParam SoPlexBase<R>::Settings::boolParam = BoolParam();
44   	
45   	template <class R>
46   	SoPlexBase<R>::Settings::BoolParam::BoolParam()
47   	{
48   	   // should lifting be used to reduce range of nonzero matrix coefficients?
49   	   name[SoPlexBase<R>::LIFTING] = "lifting";
50   	   description[SoPlexBase<R>::LIFTING] =
51   	      "should lifting be used to reduce range of nonzero matrix coefficients?";
52   	   defaultValue[SoPlexBase<R>::LIFTING] = false;
53   	
54   	   // should LP be transformed to equality form before a rational solve?
55   	   name[SoPlexBase<R>::EQTRANS] = "eqtrans";
56   	   description[SoPlexBase<R>::EQTRANS] =
57   	      "should LP be transformed to equality form before a rational solve?";
58   	   defaultValue[SoPlexBase<R>::EQTRANS] = false;
59   	
60   	   // should dual infeasibility be tested in order to try to return a dual solution even if primal infeasible?
61   	   name[SoPlexBase<R>::TESTDUALINF] = "testdualinf";
62   	   description[SoPlexBase<R>::TESTDUALINF] =
63   	      "should dual infeasibility be tested in order to try to return a dual solution even if primal infeasible?";
64   	   defaultValue[SoPlexBase<R>::TESTDUALINF] = false;
65   	
66   	   // should a rational factorization be performed after iterative refinement?
67   	   name[SoPlexBase<R>::RATFAC] = "ratfac";
68   	   description[SoPlexBase<R>::RATFAC] =
69   	      "should a rational factorization be performed after iterative refinement?";
70   	   defaultValue[SoPlexBase<R>::RATFAC] = true;
71   	
72   	   // should the decomposition based dual simplex be used to solve the LP? Setting this to true forces the solve mode to
73   	   // SOLVEMODE_REAL and the basis representation to REPRESENTATION_ROW
74   	   name[SoPlexBase<R>::USEDECOMPDUALSIMPLEX] = "decompositiondualsimplex";
75   	   description[SoPlexBase<R>::USEDECOMPDUALSIMPLEX] =
76   	      "should the decomposition based dual simplex be used to solve the LP?";
77   	   defaultValue[SoPlexBase<R>::USEDECOMPDUALSIMPLEX] = false;
78   	
79   	   // should the degeneracy be computed for each basis?
80   	   name[SoPlexBase<R>::COMPUTEDEGEN] = "computedegen";
81   	   description[SoPlexBase<R>::COMPUTEDEGEN] = "should the degeneracy be computed for each basis?";
82   	   defaultValue[SoPlexBase<R>::COMPUTEDEGEN] = false;
83   	
84   	   // should the dual of the complementary problem be used in the decomposition simplex?
85   	   name[SoPlexBase<R>::USECOMPDUAL] = "usecompdual";
86   	   description[SoPlexBase<R>::USECOMPDUAL] =
87   	      "should the dual of the complementary problem be used in the decomposition simplex?";
88   	   defaultValue[SoPlexBase<R>::USECOMPDUAL] = false;
89   	
90   	   /// should row and bound violations be computed explicitly in the update of reduced problem in the decomposition
91   	   // simplex
92   	   name[SoPlexBase<R>::EXPLICITVIOL] = "explicitviol";
93   	   description[SoPlexBase<R>::EXPLICITVIOL] =
94   	      "Should violations of the original problem be explicitly computed in the decomposition simplex?";
95   	   defaultValue[SoPlexBase<R>::EXPLICITVIOL] = false;
96   	
97   	   // should cycling solutions be accepted during iterative refinement?
98   	   name[SoPlexBase<R>::ACCEPTCYCLING] = "acceptcycling";
99   	   description[SoPlexBase<R>::ACCEPTCYCLING] =
100  	      "should cycling solutions be accepted during iterative refinement?";
101  	   defaultValue[SoPlexBase<R>::ACCEPTCYCLING] = false;
102  	
103  	   // apply rational reconstruction after each iterative refinement?
104  	   name[SoPlexBase<R>::RATREC] = "ratrec";
105  	   description[SoPlexBase<R>::RATREC] =
106  	      "apply rational reconstruction after each iterative refinement?";
107  	   defaultValue[SoPlexBase<R>::RATREC] = true;
108  	
109  	   // round scaling factors for iterative refinement to powers of two?
110  	   name[SoPlexBase<R>::POWERSCALING] = "powerscaling";
111  	   description[SoPlexBase<R>::POWERSCALING] =
112  	      "round scaling factors for iterative refinement to powers of two?";
113  	   defaultValue[SoPlexBase<R>::POWERSCALING] = true;
114  	
115  	   // continue iterative refinement with exact basic solution if not optimal?
116  	   name[SoPlexBase<R>::RATFACJUMP] = "ratfacjump";
117  	   description[SoPlexBase<R>::RATFACJUMP] =
118  	      "continue iterative refinement with exact basic solution if not optimal?";
119  	   defaultValue[SoPlexBase<R>::RATFACJUMP] = false;
120  	
121  	   // use bound flipping also for row representation?
122  	   name[SoPlexBase<R>::ROWBOUNDFLIPS] = "rowboundflips";
123  	   description[SoPlexBase<R>::ROWBOUNDFLIPS] = "use bound flipping also for row representation?";
124  	   defaultValue[SoPlexBase<R>::ROWBOUNDFLIPS] = false;
125  	
126  	   // use persistent scaling?
127  	   name[SoPlexBase<R>::PERSISTENTSCALING] = "persistentscaling";
128  	   description[SoPlexBase<R>::PERSISTENTSCALING] = "should persistent scaling be used?";
129  	   defaultValue[SoPlexBase<R>::PERSISTENTSCALING] = true;
130  	
131  	   // perturb the entire problem or only the relevant bounds of s single pivot?
132  	   name[SoPlexBase<R>::FULLPERTURBATION] = "fullperturbation";
133  	   description[SoPlexBase<R>::FULLPERTURBATION] =
134  	      "should perturbation be applied to the entire problem?";
135  	   defaultValue[SoPlexBase<R>::FULLPERTURBATION] = false;
136  	
137  	   /// re-optimize the original problem to get a proof of infeasibility/unboundedness?
138  	   name[SoPlexBase<R>::ENSURERAY] = "ensureray";
139  	   description[SoPlexBase<R>::ENSURERAY] =
140  	      "re-optimize the original problem to get a proof (ray) of infeasibility/unboundedness?";
141  	   defaultValue[SoPlexBase<R>::ENSURERAY] = false;
142  	
143  	   /// try to enforce that the optimal solution is a basic solution
144  	   name[SoPlexBase<Real>::FORCEBASIC] = "forcebasic";
145  	   description[SoPlexBase<Real>::FORCEBASIC] =
146  	      "try to enforce that the optimal solution is a basic solution";
147  	   defaultValue[SoPlexBase<Real>::FORCEBASIC] = false;
148  	}
149  	
150  	template <class R>
151  	SoPlexBase<R>::Settings::IntParam::IntParam()
152  	{
153  	   // objective sense
154  	   name[SoPlexBase<R>::OBJSENSE] = "objsense";
155  	   description[SoPlexBase<R>::OBJSENSE] = "objective sense (-1 - minimize, +1 - maximize)";
156  	   lower[SoPlexBase<R>::OBJSENSE] = -1;
157  	   upper[SoPlexBase<R>::OBJSENSE] = 1;
158  	   defaultValue[SoPlexBase<R>::OBJSENSE] = SoPlexBase<R>::OBJSENSE_MAXIMIZE;
159  	
160  	   // type of computational form, i.e., column or row representation
161  	   name[SoPlexBase<R>::REPRESENTATION] = "representation";
162  	   description[SoPlexBase<R>::REPRESENTATION] =
163  	      "type of computational form (0 - auto, 1 - column representation, 2 - row representation)";
164  	   lower[SoPlexBase<R>::REPRESENTATION] = 0;
165  	   upper[SoPlexBase<R>::REPRESENTATION] = 2;
166  	   defaultValue[SoPlexBase<R>::REPRESENTATION] = SoPlexBase<R>::REPRESENTATION_AUTO;
167  	
168  	   // type of algorithm, i.e., primal or dual
169  	   name[SoPlexBase<R>::ALGORITHM] = "algorithm";
170  	   description[SoPlexBase<R>::ALGORITHM] = "type of algorithm (0 - primal, 1 - dual)";
171  	   lower[SoPlexBase<R>::ALGORITHM] = 0;
172  	   upper[SoPlexBase<R>::ALGORITHM] = 1;
173  	   defaultValue[SoPlexBase<R>::ALGORITHM] = SoPlexBase<R>::ALGORITHM_DUAL;
174  	
175  	   // type of LU update
176  	   name[SoPlexBase<R>::FACTOR_UPDATE_TYPE] = "factor_update_type";
177  	   description[SoPlexBase<R>::FACTOR_UPDATE_TYPE] =
178  	      "type of LU update (0 - eta update, 1 - Forrest-Tomlin update)";
179  	   lower[SoPlexBase<R>::FACTOR_UPDATE_TYPE] = 0;
180  	   upper[SoPlexBase<R>::FACTOR_UPDATE_TYPE] = 1;
181  	   defaultValue[SoPlexBase<R>::FACTOR_UPDATE_TYPE] = SoPlexBase<R>::FACTOR_UPDATE_TYPE_FT;
182  	
183  	   // maximum number of updates without fresh factorization
184  	   name[SoPlexBase<R>::FACTOR_UPDATE_MAX] = "factor_update_max";
185  	   description[SoPlexBase<R>::FACTOR_UPDATE_MAX] =
186  	      "maximum number of LU updates without fresh factorization (0 - auto)";
187  	   lower[SoPlexBase<R>::FACTOR_UPDATE_MAX] = 0;
188  	   upper[SoPlexBase<R>::FACTOR_UPDATE_MAX] = INT_MAX;
189  	   defaultValue[SoPlexBase<R>::FACTOR_UPDATE_MAX] = 0;
190  	
191  	   // iteration limit (-1 if unlimited)
192  	   name[SoPlexBase<R>::ITERLIMIT] = "iterlimit";
193  	   description[SoPlexBase<R>::ITERLIMIT] = "iteration limit (-1 - no limit)";
194  	   lower[SoPlexBase<R>::ITERLIMIT] = -1;
195  	   upper[SoPlexBase<R>::ITERLIMIT] = INT_MAX;
196  	   defaultValue[SoPlexBase<R>::ITERLIMIT] = -1;
197  	
198  	   // refinement limit (-1 if unlimited)
199  	   name[SoPlexBase<R>::REFLIMIT] = "reflimit";
200  	   description[SoPlexBase<R>::REFLIMIT] = "refinement limit (-1 - no limit)";
201  	   lower[SoPlexBase<R>::REFLIMIT] = -1;
202  	   upper[SoPlexBase<R>::REFLIMIT] = INT_MAX;
203  	   defaultValue[SoPlexBase<R>::REFLIMIT] = -1;
204  	
205  	   // stalling refinement limit (-1 if unlimited)
206  	   name[SoPlexBase<R>::STALLREFLIMIT] = "stallreflimit";
207  	   description[SoPlexBase<R>::STALLREFLIMIT] = "stalling refinement limit (-1 - no limit)";
208  	   lower[SoPlexBase<R>::STALLREFLIMIT] = -1;
209  	   upper[SoPlexBase<R>::STALLREFLIMIT] = INT_MAX;
210  	   defaultValue[SoPlexBase<R>::STALLREFLIMIT] = -1;
211  	
212  	   // display frequency
213  	   name[SoPlexBase<R>::DISPLAYFREQ] = "displayfreq";
214  	   description[SoPlexBase<R>::DISPLAYFREQ] = "display frequency";
215  	   lower[SoPlexBase<R>::DISPLAYFREQ] = 1;
216  	   upper[SoPlexBase<R>::DISPLAYFREQ] = INT_MAX;
217  	   defaultValue[SoPlexBase<R>::DISPLAYFREQ] = 200;
218  	
219  	   // verbosity level
220  	   name[SoPlexBase<R>::VERBOSITY] = "verbosity";
221  	   description[SoPlexBase<R>::VERBOSITY] =
222  	      "verbosity level (0 - error, 1 - warning, 2 - debug, 3 - normal, 4 - high, 5 - full)";
223  	   lower[SoPlexBase<R>::VERBOSITY] = 0;
224  	   upper[SoPlexBase<R>::VERBOSITY] = 5;
225  	   defaultValue[SoPlexBase<R>::VERBOSITY] = SoPlexBase<R>::VERBOSITY_NORMAL;
226  	   //_intParamDefault[SoPlexBase<R>::VERBOSITY] = SoPlexBase<R>::VERBOSITY_FULL;
227  	
228  	   // type of simplifier
229  	   name[SoPlexBase<R>::SIMPLIFIER] = "simplifier";
230  	   description[SoPlexBase<R>::SIMPLIFIER] = "simplifier (0 - off, 1 - internal, 2 - PaPILO)";
231  	   lower[SoPlexBase<R>::SIMPLIFIER] = 0;
232  	   upper[SoPlexBase<R>::SIMPLIFIER] = 2;
233  	   defaultValue[SoPlexBase<R>::SIMPLIFIER] = SoPlexBase<R>::SIMPLIFIER_INTERNAL;
234  	
235  	   // type of scaler
236  	   name[SoPlexBase<R>::SCALER] = "scaler";
237  	   description[SoPlexBase<R>::SCALER] =
238  	      "scaling (0 - off, 1 - uni-equilibrium, 2 - bi-equilibrium, 3 - geometric, 4 - iterated geometric, 5 - least squares, 6 - geometric-equilibrium)";
239  	   lower[SoPlexBase<R>::SCALER] = 0;
240  	   upper[SoPlexBase<R>::SCALER] = 6;
241  	   defaultValue[SoPlexBase<R>::SCALER] = SoPlexBase<R>::SCALER_BIEQUI;
242  	
243  	   // type of starter used to create crash basis
244  	   name[SoPlexBase<R>::STARTER] = "starter";
245  	   description[SoPlexBase<R>::STARTER] =
246  	      "crash basis generated when starting from scratch (0 - none, 1 - weight, 2 - sum, 3 - vector)";
247  	   lower[SoPlexBase<R>::STARTER] = 0;
248  	   upper[SoPlexBase<R>::STARTER] = 3;
249  	   defaultValue[SoPlexBase<R>::STARTER] = SoPlexBase<R>::STARTER_OFF;
250  	
251  	   // type of pricer
252  	   name[SoPlexBase<R>::PRICER] = "pricer";
253  	   description[SoPlexBase<R>::PRICER] =
254  	      "pricing method (0 - auto, 1 - dantzig, 2 - parmult, 3 - devex, 4 - quicksteep, 5 - steep)";
255  	   lower[SoPlexBase<R>::PRICER] = 0;
256  	   upper[SoPlexBase<R>::PRICER] = 5;
257  	   defaultValue[SoPlexBase<R>::PRICER] = SoPlexBase<R>::PRICER_AUTO;
258  	
259  	   // type of ratio test
260  	   name[SoPlexBase<R>::RATIOTESTER] = "ratiotester";
261  	   description[SoPlexBase<R>::RATIOTESTER] =
262  	      "method for ratio test (0 - textbook, 1 - harris, 2 - fast, 3 - boundflipping)";
263  	   lower[SoPlexBase<R>::RATIOTESTER] = 0;
264  	   upper[SoPlexBase<R>::RATIOTESTER] = 3;
265  	   defaultValue[SoPlexBase<R>::RATIOTESTER] = SoPlexBase<R>::RATIOTESTER_BOUNDFLIPPING;
266  	
267  	   // mode for synchronizing real and rational LP
268  	   name[SoPlexBase<R>::SYNCMODE] = "syncmode";
269  	   description[SoPlexBase<R>::SYNCMODE] =
270  	      "mode for synchronizing real and rational LP (0 - store only real LP, 1 - auto, 2 - manual)";
271  	   lower[SoPlexBase<R>::SYNCMODE] = 0;
272  	   upper[SoPlexBase<R>::SYNCMODE] = 2;
273  	   defaultValue[SoPlexBase<R>::SYNCMODE] = SoPlexBase<R>::SYNCMODE_ONLYREAL;
274  	
275  	   // mode for reading LP files
276  	   name[SoPlexBase<R>::READMODE] = "readmode";
277  	   description[SoPlexBase<R>::READMODE] =
278  	      "mode for reading LP files (0 - floating-point, 1 - rational)";
279  	   lower[SoPlexBase<R>::READMODE] = 0;
280  	   upper[SoPlexBase<R>::READMODE] = 1;
281  	   defaultValue[SoPlexBase<R>::READMODE] = SoPlexBase<R>::READMODE_REAL;
282  	
283  	   // mode for iterative refinement strategy
284  	   name[SoPlexBase<R>::SOLVEMODE] = "solvemode";
285  	   description[SoPlexBase<R>::SOLVEMODE] =
286  	      "mode for iterative refinement strategy (0 - floating-point solve, 1 - auto, 2 - exact rational solve)";
287  	   lower[SoPlexBase<R>::SOLVEMODE] = 0;
288  	   upper[SoPlexBase<R>::SOLVEMODE] = 2;
289  	   defaultValue[SoPlexBase<R>::SOLVEMODE] = SoPlexBase<R>::SOLVEMODE_AUTO;
290  	
291  	   // mode for iterative refinement strategy
292  	   name[SoPlexBase<R>::CHECKMODE] = "checkmode";
293  	   description[SoPlexBase<R>::CHECKMODE] =
294  	      "mode for a posteriori feasibility checks (0 - floating-point check, 1 - auto, 2 - exact rational check)";
295  	   lower[SoPlexBase<R>::CHECKMODE] = 0;
296  	   upper[SoPlexBase<R>::CHECKMODE] = 2;
297  	   defaultValue[SoPlexBase<R>::CHECKMODE] = SoPlexBase<R>::CHECKMODE_AUTO;
298  	
299  	   // type of timing
300  	   name[SoPlexBase<R>::TIMER] = "timer";
301  	   description[SoPlexBase<R>::TIMER] =
302  	      "type of timer (1 - cputime, aka. usertime, 2 - wallclock time, 0 - no timing)";
303  	   lower[SoPlexBase<R>::TIMER] = 0;
304  	   upper[SoPlexBase<R>::TIMER] = 2;
305  	   defaultValue[SoPlexBase<R>::TIMER] = SoPlexBase<R>::TIMER_CPU;
306  	
307  	   // mode for hyper sparse pricing
308  	   name[SoPlexBase<R>::HYPER_PRICING] = "hyperpricing";
309  	   description[SoPlexBase<R>::HYPER_PRICING] =
310  	      "mode for hyper sparse pricing (0 - off, 1 - auto, 2 - always)";
311  	   lower[SoPlexBase<R>::HYPER_PRICING] = 0;
312  	   upper[SoPlexBase<R>::HYPER_PRICING] = 2;
313  	   defaultValue[SoPlexBase<R>::HYPER_PRICING] = SoPlexBase<R>::HYPER_PRICING_AUTO;
314  	
315  	   // minimum number of stalling refinements since last pivot to trigger rational factorization
316  	   name[SoPlexBase<R>::RATFAC_MINSTALLS] = "ratfac_minstalls";
317  	   description[SoPlexBase<R>::RATFAC_MINSTALLS] =
318  	      "minimum number of stalling refinements since last pivot to trigger rational factorization";
319  	   lower[SoPlexBase<R>::RATFAC_MINSTALLS] = 0;
320  	   upper[SoPlexBase<R>::RATFAC_MINSTALLS] = INT_MAX;
321  	   defaultValue[SoPlexBase<R>::RATFAC_MINSTALLS] = 2;
322  	
323  	   // maximum number of conjugate gradient iterations in least square scaling
324  	   name[SoPlexBase<R>::LEASTSQ_MAXROUNDS] = "leastsq_maxrounds";
325  	   description[SoPlexBase<R>::LEASTSQ_MAXROUNDS] =
326  	      "maximum number of conjugate gradient iterations in least square scaling";
327  	   lower[SoPlexBase<R>::LEASTSQ_MAXROUNDS] = 0;
328  	   upper[SoPlexBase<R>::LEASTSQ_MAXROUNDS] = INT_MAX;
329  	   defaultValue[SoPlexBase<R>::LEASTSQ_MAXROUNDS] = 50;
330  	
331  	   // mode for solution polishing
332  	   name[SoPlexBase<R>::SOLUTION_POLISHING] = "solution_polishing";
333  	   description[SoPlexBase<R>::SOLUTION_POLISHING] =
334  	      "mode for solution polishing (0 - off, 1 - max basic slack, 2 - min basic slack)";
335  	   lower[SoPlexBase<R>::SOLUTION_POLISHING] = 0;
336  	   upper[SoPlexBase<R>::SOLUTION_POLISHING] = 2;
337  	   defaultValue[SoPlexBase<R>::SOLUTION_POLISHING] = SoPlexBase<R>::POLISHING_OFF;
338  	
339  	   // the number of iterations before the decomposition simplex initialisation is terminated.
340  	   name[SoPlexBase<R>::DECOMP_ITERLIMIT] = "decomp_iterlimit";
341  	   description[SoPlexBase<R>::DECOMP_ITERLIMIT] =
342  	      "the number of iterations before the decomposition simplex initialisation solve is terminated";
343  	   lower[SoPlexBase<R>::DECOMP_ITERLIMIT] = 1;
344  	   upper[SoPlexBase<R>::DECOMP_ITERLIMIT] = INT_MAX;
345  	   defaultValue[SoPlexBase<R>::DECOMP_ITERLIMIT] = 100;
346  	
347  	   // maximum number of violated rows added in each iteration of the decomposition simplex
348  	   name[SoPlexBase<R>::DECOMP_MAXADDEDROWS] = "decomp_maxaddedrows";
349  	   description[SoPlexBase<R>::DECOMP_MAXADDEDROWS] =
350  	      "maximum number of rows that are added to the reduced problem when using the decomposition based simplex";
351  	   lower[SoPlexBase<R>::DECOMP_MAXADDEDROWS] = 1;
352  	   upper[SoPlexBase<R>::DECOMP_MAXADDEDROWS] = INT_MAX;
353  	   defaultValue[SoPlexBase<R>::DECOMP_MAXADDEDROWS] = 500;
354  	
355  	   // maximum number of violated rows added in each iteration of the decomposition simplex
356  	   name[SoPlexBase<R>::DECOMP_DISPLAYFREQ] = "decomp_displayfreq";
357  	   description[SoPlexBase<R>::DECOMP_DISPLAYFREQ] =
358  	      "the frequency that the decomposition based simplex status output is displayed.";
359  	   lower[SoPlexBase<R>::DECOMP_DISPLAYFREQ] = 1;
360  	   upper[SoPlexBase<R>::DECOMP_DISPLAYFREQ] = INT_MAX;
361  	   defaultValue[SoPlexBase<R>::DECOMP_DISPLAYFREQ] = 50;
362  	
363  	   // the verbosity of the decomposition based simplex
364  	   name[SoPlexBase<R>::DECOMP_VERBOSITY] = "decomp_verbosity";
365  	   description[SoPlexBase<R>::DECOMP_VERBOSITY] =
366  	      "the verbosity of decomposition based simplex (0 - error, 1 - warning, 2 - debug, 3 - normal, 4 - high, 5 - full).";
367  	   lower[SoPlexBase<R>::DECOMP_VERBOSITY] = 1;
368  	   upper[SoPlexBase<R>::DECOMP_VERBOSITY] = 5;
369  	   defaultValue[SoPlexBase<R>::DECOMP_VERBOSITY] = VERBOSITY_ERROR;
370  	
371  	   // printing condition number during the solve
372  	   name[SoPlexBase<R>::PRINTBASISMETRIC] = "printbasismetric";
373  	   description[SoPlexBase<R>::PRINTBASISMETRIC] =
374  	      "print basis metric during the solve (-1 - off, 0 - condition estimate , 1 - trace, 2 - determinant, 3 - condition)";
375  	   lower[SoPlexBase<R>::PRINTBASISMETRIC] = -1;
376  	   upper[SoPlexBase<R>::PRINTBASISMETRIC] = 3;
377  	   defaultValue[SoPlexBase<R>::PRINTBASISMETRIC] = -1;
378  	
379  	   /// measure time spent in solving steps, e.g. factorization time
380  	   name[SoPlexBase<R>::STATTIMER] = "stattimer";
381  	   description[SoPlexBase<R>::STATTIMER] =
382  	      "measure for statistics, e.g. factorization time (0 - off, 1 - user time, 2 - wallclock time)";
383  	   lower[SoPlexBase<R>::STATTIMER] = 0;
384  	   upper[SoPlexBase<R>::STATTIMER] = 2;
385  	   defaultValue[SoPlexBase<R>::STATTIMER] = 1;
386  	}
387  	
388  	template <class R>
389  	SoPlexBase<R>::Settings::RealParam::RealParam()
390  	{
391  	   // primal feasibility tolerance
392  	   name[SoPlexBase<R>::FEASTOL] = "feastol";
393  	   description[SoPlexBase<R>::FEASTOL] = "primal feasibility tolerance";
394  	   lower[SoPlexBase<R>::FEASTOL] = 0.0;
395  	   upper[SoPlexBase<R>::FEASTOL] = 1.0;
396  	   defaultValue[SoPlexBase<R>::FEASTOL] = 1e-6;
397  	
398  	   // dual feasibility tolerance
399  	   name[SoPlexBase<R>::OPTTOL] = "opttol";
400  	   description[SoPlexBase<R>::OPTTOL] = "dual feasibility tolerance";
401  	   lower[SoPlexBase<R>::OPTTOL] = 0.0;
402  	   upper[SoPlexBase<R>::OPTTOL] = 1.0;
403  	   defaultValue[SoPlexBase<R>::OPTTOL] = 1e-6;
404  	
405  	   ///@todo define suitable values depending on R type
406  	   // general zero tolerance
407  	   name[SoPlexBase<R>::EPSILON_ZERO] = "epsilon_zero";
408  	   description[SoPlexBase<R>::EPSILON_ZERO] = "general zero tolerance";
409  	   lower[SoPlexBase<R>::EPSILON_ZERO] = 0.0;
410  	   upper[SoPlexBase<R>::EPSILON_ZERO] = 1.0;
411  	   defaultValue[SoPlexBase<R>::EPSILON_ZERO] = DEFAULT_EPS_ZERO;
412  	
413  	   ///@todo define suitable values depending on R type
414  	   // zero tolerance used in factorization
415  	   name[SoPlexBase<R>::EPSILON_FACTORIZATION] = "epsilon_factorization";
416  	   description[SoPlexBase<R>::EPSILON_FACTORIZATION] = "zero tolerance used in factorization";
417  	   lower[SoPlexBase<R>::EPSILON_FACTORIZATION] = 0.0;
418  	   upper[SoPlexBase<R>::EPSILON_FACTORIZATION] = 1.0;
419  	   defaultValue[SoPlexBase<R>::EPSILON_FACTORIZATION] = DEFAULT_EPS_FACTOR;
420  	
421  	   ///@todo define suitable values depending on R type
422  	   // zero tolerance used in update of the factorization
423  	   name[SoPlexBase<R>::EPSILON_UPDATE] = "epsilon_update";
424  	   description[SoPlexBase<R>::EPSILON_UPDATE] = "zero tolerance used in update of the factorization";
425  	   lower[SoPlexBase<R>::EPSILON_UPDATE] = 0.0;
426  	   upper[SoPlexBase<R>::EPSILON_UPDATE] = 1.0;
427  	   defaultValue[SoPlexBase<R>::EPSILON_UPDATE] = DEFAULT_EPS_UPDATE;
428  	
429  	   ///@todo define suitable values depending on R type
430  	   // pivot zero tolerance used in factorization
431  	   name[SoPlexBase<R>::EPSILON_PIVOT] = "epsilon_pivot";
432  	   description[SoPlexBase<R>::EPSILON_PIVOT] = "pivot zero tolerance used in factorization";
433  	   lower[SoPlexBase<R>::EPSILON_PIVOT] = 0.0;
434  	   upper[SoPlexBase<R>::EPSILON_PIVOT] = 1.0;
435  	   defaultValue[SoPlexBase<R>::EPSILON_PIVOT] = DEFAULT_EPS_PIVOT;
436  	
437  	   ///@todo define suitable values depending on R type
438  	   // infinity threshold
439  	   name[SoPlexBase<R>::INFTY] = "infty";
440  	   description[SoPlexBase<R>::INFTY] = "infinity threshold";
441  	   lower[SoPlexBase<R>::INFTY] = 1e10;
442  	   upper[SoPlexBase<R>::INFTY] = 1e100;
443  	   defaultValue[SoPlexBase<R>::INFTY] = DEFAULT_INFINITY;
444  	
445  	   // time limit in seconds (INFTY if unlimited)
446  	   name[SoPlexBase<R>::TIMELIMIT] = "timelimit";
447  	   description[SoPlexBase<R>::TIMELIMIT] = "time limit in seconds";
448  	   lower[SoPlexBase<R>::TIMELIMIT] = 0.0;
449  	   upper[SoPlexBase<R>::TIMELIMIT] = DEFAULT_INFINITY;
450  	   defaultValue[SoPlexBase<R>::TIMELIMIT] = DEFAULT_INFINITY;
451  	
452  	   // lower limit on objective value
453  	   name[SoPlexBase<R>::OBJLIMIT_LOWER] = "objlimit_lower";
454  	   description[SoPlexBase<R>::OBJLIMIT_LOWER] = "lower limit on objective value";
455  	   lower[SoPlexBase<R>::OBJLIMIT_LOWER] = -DEFAULT_INFINITY;
456  	   upper[SoPlexBase<R>::OBJLIMIT_LOWER] = DEFAULT_INFINITY;
457  	   defaultValue[SoPlexBase<R>::OBJLIMIT_LOWER] = -DEFAULT_INFINITY;
458  	
459  	   // upper limit on objective value
460  	   name[SoPlexBase<R>::OBJLIMIT_UPPER] = "objlimit_upper";
461  	   description[SoPlexBase<R>::OBJLIMIT_UPPER] = "upper limit on objective value";
462  	   lower[SoPlexBase<R>::OBJLIMIT_UPPER] = -DEFAULT_INFINITY;
463  	   upper[SoPlexBase<R>::OBJLIMIT_UPPER] = DEFAULT_INFINITY;
464  	   defaultValue[SoPlexBase<R>::OBJLIMIT_UPPER] = DEFAULT_INFINITY;
465  	
466  	   // working tolerance for feasibility in floating-point solver during iterative refinement
467  	   name[SoPlexBase<R>::FPFEASTOL] = "fpfeastol";
468  	   description[SoPlexBase<R>::FPFEASTOL] =
469  	      "working tolerance for feasibility in floating-point solver during iterative refinement";
470  	   lower[SoPlexBase<R>::FPFEASTOL] = 1e-12;
471  	   upper[SoPlexBase<R>::FPFEASTOL] = 1.0;
472  	   defaultValue[SoPlexBase<R>::FPFEASTOL] = 1e-9;
473  	
474  	   // working tolerance for optimality in floating-point solver during iterative refinement
475  	   name[SoPlexBase<R>::FPOPTTOL] = "fpopttol";
476  	   description[SoPlexBase<R>::FPOPTTOL] =
477  	      "working tolerance for optimality in floating-point solver during iterative refinement";
478  	   lower[SoPlexBase<R>::FPOPTTOL] = 1e-12;
479  	   upper[SoPlexBase<R>::FPOPTTOL] = 1.0;
480  	   defaultValue[SoPlexBase<R>::FPOPTTOL] = 1e-9;
481  	
482  	   // maximum increase of scaling factors between refinements
483  	   name[SoPlexBase<R>::MAXSCALEINCR] = "maxscaleincr";
484  	   description[SoPlexBase<R>::MAXSCALEINCR] =
485  	      "maximum increase of scaling factors between refinements";
486  	   lower[SoPlexBase<R>::MAXSCALEINCR] = 1.0;
487  	   upper[SoPlexBase<R>::MAXSCALEINCR] = DEFAULT_INFINITY;
488  	   defaultValue[SoPlexBase<R>::MAXSCALEINCR] = 1e25;
489  	
490  	   // lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)
491  	   name[SoPlexBase<R>::LIFTMINVAL] = "liftminval";
492  	   description[SoPlexBase<R>::LIFTMINVAL] =
493  	      "lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)";
494  	   lower[SoPlexBase<R>::LIFTMINVAL] = 0.0;
495  	   upper[SoPlexBase<R>::LIFTMINVAL] = 0.1;
496  	   defaultValue[SoPlexBase<R>::LIFTMINVAL] = 0.000976562; // = 1/1024
497  	
498  	   // upper threshold in lifting (nonzero matrix coefficients with larger absolute value will be reformulated)
499  	   name[SoPlexBase<R>::LIFTMAXVAL] = "liftmaxval";
500  	   description[SoPlexBase<R>::LIFTMAXVAL] =
501  	      "lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)";
502  	   lower[SoPlexBase<R>::LIFTMAXVAL] = 10.0;
503  	   upper[SoPlexBase<R>::LIFTMAXVAL] = DEFAULT_INFINITY;
504  	   defaultValue[SoPlexBase<R>::LIFTMAXVAL] = 1024.0;
505  	
506  	   // threshold for using sparse pricing (no. of violations need to be smaller than threshold * dimension of problem)
507  	   name[SoPlexBase<R>::SPARSITY_THRESHOLD] = "sparsity_threshold";
508  	   description[SoPlexBase<R>::SPARSITY_THRESHOLD] =
509  	      "sparse pricing threshold (#violations < dimension * SPARSITY_THRESHOLD activates sparse pricing)";
510  	   lower[SoPlexBase<R>::SPARSITY_THRESHOLD] = 0.0;
511  	   upper[SoPlexBase<R>::SPARSITY_THRESHOLD] = 1.0;
512  	   defaultValue[SoPlexBase<R>::SPARSITY_THRESHOLD] = 0.6;
513  	
514  	   // threshold on number of rows vs. number of columns for switching from column to row representations in auto mode
515  	   name[SoPlexBase<R>::REPRESENTATION_SWITCH] = "representation_switch";
516  	   description[SoPlexBase<R>::REPRESENTATION_SWITCH] =
517  	      "threshold on number of rows vs. number of columns for switching from column to row representations in auto mode";
518  	   lower[SoPlexBase<R>::REPRESENTATION_SWITCH] = 0.0;
519  	   upper[SoPlexBase<R>::REPRESENTATION_SWITCH] = DEFAULT_INFINITY;
520  	   defaultValue[SoPlexBase<R>::REPRESENTATION_SWITCH] = 1.2;
521  	
522  	   // geometric frequency at which to apply rational reconstruction
523  	   name[SoPlexBase<R>::RATREC_FREQ] = "ratrec_freq";
524  	   description[SoPlexBase<R>::RATREC_FREQ] =
525  	      "geometric frequency at which to apply rational reconstruction";
526  	   lower[SoPlexBase<R>::RATREC_FREQ] = 1.0;
527  	   upper[SoPlexBase<R>::RATREC_FREQ] = DEFAULT_INFINITY;
528  	   defaultValue[SoPlexBase<R>::RATREC_FREQ] = 1.2;
529  	
530  	   // minimal reduction (sum of removed rows/cols) to continue simplification
531  	   name[SoPlexBase<R>::MINRED] = "minred";
532  	   description[SoPlexBase<R>::MINRED] =
533  	      "minimal reduction (sum of removed rows/cols) to continue simplification";
534  	   lower[SoPlexBase<R>::MINRED] = 0.0;
535  	   upper[SoPlexBase<R>::MINRED] = 1.0;
536  	   defaultValue[SoPlexBase<R>::MINRED] = 1e-4;
537  	
538  	   // refactor threshold for nonzeros in last factorized basis matrix compared to updated basis matrix
539  	   name[SoPlexBase<R>::REFAC_BASIS_NNZ] = "refac_basis_nnz";
540  	   description[SoPlexBase<R>::REFAC_BASIS_NNZ] =
541  	      "refactor threshold for nonzeros in last factorized basis matrix compared to updated basis matrix";
542  	   lower[SoPlexBase<R>::REFAC_BASIS_NNZ] = 1.0;
543  	   upper[SoPlexBase<R>::REFAC_BASIS_NNZ] = 100.0;
544  	   defaultValue[SoPlexBase<R>::REFAC_BASIS_NNZ] = 10.0;
545  	
546  	   // refactor threshold for fill-in in current factor update compared to fill-in in last factorization
547  	   name[SoPlexBase<R>::REFAC_UPDATE_FILL] = "refac_update_fill";
548  	   description[SoPlexBase<R>::REFAC_UPDATE_FILL] =
549  	      "refactor threshold for fill-in in current factor update compared to fill-in in last factorization";
550  	   lower[SoPlexBase<R>::REFAC_UPDATE_FILL] = 1.0;
551  	   upper[SoPlexBase<R>::REFAC_UPDATE_FILL] = 100.0;
552  	   defaultValue[SoPlexBase<R>::REFAC_UPDATE_FILL] = 5.0;
553  	
554  	   // refactor threshold for memory growth in factorization since last refactorization
555  	   name[SoPlexBase<R>::REFAC_MEM_FACTOR] = "refac_mem_factor";
556  	   description[SoPlexBase<R>::REFAC_MEM_FACTOR] =
557  	      "refactor threshold for memory growth in factorization since last refactorization";
558  	   lower[SoPlexBase<R>::REFAC_MEM_FACTOR] = 1.0;
559  	   upper[SoPlexBase<R>::REFAC_MEM_FACTOR] = 10.0;
560  	   defaultValue[SoPlexBase<R>::REFAC_MEM_FACTOR] = 1.5;
561  	
562  	   // accuracy of conjugate gradient method in least squares scaling (higher value leads to more iterations)
563  	   name[SoPlexBase<R>::LEASTSQ_ACRCY] = "leastsq_acrcy";
564  	   description[SoPlexBase<R>::LEASTSQ_ACRCY] =
565  	      "accuracy of conjugate gradient method in least squares scaling (higher value leads to more iterations)";
566  	   lower[SoPlexBase<R>::LEASTSQ_ACRCY] = 1.0;
567  	   upper[SoPlexBase<R>::LEASTSQ_ACRCY] = DEFAULT_INFINITY;
568  	   defaultValue[SoPlexBase<R>::LEASTSQ_ACRCY] = 1000.0;
569  	
570  	   // objective offset
571  	   name[SoPlexBase<R>::OBJ_OFFSET] = "obj_offset";
572  	   description[SoPlexBase<R>::OBJ_OFFSET] = "objective offset to be used";
573  	   lower[SoPlexBase<R>::OBJ_OFFSET] = -DEFAULT_INFINITY;
574  	   upper[SoPlexBase<R>::OBJ_OFFSET] = DEFAULT_INFINITY;
575  	   defaultValue[SoPlexBase<R>::OBJ_OFFSET] = 0.0;
576  	
577  	   // minimal Markowitz threshold to control sparsity/stability in LU factorization
578  	   name[SoPlexBase<R>::MIN_MARKOWITZ] = "min_markowitz";
579  	   description[SoPlexBase<R>::MIN_MARKOWITZ] = "minimal Markowitz threshold in LU factorization";
580  	   lower[SoPlexBase<R>::MIN_MARKOWITZ] = 0.0001;
581  	   upper[SoPlexBase<R>::MIN_MARKOWITZ] = 0.9999;
582  	   defaultValue[SoPlexBase<R>::MIN_MARKOWITZ] = 0.01;
583  	
584  	   // modification
585  	   name[SoPlexBase<R>::SIMPLIFIER_MODIFYROWFAC] = "simplifier_modifyrowfac";
586  	   description[SoPlexBase<R>::SIMPLIFIER_MODIFYROWFAC] =
587  	      "modify constraints when the number of nonzeros or rows is at most this factor times the number of nonzeros or rows before presolving";
588  	   lower[SoPlexBase<R>::SIMPLIFIER_MODIFYROWFAC] = 0;
589  	   upper[SoPlexBase<R>::SIMPLIFIER_MODIFYROWFAC] = 1;
590  	   defaultValue[SoPlexBase<R>::SIMPLIFIER_MODIFYROWFAC] = 1.0;
591  	}
592  	
593  	template <class R>
594  	typename SoPlexBase<R>::Settings& SoPlexBase<R>::Settings::operator=(const Settings& settings)
595  	{
596  	   for(int i = 0; i < SoPlexBase<R>::BOOLPARAM_COUNT; i++)
597  	      _boolParamValues[i] = settings._boolParamValues[i];
598  	
599  	   for(int i = 0; i < SoPlexBase<R>::INTPARAM_COUNT; i++)
600  	      _intParamValues[i] = settings._intParamValues[i];
601  	
602  	   for(int i = 0; i < SoPlexBase<R>::REALPARAM_COUNT; i++)
603  	      _realParamValues[i] = settings._realParamValues[i];
604  	
605  	#ifdef SOPLEX_WITH_RATIONALPARAM
606  	
607  	   for(int i = 0; i < SoPlexBase<R>::RATIONALPARAM_COUNT; i++)
608  	      _rationalParamValues[i] = settings._rationalParamValues[i];
609  	
610  	#endif
611  	
612  	   return *this;
613  	}
614  	
615  	
616  	#ifdef SOPLEX_WITH_RATIONALPARAM
617  	SoPlexBase<R>::Settings::RationalParam::RationalParam() {}
618  	#endif
619  	
620  	
621  	template <class R>
622  	SoPlexBase<R>::Settings::Settings()
623  	{
624  	   for(int i = 0; i < SoPlexBase<R>::BOOLPARAM_COUNT; i++)
625  	      _boolParamValues[i] = boolParam.defaultValue[i];
626  	
627  	   for(int i = 0; i < SoPlexBase<R>::INTPARAM_COUNT; i++)
628  	      _intParamValues[i] = intParam.defaultValue[i];
629  	
630  	   for(int i = 0; i < SoPlexBase<R>::REALPARAM_COUNT; i++)
631  	      _realParamValues[i] = realParam.defaultValue[i];
632  	
633  	#ifdef SOPLEX_WITH_RATIONALPARAM
634  	
635  	   for(int i = 0; i < SoPlexBase<R>::RATIONALPARAM_COUNT; i++)
636  	      _rationalParamValues[i] = rationalParam.defaultValue[i];
637  	
638  	#endif
639  	}
640  	
641  	template <class R>
642  	SoPlexBase<R>::Settings::Settings(const Settings& settings)
643  	{
644  	   *this = settings;
645  	}
646  	
647  	
648  	#ifdef SOPLEX_WITH_RATIONALPARAM
649  	template <class R>
650  	SoPlexBase<R>::Settings::RationalParam SoPlexBase<R>::Settings::rationalParam;
651  	#endif
652  	
653  	
654  	/// copy constructor
655  	///@todo improve performance by implementing a separate copy constructor
656  	template <class R>
657  	SoPlexBase<R>::SoPlexBase(const SoPlexBase<R>& rhs)
658  	{
659  	   // allocate memory as in default constructor
660  	   _statistics = nullptr;
661  	   spx_alloc(_statistics);
662  	   _statistics = new(_statistics) Statistics();
663  	
664  	   _currentSettings = nullptr;
665  	   spx_alloc(_currentSettings);
666  	   _currentSettings = new(_currentSettings) Settings();
667  	
668  	   // call assignment operator
669  	   *this = rhs;
670  	}
671  	
672  	
673  	
674  	/// destructor
675  	template <class R>
676  	SoPlexBase<R>::~SoPlexBase()
677  	{
678  	   assert(_isConsistent());
679  	
680  	   // free settings
681  	   _currentSettings->~Settings();
682  	   spx_free(_currentSettings);
683  	
684  	   // free statistics
685  	   _statistics->~Statistics();
686  	   spx_free(_statistics);
687  	
688  	   // free real LP if different from the LP in the solver
689  	   assert(_realLP != nullptr);
690  	
691  	   if(_realLP != &_solver)
692  	   {
693  	      _realLP->~SPxLPBase<R>();
694  	      spx_free(_realLP);
695  	   }
696  	
697  	   // free rational LP
698  	   if(_rationalLP != nullptr)
699  	   {
700  	      _rationalLP->~SPxLPRational();
701  	      spx_free(_rationalLP);
702  	   }
703  	
704  	   // free unit vectors
705  	   auto uMatSize = _unitMatrixRational.size();
706  	
707  	   for(decltype(uMatSize) i = 0; i < uMatSize; i++)
708  	   {
709  	      if(_unitMatrixRational[i] != nullptr)
710  	      {
711  	         _unitMatrixRational[i]->~UnitVectorRational();
712  	         spx_free(_unitMatrixRational[i]);
713  	      }
714  	   }
715  	}
716  	
717  	// For SCIP compatibility
718  	template <class R>
719  	int SoPlexBase<R>::numRowsReal() const
720  	{
721  	   return numRows();
722  	}
723  	
724  	
725  	// Wrapper for reverse compatibility
726  	template <class R>
727  	int SoPlexBase<R>::numColsReal() const
728  	{
729  	   return numCols();
730  	}
731  	
732  	
733  	// Wrapper function for reverse compatibility
734  	template <class R>
735  	bool SoPlexBase<R>::getPrimalRayReal(R* vector, int dim)
736  	{
737  	   if(hasPrimalRay() && dim >= numCols())
738  	   {
739  	      _syncRealSolution();
740  	      auto& primalRay = _solReal._primalRay;
741  	      std::copy(primalRay.begin(), primalRay.end(), vector);
742  	
743  	      return true;
744  	   }
745  	   else
746  	      return false;
747  	
748  	}
749  	
750  	
751  	// Wrapper function for reverse compatibility
752  	template <class R>
753  	bool SoPlexBase<R>::getDualReal(R* p_vector, int dim) // For SCIP
754  	{
755  	   if(hasSol() && dim >= numRows())
756  	   {
757  	      _syncRealSolution();
758  	      auto& dual = _solReal._dual;
759  	      std::copy(dual.begin(), dual.end(), p_vector);
760  	
761  	      return true;
762  	   }
763  	   else
764  	      return false;
765  	
766  	}
767  	
768  	
769  	
770  	/// wrapper for backwards compatibility
771  	template <class R>
772  	bool SoPlexBase<R>::getRedCostReal(R* p_vector, int dim) // For SCIP compatibility
773  	{
774  	   if(hasSol() && dim >= numCols())
775  	   {
776  	      _syncRealSolution();
777  	      auto& redcost = _solReal._redCost;
778  	      std::copy(redcost.begin(), redcost.end(), p_vector);
779  	
780  	      return true;
781  	   }
782  	   else
783  	      return false;
784  	
785  	}
786  	
787  	
788  	
789  	
790  	// Wrapping the function for reverse Compatibility
791  	template <class R>
792  	bool SoPlexBase<R>::getDualFarkasReal(R* vector, int dim)
793  	{
794  	   if(hasDualFarkas() && dim >= numRows())
795  	   {
796  	      _syncRealSolution();
797  	      auto& dualFarkas = _solReal._dualFarkas;
798  	      std::copy(dualFarkas.begin(), dualFarkas.end(), vector);
799  	
800  	      return true;
801  	   }
802  	   else
803  	      return false;
804  	
805  	}
806  	
807  	
808  	
809  	#ifdef SOPLEX_WITH_GMP
810  	/// gets the primal solution vector if available; returns true on success (GMP only method)
811  	template <class R>
812  	bool SoPlexBase<R>::getPrimalRational(mpq_t* vector, const int size)
813  	{
814  	#ifndef SOPLEX_WITH_BOOST
815  	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
816  	   return false;
817  	#else
818  	   assert(size >= numColsRational());
819  	
820  	   if(hasSol())
821  	   {
822  	      _syncRationalSolution();
823  	
824  	      for(int i = 0; i < numColsRational(); i++)
825  	         mpq_set(vector[i], _solRational._primal[i].backend().data());
826  	
827  	      return true;
828  	   }
829  	   else
830  	      return false;
831  	
832  	#endif
833  	}
834  	
835  	
836  	/// gets the vector of slack values if available; returns true on success (GMP only method)
837  	template <class R>
838  	bool SoPlexBase<R>::getSlacksRational(mpq_t* vector, const int size)
839  	{
840  	#ifndef SOPLEX_WITH_BOOST
841  	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
842  	   return false;
843  	#else
844  	   assert(size >= numRowsRational());
845  	
846  	   if(hasSol())
847  	   {
848  	      _syncRationalSolution();
849  	
850  	      for(int i = 0; i < numRowsRational(); i++)
851  	         mpq_set(vector[i], _solRational._slacks[i].backend().data());
852  	
853  	      return true;
854  	   }
855  	   else
856  	      return false;
857  	
858  	#endif
859  	}
860  	
861  	
862  	
863  	/// gets the primal ray if LP is unbounded; returns true on success (GMP only method)
864  	template <class R>
865  	bool SoPlexBase<R>::getPrimalRayRational(mpq_t* vector, const int size)
866  	{
867  	#ifndef SOPLEX_WITH_BOOST
868  	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
869  	   return false;
870  	#else
871  	   assert(size >= numColsRational());
872  	
873  	   if(hasPrimalRay())
874  	   {
875  	      _syncRationalSolution();
876  	
877  	      for(int i = 0; i < numColsRational(); i++)
878  	         mpq_set(vector[i], _solRational._primalRay[i].backend().data());
879  	
880  	      return true;
881  	   }
882  	   else
883  	      return false;
884  	
885  	#endif
886  	}
887  	
888  	
889  	
890  	/// gets the dual solution vector if available; returns true on success (GMP only method)
891  	template <class R>
892  	bool SoPlexBase<R>::getDualRational(mpq_t* vector, const int size)
893  	{
894  	#ifndef SOPLEX_WITH_BOOST
895  	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
896  	   return false;
897  	#else
898  	   assert(size >= numRowsRational());
899  	
900  	   if(hasSol())
901  	   {
902  	      _syncRationalSolution();
903  	
904  	      for(int i = 0; i < numRowsRational(); i++)
905  	         mpq_set(vector[i], _solRational._dual[i].backend().data());
906  	
907  	      return true;
908  	   }
909  	   else
910  	      return false;
911  	
912  	#endif
913  	}
914  	
915  	
916  	
917  	/// gets the vector of reduced cost values if available; returns true on success (GMP only method)
918  	template <class R>
919  	bool SoPlexBase<R>::getRedCostRational(mpq_t* vector, const int size)
920  	{
921  	#ifndef SOPLEX_WITH_BOOST
922  	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
923  	   return false;
924  	#else
925  	   assert(size >= numColsRational());
926  	
927  	   if(hasSol())
928  	   {
929  	      _syncRationalSolution();
930  	
931  	      for(int i = 0; i < numColsRational(); i++)
932  	         mpq_set(vector[i], _solRational._redCost[i].backend().data());
933  	
934  	      return true;
935  	   }
936  	   else
937  	      return false;
938  	
939  	#endif
940  	}
941  	
942  	
943  	
944  	/// gets the Farkas proof if LP is infeasible; returns true on success (GMP only method)
945  	template <class R>
946  	bool SoPlexBase<R>::getDualFarkasRational(mpq_t* vector, const int size)
947  	{
948  	#ifndef SOPLEX_WITH_BOOST
949  	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
950  	   return false;
951  	#else
952  	   assert(size >= numRowsRational());
953  	
954  	   if(hasDualFarkas())
955  	   {
956  	      _syncRationalSolution();
957  	
958  	      for(int i = 0; i < numRowsRational(); i++)
959  	         mpq_set(vector[i], _solRational._dualFarkas[i].backend().data());
960  	
961  	      return true;
962  	   }
963  	   else
964  	      return false;
965  	
966  	#endif
967  	}
968  	#endif
969  	
970  	
971  	// Alias for writeFile; SCIP
972  	template <class R>
973  	bool SoPlexBase<R>::writeFileReal(const char* filename, const NameSet* rowNames,
974  	                                  const NameSet* colNames, const DIdxSet* intVars, const bool unscale) const
975  	{
976  	   return writeFile(filename, rowNames, colNames, intVars, unscale);
977  	}
978  	
979  	/// writes rational LP to file; LP or MPS format is chosen from the extension in \p filename; if \p rowNames and \p
980  	/// colNames are \c NULL, default names are used; if \p intVars is not \c NULL, the variables contained in it are
981  	/// marked as integer; returns true on success
982  	/// Here unscale is just a junk variable that is used to match the type with the real write function
983  	template <class R>
984  	bool SoPlexBase<R>::writeFileRational(const char* filename, const NameSet* rowNames,
985  	                                      const NameSet* colNames, const DIdxSet* intVars) const
986  	{
987  	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
988  	      return false;
989  	   else
990  	   {
991  	      assert(_rationalLP != 0);
992  	      _rationalLP->writeFileLPBase(filename, rowNames, colNames, intVars);
993  	
994  	      ///@todo implement return value
995  	      return true;
996  	   }
997  	}
998  	
999  	
1000 	
1001 	
1002 	
1003 	
1004 	/// writes internal LP, basis information, and parameter settings; if \p rowNames and \p colNames are \c NULL,
1005 	/// default names are used
1006 	template <class R>
1007 	void SoPlexBase<R>::writeStateReal(const char* filename, const NameSet* rowNames,
1008 	                                   const NameSet* colNames, const bool cpxFormat) const
1009 	{
1010 	   std::string ofname;
1011 	
1012 	   // write parameter settings
1013 	   ofname = std::string(filename) + ".set";
1014 	   saveSettingsFile(ofname.c_str());
1015 	
1016 	   // write problem in MPS/LP format
1017 	   ofname = std::string(filename) + ((cpxFormat) ? ".lp" : ".mps");
1018 	   writeFile(ofname.c_str(), rowNames, colNames, 0);
1019 	
1020 	   // write basis
1021 	   ofname = std::string(filename) + ".bas";
1022 	   writeBasisFile(ofname.c_str(), rowNames, colNames, cpxFormat);
1023 	}
1024 	
1025 	
1026 	
1027 	/// writes internal LP, basis information, and parameter settings; if \p rowNames and \p colNames are \c NULL,
1028 	/// default names are used
1029 	template <class R>
1030 	void SoPlexBase<R>::writeStateRational(const char* filename, const NameSet* rowNames,
1031 	                                       const NameSet* colNames, const bool cpxFormat) const
1032 	{
1033 	   std::string ofname;
1034 	
1035 	   // write parameter settings
1036 	   ofname = std::string(filename) + ".set";
1037 	   saveSettingsFile(ofname.c_str());
1038 	
1039 	   // write problem in MPS/LP format
1040 	   ofname = std::string(filename) + ((cpxFormat) ? ".lp" : ".mps");
1041 	   writeFileRational(ofname.c_str(), rowNames, colNames, 0);
1042 	
1043 	   // write basis
1044 	   ofname = std::string(filename) + ".bas";
1045 	   writeBasisFile(ofname.c_str(), rowNames, colNames, cpxFormat);
1046 	}
1047 	
1048 	/// returns number of columns
1049 	template <class R>
1050 	int SoPlexBase<R>::numCols() const
1051 	{
1052 	   assert(_realLP != nullptr);
1053 	   return _realLP->nCols();
1054 	}
1055 	
1056 	/// returns number of rows
1057 	template <class R>
1058 	int SoPlexBase<R>::numRows() const
1059 	{
1060 	   assert(_realLP != nullptr);
1061 	   return _realLP->nRows();
1062 	}
1063 	
1064 	/// returns number of nonzeros
1065 	template <class R>
1066 	int SoPlexBase<R>::numNonzeros() const
1067 	{
1068 	   assert(_realLP != 0);
1069 	   return _realLP->nNzos();
1070 	}
1071 	
1072 	/// gets the primal solution vector if available; returns true on success
1073 	template <class R>
1074 	bool SoPlexBase<R>::getPrimal(VectorBase<R>& vector)
1075 	{
1076 	   if(hasSol() && vector.dim() >= numCols())
1077 	   {
1078 	      _syncRealSolution();
1079 	      _solReal.getPrimalSol(vector);
1080 	      return true;
1081 	   }
1082 	   else
1083 	      return false;
1084 	}
1085 	
1086 	// A custom function for compatibility with scip and avoid making unnecessary
1087 	// copies.
1088 	template <class R>
1089 	bool SoPlexBase<R>::getPrimalReal(R* p_vector, int size)
1090 	{
1091 	   if(hasSol() && size >= numCols())
1092 	   {
1093 	      _syncRealSolution();
1094 	
1095 	      auto& primal = _solReal._primal;
1096 	      std::copy(primal.begin(), primal.end(), p_vector);
1097 	
1098 	      return true;
1099 	   }
1100 	   else
1101 	      return false;
1102 	}
1103 	
1104 	/// gets the primal ray if available; returns true on success
1105 	template <class R>
1106 	bool SoPlexBase<R>::getPrimalRay(VectorBase<R>& vector)
1107 	{
1108 	   if(hasPrimalRay() && vector.dim() >= numCols())
1109 	   {
1110 	      _syncRealSolution();
1111 	      _solReal.getPrimalRaySol(vector);
1112 	      return true;
1113 	   }
1114 	   else
1115 	      return false;
1116 	
1117 	}
1118 	
1119 	
1120 	/// gets the dual solution vector if available; returns true on success
1121 	template <class R>
1122 	bool SoPlexBase<R>::getDual(VectorBase<R>& vector)
1123 	{
1124 	   if(hasSol() && vector.dim() >= numRows())
1125 	   {
1126 	      _syncRealSolution();
1127 	      _solReal.getDualSol(vector);
1128 	      return true;
1129 	   }
1130 	   else
1131 	      return false;
1132 	}
1133 	
1134 	
1135 	
1136 	/// gets the Farkas proof if available; returns true on success
1137 	template <class R>
1138 	bool SoPlexBase<R>::getDualFarkas(VectorBase<R>& vector)
1139 	{
1140 	   if(hasDualFarkas() && vector.dim() >= numRows())
1141 	   {
1142 	      _syncRealSolution();
1143 	      _solReal.getDualFarkasSol(vector);
1144 	      return true;
1145 	   }
1146 	   else
1147 	      return false;
1148 	}
1149 	
1150 	
1151 	/// gets violation of bounds; returns true on success
1152 	template <class R>
1153 	bool SoPlexBase<R>::getBoundViolation(R& maxviol, R& sumviol)
1154 	{
1155 	   if(!isPrimalFeasible())
1156 	      return false;
1157 	
1158 	   _syncRealSolution();
1159 	   VectorBase<R>& primal = _solReal._primal;
1160 	   assert(primal.dim() == numCols());
1161 	
1162 	   maxviol = 0.0;
1163 	   sumviol = 0.0;
1164 	
1165 	   for(int i = numCols() - 1; i >= 0; i--)
1166 	   {
1167 	      R lower = _realLP->lowerUnscaled(i);
1168 	      R upper = _realLP->upperUnscaled(i);
1169 	      R viol = lower - primal[i];
1170 	
1171 	      if(viol > 0.0)
1172 	      {
1173 	         sumviol += viol;
1174 	
1175 	         if(viol > maxviol)
1176 	            maxviol = viol;
1177 	      }
1178 	
1179 	      viol = primal[i] - upper;
1180 	
1181 	      if(viol > 0.0)
1182 	      {
1183 	         sumviol += viol;
1184 	
1185 	         if(viol > maxviol)
1186 	            maxviol = viol;
1187 	      }
1188 	   }
1189 	
1190 	   return true;
1191 	}
1192 	
1193 	/// gets the vector of reduced cost values if available; returns true on success
1194 	template <class R>
1195 	bool SoPlexBase<R>::getRedCost(VectorBase<R>& vector)
1196 	{
1197 	   if(hasSol() && vector.dim() >= numCols())
1198 	   {
1199 	      _syncRealSolution();
1200 	      _solReal.getRedCostSol(vector);
1201 	      return true;
1202 	   }
1203 	   else
1204 	      return false;
1205 	}
1206 	
1207 	/// gets violation of constraints; returns true on success
1208 	template <class R>
1209 	bool SoPlexBase<R>::getRowViolation(R& maxviol, R& sumviol)
1210 	{
1211 	   if(!isPrimalFeasible())
1212 	      return false;
1213 	
1214 	   _syncRealSolution();
1215 	   VectorBase<R>& primal = _solReal._primal;
1216 	   assert(primal.dim() == numCols());
1217 	
1218 	   VectorBase<R> activity(numRows());
1219 	   _realLP->computePrimalActivity(primal, activity, true);
1220 	   maxviol = 0.0;
1221 	   sumviol = 0.0;
1222 	
1223 	   for(int i = numRows() - 1; i >= 0; i--)
1224 	   {
1225 	      R lhs = _realLP->lhsUnscaled(i);
1226 	      R rhs = _realLP->rhsUnscaled(i);
1227 	
1228 	      R viol = lhs - activity[i];
1229 	
1230 	      if(viol > 0.0)
1231 	      {
1232 	         sumviol += viol;
1233 	
1234 	         if(viol > maxviol)
1235 	            maxviol = viol;
1236 	      }
1237 	
1238 	      viol = activity[i] - rhs;
1239 	
1240 	      if(viol > 0.0)
1241 	      {
1242 	         sumviol += viol;
1243 	
1244 	         if(viol > maxviol)
1245 	            maxviol = viol;
1246 	      }
1247 	   }
1248 	
1249 	   return true;
1250 	}
1251 	
1252 	/// gets violation of dual multipliers; returns true on success
1253 	template <class R>
1254 	bool SoPlexBase<R>::getDualViolation(R& maxviol, R& sumviol)
1255 	{
1256 	   if(!isDualFeasible() || !hasBasis())
1257 	      return false;
1258 	
1259 	   _syncRealSolution();
1260 	   VectorBase<R>& dual = _solReal._dual;
1261 	   assert(dual.dim() == numRows());
1262 	
1263 	   maxviol = 0.0;
1264 	   sumviol = 0.0;
1265 	
1266 	   for(int r = numRows() - 1; r >= 0; r--)
1267 	   {
1268 	      typename SPxSolverBase<R>::VarStatus rowStatus = basisRowStatus(r);
1269 	
1270 	      if(intParam(SoPlexBase<R>::OBJSENSE) == OBJSENSE_MINIMIZE)
1271 	      {
1272 	         if(rowStatus != SPxSolverBase<R>::ON_UPPER && rowStatus != SPxSolverBase<R>::FIXED && dual[r] < 0.0)
1273 	         {
1274 	            sumviol += -dual[r];
1275 	
1276 	            if(dual[r] < -maxviol)
1277 	               maxviol = -dual[r];
1278 	         }
1279 	
1280 	         if(rowStatus != SPxSolverBase<R>::ON_LOWER && rowStatus != SPxSolverBase<R>::FIXED && dual[r] > 0.0)
1281 	         {
1282 	            sumviol += dual[r];
1283 	
1284 	            if(dual[r] > maxviol)
1285 	               maxviol = dual[r];
1286 	         }
1287 	      }
1288 	      else
1289 	      {
1290 	         if(rowStatus != SPxSolverBase<R>::ON_UPPER && rowStatus != SPxSolverBase<R>::FIXED && dual[r] > 0.0)
1291 	         {
1292 	            sumviol += dual[r];
1293 	
1294 	            if(dual[r] > maxviol)
1295 	               maxviol = dual[r];
1296 	         }
1297 	
1298 	         if(rowStatus != SPxSolverBase<R>::ON_LOWER && rowStatus != SPxSolverBase<R>::FIXED && dual[r] < 0.0)
1299 	         {
1300 	            sumviol += -dual[r];
1301 	
1302 	            if(dual[r] < -maxviol)
1303 	               maxviol = -dual[r];
1304 	         }
1305 	      }
1306 	   }
1307 	
1308 	   return true;
1309 	}
1310 	
1311 	/// gets violation of reduced costs; returns true on success
1312 	template <class R>
1313 	bool SoPlexBase<R>::getRedCostViolation(R& maxviol, R& sumviol)
1314 	{
1315 	   if(!isDualFeasible() || !hasBasis())
1316 	      return false;
1317 	
1318 	   _syncRealSolution();
1319 	   VectorBase<R>& redcost = _solReal._redCost;
1320 	   assert(redcost.dim() == numCols());
1321 	
1322 	   maxviol = 0.0;
1323 	   sumviol = 0.0;
1324 	
1325 	   for(int c = numCols() - 1; c >= 0; c--)
1326 	   {
1327 	      typename SPxSolverBase<R>::VarStatus colStatus = basisColStatus(c);
1328 	
1329 	      if(intParam(SoPlexBase<R>::OBJSENSE) == OBJSENSE_MINIMIZE)
1330 	      {
1331 	         if(colStatus != SPxSolverBase<R>::ON_UPPER && colStatus != SPxSolverBase<R>::FIXED
1332 	               && redcost[c] < 0.0)
1333 	         {
1334 	            sumviol += -redcost[c];
1335 	
1336 	            if(redcost[c] < -maxviol)
1337 	               maxviol = -redcost[c];
1338 	         }
1339 	
1340 	         if(colStatus != SPxSolverBase<R>::ON_LOWER && colStatus != SPxSolverBase<R>::FIXED
1341 	               && redcost[c] > 0.0)
1342 	         {
1343 	            sumviol += redcost[c];
1344 	
1345 	            if(redcost[c] > maxviol)
1346 	               maxviol = redcost[c];
1347 	         }
1348 	      }
1349 	      else
1350 	      {
1351 	         if(colStatus != SPxSolverBase<R>::ON_UPPER && colStatus != SPxSolverBase<R>::FIXED
1352 	               && redcost[c] > 0.0)
1353 	         {
1354 	            sumviol += redcost[c];
1355 	
1356 	            if(redcost[c] > maxviol)
1357 	               maxviol = redcost[c];
1358 	         }
1359 	
1360 	         if(colStatus != SPxSolverBase<R>::ON_LOWER && colStatus != SPxSolverBase<R>::FIXED
1361 	               && redcost[c] < 0.0)
1362 	         {
1363 	            sumviol += -redcost[c];
1364 	
1365 	            if(redcost[c] < -maxviol)
1366 	               maxviol = -redcost[c];
1367 	         }
1368 	      }
1369 	   }
1370 	
1371 	   return true;
1372 	}
1373 	
1374 	
1375 	/// assignment operator
1376 	template <class R>
1377 	SoPlexBase<R>& SoPlexBase<R>::operator=(const SoPlexBase<R>& rhs)
1378 	{
1379 	   if(this != &rhs)
1380 	   {
1381 	      // copy message handler
1382 	      spxout = rhs.spxout;
1383 	
1384 	      // copy statistics
1385 	      *_statistics = *(rhs._statistics);
1386 	
1387 	      // copy settings
1388 	      *_currentSettings = *(rhs._currentSettings);
1389 	
1390 	      // copy solver components
1391 	      _solver = rhs._solver;
1392 	      _slufactor = rhs._slufactor;
1393 	      _simplifierMainSM = rhs._simplifierMainSM;
1394 	      _simplifierPaPILO = rhs._simplifierPaPILO;
1395 	      _scalerUniequi = rhs._scalerUniequi;
1396 	      _scalerBiequi = rhs._scalerBiequi;
1397 	      _scalerGeo1 = rhs._scalerGeo1;
1398 	      _scalerGeo8 = rhs._scalerGeo8;
1399 	      _scalerGeoequi = rhs._scalerGeoequi;
1400 	      _scalerLeastsq = rhs._scalerLeastsq;
1401 	      _starterWeight = rhs._starterWeight;
1402 	      _starterSum = rhs._starterSum;
1403 	      _starterVector = rhs._starterVector;
1404 	      _pricerAuto = rhs._pricerAuto;
1405 	      _pricerDantzig = rhs._pricerDantzig;
1406 	      _pricerParMult = rhs._pricerParMult;
1407 	      _pricerDevex = rhs._pricerDevex;
1408 	      _pricerQuickSteep = rhs._pricerQuickSteep;
1409 	      _pricerSteep = rhs._pricerSteep;
1410 	      _ratiotesterTextbook = rhs._ratiotesterTextbook;
1411 	      _ratiotesterHarris = rhs._ratiotesterHarris;
1412 	      _ratiotesterFast = rhs._ratiotesterFast;
1413 	      _ratiotesterBoundFlipping = rhs._ratiotesterBoundFlipping;
1414 	
1415 	      // copy solution data
1416 	      _status = rhs._status;
1417 	      _lastSolveMode = rhs._lastSolveMode;
1418 	      _basisStatusRows = rhs._basisStatusRows;
1419 	      _basisStatusCols = rhs._basisStatusCols;
1420 	
1421 	      if(rhs._hasSolReal)
1422 	         _solReal = rhs._solReal;
1423 	
1424 	      if(rhs._hasSolRational)
1425 	         _solRational = rhs._solRational;
1426 	
1427 	      // set message handlers in members
1428 	      _solver.setOutstream(spxout);
1429 	      _simplifier->setOutstream(spxout);
1430 	      _scalerUniequi.setOutstream(spxout);
1431 	      _scalerBiequi.setOutstream(spxout);
1432 	      _scalerGeo1.setOutstream(spxout);
1433 	      _scalerGeo8.setOutstream(spxout);
1434 	      _scalerGeoequi.setOutstream(spxout);
1435 	      _scalerLeastsq.setOutstream(spxout);
1436 	
1437 	      // transfer the lu solver
1438 	      _solver.setBasisSolver(&_slufactor);
1439 	
1440 	      // initialize pointers for simplifier, scaler, and starter
1441 	      setIntParam(SoPlexBase<R>::SIMPLIFIER, intParam(SoPlexBase<R>::SIMPLIFIER), true);
1442 	      setIntParam(SoPlexBase<R>::SCALER, intParam(SoPlexBase<R>::SCALER), true);
1443 	      setIntParam(SoPlexBase<R>::STARTER, intParam(SoPlexBase<R>::STARTER), true);
1444 	
1445 	      // copy real LP if different from the LP in the solver
1446 	      if(rhs._realLP != &(rhs._solver))
1447 	      {
1448 	         _realLP = 0;
1449 	         spx_alloc(_realLP);
1450 	         _realLP = new(_realLP) SPxLPBase<R>(*(rhs._realLP));
1451 	      }
1452 	      else
1453 	         _realLP = &_solver;
1454 	
1455 	      // copy rational LP
1456 	      if(rhs._rationalLP == 0)
1457 	      {
1458 	         assert(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL);
1459 	         _rationalLP = 0;
1460 	      }
1461 	      else
1462 	      {
1463 	         assert(intParam(SoPlexBase<R>::SYNCMODE) != SYNCMODE_ONLYREAL);
1464 	         _rationalLP = 0;
1465 	         spx_alloc(_rationalLP);
1466 	         _rationalLP = new(_rationalLP) SPxLPRational(*rhs._rationalLP);
1467 	      }
1468 	
1469 	      // copy rational factorization
1470 	      if(rhs._rationalLUSolver.status() == SLinSolverRational::OK)
1471 	         _rationalLUSolver = rhs._rationalLUSolver;
1472 	
1473 	      // copy boolean flags
1474 	      _isRealLPLoaded = rhs._isRealLPLoaded;
1475 	      _isRealLPScaled = rhs._isRealLPScaled;
1476 	      _hasSolReal = rhs._hasSolReal;
1477 	      _hasSolRational = rhs._hasSolRational;
1478 	      _hasBasis = rhs._hasBasis;
1479 	      _applyPolishing = rhs._applyPolishing;
1480 	
1481 	      // rational constants do not need to be assigned
1482 	      _rationalPosone = 1;
1483 	      _rationalNegone = -1;
1484 	      _rationalZero = 0;
1485 	   }
1486 	
1487 	   assert(_isConsistent());
1488 	
1489 	   return *this;
1490 	}
1491 	
1492 	/// returns smallest non-zero element in absolute value
1493 	template <class R>
1494 	R SoPlexBase<R>::minAbsNonzeroReal() const
1495 	{
1496 	   assert(_realLP != 0);
1497 	   return _realLP->minAbsNzo();
1498 	}
1499 	
1500 	
1501 	/// returns biggest non-zero element in absolute value
1502 	template <class R>
1503 	R SoPlexBase<R>::maxAbsNonzeroReal() const
1504 	{
1505 	   assert(_realLP != 0);
1506 	   return _realLP->maxAbsNzo();
1507 	}
1508 	
1509 	
1510 	/// returns (unscaled) coefficient
1511 	template <class R>
1512 	R SoPlexBase<R>::coefReal(int row, int col) const
1513 	{
1514 	   if(_realLP->isScaled())
1515 	   {
1516 	      assert(_scaler);
1517 	      return _scaler->getCoefUnscaled(*_realLP, row, col);
1518 	   }
1519 	   else
1520 	      return colVectorRealInternal(col)[row];
1521 	}
1522 	
1523 	/// returns vector of row \p i, ignoring scaling
1524 	template <class R>
1525 	const SVectorBase<R>& SoPlexBase<R>::rowVectorRealInternal(int i) const
1526 	{
1527 	   assert(_realLP != 0);
1528 	   return _realLP->rowVector(i);
1529 	}
1530 	
1531 	/// gets vector of row \p i
1532 	template <class R>
1533 	void SoPlexBase<R>::getRowVectorReal(int i, DSVectorBase<R>& row) const
1534 	{
1535 	   assert(_realLP);
1536 	
1537 	   if(_realLP->isScaled())
1538 	   {
1539 	      assert(_scaler);
1540 	      row.setMax(_realLP->rowVector(i).size());
1541 	      _scaler->getRowUnscaled(*_realLP, i, row);
1542 	   }
1543 	   else
1544 	      row = _realLP->rowVector(i);
1545 	}
1546 	
1547 	
1548 	/// returns right-hand side vector, ignoring scaling
1549 	template <class R>
1550 	const VectorBase<R>& SoPlexBase<R>::rhsRealInternal() const
1551 	{
1552 	   assert(_realLP != 0);
1553 	   return _realLP->rhs();
1554 	}
1555 	
1556 	
1557 	
1558 	/// gets right-hand side vector
1559 	template <class R>
1560 	void SoPlexBase<R>::getRhsReal(VectorBase<R>& rhs) const
1561 	{
1562 	   assert(_realLP);
1563 	   _realLP->getRhsUnscaled(rhs);
1564 	}
1565 	
1566 	
1567 	
1568 	/// returns right-hand side of row \p i
1569 	template <class R>
1570 	R SoPlexBase<R>::rhsReal(int i) const
1571 	{
1572 	   assert(_realLP != 0);
1573 	   return _realLP->rhsUnscaled(i);
1574 	}
1575 	
1576 	/// returns left-hand side vector, ignoring scaling
1577 	template <class R>
1578 	const VectorBase<R>& SoPlexBase<R>::lhsRealInternal() const
1579 	{
1580 	   assert(_realLP != 0);
1581 	   return _realLP->lhs();
1582 	}
1583 	
1584 	/// gets left-hand side vector
1585 	template <class R>
1586 	void SoPlexBase<R>::getLhsReal(VectorBase<R>& lhs) const
1587 	{
1588 	   assert(_realLP);
1589 	   _realLP->getLhsUnscaled(lhs);
1590 	}
1591 	
1592 	/// returns left-hand side of row \p i
1593 	template <class R>
1594 	R SoPlexBase<R>::lhsReal(int i) const
1595 	{
1596 	   assert(_realLP != 0);
1597 	   return _realLP->lhsUnscaled(i);
1598 	}
1599 	
1600 	
1601 	/// returns inequality type of row \p i
1602 	template <class R>
1603 	typename LPRowBase<R>::Type SoPlexBase<R>::rowTypeReal(int i) const
1604 	{
1605 	   assert(_realLP != 0);
1606 	   return _realLP->rowType(i);
1607 	}
1608 	
1609 	/// returns vector of col \p i, ignoring scaling
1610 	template <class R>
1611 	const SVectorBase<R>& SoPlexBase<R>::colVectorRealInternal(int i) const
1612 	{
1613 	   assert(_realLP != 0);
1614 	   return _realLP->colVector(i);
1615 	}
1616 	
1617 	/// gets vector of col \p i
1618 	template <class R>
1619 	void SoPlexBase<R>::getColVectorReal(int i, DSVectorBase<R>& col) const
1620 	{
1621 	   assert(_realLP);
1622 	   _realLP->getColVectorUnscaled(i, col);
1623 	}
1624 	
1625 	
1626 	/// returns upper bound vector
1627 	template <class R>
1628 	const VectorBase<R>& SoPlexBase<R>::upperRealInternal() const
1629 	{
1630 	   assert(_realLP != 0);
1631 	   return _realLP->upper();
1632 	}
1633 	
1634 	
1635 	/// returns upper bound of column \p i
1636 	template <class R>
1637 	R SoPlexBase<R>::upperReal(int i) const
1638 	{
1639 	   assert(_realLP != 0);
1640 	   return _realLP->upperUnscaled(i);
1641 	}
1642 	
1643 	
1644 	/// gets upper bound vector
1645 	template <class R>
1646 	void SoPlexBase<R>::getUpperReal(VectorBase<R>& upper) const
1647 	{
1648 	   assert(_realLP != 0);
1649 	   _realLP->getUpperUnscaled(upper);
1650 	}
1651 	
1652 	
1653 	/// returns lower bound vector
1654 	template <class R>
1655 	const VectorBase<R>& SoPlexBase<R>::lowerRealInternal() const
1656 	{
1657 	   assert(_realLP != 0);
1658 	   return _realLP->lower();
1659 	}
1660 	
1661 	
1662 	
1663 	/// returns lower bound of column \p i
1664 	template <class R>
1665 	R SoPlexBase<R>::lowerReal(int i) const
1666 	{
1667 	   assert(_realLP != 0);
1668 	   return _realLP->lowerUnscaled(i);
1669 	}
1670 	
1671 	
1672 	/// gets lower bound vector
1673 	template <class R>
1674 	void SoPlexBase<R>::getLowerReal(VectorBase<R>& lower) const
1675 	{
1676 	   assert(_realLP != 0);
1677 	   _realLP->getLowerUnscaled(lower);
1678 	}
1679 	
1680 	
1681 	/// gets objective function vector
1682 	template <class R>
1683 	void SoPlexBase<R>::getObjReal(VectorBase<R>& obj) const
1684 	{
1685 	   assert(_realLP != 0);
1686 	   _realLP->getObjUnscaled(obj);
1687 	}
1688 	
1689 	
1690 	/// returns objective value of column \p i
1691 	template <class R>
1692 	R SoPlexBase<R>::objReal(int i) const
1693 	{
1694 	   assert(_realLP != 0);
1695 	   return _realLP->objUnscaled(i);
1696 	}
1697 	
1698 	
1699 	/// returns objective function vector after transformation to a maximization problem; since this is how it is stored
1700 	/// internally, this is generally faster
1701 	template <class R>
1702 	const VectorBase<R>& SoPlexBase<R>::maxObjRealInternal() const
1703 	{
1704 	   assert(_realLP != 0);
1705 	   return _realLP->maxObj();
1706 	}
1707 	
1708 	
1709 	/// returns objective value of column \p i after transformation to a maximization problem; since this is how it is
1710 	/// stored internally, this is generally faster
1711 	template <class R>
1712 	R SoPlexBase<R>::maxObjReal(int i) const
1713 	{
1714 	   assert(_realLP != 0);
1715 	   return _realLP->maxObjUnscaled(i);
1716 	}
1717 	
1718 	
1719 	/// gets number of available dual norms
1720 	template <class R>
1721 	void SoPlexBase<R>::getNdualNorms(int& nnormsRow, int& nnormsCol) const
1722 	{
1723 	   _solver.getNdualNorms(nnormsRow, nnormsCol);
1724 	}
1725 	
1726 	
1727 	/// gets steepest edge norms and returns false if they are not available
1728 	template <class R>
1729 	bool SoPlexBase<R>::getDualNorms(int& nnormsRow, int& nnormsCol, R* norms) const
1730 	{
1731 	   return _solver.getDualNorms(nnormsRow, nnormsCol, norms);
1732 	}
1733 	
1734 	
1735 	/// sets steepest edge norms and returns false if that's not possible
1736 	template <class R>
1737 	bool SoPlexBase<R>::setDualNorms(int nnormsRow, int nnormsCol, R* norms)
1738 	{
1739 	   return _solver.setDualNorms(nnormsRow, nnormsCol, norms);
1740 	}
1741 	
1742 	
1743 	/// pass integrality information about the variables to the solver
1744 	template <class R>
1745 	void SoPlexBase<R>::setIntegralityInformation(int ncols, int* intInfo)
1746 	{
1747 	   assert(ncols == _solver.nCols() || (ncols == 0 && intInfo == NULL));
1748 	   _solver.setIntegralityInformation(ncols, intInfo);
1749 	}
1750 	
1751 	
1752 	template <class R>
1753 	int SoPlexBase<R>::numRowsRational() const
1754 	{
1755 	   assert(_rationalLP != 0);
1756 	   return _rationalLP->nRows();
1757 	}
1758 	
1759 	/// returns number of columns
1760 	template <class R>
1761 	int SoPlexBase<R>::numColsRational() const
1762 	{
1763 	   assert(_rationalLP != 0);
1764 	   return _rationalLP->nCols();
1765 	}
1766 	
1767 	/// returns number of nonzeros
1768 	template <class R>
1769 	int SoPlexBase<R>::numNonzerosRational() const
1770 	{
1771 	   assert(_rationalLP != 0);
1772 	   return _rationalLP->nNzos();
1773 	}
1774 	
1775 	/// returns smallest non-zero element in absolute value
1776 	template <class R>
1777 	Rational SoPlexBase<R>::minAbsNonzeroRational() const
1778 	{
1779 	   assert(_rationalLP != 0);
1780 	   return _rationalLP->minAbsNzo();
1781 	}
1782 	
1783 	/// returns biggest non-zero element in absolute value
1784 	template <class R>
1785 	Rational SoPlexBase<R>::maxAbsNonzeroRational() const
1786 	{
1787 	   assert(_rationalLP != 0);
1788 	   return _rationalLP->maxAbsNzo();
1789 	}
1790 	
1791 	/// gets row \p i
1792 	template <class R>
1793 	void SoPlexBase<R>::getRowRational(int i, LPRowRational& lprow) const
1794 	{
1795 	   assert(_rationalLP != 0);
1796 	   _rationalLP->getRow(i, lprow);
1797 	}
1798 	
1799 	
1800 	/// gets rows \p start, ..., \p end.
1801 	template <class R>
1802 	void SoPlexBase<R>::getRowsRational(int start, int end, LPRowSetRational& lprowset) const
1803 	{
1804 	   assert(_rationalLP != 0);
1805 	   _rationalLP->getRows(start, end, lprowset);
1806 	}
1807 	
1808 	
1809 	
1810 	/// returns vector of row \p i
1811 	template <class R>
1812 	const SVectorRational& SoPlexBase<R>::rowVectorRational(int i) const
1813 	{
1814 	   assert(_rationalLP != 0);
1815 	   return _rationalLP->rowVector(i);
1816 	}
1817 	
1818 	/// returns right-hand side vector
1819 	template <class R>
1820 	const VectorRational& SoPlexBase<R>::rhsRational() const
1821 	{
1822 	   assert(_rationalLP != 0);
1823 	   return _rationalLP->rhs();
1824 	}
1825 	
1826 	
1827 	
1828 	/// returns right-hand side of row \p i
1829 	template <class R>
1830 	const Rational& SoPlexBase<R>::rhsRational(int i) const
1831 	{
1832 	   assert(_rationalLP != 0);
1833 	   return _rationalLP->rhs(i);
1834 	}
1835 	
1836 	
1837 	/// returns left-hand side vector
1838 	template <class R>
1839 	const VectorRational& SoPlexBase<R>::lhsRational() const
1840 	{
1841 	   assert(_rationalLP != 0);
1842 	   return _rationalLP->lhs();
1843 	}
1844 	
1845 	
1846 	
1847 	/// returns left-hand side of row \p i
1848 	template <class R>
1849 	const Rational& SoPlexBase<R>::lhsRational(int i) const
1850 	{
1851 	   assert(_rationalLP != 0);
1852 	   return _rationalLP->lhs(i);
1853 	}
1854 	
1855 	
1856 	
1857 	/// returns inequality type of row \p i
1858 	template <class R>
1859 	LPRowRational::Type SoPlexBase<R>::rowTypeRational(int i) const
1860 	{
1861 	   assert(_rationalLP != 0);
1862 	   return _rationalLP->rowType(i);
1863 	}
1864 	
1865 	
1866 	
1867 	/// gets column \p i
1868 	template <class R>
1869 	void SoPlexBase<R>::getColRational(int i, LPColRational& lpcol) const
1870 	{
1871 	   assert(_rationalLP != 0);
1872 	   return _rationalLP->getCol(i, lpcol);
1873 	}
1874 	
1875 	
1876 	
1877 	/// gets columns \p start, ..., \p end
1878 	template <class R>
1879 	void SoPlexBase<R>::getColsRational(int start, int end, LPColSetRational& lpcolset) const
1880 	{
1881 	   assert(_rationalLP != 0);
1882 	   return _rationalLP->getCols(start, end, lpcolset);
1883 	}
1884 	
1885 	
1886 	/// returns vector of column \p i
1887 	template <class R>
1888 	const SVectorRational& SoPlexBase<R>::colVectorRational(int i) const
1889 	{
1890 	   assert(_rationalLP != 0);
1891 	   return _rationalLP->colVector(i);
1892 	}
1893 	
1894 	
1895 	
1896 	/// returns upper bound vector
1897 	template <class R>
1898 	const VectorRational& SoPlexBase<R>::upperRational() const
1899 	{
1900 	   assert(_rationalLP != 0);
1901 	   return _rationalLP->upper();
1902 	}
1903 	
1904 	
1905 	
1906 	/// returns upper bound of column \p i
1907 	template <class R>
1908 	const Rational& SoPlexBase<R>::upperRational(int i) const
1909 	{
1910 	   assert(_rationalLP != 0);
1911 	   return _rationalLP->upper(i);
1912 	}
1913 	
1914 	
1915 	
1916 	/// returns lower bound vector
1917 	template <class R>
1918 	const VectorRational& SoPlexBase<R>::lowerRational() const
1919 	{
1920 	   assert(_rationalLP != 0);
1921 	   return _rationalLP->lower();
1922 	}
1923 	
1924 	/// returns lower bound of column \p i
1925 	template <class R>
1926 	const Rational& SoPlexBase<R>::lowerRational(int i) const
1927 	{
1928 	   assert(_rationalLP != 0);
1929 	   return _rationalLP->lower(i);
1930 	}
1931 	
1932 	
1933 	
1934 	/// gets objective function vector
1935 	template <class R>
1936 	void SoPlexBase<R>::getObjRational(VectorRational& obj) const
1937 	{
1938 	   assert(_rationalLP != 0);
1939 	   _rationalLP->getObj(obj);
1940 	}
1941 	
1942 	
1943 	
1944 	/// gets objective value of column \p i
1945 	template <class R>
1946 	void SoPlexBase<R>::getObjRational(int i, Rational& obj) const
1947 	{
1948 	   obj = maxObjRational(i);
1949 	
1950 	   if(intParam(SoPlexBase<R>::OBJSENSE) == SoPlexBase<R>::OBJSENSE_MINIMIZE)
1951 	      obj *= -1;
1952 	}
1953 	
1954 	
1955 	
1956 	/// returns objective value of column \p i
1957 	template <class R>
1958 	Rational SoPlexBase<R>::objRational(int i) const
1959 	{
1960 	   assert(_rationalLP != 0);
1961 	   return _rationalLP->obj(i);
1962 	}
1963 	
1964 	
1965 	
1966 	/// returns objective function vector after transformation to a maximization problem; since this is how it is stored
1967 	/// internally, this is generally faster
1968 	template <class R>
1969 	const VectorRational& SoPlexBase<R>::maxObjRational() const
1970 	{
1971 	   assert(_rationalLP != 0);
1972 	   return _rationalLP->maxObj();
1973 	}
1974 	
1975 	
1976 	
1977 	/// returns objective value of column \p i after transformation to a maximization problem; since this is how it is
1978 	/// stored internally, this is generally faster
1979 	template <class R>
1980 	const Rational& SoPlexBase<R>::maxObjRational(int i) const
1981 	{
1982 	   assert(_rationalLP != 0);
1983 	   return _rationalLP->maxObj(i);
1984 	}
1985 	
1986 	
1987 	
1988 	/// adds a single row
1989 	template <class R>
1990 	void SoPlexBase<R>::addRowReal(const LPRowBase<R>& lprow)
1991 	{
1992 	   assert(_realLP != 0);
1993 	
1994 	   _addRowReal(lprow);
1995 	
1996 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
1997 	   {
1998 	      _rationalLP->addRow(lprow);
1999 	      _completeRangeTypesRational();
2000 	   }
2001 	
2002 	   _invalidateSolution();
2003 	}
2004 	
2005 	
2006 	
2007 	/// adds multiple rows
2008 	template <class R>
2009 	void SoPlexBase<R>::addRowsReal(const LPRowSetBase<R>& lprowset)
2010 	{
2011 	   assert(_realLP != 0);
2012 	
2013 	   _addRowsReal(lprowset);
2014 	
2015 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2016 	   {
2017 	      _rationalLP->addRows(lprowset);
2018 	      _completeRangeTypesRational();
2019 	   }
2020 	
2021 	   _invalidateSolution();
2022 	}
2023 	
2024 	
2025 	
2026 	/// adds a single column
2027 	template <class R>
2028 	void SoPlexBase<R>::addColReal(const LPColBase<R>& lpcol)
2029 	{
2030 	   assert(_realLP != 0);
2031 	
2032 	   _addColReal(lpcol);
2033 	
2034 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2035 	   {
2036 	      _rationalLP->addCol(lpcol);
2037 	      _completeRangeTypesRational();
2038 	   }
2039 	
2040 	   _invalidateSolution();
2041 	}
2042 	
2043 	
2044 	
2045 	/// adds multiple columns
2046 	template <class R>
2047 	void SoPlexBase<R>::addColsReal(const LPColSetBase<R>& lpcolset)
2048 	{
2049 	   assert(_realLP != 0);
2050 	
2051 	   _addColsReal(lpcolset);
2052 	
2053 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2054 	   {
2055 	      _rationalLP->addCols(lpcolset);
2056 	      _completeRangeTypesRational();
2057 	   }
2058 	
2059 	   _invalidateSolution();
2060 	}
2061 	
2062 	
2063 	
2064 	/// replaces row \p i with \p lprow
2065 	template <class R>
2066 	void SoPlexBase<R>::changeRowReal(int i, const LPRowBase<R>& lprow)
2067 	{
2068 	   assert(_realLP != 0);
2069 	
2070 	   _changeRowReal(i, lprow);
2071 	
2072 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2073 	   {
2074 	      _rationalLP->changeRow(i, lprow);
2075 	      _rowTypes[i] = _rangeTypeReal(lprow.lhs(), lprow.rhs());
2076 	      _completeRangeTypesRational();
2077 	   }
2078 	
2079 	   _invalidateSolution();
2080 	}
2081 	#ifdef SOPLEX_WITH_GMP
2082 	/// adds a single column (GMP only method)
2083 	template <class R>
2084 	void SoPlexBase<R>::addColRational(const mpq_t* obj, const mpq_t* lower, const mpq_t* colValues,
2085 	                                   const int* colIndices, const int colSize, const mpq_t* upper)
2086 	{
2087 	   assert(_rationalLP != 0);
2088 	
2089 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2090 	      return;
2091 	
2092 	   _rationalLP->addCol(obj, lower, colValues, colIndices, colSize, upper);
2093 	   int i = numColsRational() - 1;
2094 	   _completeRangeTypesRational();
2095 	
2096 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2097 	      _addColReal(R(maxObjRational(i)) * (intParam(SoPlexBase<R>::OBJSENSE) ==
2098 	                                          SoPlexBase<R>::OBJSENSE_MAXIMIZE ? 1.0 : -1.0),
2099 	                  R(lowerRational(i)), DSVectorBase<R>(_rationalLP->colVector(i)), R(upperRational(i)));
2100 	
2101 	   _invalidateSolution();
2102 	}
2103 	
2104 	
2105 	
2106 	/// adds a set of columns (GMP only method)
2107 	template <class R>
2108 	void SoPlexBase<R>::addColsRational(const mpq_t* obj, const mpq_t* lower, const mpq_t* colValues,
2109 	                                    const int* colIndices, const int* colStarts, const int* colLengths, const int numCols,
2110 	                                    const int numValues, const mpq_t* upper)
2111 	{
2112 	   assert(_rationalLP != 0);
2113 	
2114 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2115 	      return;
2116 	
2117 	   _rationalLP->addCols(obj, lower, colValues, colIndices, colStarts, colLengths, numCols, numValues,
2118 	                        upper);
2119 	   _completeRangeTypesRational();
2120 	
2121 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2122 	   {
2123 	      LPColSetReal lpcolset;
2124 	
2125 	      for(int i = numColsRational() - numCols; i < numColsRational(); i++)
2126 	         lpcolset.add(R(maxObjRational(i)) * (intParam(SoPlexBase<R>::OBJSENSE) ==
2127 	                                              SoPlexBase<R>::OBJSENSE_MAXIMIZE ? 1.0 : -1.0),
2128 	                      R(lowerRational(i)), DSVectorBase<R>(_rationalLP->colVector(i)), R(upperRational(i)));
2129 	
2130 	      _addColsReal(lpcolset);
2131 	   }
2132 	
2133 	   _invalidateSolution();
2134 	}
2135 	#endif
2136 	
2137 	
2138 	/// changes left-hand side vector for constraints to \p lhs
2139 	template <class R>
2140 	void SoPlexBase<R>::changeLhsReal(const VectorBase<R>& lhs)
2141 	{
2142 	   assert(_realLP != 0);
2143 	
2144 	   _changeLhsReal(lhs);
2145 	
2146 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2147 	   {
2148 	      _rationalLP->changeLhs(VectorRational(lhs));
2149 	
2150 	      for(int i = 0; i < numRowsRational(); i++)
2151 	         _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), _rationalLP->rhs(i));
2152 	   }
2153 	
2154 	   _invalidateSolution();
2155 	}
2156 	
2157 	
2158 	
2159 	/// changes left-hand side of row \p i to \p lhs
2160 	template <class R>
2161 	void SoPlexBase<R>::changeLhsReal(int i, const R& lhs)
2162 	{
2163 	   assert(_realLP != 0);
2164 	
2165 	   _changeLhsReal(i, lhs);
2166 	
2167 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2168 	   {
2169 	      _rationalLP->changeLhs(i, lhs);
2170 	      _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), _rationalLP->rhs(i));
2171 	   }
2172 	
2173 	   _invalidateSolution();
2174 	}
2175 	
2176 	
2177 	
2178 	/// changes right-hand side vector to \p rhs
2179 	template <class R>
2180 	void SoPlexBase<R>::changeRhsReal(const VectorBase<R>& rhs)
2181 	{
2182 	   assert(_realLP != 0);
2183 	
2184 	   _changeRhsReal(rhs);
2185 	
2186 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2187 	   {
2188 	      _rationalLP->changeRhs(VectorRational(rhs));
2189 	
2190 	      for(int i = 0; i < numRowsRational(); i++)
2191 	         _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), _rationalLP->rhs(i));
2192 	   }
2193 	
2194 	   _invalidateSolution();
2195 	}
2196 	
2197 	
2198 	
2199 	/// changes right-hand side of row \p i to \p rhs
2200 	template <class R>
2201 	void SoPlexBase<R>::changeRhsReal(int i, const R& rhs)
2202 	{
2203 	   assert(_realLP != 0);
2204 	
2205 	   _changeRhsReal(i, rhs);
2206 	
2207 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2208 	   {
2209 	      _rationalLP->changeRhs(i, rhs);
2210 	      _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), _rationalLP->rhs(i));
2211 	   }
2212 	
2213 	   _invalidateSolution();
2214 	}
2215 	
2216 	
2217 	/// changes left- and right-hand side vectors
2218 	template <class R>
2219 	void SoPlexBase<R>::changeRangeReal(const VectorBase<R>& lhs, const VectorBase<R>& rhs)
2220 	{
2221 	   assert(_realLP != 0);
2222 	
2223 	   _changeRangeReal(lhs, rhs);
2224 	
2225 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2226 	   {
2227 	      _rationalLP->changeRange(VectorRational(lhs), VectorRational(rhs));
2228 	
2229 	      for(int i = 0; i < numRowsRational(); i++)
2230 	         _rowTypes[i] = _rangeTypeReal(lhs[i], rhs[i]);
2231 	   }
2232 	
2233 	   _invalidateSolution();
2234 	}
2235 	
2236 	
2237 	
2238 	/// changes left- and right-hand side of row \p i
2239 	template <class R>
2240 	void SoPlexBase<R>::changeRangeReal(int i, const R& lhs, const R& rhs)
2241 	{
2242 	   assert(_realLP != 0);
2243 	
2244 	   _changeRangeReal(i, lhs, rhs);
2245 	
2246 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2247 	   {
2248 	      _rationalLP->changeRange(i, lhs, rhs);
2249 	      _rowTypes[i] = _rangeTypeReal(lhs, rhs);
2250 	   }
2251 	
2252 	   _invalidateSolution();
2253 	}
2254 	
2255 	
2256 	
2257 	/// replaces column \p i with \p lpcol
2258 	template <class R>
2259 	void SoPlexBase<R>::changeColReal(int i, const LPColReal& lpcol)
2260 	{
2261 	   assert(_realLP != 0);
2262 	
2263 	   _changeColReal(i, lpcol);
2264 	
2265 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2266 	   {
2267 	      _rationalLP->changeCol(i, lpcol);
2268 	      _colTypes[i] = _rangeTypeReal(lpcol.lower(), lpcol.upper());
2269 	      _completeRangeTypesRational();
2270 	   }
2271 	
2272 	   _invalidateSolution();
2273 	}
2274 	
2275 	
2276 	
2277 	/// changes vector of lower bounds to \p lower
2278 	template <class R>
2279 	void SoPlexBase<R>::changeLowerReal(const VectorBase<R>& lower)
2280 	{
2281 	   assert(_realLP != 0);
2282 	
2283 	   _changeLowerReal(lower);
2284 	
2285 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2286 	   {
2287 	      _rationalLP->changeLower(VectorRational(lower));
2288 	
2289 	      for(int i = 0; i < numColsRational(); i++)
2290 	         _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), _rationalLP->upper(i));
2291 	   }
2292 	
2293 	
2294 	   _invalidateSolution();
2295 	}
2296 	
2297 	
2298 	
2299 	/// changes lower bound of column i to \p lower
2300 	template <class R>
2301 	void SoPlexBase<R>::changeLowerReal(int i, const R& lower)
2302 	{
2303 	   assert(_realLP != 0);
2304 	
2305 	   _changeLowerReal(i, lower);
2306 	
2307 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2308 	   {
2309 	      _rationalLP->changeLower(i, lower);
2310 	      _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), _rationalLP->upper(i));
2311 	   }
2312 	
2313 	   _invalidateSolution();
2314 	}
2315 	
2316 	
2317 	
2318 	/// changes vector of upper bounds to \p upper
2319 	template <class R>
2320 	void SoPlexBase<R>::changeUpperReal(const VectorBase<R>& upper)
2321 	{
2322 	   assert(_realLP != 0);
2323 	
2324 	   _changeUpperReal(upper);
2325 	
2326 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2327 	   {
2328 	      _rationalLP->changeUpper(VectorRational(upper));
2329 	
2330 	      for(int i = 0; i < numColsRational(); i++)
2331 	         _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), _rationalLP->upper(i));
2332 	   }
2333 	
2334 	   _invalidateSolution();
2335 	}
2336 	
2337 	
2338 	
2339 	/// changes \p i 'th upper bound to \p upper
2340 	template <class R>
2341 	void SoPlexBase<R>::changeUpperReal(int i, const R& upper)
2342 	{
2343 	   assert(_realLP != 0);
2344 	
2345 	   _changeUpperReal(i, upper);
2346 	
2347 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2348 	   {
2349 	      _rationalLP->changeUpper(i, upper);
2350 	      _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), _rationalLP->upper(i));
2351 	   }
2352 	
2353 	   _invalidateSolution();
2354 	}
2355 	
2356 	
2357 	
2358 	/// changes vectors of column bounds to \p lower and \p upper
2359 	template <class R>
2360 	void SoPlexBase<R>::changeBoundsReal(const VectorBase<R>& lower, const VectorBase<R>& upper)
2361 	{
2362 	   assert(_realLP != 0);
2363 	
2364 	   _changeBoundsReal(lower, upper);
2365 	
2366 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2367 	   {
2368 	      _rationalLP->changeBounds(VectorRational(lower), VectorRational(upper));
2369 	
2370 	      for(int i = 0; i < numColsRational(); i++)
2371 	         _colTypes[i] = _rangeTypeReal(lower[i], upper[i]);
2372 	   }
2373 	
2374 	   _invalidateSolution();
2375 	}
2376 	
2377 	
2378 	
2379 	/// changes bounds of column \p i to \p lower and \p upper
2380 	template <class R>
2381 	void SoPlexBase<R>::changeBoundsReal(int i, const R& lower, const R& upper)
2382 	{
2383 	   assert(_realLP != 0);
2384 	
2385 	   _changeBoundsReal(i, lower, upper);
2386 	
2387 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2388 	   {
2389 	      _rationalLP->changeBounds(i, lower, upper);
2390 	      _colTypes[i] = _rangeTypeReal(lower, upper);
2391 	   }
2392 	
2393 	   _invalidateSolution();
2394 	}
2395 	
2396 	
2397 	/// changes objective function vector to \p obj
2398 	template <class R>
2399 	void SoPlexBase<R>::changeObjReal(const VectorBase<R>& obj)
2400 	{
2401 	   assert(_realLP != 0);
2402 	
2403 	   bool scale = _realLP->isScaled();
2404 	   _realLP->changeObj(obj, scale);
2405 	
2406 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2407 	      _rationalLP->changeObj(VectorRational(obj));
2408 	
2409 	   _invalidateSolution();
2410 	}
2411 	
2412 	
2413 	
2414 	/// changes objective coefficient of column i to \p obj
2415 	template <class R>
2416 	void SoPlexBase<R>::changeObjReal(int i, const R& obj)
2417 	{
2418 	   assert(_realLP != 0);
2419 	
2420 	   bool scale = _realLP->isScaled();
2421 	   _realLP->changeObj(i, obj, scale);
2422 	
2423 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2424 	      _rationalLP->changeObj(i, obj);
2425 	
2426 	   _invalidateSolution();
2427 	}
2428 	
2429 	
2430 	
2431 	/// changes matrix entry in row \p i and column \p j to \p val
2432 	template <class R>
2433 	void SoPlexBase<R>::changeElementReal(int i, int j, const R& val)
2434 	{
2435 	   assert(_realLP != 0);
2436 	
2437 	   _changeElementReal(i, j, val);
2438 	
2439 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2440 	      _rationalLP->changeElement(i, j, val);
2441 	
2442 	   _invalidateSolution();
2443 	}
2444 	
2445 	
2446 	
2447 	/// removes row \p i
2448 	template <class R>
2449 	void SoPlexBase<R>::removeRowReal(int i)
2450 	{
2451 	   assert(_realLP != 0);
2452 	
2453 	   _removeRowReal(i);
2454 	
2455 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2456 	   {
2457 	      _rationalLP->removeRow(i);
2458 	
2459 	      // only swap elements if not the last one was removed
2460 	      if(i < _rationalLP->nRows())
2461 	      {
2462 	         _rowTypes[i] = _rowTypes[_rationalLP->nRows()];
2463 	         assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
2464 	      }
2465 	
2466 	      _rowTypes.reSize(_rationalLP->nRows());
2467 	   }
2468 	
2469 	   _invalidateSolution();
2470 	}
2471 	
2472 	
2473 	
2474 	/// removes all rows with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
2475 	/// new index where row \p i has been moved to; note that \p perm must point to an array of size at least
2476 	/// #numRows()
2477 	template <class R>
2478 	void SoPlexBase<R>::removeRowsReal(int perm[])
2479 	{
2480 	   assert(_realLP != 0);
2481 	
2482 	   const int oldsize = numRows();
2483 	   _removeRowsReal(perm);
2484 	
2485 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2486 	   {
2487 	      _rationalLP->removeRows(perm);
2488 	
2489 	      for(int i = 0; i < oldsize; i++)
2490 	      {
2491 	         if(perm[i] >= 0)
2492 	            _rowTypes[perm[i]] = _rowTypes[i];
2493 	      }
2494 	
2495 	      _rowTypes.reSize(_rationalLP->nRows());
2496 	
2497 	      for(int i = 0; i < numRowsRational(); i++)
2498 	      {
2499 	         assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
2500 	      }
2501 	   }
2502 	
2503 	   _invalidateSolution();
2504 	}
2505 	
2506 	
2507 	
2508 	/// remove all rows with indices in array \p idx of size \p n; an array \p perm of size #numRows() may be passed
2509 	/// as buffer memory
2510 	template <class R>
2511 	void SoPlexBase<R>::removeRowsReal(int idx[], int n, int perm[])
2512 	{
2513 	   if(perm == 0)
2514 	   {
2515 	      DataArray< int > p(numRows());
2516 	      _idxToPerm(idx, n, p.get_ptr(), numRows());
2517 	      SoPlexBase<R>::removeRowsReal(p.get_ptr());
2518 	   }
2519 	   else
2520 	   {
2521 	      _idxToPerm(idx, n, perm, numRows());
2522 	      SoPlexBase<R>::removeRowsReal(perm);
2523 	   }
2524 	}
2525 	
2526 	
2527 	
2528 	/// removes rows \p start to \p end including both; an array \p perm of size #numRows() may be passed as buffer
2529 	/// memory
2530 	template <class R>
2531 	void SoPlexBase<R>::removeRowRangeReal(int start, int end, int perm[])
2532 	{
2533 	   if(perm == 0)
2534 	   {
2535 	      DataArray< int > p(numRows());
2536 	      _rangeToPerm(start, end, p.get_ptr(), numRows());
2537 	      SoPlexBase<R>::removeRowsReal(p.get_ptr());
2538 	   }
2539 	   else
2540 	   {
2541 	      _rangeToPerm(start, end, perm, numRows());
2542 	      SoPlexBase<R>::removeRowsReal(perm);
2543 	   }
2544 	}
2545 	
2546 	
2547 	
2548 	/// removes column i
2549 	template <class R>
2550 	void SoPlexBase<R>::removeColReal(int i)
2551 	{
2552 	   assert(_realLP != 0);
2553 	
2554 	   _removeColReal(i);
2555 	
2556 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2557 	   {
2558 	      _rationalLP->removeCol(i);
2559 	
2560 	      // only swap elements if not the last one was removed
2561 	      if(i < _rationalLP->nCols())
2562 	      {
2563 	         _colTypes[i] = _colTypes[_rationalLP->nCols()];
2564 	         assert(_colTypes[i] == _rangeTypeRational(lowerRational(i), upperRational(i)));
2565 	      }
2566 	
2567 	      _colTypes.reSize(_rationalLP->nCols());
2568 	   }
2569 	
2570 	   _invalidateSolution();
2571 	}
2572 	
2573 	
2574 	
2575 	/// removes all columns with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
2576 	/// new index where column \p i has been moved to; note that \p perm must point to an array of size at least
2577 	/// #numColsReal()
2578 	template <class R>
2579 	void SoPlexBase<R>::removeColsReal(int perm[])
2580 	{
2581 	   assert(_realLP != 0);
2582 	
2583 	   const int oldsize = numCols();
2584 	   _removeColsReal(perm);
2585 	
2586 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2587 	   {
2588 	      _rationalLP->removeCols(perm);
2589 	
2590 	      for(int i = 0; i < oldsize; i++)
2591 	      {
2592 	         if(perm[i] >= 0)
2593 	            _colTypes[perm[i]] = _colTypes[i];
2594 	      }
2595 	
2596 	      _colTypes.reSize(_rationalLP->nCols());
2597 	
2598 	      for(int i = 0; i < numColsRational(); i++)
2599 	      {
2600 	         assert(_colTypes[i] == _rangeTypeRational(lowerRational(i), upperRational(i)));
2601 	      }
2602 	   }
2603 	
2604 	   _invalidateSolution();
2605 	}
2606 	
2607 	
2608 	
2609 	/// remove all columns with indices in array \p idx of size \p n; an array \p perm of size #numColsReal() may be
2610 	/// passed as buffer memory
2611 	template <class R>
2612 	void SoPlexBase<R>::removeColsReal(int idx[], int n, int perm[])
2613 	{
2614 	   if(perm == 0)
2615 	   {
2616 	      DataArray< int > p(numCols());
2617 	      _idxToPerm(idx, n, p.get_ptr(), numCols());
2618 	      SoPlexBase<R>::removeColsReal(p.get_ptr());
2619 	   }
2620 	   else
2621 	   {
2622 	      _idxToPerm(idx, n, perm, numCols());
2623 	      SoPlexBase<R>::removeColsReal(perm);
2624 	   }
2625 	}
2626 	
2627 	
2628 	
2629 	/// removes columns \p start to \p end including both; an array \p perm of size #numCols() may be passed as
2630 	/// buffer memory
2631 	template <class R>
2632 	void SoPlexBase<R>::removeColRangeReal(int start, int end, int perm[])
2633 	{
2634 	   if(perm == 0)
2635 	   {
2636 	      DataArray< int > p(numCols());
2637 	      _rangeToPerm(start, end, p.get_ptr(), numCols());
2638 	      SoPlexBase<R>::removeColsReal(p.get_ptr());
2639 	   }
2640 	   else
2641 	   {
2642 	      _rangeToPerm(start, end, perm, numCols());
2643 	      SoPlexBase<R>::removeColsReal(perm);
2644 	   }
2645 	}
2646 	
2647 	
2648 	
2649 	/// clears the LP
2650 	template <class R>
2651 	void SoPlexBase<R>::clearLPReal()
2652 	{
2653 	   assert(_realLP != 0);
2654 	
2655 	   _realLP->clear();
2656 	   _hasBasis = false;
2657 	   _rationalLUSolver.clear();
2658 	
2659 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2660 	   {
2661 	      _rationalLP->clear();
2662 	      _rowTypes.clear();
2663 	      _colTypes.clear();
2664 	   }
2665 	
2666 	   _invalidateSolution();
2667 	}
2668 	
2669 	
2670 	
2671 	/// synchronizes R LP with rational LP, i.e., copies (rounded) rational LP into R LP, if sync mode is manual
2672 	template <class R>
2673 	void SoPlexBase<R>::syncLPReal()
2674 	{
2675 	   assert(_isConsistent());
2676 	
2677 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_MANUAL)
2678 	      _syncLPReal();
2679 	}
2680 	
2681 	
2682 	
2683 	/// adds a single row
2684 	template <class R>
2685 	void SoPlexBase<R>::addRowRational(const LPRowRational& lprow)
2686 	{
2687 	   assert(_rationalLP != 0);
2688 	
2689 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2690 	      return;
2691 	
2692 	   _rationalLP->addRow(lprow);
2693 	   _completeRangeTypesRational();
2694 	
2695 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2696 	      _addRowReal(lprow);
2697 	
2698 	   _invalidateSolution();
2699 	}
2700 	
2701 	
2702 	
2703 	#ifdef SOPLEX_WITH_GMP
2704 	/// adds a single row  (GMP only method)
2705 	template <class R>
2706 	void SoPlexBase<R>::addRowRational(const mpq_t* lhs, const mpq_t* rowValues, const int* rowIndices,
2707 	                                   const int rowSize, const mpq_t* rhs)
2708 	{
2709 	   assert(_rationalLP != 0);
2710 	
2711 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2712 	      return;
2713 	
2714 	   _rationalLP->addRow(lhs, rowValues, rowIndices, rowSize, rhs);
2715 	   _completeRangeTypesRational();
2716 	
2717 	   int i = numRowsRational() - 1;
2718 	
2719 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2720 	      _addRowReal(R(lhsRational(i)), DSVectorBase<R>(_rationalLP->rowVector(i)), R(rhsRational(i)));
2721 	
2722 	   _invalidateSolution();
2723 	}
2724 	
2725 	
2726 	
2727 	/// adds a set of rows  (GMP only method)
2728 	template <class R>
2729 	void SoPlexBase<R>::addRowsRational(const mpq_t* lhs, const mpq_t* rowValues, const int* rowIndices,
2730 	                                    const int* rowStarts, const int* rowLengths, const int numRows, const int numValues,
2731 	                                    const mpq_t* rhs)
2732 	{
2733 	   assert(_rationalLP != 0);
2734 	
2735 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2736 	      return;
2737 	
2738 	   _rationalLP->addRows(lhs, rowValues, rowIndices, rowStarts, rowLengths, numRows, numValues, rhs);
2739 	   _completeRangeTypesRational();
2740 	
2741 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2742 	   {
2743 	      LPRowSetBase<R> lprowset;
2744 	
2745 	      for(int i = numRowsRational() - numRows; i < numRowsRational(); i++)
2746 	         lprowset.add(R(lhsRational(i)), DSVectorBase<R>(_rationalLP->rowVector(i)), R(rhsRational(i)));
2747 	
2748 	      _addRowsReal(lprowset);
2749 	   }
2750 	
2751 	   _invalidateSolution();
2752 	}
2753 	#endif
2754 	
2755 	
2756 	
2757 	/// adds multiple rows
2758 	template <class R>
2759 	void SoPlexBase<R>::addRowsRational(const LPRowSetRational& lprowset)
2760 	{
2761 	   assert(_rationalLP != 0);
2762 	
2763 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2764 	      return;
2765 	
2766 	   _rationalLP->addRows(lprowset);
2767 	   _completeRangeTypesRational();
2768 	
2769 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2770 	      _addRowsReal(lprowset);
2771 	
2772 	   _invalidateSolution();
2773 	}
2774 	
2775 	
2776 	/// adds a single column
2777 	template <class R>
2778 	void SoPlexBase<R>::addColRational(const LPColRational& lpcol)
2779 	{
2780 	   assert(_rationalLP != 0);
2781 	
2782 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2783 	      return;
2784 	
2785 	   _rationalLP->addCol(lpcol);
2786 	   _completeRangeTypesRational();
2787 	
2788 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2789 	      _addColReal(lpcol);
2790 	
2791 	   _invalidateSolution();
2792 	}
2793 	
2794 	
2795 	
2796 	
2797 	
2798 	/// adds multiple columns
2799 	template <class R>
2800 	void SoPlexBase<R>::addColsRational(const LPColSetRational& lpcolset)
2801 	{
2802 	   assert(_rationalLP != 0);
2803 	
2804 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2805 	      return;
2806 	
2807 	   _rationalLP->addCols(lpcolset);
2808 	   _completeRangeTypesRational();
2809 	
2810 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2811 	      _addColsReal(lpcolset);
2812 	
2813 	   _invalidateSolution();
2814 	}
2815 	
2816 	
2817 	
2818 	/// replaces row \p i with \p lprow
2819 	template <class R>
2820 	void SoPlexBase<R>::changeRowRational(int i, const LPRowRational& lprow)
2821 	{
2822 	   assert(_rationalLP != 0);
2823 	
2824 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2825 	      return;
2826 	
2827 	   _rationalLP->changeRow(i, lprow);
2828 	   _rowTypes[i] = _rangeTypeRational(lprow.lhs(), lprow.rhs());
2829 	   _completeRangeTypesRational();
2830 	
2831 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2832 	      _changeRowReal(i, lprow);
2833 	
2834 	   _invalidateSolution();
2835 	}
2836 	
2837 	
2838 	
2839 	/// changes left-hand side vector for constraints to \p lhs
2840 	template <class R>
2841 	void SoPlexBase<R>::changeLhsRational(const VectorRational& lhs)
2842 	{
2843 	   assert(_rationalLP != 0);
2844 	
2845 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2846 	      return;
2847 	
2848 	   _rationalLP->changeLhs(lhs);
2849 	
2850 	   for(int i = 0; i < numRowsRational(); i++)
2851 	      _rowTypes[i] = _rangeTypeRational(lhs[i], _rationalLP->rhs(i));
2852 	
2853 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2854 	      _changeLhsReal(VectorBase<R>(lhs));
2855 	
2856 	   _invalidateSolution();
2857 	}
2858 	
2859 	
2860 	
2861 	/// changes left-hand side of row \p i to \p lhs
2862 	template <class R>
2863 	void SoPlexBase<R>::changeLhsRational(int i, const Rational& lhs)
2864 	{
2865 	   assert(_rationalLP != 0);
2866 	
2867 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2868 	      return;
2869 	
2870 	   _rationalLP->changeLhs(i, lhs);
2871 	   _rowTypes[i] = _rangeTypeRational(lhs, _rationalLP->rhs(i));
2872 	
2873 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2874 	      _changeLhsReal(i, R(lhs));
2875 	
2876 	   _invalidateSolution();
2877 	}
2878 	
2879 	
2880 	
2881 	#ifdef SOPLEX_WITH_GMP
2882 	/// changes left-hand side of row \p i to \p lhs (GMP only method)
2883 	template <class R>
2884 	void SoPlexBase<R>::changeLhsRational(int i, const mpq_t* lhs)
2885 	{
2886 	   assert(_rationalLP != 0);
2887 	
2888 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2889 	      return;
2890 	
2891 	#ifndef SOPLEX_WITH_BOOST
2892 	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
2893 	#endif
2894 	
2895 	   _rationalLP->changeLhs(i, lhs);
2896 	   _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), _rationalLP->rhs(i));
2897 	
2898 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2899 	      _changeLhsReal(i, R(lhsRational(i)));
2900 	
2901 	   _invalidateSolution();
2902 	}
2903 	#endif
2904 	
2905 	
2906 	
2907 	/// changes right-hand side vector to \p rhs
2908 	template <class R>
2909 	void SoPlexBase<R>::changeRhsRational(const VectorRational& rhs)
2910 	{
2911 	   assert(_rationalLP != 0);
2912 	
2913 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2914 	      return;
2915 	
2916 	   _rationalLP->changeRhs(rhs);
2917 	
2918 	   for(int i = 0; i < numRowsRational(); i++)
2919 	      _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), rhs[i]);
2920 	
2921 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2922 	      _changeRhsReal(VectorBase<R>(rhs));
2923 	
2924 	   _invalidateSolution();
2925 	}
2926 	
2927 	
2928 	
2929 	#ifdef SOPLEX_WITH_GMP
2930 	/// changes right-hand side vector to \p rhs (GMP only method)
2931 	template <class R>
2932 	void SoPlexBase<R>::changeRhsRational(const mpq_t* rhs, int rhsSize)
2933 	{
2934 	   assert(_rationalLP != 0);
2935 	
2936 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2937 	      return;
2938 	
2939 	#ifndef SOPLEX_WITH_BOOST
2940 	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
2941 	#endif
2942 	
2943 	   for(int i = 0; i < rhsSize; i++)
2944 	   {
2945 	      _rationalLP->changeRhs(i, Rational(rhs[i]));
2946 	      _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), _rationalLP->rhs(i));
2947 	   }
2948 	
2949 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2950 	      _changeRhsReal(VectorBase<R>(rhsRational()));
2951 	
2952 	   _invalidateSolution();
2953 	}
2954 	#endif
2955 	
2956 	
2957 	
2958 	/// changes right-hand side of row \p i to \p rhs
2959 	template <class R>
2960 	void SoPlexBase<R>::changeRhsRational(int i, const Rational& rhs)
2961 	{
2962 	   assert(_rationalLP != 0);
2963 	
2964 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2965 	      return;
2966 	
2967 	   _rationalLP->changeRhs(i, rhs);
2968 	   _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), rhs);
2969 	
2970 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2971 	      _changeRhsReal(i, R(rhs));
2972 	
2973 	   _invalidateSolution();
2974 	}
2975 	
2976 	
2977 	
2978 	/// changes left- and right-hand side vectors
2979 	template <class R>
2980 	void SoPlexBase<R>::changeRangeRational(const VectorRational& lhs, const VectorRational& rhs)
2981 	{
2982 	   assert(_rationalLP != 0);
2983 	
2984 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
2985 	      return;
2986 	
2987 	   _rationalLP->changeRange(lhs, rhs);
2988 	
2989 	   for(int i = 0; i < numRowsRational(); i++)
2990 	      _rowTypes[i] = _rangeTypeRational(lhs[i], rhs[i]);
2991 	
2992 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
2993 	      _changeRangeReal(VectorBase<R>(lhs), VectorBase<R>(rhs));
2994 	
2995 	   _invalidateSolution();
2996 	}
2997 	
2998 	
2999 	
3000 	/// changes left- and right-hand side of row \p i
3001 	template <class R>
3002 	void SoPlexBase<R>::changeRangeRational(int i, const Rational& lhs, const Rational& rhs)
3003 	{
3004 	   assert(_rationalLP != 0);
3005 	
3006 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3007 	      return;
3008 	
3009 	   _rationalLP->changeRange(i, lhs, rhs);
3010 	   _rowTypes[i] = _rangeTypeRational(lhs, rhs);
3011 	
3012 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3013 	      _changeRangeReal(i, R(lhs), R(rhs));
3014 	
3015 	   _invalidateSolution();
3016 	}
3017 	
3018 	
3019 	
3020 	#ifdef SOPLEX_WITH_GMP
3021 	/// changes left-hand side of row \p i to \p lhs (GMP only method)
3022 	template <class R>
3023 	void SoPlexBase<R>::changeRangeRational(int i, const mpq_t* lhs, const mpq_t* rhs)
3024 	{
3025 	   assert(_rationalLP != 0);
3026 	
3027 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3028 	      return;
3029 	
3030 	#ifndef SOPLEX_WITH_BOOST
3031 	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
3032 	#endif
3033 	   _rationalLP->changeRange(i, lhs, rhs);
3034 	   _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), _rationalLP->rhs(i));
3035 	
3036 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3037 	      _changeRangeReal(i, R(lhsRational(i)), R(rhsRational(i)));
3038 	
3039 	   _invalidateSolution();
3040 	}
3041 	#endif
3042 	
3043 	
3044 	
3045 	/// replaces column \p i with \p lpcol
3046 	template <class R>
3047 	void SoPlexBase<R>::changeColRational(int i, const LPColRational& lpcol)
3048 	{
3049 	   assert(_rationalLP != 0);
3050 	
3051 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3052 	      return;
3053 	
3054 	   _rationalLP->changeCol(i, lpcol);
3055 	   _colTypes[i] = _rangeTypeRational(lpcol.lower(), lpcol.upper());
3056 	   _completeRangeTypesRational();
3057 	
3058 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3059 	      _changeColReal(i, lpcol);
3060 	
3061 	   _invalidateSolution();
3062 	}
3063 	
3064 	
3065 	
3066 	/// changes vector of lower bounds to \p lower
3067 	template <class R>
3068 	void SoPlexBase<R>::changeLowerRational(const VectorRational& lower)
3069 	{
3070 	   assert(_rationalLP != 0);
3071 	
3072 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3073 	      return;
3074 	
3075 	   _rationalLP->changeLower(lower);
3076 	
3077 	   for(int i = 0; i < numColsRational(); i++)
3078 	      _colTypes[i] = _rangeTypeRational(lower[i], _rationalLP->upper(i));
3079 	
3080 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3081 	      _changeLowerReal(VectorBase<R>(lower));
3082 	
3083 	   _invalidateSolution();
3084 	}
3085 	
3086 	
3087 	
3088 	/// changes lower bound of column i to \p lower
3089 	template <class R>
3090 	void SoPlexBase<R>::changeLowerRational(int i, const Rational& lower)
3091 	{
3092 	   assert(_rationalLP != 0);
3093 	
3094 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3095 	      return;
3096 	
3097 	   _rationalLP->changeLower(i, lower);
3098 	   _colTypes[i] = _rangeTypeRational(lower, _rationalLP->upper(i));
3099 	
3100 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3101 	      _changeLowerReal(i, R(lower));
3102 	
3103 	   _invalidateSolution();
3104 	}
3105 	
3106 	
3107 	
3108 	#ifdef SOPLEX_WITH_GMP
3109 	/// changes lower bound of column i to \p lower (GMP only method)
3110 	template <class R>
3111 	void SoPlexBase<R>::changeLowerRational(int i, const mpq_t* lower)
3112 	{
3113 	   assert(_rationalLP != 0);
3114 	
3115 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3116 	      return;
3117 	
3118 	#ifndef SOPLEX_WITH_BOOST
3119 	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
3120 	#endif
3121 	   _rationalLP->changeLower(i, lower);
3122 	   _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), _rationalLP->upper(i));
3123 	
3124 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3125 	      _changeLowerReal(i, R(lowerRational(i)));
3126 	
3127 	   _invalidateSolution();
3128 	}
3129 	#endif
3130 	
3131 	
3132 	
3133 	/// changes vector of upper bounds to \p upper
3134 	template <class R>
3135 	void SoPlexBase<R>::changeUpperRational(const VectorRational& upper)
3136 	{
3137 	   assert(_rationalLP != 0);
3138 	
3139 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3140 	      return;
3141 	
3142 	   _rationalLP->changeUpper(upper);
3143 	
3144 	   for(int i = 0; i < numColsRational(); i++)
3145 	      _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), upper[i]);
3146 	
3147 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3148 	      _changeUpperReal(VectorBase<R>(upper));
3149 	
3150 	   _invalidateSolution();
3151 	}
3152 	
3153 	
3154 	
3155 	
3156 	/// changes \p i 'th upper bound to \p upper
3157 	template <class R>
3158 	void SoPlexBase<R>::changeUpperRational(int i, const Rational& upper)
3159 	{
3160 	   assert(_rationalLP != 0);
3161 	
3162 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3163 	      return;
3164 	
3165 	   _rationalLP->changeUpper(i, upper);
3166 	   _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), upper);
3167 	
3168 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3169 	      _changeUpperReal(i, R(upper));
3170 	
3171 	   _invalidateSolution();
3172 	}
3173 	
3174 	
3175 	
3176 	#ifdef SOPLEX_WITH_GMP
3177 	/// changes upper bound of column i to \p upper (GMP only method)
3178 	template <class R>
3179 	void SoPlexBase<R>::changeUpperRational(int i, const mpq_t* upper)
3180 	{
3181 	   assert(_rationalLP != 0);
3182 	
3183 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3184 	      return;
3185 	
3186 	#ifndef SOPLEX_WITH_BOOST
3187 	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
3188 	#endif
3189 	   _rationalLP->changeUpper(i, upper);
3190 	   _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), _rationalLP->upper(i));
3191 	
3192 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3193 	      _changeUpperReal(i, R(upperRational(i)));
3194 	
3195 	   _invalidateSolution();
3196 	}
3197 	#endif
3198 	
3199 	
3200 	
3201 	/// changes vectors of column bounds to \p lower and \p upper
3202 	template <class R>
3203 	void SoPlexBase<R>::changeBoundsRational(const VectorRational& lower, const VectorRational& upper)
3204 	{
3205 	   assert(_rationalLP != 0);
3206 	
3207 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3208 	      return;
3209 	
3210 	   _rationalLP->changeBounds(lower, upper);
3211 	
3212 	   for(int i = 0; i < numColsRational(); i++)
3213 	      _colTypes[i] = _rangeTypeRational(lower[i], upper[i]);
3214 	
3215 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3216 	      _changeBoundsReal(VectorBase<R>(lower), VectorBase<R>(upper));
3217 	
3218 	   _invalidateSolution();
3219 	}
3220 	
3221 	
3222 	
3223 	/// changes bounds of column \p i to \p lower and \p upper
3224 	template <class R>
3225 	void SoPlexBase<R>::changeBoundsRational(int i, const Rational& lower, const Rational& upper)
3226 	{
3227 	   assert(_rationalLP != 0);
3228 	
3229 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3230 	      return;
3231 	
3232 	   _rationalLP->changeBounds(i, lower, upper);
3233 	   _colTypes[i] = _rangeTypeRational(lower, upper);
3234 	
3235 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3236 	      _changeBoundsReal(i, R(lower), R(upper));
3237 	
3238 	   _invalidateSolution();
3239 	}
3240 	
3241 	
3242 	
3243 	#ifdef SOPLEX_WITH_GMP
3244 	/// changes bounds of column \p i to \p lower and \p upper (GMP only method)
3245 	template <class R>
3246 	void SoPlexBase<R>::changeBoundsRational(int i, const mpq_t* lower, const mpq_t* upper)
3247 	{
3248 	   assert(_rationalLP != 0);
3249 	
3250 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3251 	      return;
3252 	
3253 	#ifndef SOPLEX_WITH_BOOST
3254 	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
3255 	#endif
3256 	   _rationalLP->changeBounds(i, lower, upper);
3257 	   _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), _rationalLP->upper(i));
3258 	
3259 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3260 	      _changeBoundsReal(i, R(lowerRational(i)), R(upperRational(i)));
3261 	
3262 	   _invalidateSolution();
3263 	}
3264 	#endif
3265 	
3266 	
3267 	
3268 	/// changes objective function vector to \p obj
3269 	template <class R>
3270 	void SoPlexBase<R>::changeObjRational(const VectorRational& obj)
3271 	{
3272 	   assert(_rationalLP != 0);
3273 	
3274 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3275 	      return;
3276 	
3277 	   _rationalLP->changeObj(obj);
3278 	
3279 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3280 	      _realLP->changeObj(VectorBase<R>(obj));
3281 	
3282 	   _invalidateSolution();
3283 	}
3284 	
3285 	
3286 	
3287 	/// changes objective coefficient of column i to \p obj
3288 	template <class R>
3289 	void SoPlexBase<R>::changeObjRational(int i, const Rational& obj)
3290 	{
3291 	   assert(_rationalLP != 0);
3292 	
3293 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3294 	      return;
3295 	
3296 	   _rationalLP->changeObj(i, obj);
3297 	
3298 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3299 	      _realLP->changeObj(i, R(obj));
3300 	
3301 	   _invalidateSolution();
3302 	}
3303 	
3304 	
3305 	
3306 	#ifdef SOPLEX_WITH_GMP
3307 	/// changes objective coefficient of column i to \p obj (GMP only method)
3308 	template <class R>
3309 	void SoPlexBase<R>::changeObjRational(int i, const mpq_t* obj)
3310 	{
3311 	   assert(_rationalLP != 0);
3312 	
3313 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3314 	      return;
3315 	
3316 	#ifndef SOPLEX_WITH_BOOST
3317 	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
3318 	#endif
3319 	   _rationalLP->changeObj(i, obj);
3320 	
3321 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3322 	      _realLP->changeObj(i, R(objRational(i)));
3323 	
3324 	   _invalidateSolution();
3325 	}
3326 	#endif
3327 	
3328 	
3329 	
3330 	/// changes matrix entry in row \p i and column \p j to \p val
3331 	template <class R>
3332 	void SoPlexBase<R>::changeElementRational(int i, int j, const Rational& val)
3333 	{
3334 	   assert(_rationalLP != 0);
3335 	
3336 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3337 	      return;
3338 	
3339 	   _rationalLP->changeElement(i, j, val);
3340 	
3341 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3342 	      _changeElementReal(i, j, R(val));
3343 	
3344 	   _invalidateSolution();
3345 	}
3346 	
3347 	
3348 	#ifdef SOPLEX_WITH_GMP
3349 	/// changes matrix entry in row \p i and column \p j to \p val (GMP only method)
3350 	template <class R>
3351 	void SoPlexBase<R>::changeElementRational(int i, int j, const mpq_t* val)
3352 	{
3353 	   assert(_rationalLP != 0);
3354 	
3355 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3356 	      return;
3357 	
3358 	#ifndef SOPLEX_WITH_BOOST
3359 	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
3360 	#endif
3361 	   _rationalLP->changeElement(i, j, val);
3362 	
3363 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3364 	      _changeElementReal(i, j, mpq_get_d(*val));
3365 	
3366 	   _invalidateSolution();
3367 	}
3368 	#endif
3369 	
3370 	
3371 	/// removes row \p i
3372 	template <class R>
3373 	void SoPlexBase<R>::removeRowRational(int i)
3374 	{
3375 	   assert(_rationalLP != 0);
3376 	
3377 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3378 	      return;
3379 	
3380 	   _rationalLP->removeRow(i);
3381 	
3382 	   // only swap elements if not the last one was removed
3383 	   if(i < _rationalLP->nRows())
3384 	   {
3385 	      _rowTypes[i] = _rowTypes[_rationalLP->nRows()];
3386 	      assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
3387 	   }
3388 	
3389 	   _rowTypes.reSize(_rationalLP->nRows());
3390 	
3391 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3392 	      _removeRowReal(i);
3393 	
3394 	   _invalidateSolution();
3395 	}
3396 	
3397 	
3398 	
3399 	/// removes all rows with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the new
3400 	/// index where row \p i has been moved to; note that \p perm must point to an array of size at least
3401 	/// #numRowsRational()
3402 	template <class R>
3403 	void SoPlexBase<R>::removeRowsRational(int perm[])
3404 	{
3405 	   assert(_rationalLP != 0);
3406 	
3407 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3408 	      return;
3409 	
3410 	   const int oldsize = numRowsRational();
3411 	   _rationalLP->removeRows(perm);
3412 	
3413 	   for(int i = 0; i < oldsize; i++)
3414 	   {
3415 	      if(perm[i] >= 0)
3416 	         _rowTypes[perm[i]] = _rowTypes[i];
3417 	   }
3418 	
3419 	   _rowTypes.reSize(_rationalLP->nRows());
3420 	
3421 	   for(int i = 0; i < numRowsRational(); i++)
3422 	   {
3423 	      assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
3424 	   }
3425 	
3426 	
3427 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3428 	      _removeRowsReal(perm);
3429 	
3430 	   _invalidateSolution();
3431 	}
3432 	
3433 	
3434 	
3435 	/// remove all rows with indices in array \p idx of size \p n; an array \p perm of size #numRowsRational() may be
3436 	/// passed as buffer memory
3437 	template <class R>
3438 	void SoPlexBase<R>::removeRowsRational(int idx[], int n, int perm[])
3439 	{
3440 	   if(perm == 0)
3441 	   {
3442 	      DataArray< int > p(numRowsRational());
3443 	      _idxToPerm(idx, n, p.get_ptr(), numRowsRational());
3444 	      SoPlexBase<R>::removeRowsRational(p.get_ptr());
3445 	   }
3446 	   else
3447 	   {
3448 	      _idxToPerm(idx, n, perm, numRowsRational());
3449 	      SoPlexBase<R>::removeRowsRational(perm);
3450 	   }
3451 	}
3452 	
3453 	
3454 	
3455 	/// removes rows \p start to \p end including both; an array \p perm of size #numRowsRational() may be passed as
3456 	/// buffer memory
3457 	template <class R>
3458 	void SoPlexBase<R>::removeRowRangeRational(int start, int end, int perm[])
3459 	{
3460 	   if(perm == 0)
3461 	   {
3462 	      DataArray< int > p(numRowsRational());
3463 	      _rangeToPerm(start, end, p.get_ptr(), numRowsRational());
3464 	      SoPlexBase<R>::removeRowsRational(p.get_ptr());
3465 	   }
3466 	   else
3467 	   {
3468 	      _rangeToPerm(start, end, perm, numRowsRational());
3469 	      SoPlexBase<R>::removeRowsRational(perm);
3470 	   }
3471 	}
3472 	
3473 	
3474 	
3475 	/// removes column i
3476 	template <class R>
3477 	void SoPlexBase<R>::removeColRational(int i)
3478 	{
3479 	   assert(_rationalLP != 0);
3480 	
3481 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3482 	      return;
3483 	
3484 	   _rationalLP->removeCol(i);
3485 	
3486 	   // only swap elements if not the last one was removed
3487 	   if(i < _rationalLP->nCols())
3488 	   {
3489 	      _colTypes[i] = _colTypes[_rationalLP->nCols()];
3490 	      assert(_colTypes[i] == _rangeTypeRational(lowerRational(i), upperRational(i)));
3491 	   }
3492 	
3493 	   _colTypes.reSize(_rationalLP->nCols());
3494 	
3495 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3496 	      _removeColReal(i);
3497 	
3498 	   _invalidateSolution();
3499 	}
3500 	
3501 	
3502 	
3503 	/// removes all columns with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
3504 	/// new index where column \p i has been moved to; note that \p perm must point to an array of size at least
3505 	/// #numColsRational()
3506 	template <class R>
3507 	void SoPlexBase<R>::removeColsRational(int perm[])
3508 	{
3509 	   assert(_rationalLP != 0);
3510 	
3511 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3512 	      return;
3513 	
3514 	   const int oldsize = numColsRational();
3515 	   _rationalLP->removeCols(perm);
3516 	
3517 	   for(int i = 0; i < oldsize; i++)
3518 	   {
3519 	      if(perm[i] >= 0)
3520 	         _colTypes[perm[i]] = _colTypes[i];
3521 	   }
3522 	
3523 	   _colTypes.reSize(_rationalLP->nCols());
3524 	
3525 	   for(int i = 0; i < numColsRational(); i++)
3526 	   {
3527 	      assert(_colTypes[i] == _rangeTypeRational(lowerRational(i), upperRational(i)));
3528 	   }
3529 	
3530 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3531 	      _removeColsReal(perm);
3532 	
3533 	   _invalidateSolution();
3534 	}
3535 	
3536 	
3537 	
3538 	/// remove all columns with indices in array \p idx of size \p n; an array \p perm of size #numColsRational() may be
3539 	/// passed as buffer memory
3540 	template <class R>
3541 	void SoPlexBase<R>::removeColsRational(int idx[], int n, int perm[])
3542 	{
3543 	   if(perm == 0)
3544 	   {
3545 	      DataArray< int > p(numColsRational());
3546 	      _idxToPerm(idx, n, p.get_ptr(), numColsRational());
3547 	      SoPlexBase<R>::removeColsRational(p.get_ptr());
3548 	   }
3549 	   else
3550 	   {
3551 	      _idxToPerm(idx, n, perm, numColsRational());
3552 	      SoPlexBase<R>::removeColsRational(perm);
3553 	   }
3554 	}
3555 	
3556 	
3557 	
3558 	/// removes columns \p start to \p end including both; an array \p perm of size #numColsRational() may be passed as
3559 	/// buffer memory
3560 	template <class R>
3561 	void SoPlexBase<R>::removeColRangeRational(int start, int end, int perm[])
3562 	{
3563 	   if(perm == 0)
3564 	   {
3565 	      DataArray< int > p(numColsRational());
3566 	      _rangeToPerm(start, end, p.get_ptr(), numColsRational());
3567 	      SoPlexBase<R>::removeColsRational(p.get_ptr());
3568 	   }
3569 	   else
3570 	   {
3571 	      _rangeToPerm(start, end, perm, numColsRational());
3572 	      SoPlexBase<R>::removeColsRational(perm);
3573 	   }
3574 	}
3575 	
3576 	
3577 	
3578 	/// clears the LP
3579 	template <class R>
3580 	void SoPlexBase<R>::clearLPRational()
3581 	{
3582 	   assert(_rationalLP != 0);
3583 	
3584 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3585 	      return;
3586 	
3587 	   _rationalLP->clear();
3588 	   _rationalLUSolver.clear();
3589 	   _rowTypes.clear();
3590 	   _colTypes.clear();
3591 	
3592 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
3593 	   {
3594 	      _realLP->clear();
3595 	      _hasBasis = false;
3596 	   }
3597 	
3598 	   _invalidateSolution();
3599 	}
3600 	
3601 	
3602 	
3603 	/// synchronizes rational LP with R LP, i.e., copies R LP to rational LP, if sync mode is manual
3604 	template <class R>
3605 	void SoPlexBase<R>::syncLPRational()
3606 	{
3607 	   assert(_isConsistent());
3608 	
3609 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_MANUAL)
3610 	      _syncLPRational();
3611 	}
3612 	
3613 	/// returns the current solver status
3614 	template <class R>
3615 	typename SPxSolverBase<R>::Status SoPlexBase<R>::status() const
3616 	{
3617 	   return _status;
3618 	}
3619 	
3620 	/// returns the current basis status
3621 	template <class R>
3622 	typename SPxBasisBase<R>::SPxStatus SoPlexBase<R>::basisStatus() const
3623 	{
3624 	   if(!hasBasis())
3625 	      return SPxBasisBase<R>::NO_PROBLEM;
3626 	   else
3627 	      return _solver.getBasisStatus();
3628 	}
3629 	
3630 	
3631 	/// returns the objective value if a primal or dual solution is available
3632 	template <class R>
3633 	R SoPlexBase<R>::objValueReal()
3634 	{
3635 	   assert(OBJSENSE_MAXIMIZE == 1);
3636 	   assert(OBJSENSE_MINIMIZE == -1);
3637 	
3638 	   if(status() == SPxSolverBase<R>::UNBOUNDED)
3639 	      return realParam(SoPlexBase<R>::INFTY) * intParam(SoPlexBase<R>::OBJSENSE);
3640 	   else if(status() == SPxSolverBase<R>::INFEASIBLE)
3641 	      return -realParam(SoPlexBase<R>::INFTY) * intParam(SoPlexBase<R>::OBJSENSE);
3642 	   else if(hasSol())
3643 	   {
3644 	      _syncRealSolution();
3645 	      return _solReal._objVal;
3646 	   }
3647 	   else
3648 	      return 0.0;
3649 	}
3650 	
3651 	
3652 	/// returns the objective value if a primal or dual solution is available
3653 	template <class R>
3654 	Rational SoPlexBase<R>::objValueRational()
3655 	{
3656 	   assert(OBJSENSE_MAXIMIZE == 1);
3657 	   assert(OBJSENSE_MINIMIZE == -1);
3658 	
3659 	   if(this->status() == SPxSolverBase<R>::UNBOUNDED)
3660 	   {
3661 	      if(intParam(SoPlexBase<R>::OBJSENSE) == OBJSENSE_MAXIMIZE)
3662 	         return _rationalPosInfty;
3663 	      else
3664 	         return _rationalNegInfty;
3665 	   }
3666 	   else if(this->status() == SPxSolverBase<R>::INFEASIBLE)
3667 	   {
3668 	      if(intParam(SoPlexBase<R>::OBJSENSE) == OBJSENSE_MAXIMIZE)
3669 	         return _rationalNegInfty;
3670 	      else
3671 	         return _rationalPosInfty;
3672 	   }
3673 	   else if(hasSol())
3674 	   {
3675 	      _syncRationalSolution();
3676 	      return _solRational._objVal;
3677 	   }
3678 	   else
3679 	      return _rationalZero;
3680 	}
3681 	
3682 	/// Is stored primal solution feasible?
3683 	template <class R>
3684 	bool SoPlexBase<R>::isPrimalFeasible() const
3685 	{
3686 	   return (_hasSolReal && _solReal.isPrimalFeasible()) || (_hasSolRational
3687 	          && _solRational.isPrimalFeasible());
3688 	}
3689 	
3690 	/// is a solution available (not necessarily feasible)?
3691 	template <class R>
3692 	bool SoPlexBase<R>::hasSol() const
3693 	{
3694 	   return _hasSolReal || _hasSolRational;
3695 	}
3696 	
3697 	/// is a primal unbounded ray available?
3698 	template <class R>
3699 	bool SoPlexBase<R>::hasPrimalRay() const
3700 	{
3701 	   return (_hasSolReal && _solReal.hasPrimalRay()) || (_hasSolRational && _solRational.hasPrimalRay());
3702 	}
3703 	
3704 	
3705 	/// is stored dual solution feasible?
3706 	template <class R>
3707 	bool SoPlexBase<R>::isDualFeasible() const
3708 	{
3709 	   return (_hasSolReal && _solReal.isDualFeasible()) || (_hasSolRational
3710 	          && _solRational.isDualFeasible());
3711 	
3712 	}
3713 	
3714 	/// is Farkas proof of infeasibility available?
3715 	template <class R>
3716 	bool SoPlexBase<R>::hasDualFarkas() const
3717 	{
3718 	   return (_hasSolReal && _solReal.hasDualFarkas()) || (_hasSolRational
3719 	          && _solRational.hasDualFarkas());
3720 	}
3721 	
3722 	/// gets the vector of slack values if available; returns true on success
3723 	template <class R>
3724 	bool SoPlexBase<R>::getSlacksReal(VectorBase<R>& vector)
3725 	{
3726 	   if(hasSol() && vector.dim() >= numRows())
3727 	   {
3728 	      _syncRealSolution();
3729 	      _solReal.getSlacks(vector);
3730 	      return true;
3731 	   }
3732 	   else
3733 	      return false;
3734 	}
3735 	
3736 	template <class R>
3737 	bool SoPlexBase<R>::getSlacksReal(R* p_vector, int dim)
3738 	{
3739 	   if(hasSol() && dim >= numRows())
3740 	   {
3741 	      _syncRealSolution();
3742 	
3743 	      auto& slacks = _solReal._slacks;
3744 	      std::copy(slacks.begin(), slacks.end(), p_vector);
3745 	
3746 	      return true;
3747 	   }
3748 	   else
3749 	      return false;
3750 	}
3751 	
3752 	
3753 	/// gets the primal solution vector if available; returns true on success
3754 	template <class R>
3755 	bool SoPlexBase<R>::getPrimalRational(VectorBase<Rational>& vector)
3756 	{
3757 	   if(_rationalLP != 0 && hasSol() && vector.dim() >= numColsRational())
3758 	   {
3759 	      _syncRationalSolution();
3760 	      _solRational.getPrimalSol(vector);
3761 	      return true;
3762 	   }
3763 	   else
3764 	      return false;
3765 	}
3766 	
3767 	
3768 	/// gets the vector of slack values if available; returns true on success
3769 	template <class R>
3770 	bool SoPlexBase<R>::getSlacksRational(VectorRational& vector)
3771 	{
3772 	   if(_rationalLP != 0 && hasSol() && vector.dim() >= numRowsRational())
3773 	   {
3774 	      _syncRationalSolution();
3775 	      _solRational.getSlacks(vector);
3776 	      return true;
3777 	   }
3778 	   else
3779 	      return false;
3780 	}
3781 	
3782 	template <class R>
3783 	bool SoPlexBase<R>::getPrimalRayRational(VectorBase<Rational>& vector)
3784 	{
3785 	   if(_rationalLP != 0 && hasPrimalRay() && vector.dim() >= numColsRational())
3786 	   {
3787 	      _syncRationalSolution();
3788 	      _solRational.getPrimalRaySol(vector);
3789 	      return true;
3790 	   }
3791 	   else
3792 	      return false;
3793 	}
3794 	
3795 	
3796 	
3797 	/// gets the dual solution vector if available; returns true on success
3798 	template <class R>
3799 	bool SoPlexBase<R>::getDualRational(VectorBase<Rational>& vector)
3800 	{
3801 	   if(_rationalLP != 0 && hasSol() && vector.dim() >= numRowsRational())
3802 	   {
3803 	      _syncRationalSolution();
3804 	      _solRational.getDualSol(vector);
3805 	      return true;
3806 	   }
3807 	   else
3808 	      return false;
3809 	}
3810 	
3811 	
3812 	
3813 	/// gets the vector of reduced cost values if available; returns true on success
3814 	template <class R>
3815 	bool SoPlexBase<R>::getRedCostRational(VectorRational& vector)
3816 	{
3817 	   if(_rationalLP != 0 && hasSol() && vector.dim() >= numColsRational())
3818 	   {
3819 	      _syncRationalSolution();
3820 	      _solRational.getRedCostSol(vector);
3821 	      return true;
3822 	   }
3823 	   else
3824 	      return false;
3825 	}
3826 	
3827 	/// gets the Farkas proof if LP is infeasible; returns true on success
3828 	template <class R>
3829 	bool SoPlexBase<R>::getDualFarkasRational(VectorBase<Rational>& vector)
3830 	{
3831 	   if(_rationalLP != 0 && hasDualFarkas() && vector.dim() >= numRowsRational())
3832 	   {
3833 	      _syncRationalSolution();
3834 	      _solRational.getDualFarkasSol(vector);
3835 	      return true;
3836 	   }
3837 	   else
3838 	      return false;
3839 	}
3840 	
3841 	
3842 	
3843 	/// gets violation of bounds; returns true on success
3844 	template <class R>
3845 	bool SoPlexBase<R>::getBoundViolationRational(Rational& maxviol, Rational& sumviol)
3846 	{
3847 	   if(!isPrimalFeasible())
3848 	      return false;
3849 	
3850 	   // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3851 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3852 	      _syncLPRational(false);
3853 	
3854 	   _syncRationalSolution();
3855 	   VectorRational& primal = _solRational._primal;
3856 	   assert(primal.dim() == numColsRational());
3857 	
3858 	   maxviol = 0;
3859 	   sumviol = 0;
3860 	
3861 	   for(int i = numColsRational() - 1; i >= 0; i--)
3862 	   {
3863 	      Rational viol = lowerRational(i) - primal[i];
3864 	
3865 	      if(viol > 0)
3866 	      {
3867 	         sumviol += viol;
3868 	
3869 	         if(viol > maxviol)
3870 	         {
3871 	            maxviol = viol;
3872 	            MSG_DEBUG(std::cout << "increased bound violation for column " << i << ": " << viol.str()
3873 	                      << " lower: " << lowerRational(i).str()
3874 	                      << ", primal: " << primal[i].str() << "\n");
3875 	         }
3876 	      }
3877 	
3878 	      viol = primal[i] - upperRational(i);
3879 	
3880 	      if(viol > 0)
3881 	      {
3882 	         sumviol += viol;
3883 	
3884 	         if(viol > maxviol)
3885 	         {
3886 	            maxviol = viol;
3887 	            MSG_DEBUG(std::cout << "increased bound violation for column " << i << ": " << viol.str()
3888 	                      << " upper: " << upperRational(i).str()
3889 	                      << ", primal: " << primal[i].str() << "\n");
3890 	         }
3891 	      }
3892 	   }
3893 	
3894 	   return true;
3895 	}
3896 	
3897 	
3898 	
3899 	/// gets violation of constraints; returns true on success
3900 	template <class R>
3901 	bool SoPlexBase<R>::getRowViolationRational(Rational& maxviol, Rational& sumviol)
3902 	{
3903 	   if(!isPrimalFeasible())
3904 	      return false;
3905 	
3906 	   // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3907 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3908 	      _syncLPRational(false);
3909 	
3910 	   _syncRationalSolution();
3911 	   VectorRational& primal = _solRational._primal;
3912 	   assert(primal.dim() == numColsRational());
3913 	
3914 	   VectorRational activity(numRowsRational());
3915 	   _rationalLP->computePrimalActivity(primal, activity);
3916 	   maxviol = 0;
3917 	   sumviol = 0;
3918 	
3919 	   for(int i = numRowsRational() - 1; i >= 0; i--)
3920 	   {
3921 	      Rational viol = lhsRational(i) - activity[i];
3922 	
3923 	      if(viol > 0)
3924 	      {
3925 	         sumviol += viol;
3926 	
3927 	         if(viol > maxviol)
3928 	         {
3929 	            maxviol = viol;
3930 	            MSG_DEBUG(std::cout << "increased constraint violation for row " << i << ": " << viol.str()
3931 	                      << " lhs: " << lhsRational(i).str()
3932 	                      << ", activity: " << activity[i].str() << "\n");
3933 	         }
3934 	      }
3935 	
3936 	      viol = activity[i] - rhsRational(i);
3937 	
3938 	      if(viol > 0)
3939 	      {
3940 	         sumviol += viol;
3941 	
3942 	         if(viol > maxviol)
3943 	         {
3944 	            maxviol = viol;
3945 	            MSG_DEBUG(std::cout << "increased constraint violation for row " << i << ": " << viol.str()
3946 	                      << " rhs: " << rhsRational(i).str()
3947 	                      << ", activity: " << activity[i].str() << "\n");
3948 	         }
3949 	      }
3950 	   }
3951 	
3952 	   return true;
3953 	}
3954 	
3955 	
3956 	
3957 	/// gets violation of reduced costs; returns true on success
3958 	template <class R>
3959 	bool SoPlexBase<R>::getRedCostViolationRational(Rational& maxviol, Rational& sumviol)
3960 	{
3961 	   if(!isPrimalFeasible() || !isDualFeasible())
3962 	      return false;
3963 	
3964 	   // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3965 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
3966 	      _syncLPRational(false);
3967 	
3968 	   _syncRationalSolution();
3969 	   VectorRational& redcost = _solRational._redCost;
3970 	   assert(redcost.dim() == numColsRational());
3971 	
3972 	   maxviol = 0;
3973 	   sumviol = 0;
3974 	
3975 	   for(int c = numCols() - 1; c >= 0; c--)
3976 	   {
3977 	      assert(!_hasBasis || basisColStatus(c) != SPxSolverBase<R>::UNDEFINED);
3978 	
3979 	      if(_colTypes[c] == RANGETYPE_FIXED)
3980 	      {
3981 	         assert(lowerRational(c) == upperRational(c));
3982 	         continue;
3983 	      }
3984 	
3985 	      // since the rational solution may be translated from a floating-point solve, feasibility and consistency of the
3986 	      // basis must not necessarily hold exactly, even within tolerances; hence the following assertions are relaxed by
3987 	      // a factor of two
3988 	      assert(!_hasBasis || basisColStatus(c) != SPxSolverBase<R>::ON_LOWER
3989 	             || spxAbs(Rational(_solRational._primal[c] - lowerRational(c))) <= 2 * _rationalFeastol);
3990 	      assert(!_hasBasis || basisColStatus(c) != SPxSolverBase<R>::ON_UPPER
3991 	             || spxAbs(Rational(_solRational._primal[c] - upperRational(c))) <= 2 * _rationalFeastol);
3992 	      assert(!_hasBasis || basisColStatus(c) != SPxSolverBase<R>::FIXED
3993 	             || spxAbs(Rational(_solRational._primal[c] - lowerRational(c))) <= 2 * _rationalFeastol);
3994 	      assert(!_hasBasis || basisColStatus(c) != SPxSolverBase<R>::FIXED
3995 	             || spxAbs(Rational(_solRational._primal[c] - upperRational(c))) <= 2 * _rationalFeastol);
3996 	
3997 	      if(intParam(SoPlexBase<R>::OBJSENSE) == OBJSENSE_MINIMIZE)
3998 	      {
3999 	         if(_solRational._primal[c] != upperRational(c) && redcost[c] < 0)
4000 	         {
4001 	            sumviol += -redcost[c];
4002 	
4003 	            if(redcost[c] < -maxviol)
4004 	            {
4005 	               MSG_DEBUG(std::cout << "increased reduced cost violation for column " << c <<
4006 	                         " not on upper bound: " << -redcost[c].str() << "\n");
4007 	               maxviol = -redcost[c];
4008 	            }
4009 	         }
4010 	
4011 	         if(_solRational._primal[c] != lowerRational(c) && redcost[c] > 0)
4012 	         {
4013 	            sumviol += redcost[c];
4014 	
4015 	            if(redcost[c] > maxviol)
4016 	            {
4017 	               MSG_DEBUG(std::cout << "increased reduced cost violation for column " << c <<
4018 	                         " not on lower bound: " << redcost[c].str() << "\n");
4019 	               maxviol = redcost[c];
4020 	            }
4021 	         }
4022 	      }
4023 	      else
4024 	      {
4025 	         if(_solRational._primal[c] != upperRational(c) && redcost[c] > 0)
4026 	         {
4027 	            sumviol += redcost[c];
4028 	
4029 	            if(redcost[c] > maxviol)
4030 	            {
4031 	               MSG_DEBUG(std::cout << "increased reduced cost violation for column " << c <<
4032 	                         " not on upper bound: " << redcost[c].str() << "\n");
4033 	               maxviol = redcost[c];
4034 	            }
4035 	         }
4036 	
4037 	         if(_solRational._primal[c] != lowerRational(c) && redcost[c] < 0)
4038 	         {
4039 	            sumviol += -redcost[c];
4040 	
4041 	            if(redcost[c] < -maxviol)
4042 	            {
4043 	               MSG_DEBUG(std::cout << "increased reduced cost violation for column " << c <<
4044 	                         " not on lower bound: " << -redcost[c].str() << "\n");
4045 	               maxviol = -redcost[c];
4046 	            }
4047 	         }
4048 	      }
4049 	   }
4050 	
4051 	   return true;
4052 	}
4053 	
4054 	
4055 	
4056 	/// gets violation of dual multipliers; returns true on success
4057 	template <class R>
4058 	bool SoPlexBase<R>::getDualViolationRational(Rational& maxviol, Rational& sumviol)
4059 	{
4060 	   if(!isDualFeasible() || !isPrimalFeasible())
4061 	      return false;
4062 	
4063 	   // if we have to synchronize, we do not measure time, because this would affect the solving statistics
4064 	   if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
4065 	      _syncLPRational(false);
4066 	
4067 	   _syncRationalSolution();
4068 	   VectorRational& dual = _solRational._dual;
4069 	   assert(dual.dim() == numRowsRational());
4070 	
4071 	   maxviol = 0;
4072 	   sumviol = 0;
4073 	
4074 	   for(int r = numRows() - 1; r >= 0; r--)
4075 	   {
4076 	      assert(!_hasBasis || basisRowStatus(r) != SPxSolverBase<R>::UNDEFINED);
4077 	
4078 	      if(_rowTypes[r] == RANGETYPE_FIXED)
4079 	      {
4080 	         assert(lhsRational(r) == rhsRational(r));
4081 	         continue;
4082 	      }
4083 	
4084 	      // since the rational solution may be translated from a floating-point solve, feasibility and consistency of the
4085 	      // basis must not necessarily hold exactly, even within tolerances; hence the following assertions are relaxed by
4086 	      // a factor of two
4087 	      assert(!_hasBasis || basisRowStatus(r) != SPxSolverBase<R>::ON_LOWER
4088 	             || spxAbs(Rational(_solRational._slacks[r] - lhsRational(r))) <= 2 * _rationalFeastol);
4089 	      assert(!_hasBasis || basisRowStatus(r) != SPxSolverBase<R>::ON_UPPER
4090 	             || spxAbs(Rational(_solRational._slacks[r] - rhsRational(r))) <= 2 * _rationalFeastol);
4091 	      assert(!_hasBasis || basisRowStatus(r) != SPxSolverBase<R>::FIXED
4092 	             || spxAbs(Rational(_solRational._slacks[r] - lhsRational(r))) <= 2 * _rationalFeastol);
4093 	      assert(!_hasBasis || basisRowStatus(r) != SPxSolverBase<R>::FIXED
4094 	             || spxAbs(Rational(_solRational._slacks[r] - rhsRational(r))) <= 2 * _rationalFeastol);
4095 	
4096 	      if(intParam(SoPlexBase<R>::OBJSENSE) == OBJSENSE_MINIMIZE)
4097 	      {
4098 	         if(_solRational._slacks[r] < rhsRational(r) - _rationalFeastol && dual[r] < 0)
4099 	         {
4100 	            sumviol += -dual[r];
4101 	
4102 	            if(dual[r] < -maxviol)
4103 	            {
4104 	               MSG_DEBUG(std::cout << "increased dual violation for row " << r << " not on upper bound: " <<
4105 	                         -dual[r].str()
4106 	                         << " (slack = " << _solRational._slacks[r].str()
4107 	                         << ", status = " << basisRowStatus(r)
4108 	                         << ", lhs = " << lhsRational(r).str()
4109 	                         << ", rhs = " << rhsRational(r).str() << ")\n");
4110 	               maxviol = -dual[r];
4111 	            }
4112 	         }
4113 	
4114 	         if(_solRational._slacks[r] > lhsRational(r) + _rationalFeastol && dual[r] > 0)
4115 	         {
4116 	            sumviol += dual[r];
4117 	
4118 	            if(dual[r] > maxviol)
4119 	            {
4120 	               MSG_DEBUG(std::cout << "increased dual violation for row " << r << " not on lower bound: " <<
4121 	                         dual[r].str()
4122 	                         << " (slack = " << _solRational._slacks[r].str()
4123 	                         << ", status = " << basisRowStatus(r)
4124 	                         << ", lhs = " << lhsRational(r).str()
4125 	                         << ", rhs = " << rhsRational(r) << ")\n".str());
4126 	               maxviol = dual[r];
4127 	            }
4128 	         }
4129 	      }
4130 	      else
4131 	      {
4132 	         if(_solRational._slacks[r] < rhsRational(r) - _rationalFeastol && dual[r] > 0)
4133 	         {
4134 	            sumviol += dual[r];
4135 	
4136 	            if(dual[r] > maxviol)
4137 	            {
4138 	               MSG_DEBUG(std::cout << "increased dual violation for row " << r << " not on upper bound: " <<
4139 	                         dual[r].str()
4140 	                         << " (slack = " << _solRational._slacks[r].str()
4141 	                         << ", status = " << basisRowStatus(r)
4142 	                         << ", lhs = " << lhsRational(r).str()
4143 	                         << ", rhs = " << rhsRational(r).str() << ")\n");
4144 	               maxviol = dual[r];
4145 	            }
4146 	         }
4147 	
4148 	         if(_solRational._slacks[r] > lhsRational(r) + _rationalFeastol && dual[r] < 0)
4149 	         {
4150 	            sumviol += -dual[r];
4151 	
4152 	            if(dual[r] < -maxviol)
4153 	            {
4154 	               MSG_DEBUG(std::cout << "increased dual violation for row " << r << " not on lower bound: " <<
4155 	                         -dual[r].str()
4156 	                         << " (slack = " << _solRational._slacks[r].str()
4157 	                         << ", status = " << basisRowStatus(r)
4158 	                         << ", lhs = " << lhsRational(r).str()
4159 	                         << ", rhs = " << rhsRational(r).str() << ")\n");
4160 	               maxviol = -dual[r];
4161 	            }
4162 	         }
4163 	      }
4164 	   }
4165 	
4166 	   return true;
4167 	}
4168 	
4169 	
4170 	/// get size of primal solution
4171 	template <class R>
4172 	int SoPlexBase<R>::totalSizePrimalRational(const int base)
4173 	{
4174 	   if(hasSol() || hasPrimalRay())
4175 	   {
4176 	      _syncRationalSolution();
4177 	      return _solRational.totalSizePrimal(base);
4178 	   }
4179 	   else
4180 	      return 0;
4181 	}
4182 	
4183 	
4184 	
4185 	/// get size of dual solution
4186 	template <class R>
4187 	int SoPlexBase<R>::totalSizeDualRational(const int base)
4188 	{
4189 	   if(hasSol() || hasDualFarkas())
4190 	   {
4191 	      _syncRationalSolution();
4192 	      return _solRational.totalSizeDual(base);
4193 	   }
4194 	   else
4195 	      return 0;
4196 	}
4197 	
4198 	
4199 	
4200 	/// get size of least common multiple of denominators in primal solution
4201 	template <class R>
4202 	int SoPlexBase<R>::dlcmSizePrimalRational(const int base)
4203 	{
4204 	   if(hasSol() || hasPrimalRay())
4205 	   {
4206 	      _syncRationalSolution();
4207 	      return _solRational.dlcmSizePrimal(base);
4208 	   }
4209 	   else
4210 	      return 0;
4211 	}
4212 	
4213 	
4214 	
4215 	/// get size of least common multiple of denominators in dual solution
4216 	template <class R>
4217 	int SoPlexBase<R>::dlcmSizeDualRational(const int base)
4218 	{
4219 	   if(hasSol() || hasDualFarkas())
4220 	   {
4221 	      _syncRationalSolution();
4222 	      return _solRational.dlcmSizeDual(base);
4223 	   }
4224 	   else
4225 	      return 0;
4226 	}
4227 	
4228 	
4229 	
4230 	/// get size of largest denominator in primal solution
4231 	template <class R>
4232 	int SoPlexBase<R>::dmaxSizePrimalRational(const int base)
4233 	{
4234 	   if(hasSol() || hasPrimalRay())
4235 	   {
4236 	      _syncRationalSolution();
4237 	      return _solRational.dmaxSizePrimal(base);
4238 	   }
4239 	   else
4240 	      return 0;
4241 	}
4242 	
4243 	
4244 	
4245 	/// get size of largest denominator in dual solution
4246 	template <class R>
4247 	int SoPlexBase<R>::dmaxSizeDualRational(const int base)
4248 	{
4249 	   if(hasSol() || hasDualFarkas())
4250 	   {
4251 	      _syncRationalSolution();
4252 	      return _solRational.dmaxSizeDual(base);
4253 	   }
4254 	   else
4255 	      return 0;
4256 	}
4257 	
4258 	/// is an advanced starting basis available?
4259 	template <class R>
4260 	bool SoPlexBase<R>::hasBasis() const
4261 	{
4262 	   return _hasBasis;
4263 	}
4264 	
4265 	
4266 	
4267 	/// returns basis status for a single row
4268 	template <class R>
4269 	typename SPxSolverBase<R>::VarStatus SoPlexBase<R>::basisRowStatus(int row) const
4270 	{
4271 	   assert(row >= 0);
4272 	   assert(row < numRows());
4273 	
4274 	   // if no basis is available, return slack basis; if index is out of range, return basic status as for a newly
4275 	   // added row
4276 	   if(!hasBasis() || row < 0 || row >= numRows())
4277 	      return SPxSolverBase<R>::BASIC;
4278 	   // if the real LP is loaded, ask solver
4279 	   else if(_isRealLPLoaded)
4280 	   {
4281 	      return _solver.getBasisRowStatus(row);
4282 	   }
4283 	   // if the real LP is not loaded, the basis is stored in the basis arrays of this class
4284 	   else
4285 	   {
4286 	      assert(row < _basisStatusRows.size());
4287 	      return _basisStatusRows[row];
4288 	   }
4289 	}
4290 	
4291 	
4292 	
4293 	/// returns basis status for a single column
4294 	template <class R>
4295 	typename SPxSolverBase<R>::VarStatus SoPlexBase<R>::basisColStatus(int col) const
4296 	{
4297 	   assert(col >= 0);
4298 	   assert(col < numCols());
4299 	
4300 	   // if index is out of range, return nonbasic status as for a newly added unbounded column
4301 	   if(col < 0 || col >= numCols())
4302 	   {
4303 	      return SPxSolverBase<R>::ZERO;
4304 	   }
4305 	   // if no basis is available, return slack basis
4306 	   else if(!hasBasis())
4307 	   {
4308 	      if(lowerReal(col) > -realParam(SoPlexBase<R>::INFTY))
4309 	         return SPxSolverBase<R>::ON_LOWER;
4310 	      else if(upperReal(col) < realParam(SoPlexBase<R>::INFTY))
4311 	         return SPxSolverBase<R>::ON_UPPER;
4312 	      else
4313 	         return SPxSolverBase<R>::ZERO;
4314 	   }
4315 	   // if the real LP is loaded, ask solver
4316 	   else if(_isRealLPLoaded)
4317 	   {
4318 	      return _solver.getBasisColStatus(col);
4319 	   }
4320 	   // if the real LP is not loaded, the basis is stored in the basis arrays of this class
4321 	   else
4322 	   {
4323 	      assert(col < _basisStatusCols.size());
4324 	      return _basisStatusCols[col];
4325 	   }
4326 	}
4327 	
4328 	
4329 	
4330 	/// gets current basis
4331 	template <class R>
4332 	void SoPlexBase<R>::getBasis(typename SPxSolverBase<R>::VarStatus rows[],
4333 	                             typename SPxSolverBase<R>::VarStatus cols[]) const
4334 	{
4335 	   // if no basis is available, return slack basis
4336 	   if(!hasBasis())
4337 	   {
4338 	      for(int i = numRows() - 1; i >= 0; i--)
4339 	         rows[i] = SPxSolverBase<R>::BASIC;
4340 	
4341 	      for(int i = numCols() - 1; i >= 0; i--)
4342 	      {
4343 	         if(lowerReal(i) > -realParam(SoPlexBase<R>::INFTY))
4344 	            cols[i] = SPxSolverBase<R>::ON_LOWER;
4345 	         else if(upperReal(i) < realParam(SoPlexBase<R>::INFTY))
4346 	            cols[i] = SPxSolverBase<R>::ON_UPPER;
4347 	         else
4348 	            cols[i] = SPxSolverBase<R>::ZERO;
4349 	      }
4350 	   }
4351 	   // if the real LP is loaded, ask solver
4352 	   else if(_isRealLPLoaded)
4353 	   {
4354 	      (void)_solver.getBasis(rows, cols);
4355 	   }
4356 	   // if the real LP is not loaded, the basis is stored in the basis arrays of this class
4357 	   else
4358 	   {
4359 	      assert(numRows() == _basisStatusRows.size());
4360 	      assert(numCols() == _basisStatusCols.size());
4361 	
4362 	      for(int i = numRows() - 1; i >= 0; i--)
4363 	         rows[i] = _basisStatusRows[i];
4364 	
4365 	      for(int i = numCols() - 1; i >= 0; i--)
4366 	         cols[i] = _basisStatusCols[i];
4367 	   }
4368 	}
4369 	
4370 	
4371 	
4372 	/// returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m
4373 	/// note: the order of the indices might not coincide with the actual order when using ROW representation
4374 	template <class R>
4375 	void SoPlexBase<R>::getBasisInd(int* bind) const
4376 	{
4377 	   // if no basis is available, return slack basis
4378 	   if(!hasBasis())
4379 	   {
4380 	      for(int i = 0; i < numRows(); ++i)
4381 	         bind[i] = -1 - i;
4382 	   }
4383 	   // if the real LP is not loaded, the basis is stored in the basis arrays of this class
4384 	   else if(!_isRealLPLoaded)
4385 	   {
4386 	      int k = 0;
4387 	
4388 	      assert(numRows() == _basisStatusRows.size());
4389 	      assert(numCols() == _basisStatusCols.size());
4390 	
4391 	      for(int i = 0; i < numRows(); ++i)
4392 	      {
4393 	         if(_basisStatusRows[i] == SPxSolverBase<R>::BASIC)
4394 	         {
4395 	            bind[k] = -1 - i;
4396 	            k++;
4397 	         }
4398 	      }
4399 	
4400 	      for(int j = 0; j < numCols(); ++j)
4401 	      {
4402 	         if(_basisStatusCols[j] == SPxSolverBase<R>::BASIC)
4403 	         {
4404 	            bind[k] = j;
4405 	            k++;
4406 	         }
4407 	      }
4408 	
4409 	      assert(k == numRows());
4410 	   }
4411 	   // if the real LP is loaded, the basis is stored in the solver and we need to distinguish between column and row
4412 	   // representation; ask the solver itself which representation it has, since the REPRESENTATION parameter of this
4413 	   // class might be set to automatic
4414 	   else if(_solver.rep() == SPxSolverBase<R>::COLUMN)
4415 	   {
4416 	      for(int i = 0; i < numRows(); ++i)
4417 	      {
4418 	         SPxId id = _solver.basis().baseId(i);
4419 	         bind[i] = (id.isSPxColId() ? _solver.number(id) : - 1 - _solver.number(id));
4420 	      }
4421 	   }
4422 	   // for row representation, return the complement of the row basis; for this, we need to loop through all rows and columns
4423 	   else
4424 	   {
4425 	      assert(_solver.rep() == SPxSolverBase<R>::ROW);
4426 	
4427 	      int k = 0;
4428 	
4429 	      for(int i = 0; i < numRows(); ++i)
4430 	      {
4431 	         if(!_solver.isRowBasic(i))
4432 	         {
4433 	            bind[k] = -1 - i;
4434 	            k++;
4435 	         }
4436 	      }
4437 	
4438 	      for(int j = 0; j < numCols(); ++j)
4439 	      {
4440 	         if(!_solver.isColBasic(j))
4441 	         {
4442 	            bind[k] = j;
4443 	            k++;
4444 	         }
4445 	      }
4446 	
4447 	      assert(k == numRows());
4448 	   }
4449 	}
4450 	
4451 	
4452 	/** compute one of several matrix metrics based on the diagonal of the LU factorization
4453 	 *  type = 0: max/min ratio
4454 	 *  type = 1: trace of U (sum of diagonal elements)
4455 	 *  type = 2: determinant (product of diagonal elements)
4456 	 */
4457 	template <class R>
4458 	bool SoPlexBase<R>::getBasisMetric(R& condition, int type)
4459 	{
4460 	   _ensureRealLPLoaded();
4461 	
4462 	   if(!_isRealLPLoaded)
4463 	      return false;
4464 	
4465 	   if(_solver.basis().status() == SPxBasisBase<R>::NO_PROBLEM)
4466 	   {
4467 	      return false;
4468 	   }
4469 	
4470 	   condition = _solver.getBasisMetric(type);
4471 	
4472 	   return true;
4473 	}
4474 	
4475 	/// computes an estimated condition number for the current basis matrix using the power method; returns true on success
4476 	template <class R>
4477 	bool SoPlexBase<R>::getEstimatedCondition(R& condition)
4478 	{
4479 	   _ensureRealLPLoaded();
4480 	
4481 	   if(!_isRealLPLoaded)
4482 	      return false;
4483 	
4484 	   if(_solver.basis().status() == SPxBasisBase<R>::NO_PROBLEM)
4485 	      return false;
4486 	
4487 	   condition = _solver.basis().getEstimatedCondition();
4488 	
4489 	   return true;
4490 	}
4491 	
4492 	/// computes the exact condition number for the current basis matrix using the power method; returns true on success
4493 	template <class R>
4494 	bool SoPlexBase<R>::getExactCondition(R& condition)
4495 	{
4496 	   _ensureRealLPLoaded();
4497 	
4498 	   if(!_isRealLPLoaded)
4499 	      return false;
4500 	
4501 	   if(_solver.basis().status() == SPxBasisBase<R>::NO_PROBLEM)
4502 	      return false;
4503 	
4504 	   condition = _solver.basis().getExactCondition();
4505 	
4506 	   return true;
4507 	}
4508 	
4509 	/// computes row r of basis inverse; returns true on success
4510 	template <class R>
4511 	bool SoPlexBase<R>::getBasisInverseRowReal(int r, R* coef, int* inds, int* ninds, bool unscale)
4512 	{
4513 	   assert(r >= 0);
4514 	   assert(r < numRows());
4515 	   assert(coef != 0);
4516 	
4517 	   if(!hasBasis() || r < 0 || r >= numRows())
4518 	      return false;
4519 	
4520 	   _ensureRealLPLoaded();
4521 	
4522 	   if(!_isRealLPLoaded)
4523 	      return false;
4524 	
4525 	   // we need to distinguish between column and row representation; ask the solver itself which representation it
4526 	   // has, since the REPRESENTATION parameter of this class might be set to automatic
4527 	   if(_solver.rep() == SPxSolverBase<R>::COLUMN)
4528 	   {
4529 	      int idx;
4530 	      SSVectorBase<R> x(numRows());
4531 	
4532 	      try
4533 	      {
4534 	         /* unscaling required? */
4535 	         if(unscale && _solver.isScaled())
4536 	         {
4537 	            /* for information on the unscaling procedure see spxscaler.h */
4538 	
4539 	            int scaleExp;
4540 	            DSVectorBase<R> rhs(_solver.unitVector(r));
4541 	
4542 	            // apply scaling \tilde{C} to rhs
4543 	            if(_solver.basis().baseId(r).isSPxColId())
4544 	               scaleExp = _scaler->getColScaleExp(_solver.number(_solver.basis().baseId(r)));
4545 	            else
4546 	               scaleExp = - _scaler->getRowScaleExp(_solver.number(_solver.basis().baseId(r)));
4547 	
4548 	            rhs *= spxLdexp(1.0, scaleExp);
4549 	
4550 	            _solver.basis().coSolve(x, rhs);
4551 	            x.setup();
4552 	            int size = x.size();
4553 	
4554 	            //apply scaling R to solution vector
4555 	            for(int i = 0; i < size; i++)
4556 	            {
4557 	               scaleExp = _scaler->getRowScaleExp(x.index(i));
4558 	               x.scaleValue(x.index(i), scaleExp);
4559 	            }
4560 	         }
4561 	         else
4562 	         {
4563 	            _solver.basis().coSolve(x, _solver.unitVector(r));
4564 	         }
4565 	      }
4566 	      catch(const SPxException& E)
4567 	      {
4568 	         MSG_INFO1(spxout, spxout << "Caught exception <" << E.what() <<
4569 	                   "> while computing basis inverse row.\n");
4570 	         return false;
4571 	      }
4572 	
4573 	      // copy sparse data to dense result vector based on coef array
4574 	      if(ninds != 0 && inds != 0)
4575 	      {
4576 	         // during solving SoPlexBase may have destroyed the sparsity structure so we need to restore it
4577 	         x.setup();
4578 	         *ninds = x.size();
4579 	
4580 	         for(int i = 0; i < *ninds; ++i)
4581 	         {
4582 	            idx = x.index(i);
4583 	            coef[idx] = x[idx];
4584 	            // set sparsity pattern of coef array
4585 	            inds[i] = idx;
4586 	         }
4587 	      }
4588 	      else
4589 	      {
4590 	         std::copy(x.vec().begin(), x.vec().end(), coef);
4591 	
4592 	         if(ninds != NULL)
4593 	            *ninds = -1;
4594 	      }
4595 	   }
4596 	   else
4597 	   {
4598 	      assert(_solver.rep() == SPxSolverBase<R>::ROW);
4599 	
4600 	      // @todo should rhs be a reference?
4601 	      DSVectorBase<R> rhs(numCols());
4602 	      SSVectorBase<R>  y(numCols());
4603 	      int* bind = 0;
4604 	      int index;
4605 	
4606 	      // get ordering of column basis matrix
4607 	      spx_alloc(bind, numRows());
4608 	      getBasisInd(bind);
4609 	
4610 	      // get vector corresponding to requested index r
4611 	      index = bind[r];
4612 	
4613 	      // r corresponds to a basic row
4614 	      if(index < 0)
4615 	      {
4616 	         // transform index to actual row index
4617 	         index = -index - 1;
4618 	
4619 	         // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
4620 	         assert(index >= 0);
4621 	         assert(index < numRows());
4622 	         assert(!_solver.isRowBasic(index));
4623 	
4624 	         // get row vector
4625 	         rhs = _solver.rowVector(index);
4626 	         rhs *= -1.0;
4627 	
4628 	         if(unscale && _solver.isScaled())
4629 	         {
4630 	            for(int i = 0; i < rhs.size(); ++i)
4631 	               rhs.value(i) = spxLdexp(rhs.value(i), -_scaler->getRowScaleExp(index));
4632 	         }
4633 	      }
4634 	      // r corresponds to a basic column
4635 	      else
4636 	      {
4637 	         // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
4638 	         assert(index < numCols());
4639 	         assert(!_solver.isColBasic(index));
4640 	
4641 	         // get unit vector
4642 	         rhs = UnitVectorBase<R>(index);
4643 	
4644 	         if(unscale && _solver.isScaled())
4645 	            rhs *= spxLdexp(1.0, _scaler->getColScaleExp(index));
4646 	      }
4647 	
4648 	      // solve system "y B = rhs", where B is the row basis matrix
4649 	      try
4650 	      {
4651 	         _solver.basis().solve(y, rhs);
4652 	      }
4653 	      catch(const SPxException& E)
4654 	      {
4655 	         MSG_INFO1(spxout, spxout << "Caught exception <" << E.what() <<
4656 	                   "> while computing basis inverse row.\n");
4657 	         return false;
4658 	      }
4659 	
4660 	      // initialize result vector x as zero
4661 	      memset(coef, 0, (unsigned int)numRows() * sizeof(R));
4662 	
4663 	      // add nonzero entries
4664 	      for(int i = 0; i < numCols(); ++i)
4665 	      {
4666 	         SPxId id = _solver.basis().baseId(i);
4667 	
4668 	         if(id.isSPxRowId())
4669 	         {
4670 	            assert(_solver.number(id) >= 0);
4671 	            assert(_solver.number(id) < numRows());
4672 	            assert(bind[r] >= 0 || _solver.number(id) != index);
4673 	
4674 	            int rowindex = _solver.number(id);
4675 	            coef[rowindex] = y[i];
4676 	
4677 	            if(unscale && _solver.isScaled())
4678 	               coef[rowindex] = spxLdexp(y[i], _scaler->getRowScaleExp(rowindex));
4679 	         }
4680 	      }
4681 	
4682 	      // if r corresponds to a row vector, we have to add a 1 at position r
4683 	      if(bind[r] < 0)
4684 	      {
4685 	         assert(coef[index] == 0.0);
4686 	         coef[index] = 1.0;
4687 	      }
4688 	
4689 	      // @todo implement returning of sparsity information like in column wise case
4690 	      if(ninds != NULL)
4691 	         *ninds = -1;
4692 	
4693 	      // free memory
4694 	      spx_free(bind);
4695 	   }
4696 	
4697 	   return true;
4698 	}
4699 	
4700 	
4701 	
4702 	/// computes column c of basis inverse; returns true on success
4703 	/// @todo does not work correctly for the row representation
4704 	template <class R>
4705 	bool SoPlexBase<R>::getBasisInverseColReal(int c, R* coef, int* inds, int* ninds, bool unscale)
4706 	{
4707 	   assert(c >= 0);
4708 	   assert(c < numRows());
4709 	   assert(coef != 0);
4710 	
4711 	   if(!hasBasis() || c < 0 || c >= numRows())
4712 	      return false;
4713 	
4714 	   _ensureRealLPLoaded();
4715 	
4716 	   if(!_isRealLPLoaded)
4717 	      return false;
4718 	
4719 	   // we need to distinguish between column and row representation; ask the solver itself which representation it
4720 	   // has, since the REPRESENTATION parameter of this class might be set to automatic
4721 	   if(_solver.rep() == SPxSolverBase<R>::COLUMN)
4722 	   {
4723 	      int idx;
4724 	      SSVectorBase<R> x(numRows());
4725 	
4726 	      try
4727 	      {
4728 	         /* unscaling required? */
4729 	         if(unscale && _solver.isScaled())
4730 	         {
4731 	            /* for information on the unscaling procedure see spxscaler.h */
4732 	
4733 	            int scaleExp = _scaler->getRowScaleExp(c);
4734 	            DSVectorBase<R> rhs(_solver.unitVector(c));
4735 	            rhs *= spxLdexp(1.0, scaleExp);
4736 	
4737 	            _solver.basis().solve(x, rhs);
4738 	
4739 	            x.setup();
4740 	            int size = x.size();
4741 	
4742 	            for(int i = 0; i < size; i++)
4743 	            {
4744 	               if(_solver.basis().baseId(x.index(i)).isSPxColId())
4745 	               {
4746 	                  idx = _solver.number(_solver.basis().baseId(x.index(i)));
4747 	                  scaleExp = _scaler->getColScaleExp(idx);
4748 	                  x.scaleValue(x.index(i), scaleExp);
4749 	               }
4750 	               else
4751 	               {
4752 	                  idx = _solver.number(_solver.basis().baseId(x.index(i)));
4753 	                  scaleExp = - _scaler->getRowScaleExp(idx);
4754 	                  x.scaleValue(x.index(i), scaleExp);
4755 	               }
4756 	            }
4757 	         }
4758 	         else
4759 	         {
4760 	            _solver.basis().solve(x, _solver.unitVector(c));
4761 	         }
4762 	      }
4763 	      catch(const SPxException& E)
4764 	      {
4765 	         MSG_INFO1(spxout, spxout << "Caught exception <" << E.what() <<
4766 	                   "> while computing basis inverse row.\n");
4767 	         return false;
4768 	      }
4769 	
4770 	      // copy sparse data to dense result vector based on coef array
4771 	      if(ninds != 0 && inds != 0)
4772 	      {
4773 	         // SoPlexBase may have destroyed the sparsity structure so we need to restore it
4774 	         x.setup();
4775 	         *ninds = x.size();
4776 	
4777 	         for(int i = 0; i < *ninds; ++i)
4778 	         {
4779 	            idx = x.index(i);
4780 	            coef[idx] = x[idx];
4781 	            // set sparsity pattern of coef array
4782 	            inds[i] = idx;
4783 	         }
4784 	      }
4785 	      else
4786 	      {
4787 	         std::copy(x.vec().begin(), x.vec().end(), coef);
4788 	
4789 	         if(ninds != 0)
4790 	            *ninds = -1;
4791 	      }
4792 	   }
4793 	   else
4794 	   {
4795 	      assert(_solver.rep() == SPxSolverBase<R>::ROW);
4796 	
4797 	      // @todo should rhs be a reference?
4798 	      int* bind = 0;
4799 	      int index;
4800 	
4801 	      // get indices of column basis matrix (not in correct order!)
4802 	      spx_alloc(bind, numRows());
4803 	      getBasisInd(bind);
4804 	
4805 	      index = bind[c];
4806 	      // index = c >= numColsReal() ? 0 : c;
4807 	
4808 	      // initialize result vector x as zero
4809 	      memset(coef, 0, (unsigned int)numRows() * sizeof(Real));
4810 	
4811 	      if(!_solver.isRowBasic(c))
4812 	      {
4813 	         // this column of B^-1 is just a unit column
4814 	         for(int i = 0; i < numRows(); i++)
4815 	         {
4816 	            if(bind[i] < 0 && -bind[i] - 1 == c)
4817 	               coef[i] = 1.0;
4818 	         }
4819 	      }
4820 	      else
4821 	      {
4822 	         SSVectorBase<R> x(numCols());
4823 	
4824 	         for(int k = 0; k < numCols(); k++)
4825 	         {
4826 	            if(c == _solver.number(_solver.basis().baseId(k)) && _solver.basis().baseId(k).isSPxRowId())
4827 	            {
4828 	               index = k;
4829 	               break;
4830 	            }
4831 	         }
4832 	
4833 	         try
4834 	         {
4835 	            if(unscale && _solver.isScaled())
4836 	            {
4837 	               int scaleExp = -_scaler->getRowScaleExp(index);
4838 	               DSVectorBase<R> rhs(1);
4839 	               rhs.add(index, spxLdexp(1.0, scaleExp));
4840 	               _solver.basis().coSolve(x, rhs);
4841 	               x.setup();
4842 	               int size = x.size();
4843 	
4844 	               // apply scaling based on \tilde{C}
4845 	               for(int i = 0; i < size; i++)
4846 	               {
4847 	                  int idx = bind[x.index(i)];
4848 	
4849 	                  if(idx < 0)
4850 	                  {
4851 	                     idx = -idx - 1;
4852 	                     scaleExp = _scaler->getRowScaleExp(idx);
4853 	                  }
4854 	                  else
4855 	                     scaleExp = - _scaler->getColScaleExp(idx);
4856 	
4857 	                  spxLdexp(x.value(i), scaleExp);
4858 	               }
4859 	            }
4860 	            else
4861 	            {
4862 	               _solver.basis().coSolve(x, _solver.unitVector(index));
4863 	            }
4864 	         }
4865 	         catch(const SPxException& E)
4866 	         {
4867 	            MSG_INFO1(spxout, spxout << "Caught exception <" << E.what() <<
4868 	                      "> while computing basis inverse column.\n");
4869 	            return false;
4870 	         }
4871 	
4872 	         // add nonzero entries into result vector
4873 	         for(int i = 0; i < numRows(); i++)
4874 	         {
4875 	            int idx = bind[i];
4876 	
4877 	            if(idx < 0)
4878 	            {
4879 	               // convert to proper row index
4880 	               idx = - idx - 1;
4881 	               // should be a valid row index, basic in the column basis
4882 	               assert(idx >= 0);
4883 	               assert(idx < numRows());
4884 	               assert(!_solver.isRowBasic(idx));
4885 	
4886 	               if(unscale && _solver.isScaled())
4887 	               {
4888 	                  DSVectorBase<R> r_unscaled(numCols());
4889 	                  _solver.getRowVectorUnscaled(idx, r_unscaled);
4890 	                  coef[i] = - (r_unscaled * x);
4891 	               }
4892 	               else
4893 	                  coef[i] = - (_solver.rowVector(idx) * x);
4894 	
4895 	               if(unscale && _solver.isScaled())
4896 	                  coef[i] = spxLdexp(coef[i], _scaler->getRowScaleExp(idx));
4897 	            }
4898 	            else
4899 	            {
4900 	               // should be a valid column index, basic in the column basis
4901 	               assert(idx >= 0);
4902 	               assert(idx < numCols());
4903 	               assert(!_solver.isColBasic(idx));
4904 	
4905 	               if(unscale && _solver.isScaled())
4906 	                  coef[i] = spxLdexp(x[idx], _scaler->getColScaleExp(idx));
4907 	               else
4908 	                  coef[i] = x[idx];
4909 	            }
4910 	         }
4911 	      }
4912 	
4913 	      // @todo implement returning of sparsity information like in column wise case
4914 	      if(ninds != NULL)
4915 	         *ninds = -1;
4916 	
4917 	      // free memory
4918 	      spx_free(bind);
4919 	   }
4920 	
4921 	   return true;
4922 	}
4923 	
4924 	
4925 	
4926 	/// computes dense solution of basis matrix B * sol = rhs; returns true on success
4927 	template <class R>
4928 	bool SoPlexBase<R>::getBasisInverseTimesVecReal(R* rhs, R* sol, bool unscale)
4929 	{
4930 	   VectorBase<R> v(numRows(), rhs);
4931 	   VectorBase<R> x(numRows(), sol);
4932 	
4933 	   if(!hasBasis())
4934 	      return false;
4935 	
4936 	   _ensureRealLPLoaded();
4937 	
4938 	   if(!_isRealLPLoaded)
4939 	      return false;
4940 	
4941 	   // we need to distinguish between column and row representation; ask the solver itself which representation it
4942 	   // has, since the REPRESENTATION parameter of this class might be set to automatic; in the column case we can use
4943 	   // the existing factorization
4944 	   if(_solver.rep() == SPxSolverBase<R>::COLUMN)
4945 	   {
4946 	      // solve system "x = B^-1 * v"
4947 	      try
4948 	      {
4949 	         /* unscaling required? */
4950 	         if(unscale && _solver.isScaled())
4951 	         {
4952 	            /* for information on the unscaling procedure see spxscaler.h */
4953 	            int scaleExp;
4954 	            int idx;
4955 	
4956 	            for(int i = 0; i < v.dim(); ++i)
4957 	            {
4958 	               if(isNotZero(v[i]))
4959 	               {
4960 	                  scaleExp = _scaler->getRowScaleExp(i);
4961 	                  v[i] = spxLdexp(v[i], scaleExp);
4962 	               }
4963 	            }
4964 	
4965 	            _solver.basis().solve(x, v);
4966 	
4967 	            for(int i = 0; i < x.dim(); i++)
4968 	            {
4969 	               if(isNotZero(x[i]))
4970 	               {
4971 	                  idx = _solver.number(_solver.basis().baseId(i));
4972 	
4973 	                  if(_solver.basis().baseId(i).isSPxColId())
4974 	                     scaleExp = _scaler->getColScaleExp(idx);
4975 	                  else
4976 	                     scaleExp = - _scaler->getRowScaleExp(idx);
4977 	
4978 	                  x[i] = spxLdexp(x[i], scaleExp);
4979 	               }
4980 	            }
4981 	         }
4982 	         else
4983 	         {
4984 	            _solver.basis().solve(x, v);
4985 	         }
4986 	      }
4987 	      catch(const SPxException& E)
4988 	      {
4989 	         MSG_INFO1(spxout, spxout << "Caught exception <" << E.what() <<
4990 	                   "> while solving with basis matrix.\n");
4991 	         return false;
4992 	      }
4993 	   }
4994 	   else
4995 	   {
4996 	      assert(_solver.rep() == SPxSolverBase<R>::ROW);
4997 	
4998 	      DSVectorBase<R> rowrhs(numCols());
4999 	      SSVectorBase<R> y(numCols());
5000 	      int* bind = 0;
5001 	
5002 	      bool adaptScaling = unscale && _realLP->isScaled();
5003 	      int scaleExp;
5004 	      int idx;
5005 	
5006 	      // get ordering of column basis matrix
5007 	      spx_alloc(bind, numRows());
5008 	      getBasisInd(bind);
5009 	
5010 	      // fill right-hand side for row-based system
5011 	      for(int i = 0; i < numCols(); ++i)
5012 	      {
5013 	         SPxId id = _solver.basis().baseId(i);
5014 	
5015 	         if(id.isSPxRowId())
5016 	         {
5017 	            assert(_solver.number(id) >= 0);
5018 	            assert(_solver.number(id) < numRows());
5019 	
5020 	            if(adaptScaling)
5021 	            {
5022 	               idx = _solver.number(id);
5023 	               scaleExp = _scaler->getRowScaleExp(idx);
5024 	               rowrhs.add(i, spxLdexp(v[idx], scaleExp));
5025 	            }
5026 	            else
5027 	               rowrhs.add(i, v[_solver.number(id)]);
5028 	         }
5029 	         else
5030 	         {
5031 	            assert(rowrhs[i] == 0.0);
5032 	         }
5033 	      }
5034 	
5035 	      // solve system "B y = rowrhs", where B is the row basis matrix
5036 	      try
5037 	      {
5038 	         _solver.basis().coSolve(y, rowrhs);
5039 	      }
5040 	      catch(const SPxException& E)
5041 	      {
5042 	         MSG_INFO1(spxout, spxout << "Caught exception <" << E.what() <<
5043 	                   "> while solving with basis matrix.\n");
5044 	         return false;
5045 	      }
5046 	
5047 	      // fill result w.r.t. order given by bind
5048 	      for(int i = 0; i < numRows(); ++i)
5049 	      {
5050 	         int index;
5051 	
5052 	         index = bind[i];
5053 	
5054 	         if(index < 0)
5055 	         {
5056 	            index = -index - 1;
5057 	
5058 	            // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
5059 	            assert(index >= 0);
5060 	            assert(index < numRows());
5061 	            assert(!_solver.isRowBasic(index));
5062 	
5063 	            x[i] = v[index] - (rowVectorRealInternal(index) * VectorBase<R>(numCols(), y.get_ptr()));
5064 	
5065 	            if(adaptScaling)
5066 	            {
5067 	               scaleExp = -_scaler->getRowScaleExp(index);
5068 	               x[i] = spxLdexp(x[i], scaleExp);
5069 	            }
5070 	         }
5071 	         else
5072 	         {
5073 	            // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
5074 	            assert(index >= 0);
5075 	            assert(index < numCols());
5076 	            assert(!_solver.isColBasic(index));
5077 	
5078 	            if(adaptScaling)
5079 	            {
5080 	               scaleExp = _scaler->getColScaleExp(index);
5081 	               x[i] = spxLdexp(y[index], scaleExp);
5082 	            }
5083 	            else
5084 	               x[i] = y[index];
5085 	         }
5086 	      }
5087 	
5088 	      // free memory
5089 	      spx_free(bind);
5090 	   }
5091 	
5092 	   std::copy(v.vec().begin(), v.vec().end(), rhs);
5093 	   std::copy(x.vec().begin(), x.vec().end(), sol);
5094 	
5095 	   return true;
5096 	}
5097 	
5098 	
5099 	
5100 	/// multiply with basis matrix; B * vec (inplace)
5101 	template <class R>
5102 	bool SoPlexBase<R>::multBasis(R* vec, bool unscale)
5103 	{
5104 	   if(!hasBasis())
5105 	      return false;
5106 	
5107 	   _ensureRealLPLoaded();
5108 	
5109 	   if(!_isRealLPLoaded)
5110 	      return false;
5111 	
5112 	   if(_solver.rep() == SPxSolverBase<R>::COLUMN)
5113 	   {
5114 	      int basisdim = numRows();
5115 	
5116 	      if(unscale && _solver.isScaled())
5117 	      {
5118 	         /* for information on the unscaling procedure see spxscaler.h */
5119 	
5120 	         int scaleExp;
5121 	
5122 	         for(int i = 0; i < basisdim; ++i)
5123 	         {
5124 	            if(isNotZero(vec[i]))
5125 	            {
5126 	               if(_solver.basis().baseId(i).isSPxColId())
5127 	                  scaleExp = - _scaler->getColScaleExp(_solver.number(_solver.basis().baseId(i)));
5128 	               else
5129 	                  scaleExp = _scaler->getRowScaleExp(_solver.number(_solver.basis().baseId(i)));
5130 	
5131 	               vec[i] = spxLdexp(vec[i], scaleExp);
5132 	            }
5133 	         }
5134 	
5135 	         // create VectorBase<R> from input values
5136 	         VectorBase<R> x(basisdim, vec);
5137 	
5138 	         _solver.basis().multBaseWith(x);
5139 	         std::copy(x.vec().begin(), x.vec().end(), vec);
5140 	
5141 	         for(int i = 0; i < basisdim; ++i)
5142 	         {
5143 	            scaleExp = _scaler->getRowScaleExp(i);
5144 	            vec[i] = spxLdexp(vec[i], -scaleExp);
5145 	         }
5146 	      }
5147 	      else
5148 	      {
5149 	         // create VectorBase<R> from input values
5150 	         VectorBase<R> x(basisdim, vec);
5151 	         _solver.basis().multBaseWith(x);
5152 	         std::copy(x.vec().begin(), x.vec().end(), vec);
5153 	      }
5154 	   }
5155 	   else
5156 	   {
5157 	      int colbasisdim = numRows();
5158 	
5159 	      DSVectorBase<R> y(colbasisdim);
5160 	
5161 	      y.clear();
5162 	
5163 	      // create VectorBase<R> from input values
5164 	      VectorBase<R> x(colbasisdim, vec);
5165 	
5166 	      int* bind = 0;
5167 	      int index;
5168 	
5169 	      // get ordering of column basis matrix
5170 	      spx_alloc(bind, colbasisdim);
5171 	      getBasisInd(bind);
5172 	
5173 	      // temporarily create the column basis and multiply every column with x
5174 	      for(int i = 0; i < colbasisdim; ++i)
5175 	      {
5176 	         if(isNotZero(x[i]))
5177 	         {
5178 	            // get vector corresponding to requested index i
5179 	            index = bind[i];
5180 	
5181 	            // r corresponds to a row vector
5182 	            if(index < 0)
5183 	            {
5184 	               // transform index to actual row index
5185 	               index = -index - 1;
5186 	
5187 	               // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
5188 	               assert(index >= 0);
5189 	               assert(index < numRows());
5190 	               assert(!_solver.isRowBasic(index));
5191 	
5192 	               y.add(x[i] * UnitVectorBase<R>(index));
5193 	            }
5194 	            // r corresponds to a column vector
5195 	            else
5196 	            {
5197 	               // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
5198 	               assert(index < numCols());
5199 	               assert(!_solver.isColBasic(index));
5200 	
5201 	               if(unscale && _solver.isScaled())
5202 	               {
5203 	                  DSVectorBase<R> col;
5204 	                  _solver.getColVectorUnscaled(index, col);
5205 	                  y.add(x[i] * col);
5206 	               }
5207 	
5208 	               y.add(x[i] * _solver.colVector(index));
5209 	            }
5210 	         }
5211 	      }
5212 	
5213 	      spx_free(bind);
5214 	      x = y;
5215 	      std::copy(x.vec().begin(), x.vec().end(), vec);
5216 	   }
5217 	
5218 	   return true;
5219 	}
5220 	
5221 	
5222 	
5223 	/// multiply with transpose of basis matrix; vec * B^T (inplace)
5224 	template <class R>
5225 	bool SoPlexBase<R>::multBasisTranspose(R* vec, bool unscale)
5226 	{
5227 	   if(!hasBasis())
5228 	      return false;
5229 	
5230 	   _ensureRealLPLoaded();
5231 	
5232 	   if(!_isRealLPLoaded)
5233 	      return false;
5234 	
5235 	   if(_solver.rep() == SPxSolverBase<R>::COLUMN)
5236 	   {
5237 	      int basisdim = numRows();
5238 	
5239 	      if(unscale && _solver.isScaled())
5240 	      {
5241 	         /* for information on the unscaling procedure see spxscaler.h */
5242 	
5243 	         int scaleExp;
5244 	
5245 	         for(int i = 0; i < basisdim; ++i)
5246 	         {
5247 	            if(isNotZero(vec[i]))
5248 	            {
5249 	               scaleExp = - _scaler->getRowScaleExp(i);
5250 	               vec[i] = spxLdexp(vec[i], scaleExp);
5251 	            }
5252 	         }
5253 	
5254 	         // create VectorBase<R> from input values
5255 	         VectorBase<R> x(basisdim, vec);
5256 	         _solver.basis().multWithBase(x);
5257 	         std::copy(x.vec().begin(), x.vec().end(), vec);
5258 	
5259 	         for(int i = 0; i < basisdim; ++i)
5260 	         {
5261 	            if(isNotZero(vec[i]))
5262 	            {
5263 	               if(_solver.basis().baseId(i).isSPxColId())
5264 	                  scaleExp = - _scaler->getColScaleExp(_solver.number(_solver.basis().baseId(i)));
5265 	               else
5266 	                  scaleExp = _scaler->getRowScaleExp(_solver.number(_solver.basis().baseId(i)));
5267 	
5268 	               vec[i] = spxLdexp(vec[i], scaleExp);
5269 	            }
5270 	         }
5271 	      }
5272 	      else
5273 	      {
5274 	         // create VectorBase<R> from input values
5275 	         VectorBase<R> x(basisdim, vec);
5276 	         _solver.basis().multWithBase(x);
5277 	         std::copy(x.vec().begin(), x.vec().end(), vec);
5278 	      }
5279 	   }
5280 	   else
5281 	   {
5282 	      int colbasisdim = numRows();
5283 	
5284 	      DSVectorBase<R> y(colbasisdim);
5285 	
5286 	      // create VectorBase<R> from input values
5287 	      VectorBase<R> x(colbasisdim, vec);
5288 	
5289 	      int* bind = 0;
5290 	      int index;
5291 	
5292 	      // get ordering of column basis matrix
5293 	      spx_alloc(bind, colbasisdim);
5294 	      getBasisInd(bind);
5295 	
5296 	      // temporarily create the column basis and multiply every column with x
5297 	      for(int i = 0; i < colbasisdim; ++i)
5298 	      {
5299 	         // get vector corresponding to requested index i
5300 	         index = bind[i];
5301 	
5302 	         // r corresponds to a row vector
5303 	         if(index < 0)
5304 	         {
5305 	            // transform index to actual row index
5306 	            index = -index - 1;
5307 	
5308 	            // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
5309 	            assert(index >= 0);
5310 	            assert(index < numRows());
5311 	            assert(!_solver.isRowBasic(index));
5312 	
5313 	            y.add(i, x * UnitVectorBase<R>(index));
5314 	         }
5315 	         // r corresponds to a column vector
5316 	         else
5317 	         {
5318 	            // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
5319 	            assert(index < numCols());
5320 	            assert(!_solver.isColBasic(index));
5321 	
5322 	            if(unscale && _solver.isScaled())
5323 	            {
5324 	               DSVectorBase<R> col;
5325 	               _solver.getColVectorUnscaled(index, col);
5326 	               y.add(i, x * col);
5327 	            }
5328 	            else
5329 	               y.add(i, x * _solver.colVector(index));
5330 	         }
5331 	      }
5332 	
5333 	      spx_free(bind);
5334 	      x = y;
5335 	      std::copy(x.vec().begin(), x.vec().end(), vec);
5336 	   }
5337 	
5338 	   return true;
5339 	}
5340 	
5341 	
5342 	
5343 	/// compute rational basis inverse; returns true on success
5344 	template <class R>
5345 	bool SoPlexBase<R>::computeBasisInverseRational()
5346 	{
5347 	   if(!hasBasis())
5348 	   {
5349 	      _rationalLUSolver.clear();
5350 	      assert(_rationalLUSolver.status() == SLinSolverRational::UNLOADED);
5351 	      return false;
5352 	   }
5353 	
5354 	   if(_rationalLUSolver.status() == SLinSolverRational::UNLOADED
5355 	         || _rationalLUSolver.status() == SLinSolverRational::TIME)
5356 	   {
5357 	      _rationalLUSolverBind.reSize(numRowsRational());
5358 	      getBasisInd(_rationalLUSolverBind.get_ptr());
5359 	      _computeBasisInverseRational();
5360 	   }
5361 	
5362 	   if(_rationalLUSolver.status() == SLinSolverRational::OK)
5363 	      return true;
5364 	
5365 	   return false;
5366 	}
5367 	
5368 	
5369 	
5370 	/// gets an array of indices for the columns of the rational basis matrix; bind[i] >= 0 means that the i-th column of
5371 	/// the basis matrix contains variable bind[i]; bind[i] < 0 means that the i-th column of the basis matrix contains
5372 	/// the slack variable for row -bind[i]-1; performs rational factorization if not available; returns true on success
5373 	template <class R>
5374 	bool SoPlexBase<R>::getBasisIndRational(DataArray<int>& bind)
5375 	{
5376 	   if(_rationalLUSolver.status() != SLinSolverRational::OK)
5377 	      computeBasisInverseRational();
5378 	
5379 	   if(_rationalLUSolver.status() != SLinSolverRational::OK)
5380 	      return false;
5381 	
5382 	   bind = _rationalLUSolverBind;
5383 	   assert(bind.size() == numRowsRational());
5384 	   return true;
5385 	}
5386 	
5387 	
5388 	
5389 	/// computes row r of basis inverse; performs rational factorization if not available; returns true on success
5390 	template <class R>
5391 	bool SoPlexBase<R>::getBasisInverseRowRational(const int r, SSVectorRational& vec)
5392 	{
5393 	   if(_rationalLUSolver.status() != SLinSolverRational::OK)
5394 	      computeBasisInverseRational();
5395 	
5396 	   if(_rationalLUSolver.status() != SLinSolverRational::OK)
5397 	      return false;
5398 	
5399 	   try
5400 	   {
5401 	      vec.reDim(numRowsRational());
5402 	      _rationalLUSolver.solveLeft(vec, *_unitVectorRational(r));
5403 	   }
5404 	   catch(const SPxException& E)
5405 	   {
5406 	      MSG_INFO1(spxout, spxout << "Caught exception <" << E.what() <<
5407 	                "> while computing rational basis inverse row.\n");
5408 	      return false;
5409 	   }
5410 	
5411 	   return true;
5412 	}
5413 	
5414 	/// computes column c of basis inverse; performs rational factorization if not available; returns true on success
5415 	template <class R>
5416 	bool SoPlexBase<R>::getBasisInverseColRational(const int c, SSVectorRational& vec)
5417 	{
5418 	   if(_rationalLUSolver.status() != SLinSolverRational::OK)
5419 	      computeBasisInverseRational();
5420 	
5421 	   if(_rationalLUSolver.status() != SLinSolverRational::OK)
5422 	      return false;
5423 	
5424 	   try
5425 	   {
5426 	      vec.reDim(numRowsRational());
5427 	      _rationalLUSolver.solveRight(vec, *_unitVectorRational(c));
5428 	   }
5429 	   catch(const SPxException& E)
5430 	   {
5431 	      MSG_INFO1(spxout, spxout << "Caught exception <" << E.what() <<
5432 	                "> while computing rational basis inverse column.\n");
5433 	      return false;
5434 	   }
5435 	
5436 	   return true;
5437 	}
5438 	
5439 	
5440 	
5441 	/// computes solution of basis matrix B * sol = rhs; performs rational factorization if not available; returns true
5442 	/// on success
5443 	template <class R>
5444 	bool SoPlexBase<R>::getBasisInverseTimesVecRational(const SVectorRational& rhs,
5445 	      SSVectorRational& sol)
5446 	{
5447 	   if(_rationalLUSolver.status() != SLinSolverRational::OK)
5448 	      computeBasisInverseRational();
5449 	
5450 	   if(_rationalLUSolver.status() != SLinSolverRational::OK)
5451 	      return false;
5452 	
5453 	   try
5454 	   {
5455 	      sol.reDim(numRowsRational());
5456 	      _rationalLUSolver.solveRight(sol, rhs);
5457 	   }
5458 	   catch(const SPxException& E)
5459 	   {
5460 	      MSG_INFO1(spxout, spxout << "Caught exception <" << E.what() <<
5461 	                "> during right solve with rational basis inverse.\n");
5462 	      return false;
5463 	   }
5464 	
5465 	   return true;
5466 	}
5467 	
5468 	
5469 	
5470 	/// sets starting basis via arrays of statuses
5471 	template <class R>
5472 	void SoPlexBase<R>::setBasis(const typename SPxSolverBase<R>::VarStatus rows[],
5473 	                             const typename SPxSolverBase<R>::VarStatus cols[])
5474 	{
5475 	   _rationalLUSolver.clear();
5476 	
5477 	   if(_isRealLPLoaded)
5478 	   {
5479 	      assert(numRows() == _solver.nRows());
5480 	      assert(numCols() == _solver.nCols());
5481 	
5482 	      _solver.setBasis(rows, cols);
5483 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
5484 	   }
5485 	   else
5486 	   {
5487 	      _basisStatusRows.reSize(numRows());
5488 	      _basisStatusCols.reSize(numCols());
5489 	
5490 	      for(int i = numRows() - 1; i >= 0; i--)
5491 	         _basisStatusRows[i] = rows[i];
5492 	
5493 	      for(int j = numCols() - 1; j >= 0; j--)
5494 	         _basisStatusCols[j] = cols[j];
5495 	
5496 	      _hasBasis = true;
5497 	   }
5498 	}
5499 	
5500 	
5501 	
5502 	/// clears starting basis
5503 	template <class R>
5504 	void SoPlexBase<R>::clearBasis()
5505 	{
5506 	   _solver.reLoad();
5507 	   _status = _solver.status();
5508 	   _hasBasis = false;
5509 	   _rationalLUSolver.clear();
5510 	}
5511 	
5512 	
5513 	
5514 	/// number of iterations since last call to solve
5515 	template <class R>
5516 	int SoPlexBase<R>::numIterations() const
5517 	{
5518 	   return _statistics->iterations;
5519 	}
5520 	
5521 	
5522 	
5523 	/// time spent in last call to solve
5524 	template <class R>
5525 	Real SoPlexBase<R>::solveTime() const
5526 	{
5527 	   return _statistics->solvingTime->time();
5528 	}
5529 	
5530 	
5531 	
5532 	/// statistical information in form of a string
5533 	template <class R>
5534 	std::string SoPlexBase<R>::statisticString() const
5535 	{
5536 	   std::stringstream s;
5537 	   s  << "Factorizations     : " << std::setw(10) << _statistics->luFactorizationsReal << std::endl
5538 	      << "  Time spent       : " << std::setw(10) << std::fixed << std::setprecision(
5539 	         2) << _statistics->luFactorizationTimeReal << std::endl
5540 	      << "Solves             : " << std::setw(10) << _statistics->luSolvesReal << std::endl
5541 	      << "  Time spent       : " << std::setw(10) << _statistics->luSolveTimeReal << std::endl
5542 	      << "Solution time      : " << std::setw(10) << std::fixed << std::setprecision(
5543 	         2) << solveTime() << std::endl
5544 	      << "Iterations         : " << std::setw(10) << numIterations() << std::endl;
5545 	
5546 	   return s.str();
5547 	}
5548 	
5549 	
5550 	
5551 	/// name of starter
5552 	template <class R>
5553 	const char* SoPlexBase<R>::getStarterName()
5554 	{
5555 	   if(_starter)
5556 	      return _starter->getName();
5557 	   else
5558 	      return "none";
5559 	}
5560 	
5561 	
5562 	
5563 	/// name of simplifier
5564 	template <class R>
5565 	const char* SoPlexBase<R>::getSimplifierName()
5566 	{
5567 	   if(_simplifier)
5568 	      return _simplifier->getName();
5569 	   else
5570 	      return "none";
5571 	}
5572 	
5573 	
5574 	
5575 	/// name of scaling method after simplifier
5576 	template <class R>
5577 	const char* SoPlexBase<R>::getScalerName()
5578 	{
5579 	   if(_scaler)
5580 	      return _scaler->getName();
5581 	   else
5582 	      return "none";
5583 	}
5584 	
5585 	
5586 	
5587 	/// name of currently loaded pricer
5588 	template <class R>
5589 	const char* SoPlexBase<R>::getPricerName()
5590 	{
5591 	   return _solver.pricer()->getName();
5592 	}
5593 	
5594 	
5595 	
5596 	/// name of currently loaded ratiotester
5597 	template <class R>
5598 	const char* SoPlexBase<R>::getRatiotesterName()
5599 	{
5600 	   return _solver.ratiotester()->getName();
5601 	}
5602 	
5603 	
5604 	/// returns boolean parameter value
5605 	template <class R>
5606 	bool SoPlexBase<R>::boolParam(const BoolParam param) const
5607 	{
5608 	   assert(param >= 0);
5609 	   assert(param < SoPlexBase<R>::BOOLPARAM_COUNT);
5610 	   return _currentSettings->_boolParamValues[param];
5611 	}
5612 	
5613 	/// returns integer parameter value
5614 	template <class R>
5615 	int SoPlexBase<R>::intParam(const IntParam param) const
5616 	{
5617 	   assert(param >= 0);
5618 	   assert(param < INTPARAM_COUNT);
5619 	   return _currentSettings->_intParamValues[param];
5620 	}
5621 	
5622 	/// returns real parameter value
5623 	template <class R>
5624 	Real SoPlexBase<R>::realParam(const RealParam param) const
5625 	{
5626 	   assert(param >= 0);
5627 	   assert(param < REALPARAM_COUNT);
5628 	   return _currentSettings->_realParamValues[param];
5629 	}
5630 	
5631 	#ifdef SOPLEX_WITH_RATIONALPARAM
5632 	/// returns rational parameter value
5633 	Rational SoPlexBase<R>::rationalParam(const RationalParam param) const
5634 	{
5635 	   assert(param >= 0);
5636 	   assert(param < RATIONALPARAM_COUNT);
5637 	   return _currentSettings->_rationalParamValues[param];
5638 	}
5639 	#endif
5640 	
5641 	
5642 	
5643 	/// returns current parameter settings
5644 	template <class R>
5645 	const typename SoPlexBase<R>::Settings& SoPlexBase<R>::settings() const
5646 	{
5647 	   return *_currentSettings;
5648 	}
5649 	
5650 	
5651 	
5652 	/// sets boolean parameter value; returns true on success
5653 	template <class R>
5654 	bool SoPlexBase<R>::setBoolParam(const BoolParam param, const bool value, const bool init)
5655 	{
5656 	   assert(param >= 0);
5657 	   assert(param < SoPlexBase<R>::BOOLPARAM_COUNT);
5658 	   assert(init || _isConsistent());
5659 	
5660 	   if(!init && value == boolParam(param))
5661 	      return true;
5662 	
5663 	   switch(param)
5664 	   {
5665 	   case LIFTING:
5666 	      break;
5667 	
5668 	   case EQTRANS:
5669 	      break;
5670 	
5671 	   case TESTDUALINF:
5672 	      break;
5673 	
5674 	   case RATFAC:
5675 	      break;
5676 	
5677 	   case USEDECOMPDUALSIMPLEX:
5678 	      break;
5679 	
5680 	   case COMPUTEDEGEN:
5681 	      break;
5682 	
5683 	   case USECOMPDUAL:
5684 	      break;
5685 	
5686 	   case EXPLICITVIOL:
5687 	      break;
5688 	
5689 	   case ACCEPTCYCLING:
5690 	      break;
5691 	
5692 	   case RATREC:
5693 	      break;
5694 	
5695 	   case POWERSCALING:
5696 	      break;
5697 	
5698 	   case RATFACJUMP:
5699 	      break;
5700 	
5701 	   case ROWBOUNDFLIPS:
5702 	      _ratiotesterBoundFlipping.useBoundFlipsRow(value);
5703 	      break;
5704 	
5705 	   case PERSISTENTSCALING:
5706 	      break;
5707 	
5708 	   case FULLPERTURBATION:
5709 	      _solver.useFullPerturbation(value);
5710 	      break;
5711 	
5712 	   case ENSURERAY:
5713 	      break;
5714 	
5715 	   case FORCEBASIC:
5716 	      break;
5717 	
5718 	   default:
5719 	      return false;
5720 	   }
5721 	
5722 	   _currentSettings->_boolParamValues[param] = value;
5723 	   return true;
5724 	}
5725 	
5726 	/// sets integer parameter value; returns true on success
5727 	template <class R>
5728 	bool SoPlexBase<R>::setIntParam(const IntParam param, const int value, const bool init)
5729 	{
5730 	   assert(param >= 0);
5731 	   assert(param < INTPARAM_COUNT);
5732 	   assert(init || _isConsistent());
5733 	
5734 	   if(!init && value == intParam(param))
5735 	      return true;
5736 	
5737 	   // check for a valid parameter value wrt bounds
5738 	   if(value < _currentSettings->intParam.lower[param]
5739 	         || value > _currentSettings->intParam.upper[param])
5740 	      return false;
5741 	
5742 	   switch(param)
5743 	   {
5744 	   // objective sense
5745 	   case SoPlexBase<R>::OBJSENSE:
5746 	      if(value != SoPlexBase<R>::OBJSENSE_MAXIMIZE && value != SoPlexBase<R>::OBJSENSE_MINIMIZE)
5747 	         return false;
5748 	
5749 	      _realLP->changeSense(value == SoPlexBase<R>::OBJSENSE_MAXIMIZE ? SPxLPBase<R>::MAXIMIZE :
5750 	                           SPxLPBase<R>::MINIMIZE);
5751 	
5752 	      if(_rationalLP != 0)
5753 	         _rationalLP->changeSense(value == SoPlexBase<R>::OBJSENSE_MAXIMIZE ? SPxLPRational::MAXIMIZE :
5754 	                                  SPxLPRational::MINIMIZE);
5755 	
5756 	      _invalidateSolution();
5757 	      break;
5758 	
5759 	   // type of computational form, i.e., column or row representation
5760 	   case SoPlexBase<R>::REPRESENTATION:
5761 	      if(value != SoPlexBase<R>::REPRESENTATION_COLUMN && value != SoPlexBase<R>::REPRESENTATION_ROW
5762 	            && value != SoPlexBase<R>::REPRESENTATION_AUTO)
5763 	         return false;
5764 	
5765 	      break;
5766 	
5767 	   // type of algorithm, i.e., primal or dual
5768 	   case SoPlexBase<R>::ALGORITHM:
5769 	      // decide upon entering/leaving at solve time depending on representation
5770 	      break;
5771 	
5772 	   // type of LU update
5773 	   case SoPlexBase<R>::FACTOR_UPDATE_TYPE:
5774 	      if(value != SoPlexBase<R>::FACTOR_UPDATE_TYPE_ETA && value != SoPlexBase<R>::FACTOR_UPDATE_TYPE_FT)
5775 	         return false;
5776 	
5777 	      _slufactor.setUtype(value == SoPlexBase<R>::FACTOR_UPDATE_TYPE_ETA ? SLUFactor<R>::ETA :
5778 	                          SLUFactor<R>::FOREST_TOMLIN);
5779 	      break;
5780 	
5781 	   // maximum number of updates before fresh factorization
5782 	   case SoPlexBase<R>::FACTOR_UPDATE_MAX:
5783 	      if(value == 0)
5784 	         _solver.basis().setMaxUpdates(DEFAULT_REFACTOR_INTERVAL);
5785 	      else
5786 	         _solver.basis().setMaxUpdates(value);
5787 	
5788 	      break;
5789 	
5790 	   // iteration limit (-1 if unlimited)
5791 	   case SoPlexBase<R>::ITERLIMIT:
5792 	      break;
5793 	
5794 	   // refinement limit (-1 if unlimited)
5795 	   case SoPlexBase<R>::REFLIMIT:
5796 	      break;
5797 	
5798 	   // stalling refinement limit (-1 if unlimited)
5799 	   case SoPlexBase<R>::STALLREFLIMIT:
5800 	      break;
5801 	
5802 	   // display frequency
5803 	   case SoPlexBase<R>::DISPLAYFREQ:
5804 	      _solver.setDisplayFreq(value);
5805 	      break;
5806 	
5807 	   // verbosity level
5808 	   case SoPlexBase<R>::VERBOSITY:
5809 	      switch(value)
5810 	      {
5811 	      case 0:
5812 	         spxout.setVerbosity(SPxOut::ERROR);
5813 	         break;
5814 	
5815 	      case 1:
5816 	         spxout.setVerbosity(SPxOut::WARNING);
5817 	         break;
5818 	
5819 	      case 2:
5820 	         spxout.setVerbosity(SPxOut::DEBUG);
5821 	         break;
5822 	
5823 	      case 3:
5824 	         spxout.setVerbosity(SPxOut::INFO1);
5825 	         break;
5826 	
5827 	      case 4:
5828 	         spxout.setVerbosity(SPxOut::INFO2);
5829 	         break;
5830 	
5831 	      case 5:
5832 	         spxout.setVerbosity(SPxOut::INFO3);
5833 	         break;
5834 	      }
5835 	
5836 	      break;
5837 	
5838 	   // type of simplifier
5839 	   case SoPlexBase<R>::SIMPLIFIER:
5840 	      switch(value)
5841 	      {
5842 	      case SIMPLIFIER_OFF:
5843 	         _simplifier = 0;
5844 	         break;
5845 	
5846 	      case SIMPLIFIER_INTERNAL:
5847 	      case SIMPLIFIER_AUTO:
5848 	         _simplifier = &_simplifierMainSM;
5849 	         assert(_simplifier != 0);
5850 	         break;
5851 	
5852 	      case SIMPLIFIER_PAPILO:
5853 	#ifdef SOPLEX_WITH_PAPILO
5854 	         _simplifier = &_simplifierPaPILO;
5855 	         assert(_simplifier != 0);
5856 	         break;
5857 	#else
5858 	         _simplifier = &_simplifierMainSM;
5859 	         assert(_simplifier != 0);
5860 	         return false;
5861 	#endif
5862 	
5863 	      default:
5864 	         return false;
5865 	      }
5866 	
5867 	      break;
5868 	
5869 	   // type of scaler
5870 	   case SoPlexBase<R>::SCALER:
5871 	      switch(value)
5872 	      {
5873 	      case SCALER_OFF:
5874 	         _scaler = nullptr;
5875 	         break;
5876 	
5877 	      case SCALER_UNIEQUI:
5878 	         _scaler = &_scalerUniequi;
5879 	         break;
5880 	
5881 	      case SCALER_BIEQUI:
5882 	         _scaler = &_scalerBiequi;
5883 	         break;
5884 	
5885 	      case SCALER_GEO1:
5886 	         _scaler = &_scalerGeo1;
5887 	         break;
5888 	
5889 	      case SCALER_GEO8:
5890 	         _scaler = &_scalerGeo8;
5891 	         break;
5892 	
5893 	      case SCALER_LEASTSQ:
5894 	         _scaler = &_scalerLeastsq;
5895 	         break;
5896 	
5897 	      case SCALER_GEOEQUI:
5898 	         _scaler = &_scalerGeoequi;
5899 	         break;
5900 	
5901 	      default:
5902 	         return false;
5903 	      }
5904 	
5905 	      break;
5906 	
5907 	   // type of starter used to create crash basis
5908 	   case SoPlexBase<R>::STARTER:
5909 	      switch(value)
5910 	      {
5911 	      case STARTER_OFF:
5912 	         _starter = 0;
5913 	         break;
5914 	
5915 	      case STARTER_WEIGHT:
5916 	         _starter = &_starterWeight;
5917 	         break;
5918 	
5919 	      case STARTER_SUM:
5920 	         _starter = &_starterSum;
5921 	         break;
5922 	
5923 	      case STARTER_VECTOR:
5924 	         _starter = &_starterVector;
5925 	         break;
5926 	
5927 	      default:
5928 	         return false;
5929 	      }
5930 	
5931 	      _solver.setStarter(_starter, false);
5932 	      break;
5933 	
5934 	   // type of pricer
5935 	   case SoPlexBase<R>::PRICER:
5936 	      switch(value)
5937 	      {
5938 	      case PRICER_AUTO:
5939 	         _solver.setPricer(&_pricerAuto);
5940 	         break;
5941 	
5942 	      case PRICER_DANTZIG:
5943 	         _solver.setPricer(&_pricerDantzig);
5944 	         break;
5945 	
5946 	      case PRICER_PARMULT:
5947 	         _solver.setPricer(&_pricerParMult);
5948 	         break;
5949 	
5950 	      case PRICER_DEVEX:
5951 	         _solver.setPricer(&_pricerDevex);
5952 	         break;
5953 	
5954 	      case PRICER_QUICKSTEEP:
5955 	         _solver.setPricer(&_pricerQuickSteep);
5956 	         break;
5957 	
5958 	      case PRICER_STEEP:
5959 	         _solver.setPricer(&_pricerSteep);
5960 	         break;
5961 	
5962 	      default:
5963 	         return false;
5964 	      }
5965 	
5966 	      break;
5967 	
5968 	   // mode for synchronizing real and rational LP
5969 	   case SoPlexBase<R>::SYNCMODE:
5970 	      switch(value)
5971 	      {
5972 	      case SYNCMODE_ONLYREAL:
5973 	         if(_rationalLP != 0)
5974 	         {
5975 	            _rationalLP->~SPxLPRational();
5976 	            spx_free(_rationalLP);
5977 	         }
5978 	
5979 	         break;
5980 	
5981 	      case SYNCMODE_AUTO:
5982 	         if(intParam(param) == SYNCMODE_ONLYREAL)
5983 	            _syncLPRational();
5984 	
5985 	         break;
5986 	
5987 	      case SYNCMODE_MANUAL:
5988 	         _ensureRationalLP();
5989 	         assert(_realLP != 0);
5990 	         _rationalLP->changeSense(_realLP->spxSense() == SPxLPBase<R>::MINIMIZE ? SPxLPRational::MINIMIZE :
5991 	                                  SPxLPRational::MAXIMIZE);
5992 	         break;
5993 	
5994 	      default:
5995 	         return false;
5996 	      }
5997 	
5998 	      break;
5999 	
6000 	   // mode for reading LP files; nothing to do but change the value if valid
6001 	   case SoPlexBase<R>::READMODE:
6002 	      switch(value)
6003 	      {
6004 	      case READMODE_REAL:
6005 	      case READMODE_RATIONAL:
6006 	         break;
6007 	
6008 	      default:
6009 	         return false;
6010 	      }
6011 	
6012 	      break;
6013 	
6014 	   // mode for iterative refinement strategy; nothing to do but change the value if valid
6015 	   case SoPlexBase<R>::SOLVEMODE:
6016 	      switch(value)
6017 	      {
6018 	      case SOLVEMODE_REAL:
6019 	      case SOLVEMODE_AUTO:
6020 	      case SOLVEMODE_RATIONAL:
6021 	         break;
6022 	
6023 	      default:
6024 	         return false;
6025 	      }
6026 	
6027 	      break;
6028 	
6029 	   // mode for a posteriori feasibility checks; nothing to do but change the value if valid
6030 	   case SoPlexBase<R>::CHECKMODE:
6031 	      switch(value)
6032 	      {
6033 	      case CHECKMODE_REAL:
6034 	      case CHECKMODE_AUTO:
6035 	      case CHECKMODE_RATIONAL:
6036 	         break;
6037 	
6038 	      default:
6039 	         return false;
6040 	      }
6041 	
6042 	      break;
6043 	
6044 	   // type of ratio test
6045 	   case SoPlexBase<R>::RATIOTESTER:
6046 	      switch(value)
6047 	      {
6048 	      case RATIOTESTER_TEXTBOOK:
6049 	         _solver.setTester(&_ratiotesterTextbook);
6050 	         break;
6051 	
6052 	      case RATIOTESTER_HARRIS:
6053 	         _solver.setTester(&_ratiotesterHarris);
6054 	         break;
6055 	
6056 	      case RATIOTESTER_FAST:
6057 	         _solver.setTester(&_ratiotesterFast);
6058 	         break;
6059 	
6060 	      case RATIOTESTER_BOUNDFLIPPING:
6061 	         _solver.setTester(&_ratiotesterBoundFlipping);
6062 	         break;
6063 	
6064 	      default:
6065 	         return false;
6066 	      }
6067 	
6068 	      break;
6069 	
6070 	   // type of timer
6071 	   case SoPlexBase<R>::TIMER:
6072 	      switch(value)
6073 	      {
6074 	      case TIMER_OFF:
6075 	         _solver.setTiming(Timer::OFF);
6076 	         break;
6077 	
6078 	      case TIMER_CPU:
6079 	         _solver.setTiming(Timer::USER_TIME);
6080 	         break;
6081 	
6082 	      case TIMER_WALLCLOCK:
6083 	         _solver.setTiming(Timer::WALLCLOCK_TIME);
6084 	         break;
6085 	
6086 	      default:
6087 	         return false;
6088 	      }
6089 	
6090 	      break;
6091 	
6092 	   // mode of hyper pricing
6093 	   case SoPlexBase<R>::HYPER_PRICING:
6094 	      switch(value)
6095 	      {
6096 	      case HYPER_PRICING_OFF:
6097 	      case HYPER_PRICING_AUTO:
6098 	      case HYPER_PRICING_ON:
6099 	         break;
6100 	
6101 	      default:
6102 	         return false;
6103 	      }
6104 	
6105 	      break;
6106 	
6107 	   // minimum number of stalling refinements since last pivot to trigger rational factorization
6108 	   case SoPlexBase<R>::RATFAC_MINSTALLS:
6109 	      break;
6110 	
6111 	   // maximum number of conjugate gradient iterations in least square scaling
6112 	   case SoPlexBase<R>::LEASTSQ_MAXROUNDS:
6113 	      if(_scaler)
6114 	         _scaler->setIntParam(value);
6115 	
6116 	      break;
6117 	
6118 	   // mode of solution polishing
6119 	   case SoPlexBase<R>::SOLUTION_POLISHING:
6120 	      switch(value)
6121 	      {
6122 	      case POLISHING_OFF:
6123 	         _solver.setSolutionPolishing(SPxSolverBase<R>::POLISH_OFF);
6124 	         break;
6125 	
6126 	      case POLISHING_INTEGRALITY:
6127 	         _solver.setSolutionPolishing(SPxSolverBase<R>::POLISH_INTEGRALITY);
6128 	         break;
6129 	
6130 	      case POLISHING_FRACTIONALITY:
6131 	         _solver.setSolutionPolishing(SPxSolverBase<R>::POLISH_FRACTIONALITY);
6132 	         break;
6133 	
6134 	      default:
6135 	         return false;
6136 	      }
6137 	
6138 	      break;
6139 	
6140 	   // the decomposition based simplex parameter settings
6141 	   case DECOMP_ITERLIMIT:
6142 	      break;
6143 	
6144 	   case DECOMP_MAXADDEDROWS:
6145 	      break;
6146 	
6147 	   case DECOMP_DISPLAYFREQ:
6148 	      break;
6149 	
6150 	   case DECOMP_VERBOSITY:
6151 	      break;
6152 	
6153 	   // printing of condition n
6154 	   case PRINTBASISMETRIC:
6155 	      _solver.setMetricInformation(value);
6156 	      break;
6157 	
6158 	   case STATTIMER:
6159 	      setTimings((Timer::TYPE) value);
6160 	      break;
6161 	
6162 	   default:
6163 	      return false;
6164 	   }
6165 	
6166 	   _currentSettings->_intParamValues[param] = value;
6167 	   return true;
6168 	}
6169 	
6170 	/// sets real parameter value; returns true on success
6171 	template <class R>
6172 	bool SoPlexBase<R>::setRealParam(const RealParam param, const Real value, const bool init)
6173 	{
6174 	   assert(param >= 0);
6175 	   assert(param < REALPARAM_COUNT);
6176 	   assert(init || _isConsistent());
6177 	
6178 	   if(!init && value == realParam(param))
6179 	      return true;
6180 	
6181 	   if(value < _currentSettings->realParam.lower[param]
6182 	         || value > _currentSettings->realParam.upper[param])
6183 	      return false;
6184 	
6185 	   // required to set a different feastol or opttol
6186 	   Real tmp_value = value;
6187 	
6188 	   switch(param)
6189 	   {
6190 	   // primal feasibility tolerance; passed to the floating point solver only when calling solve()
6191 	   case SoPlexBase<R>::FEASTOL:
6192 	#ifndef SOPLEX_WITH_BOOST
6193 	      if(value < DEFAULT_EPS_PIVOT)
6194 	      {
6195 	         MSG_WARNING(spxout, spxout << "Cannot set feasibility tolerance to small value " << value <<
6196 	                     " without GMP - using " << DEFAULT_EPS_PIVOT << ".\n");
6197 	         tmp_value = DEFAULT_EPS_PIVOT;
6198 	         _rationalFeastol = DEFAULT_EPS_PIVOT;
6199 	         break;
6200 	      }
6201 	
6202 	#endif
6203 	      _rationalFeastol = value;
6204 	      break;
6205 	
6206 	   // dual feasibility tolerance; passed to the floating point solver only when calling solve()
6207 	   case SoPlexBase<R>::OPTTOL:
6208 	#ifndef SOPLEX_WITH_GMP
6209 	      if(value < DEFAULT_EPS_PIVOT)
6210 	      {
6211 	         MSG_WARNING(spxout, spxout << "Cannot set optimality tolerance to small value " << value <<
6212 	                     " without GMP - using " << DEFAULT_EPS_PIVOT << ".\n");
6213 	         tmp_value = DEFAULT_EPS_PIVOT;
6214 	         _rationalOpttol = DEFAULT_EPS_PIVOT;
6215 	         break;
6216 	      }
6217 	
6218 	#endif
6219 	      _rationalOpttol = value;
6220 	      break;
6221 	
6222 	   // general zero tolerance
6223 	   case SoPlexBase<R>::EPSILON_ZERO:
6224 	      Param::setEpsilon(Real(value));
6225 	      break;
6226 	
6227 	   // zero tolerance used in factorization
6228 	   case SoPlexBase<R>::EPSILON_FACTORIZATION:
6229 	      Param::setEpsilonFactorization(Real(value));
6230 	      break;
6231 	
6232 	   // zero tolerance used in update of the factorization
6233 	   case SoPlexBase<R>::EPSILON_UPDATE:
6234 	      Param::setEpsilonUpdate(Real(value));
6235 	      break;
6236 	
6237 	   // pivot zero tolerance used in factorization (declare numerical singularity for small LU pivots)
6238 	   case SoPlexBase<R>::EPSILON_PIVOT:
6239 	      Param::setEpsilonPivot(Real(value));
6240 	      break;
6241 	
6242 	   // infinity threshold
6243 	   case SoPlexBase<R>::INFTY:
6244 	      _rationalPosInfty = value;
6245 	      // boost is treating -value as an expression and not just a number<T> So
6246 	      // doing -val won't work since Rational doesn't have an operator= that
6247 	      // accepts boost expressions. 0-value is a simple fix.
6248 	
6249 	      // @todo Implement expression template?
6250 	      // A work around to avoid expression template
6251 	      _rationalNegInfty = value;
6252 	      _rationalNegInfty = -_rationalNegInfty;
6253 	
6254 	      if(intParam(SoPlexBase<R>::SYNCMODE) != SYNCMODE_ONLYREAL)
6255 	         _recomputeRangeTypesRational();
6256 	
6257 	      break;
6258 	
6259 	   // time limit in seconds (INFTY if unlimited)
6260 	   case SoPlexBase<R>::TIMELIMIT:
6261 	      break;
6262 	
6263 	   // lower limit on objective value is set in solveReal()
6264 	   case SoPlexBase<R>::OBJLIMIT_LOWER:
6265 	      break;
6266 	
6267 	   // upper limit on objective value is set in solveReal()
6268 	   case SoPlexBase<R>::OBJLIMIT_UPPER:
6269 	      break;
6270 	
6271 	   // working tolerance for feasibility in floating-point solver
6272 	   case SoPlexBase<R>::FPFEASTOL:
6273 	      break;
6274 	
6275 	   // working tolerance for optimality in floating-point solver
6276 	   case SoPlexBase<R>::FPOPTTOL:
6277 	      break;
6278 	
6279 	   // maximum increase of scaling factors between refinements
6280 	   case SoPlexBase<R>::MAXSCALEINCR:
6281 	      _rationalMaxscaleincr = value;
6282 	      break;
6283 	
6284 	   // lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)
6285 	   case SoPlexBase<R>::LIFTMINVAL:
6286 	      break;
6287 	
6288 	   // upper threshold in lifting (nonzero matrix coefficients with larger absolute value will be reformulated)
6289 	   case SoPlexBase<R>::LIFTMAXVAL:
6290 	      break;
6291 	
6292 	   // threshold for sparse pricing
6293 	   case SoPlexBase<R>::SPARSITY_THRESHOLD:
6294 	      break;
6295 	
6296 	   // threshold on number of rows vs. number of columns for switching from column to row representations in auto mode
6297 	   case SoPlexBase<R>::REPRESENTATION_SWITCH:
6298 	      break;
6299 	
6300 	   // geometric frequency at which to apply rational reconstruction
6301 	   case SoPlexBase<R>::RATREC_FREQ:
6302 	      break;
6303 	
6304 	   // minimal reduction (sum of removed rows/cols) to continue simplification
6305 	   case SoPlexBase<R>::MINRED:
6306 	      break;
6307 	
6308 	   case SoPlexBase<R>::REFAC_BASIS_NNZ:
6309 	      break;
6310 	
6311 	   case SoPlexBase<R>::REFAC_UPDATE_FILL:
6312 	      break;
6313 	
6314 	   case SoPlexBase<R>::REFAC_MEM_FACTOR:
6315 	      break;
6316 	
6317 	   // accuracy of conjugate gradient method in least squares scaling (higher value leads to more iterations)
6318 	   case SoPlexBase<R>::LEASTSQ_ACRCY:
6319 	      if(_scaler)
6320 	         _scaler->setRealParam(value);
6321 	
6322 	      break;
6323 	
6324 	   // objective offset
6325 	   case SoPlexBase<R>::OBJ_OFFSET:
6326 	      if(_realLP)
6327 	         _realLP->changeObjOffset(value);
6328 	
6329 	      if(_rationalLP)
6330 	         _rationalLP->changeObjOffset(value);
6331 	
6332 	      break;
6333 	
6334 	   case SoPlexBase<R>::MIN_MARKOWITZ:
6335 	      _slufactor.setMarkowitz(value);
6336 	      break;
6337 	
6338 	   case SoPlexBase<R>::SIMPLIFIER_MODIFYROWFAC:
6339 	#ifdef SOPLEX_WITH_PAPILO
6340 	      _simplifierPaPILO.setModifyConsFrac(value);
6341 	#endif
6342 	      break;
6343 	
6344 	   default:
6345 	      return false;
6346 	   }
6347 	
6348 	   _currentSettings->_realParamValues[param] = tmp_value;
6349 	   return true;
6350 	}
6351 	
6352 	
6353 	#ifdef SOPLEX_WITH_RATIONALPARAM
6354 	/// sets rational parameter value; returns true on success
6355 	template <class R>
6356 	bool SoPlexBase<R>::setRationalParam(const RationalParam param, const Rational value,
6357 	                                     const bool init)
6358 	{
6359 	   assert(param >= 0);
6360 	   assert(param < RATIONALPARAM_COUNT);
6361 	   assert(init || _isConsistent());
6362 	
6363 	   if(!init && value == rationalParam(param))
6364 	      return true;
6365 	
6366 	   if(value < _currentSettings->rationalParam.lower[param]
6367 	         || value > _currentSettings->rationalParam.upper[param])
6368 	      return false;
6369 	
6370 	   switch(param)
6371 	   {
6372 	   default:
6373 	      // currently, there are no rational-valued parameters
6374 	      return false;
6375 	   }
6376 	
6377 	   _currentSettings->_rationalParamValues[param] = value;
6378 	   return true;
6379 	}
6380 	#endif
6381 	
6382 	
6383 	
6384 	/// sets parameter settings; returns true on success
6385 	template <class R>
6386 	bool SoPlexBase<R>::setSettings(const Settings& newSettings, const bool init)
6387 	{
6388 	   assert(init || _isConsistent());
6389 	
6390 	   bool success = true;
6391 	
6392 	   *_currentSettings = newSettings;
6393 	
6394 	   for(int i = 0; i < SoPlexBase<R>::BOOLPARAM_COUNT; i++)
6395 	      success &= setBoolParam((BoolParam)i, _currentSettings->_boolParamValues[i], init);
6396 	
6397 	   for(int i = 0; i < SoPlexBase<R>::INTPARAM_COUNT; i++)
6398 	      success &= setIntParam((IntParam)i, _currentSettings->_intParamValues[i], init);
6399 	
6400 	   for(int i = 0; i < SoPlexBase<R>::REALPARAM_COUNT; i++)
6401 	      success &= setRealParam((RealParam)i, _currentSettings->_realParamValues[i], init);
6402 	
6403 	#ifdef SOPLEX_WITH_RATIONALPARAM
6404 	
6405 	   for(int i = 0; i < SoPlexBase<R>::RATIONALPARAM_COUNT; i++)
6406 	      success &= setRationalParam((RationalParam)i, _currentSettings->_rationalParamValues[i], init);
6407 	
6408 	#endif
6409 	
6410 	   assert(_isConsistent());
6411 	
6412 	   return success;
6413 	}
6414 	
6415 	/// resets default parameter settings
6416 	template <class R>
6417 	void SoPlexBase<R>::resetSettings(const bool quiet, const bool init)
6418 	{
6419 	   for(int i = 0; i < SoPlexBase<R>::BOOLPARAM_COUNT; i++)
6420 	      setBoolParam((BoolParam)i, _currentSettings->boolParam.defaultValue[i], init);
6421 	
6422 	   for(int i = 0; i < SoPlexBase<R>::INTPARAM_COUNT; i++)
6423 	      setIntParam((IntParam)i, _currentSettings->intParam.defaultValue[i], init);
6424 	
6425 	   for(int i = 0; i < SoPlexBase<R>::REALPARAM_COUNT; i++)
6426 	      setRealParam((RealParam)i, _currentSettings->realParam.defaultValue[i], init);
6427 	
6428 	#ifdef SOPLEX_WITH_RATIONALPARAM
6429 	
6430 	   for(int i = 0; i < SoPlexBase<R>::RATIONALPARAM_COUNT; i++)
6431 	      success &= setRationalParam((RationalParam)i, _currentSettings->rationalParam.defaultValue[i],
6432 	                                  init);
6433 	
6434 	#endif
6435 	}
6436 	
6437 	/// print non-default parameter values
6438 	template <class R>
6439 	void SoPlexBase<R>::printUserSettings()
6440 	{
6441 	   bool printedValue = false;
6442 	
6443 	   SPxOut::setFixed(spxout.getCurrentStream());
6444 	
6445 	   for(int i = 0; i < SoPlexBase<R>::BOOLPARAM_COUNT; i++)
6446 	   {
6447 	      if(_currentSettings->_boolParamValues[i] == _currentSettings->boolParam.defaultValue[i])
6448 	         continue;
6449 	
6450 	      spxout << "bool:" << _currentSettings->boolParam.name[i] << " = " <<
6451 	             (_currentSettings->_boolParamValues[i] ? "true\n" : "false\n");
6452 	      printedValue = true;
6453 	   }
6454 	
6455 	   for(int i = 0; i < SoPlexBase<R>::INTPARAM_COUNT; i++)
6456 	   {
6457 	      if(_currentSettings->_intParamValues[i] == _currentSettings->intParam.defaultValue[i])
6458 	         continue;
6459 	
6460 	      spxout << "int:" << _currentSettings->intParam.name[i] << " = " <<
6461 	             _currentSettings->_intParamValues[i] << "\n";
6462 	      printedValue = true;
6463 	   }
6464 	
6465 	   SPxOut::setScientific(spxout.getCurrentStream());
6466 	
6467 	   for(int i = 0; i < SoPlexBase<R>::REALPARAM_COUNT; i++)
6468 	   {
6469 	      if(_currentSettings->_realParamValues[i] == _currentSettings->realParam.defaultValue[i])
6470 	         continue;
6471 	
6472 	      spxout << "real:" << _currentSettings->realParam.name[i] << " = " <<
6473 	             _currentSettings->_realParamValues[i] << "\n";
6474 	      printedValue = true;
6475 	   }
6476 	
6477 	#ifdef SOPLEX_WITH_RATIONALPARAM
6478 	
6479 	   for(int i = 0; i < SoPlexBase<R>::RATIONALPARAM_COUNT; i++)
6480 	   {
6481 	      if(_currentSettings->_rationalParamValues[i] == _currentSettings->rationalParam.defaultValue[i])
6482 	         continue;
6483 	
6484 	      spxout << "rational:" << _currentSettings->rationalParam.name[i] << " = " <<
6485 	             _currentSettings->_rationalParamValues[i] << "\n";
6486 	      printedValue = true;
6487 	   }
6488 	
6489 	#endif
6490 	
6491 	   if(_solver.random.getSeed() != DEFAULT_RANDOM_SEED)
6492 	   {
6493 	      spxout << "uint:random_seed = " << _solver.random.getSeed() << "\n";
6494 	      printedValue = true;
6495 	   }
6496 	
6497 	   if(printedValue)
6498 	      spxout << std::endl;
6499 	}
6500 	
6501 	/// prints status
6502 	template <class R>
6503 	void SoPlexBase<R>::printStatus(std::ostream& os, typename SPxSolverBase<R>::Status stat)
6504 	{
6505 	   os << "SoPlex status       : ";
6506 	
6507 	   switch(stat)
6508 	   {
6509 	   case SPxSolverBase<R>::ERROR:
6510 	      os << "error [unspecified]";
6511 	      break;
6512 	
6513 	   case SPxSolverBase<R>::NO_RATIOTESTER:
6514 	      os << "error [no ratiotester loaded]";
6515 	      break;
6516 	
6517 	   case SPxSolverBase<R>::NO_PRICER:
6518 	      os << "error [no pricer loaded]";
6519 	      break;
6520 	
6521 	   case SPxSolverBase<R>::NO_SOLVER:
6522 	      os << "error [no linear solver loaded]";
6523 	      break;
6524 	
6525 	   case SPxSolverBase<R>::NOT_INIT:
6526 	      os << "error [not initialized]";
6527 	      break;
6528 	
6529 	   case SPxSolverBase<R>::ABORT_CYCLING:
6530 	      os << "solving aborted [cycling]";
6531 	      break;
6532 	
6533 	   case SPxSolverBase<R>::ABORT_TIME:
6534 	      os << "solving aborted [time limit reached]";
6535 	      break;
6536 	
6537 	   case SPxSolverBase<R>::ABORT_ITER:
6538 	      os << "solving aborted [iteration limit reached]";
6539 	      break;
6540 	
6541 	   case SPxSolverBase<R>::ABORT_VALUE:
6542 	      os << "solving aborted [objective limit reached]";
6543 	      break;
6544 	
6545 	   case SPxSolverBase<R>::NO_PROBLEM:
6546 	      os << "no problem loaded";
6547 	      break;
6548 	
6549 	   case SPxSolverBase<R>::REGULAR:
6550 	      os << "basis is regular";
6551 	      break;
6552 	
6553 	   case SPxSolverBase<R>::SINGULAR:
6554 	      os << "basis is singular";
6555 	      break;
6556 	
6557 	   case SPxSolverBase<R>::OPTIMAL:
6558 	      os << "problem is solved [optimal]";
6559 	      break;
6560 	
6561 	   case SPxSolverBase<R>::UNBOUNDED:
6562 	      os << "problem is solved [unbounded]";
6563 	      break;
6564 	
6565 	   case SPxSolverBase<R>::INFEASIBLE:
6566 	      os << "problem is solved [infeasible]";
6567 	      break;
6568 	
6569 	   case SPxSolverBase<R>::INForUNBD:
6570 	      os << "problem is solved [infeasible or unbounded]";
6571 	      break;
6572 	
6573 	   case SPxSolverBase<R>::OPTIMAL_UNSCALED_VIOLATIONS:
6574 	      os << "problem is solved [optimal with unscaled violations]";
6575 	      break;
6576 	
6577 	   default:
6578 	   case SPxSolverBase<R>::UNKNOWN:
6579 	      os << "unknown";
6580 	      break;
6581 	   }
6582 	
6583 	   os << "\n";
6584 	}
6585 	
6586 	
6587 	/// prints version and compilation options
6588 	template <class R>
6589 	void SoPlexBase<R>::printVersion() const
6590 	{
6591 	   // do not use preprocessor directives within the MSG_INFO1 macro
6592 	#if (SOPLEX_SUBVERSION > 0)
6593 	   MSG_INFO1(spxout, spxout << "SoPlex version " << SOPLEX_VERSION / 100
6594 	             << "." << (SOPLEX_VERSION % 100) / 10
6595 	             << "." << SOPLEX_VERSION % 10
6596 	             << "." << SOPLEX_SUBVERSION);
6597 	#else
6598 	   MSG_INFO1(spxout, spxout << "SoPlex version " << SOPLEX_VERSION / 100
6599 	             << "." << (SOPLEX_VERSION % 100) / 10
6600 	             << "." << SOPLEX_VERSION % 10);
6601 	#endif
6602 	
6603 	#ifndef NDEBUG
6604 	   MSG_INFO1(spxout, spxout << " [mode: debug]");
6605 	#else
6606 	   MSG_INFO1(spxout, spxout << " [mode: optimized]");
6607 	#endif
6608 	
6609 	   MSG_INFO1(spxout, spxout << " [precision: " << (int)sizeof(R) << " byte]");
6610 	
6611 	#ifdef SOPLEX_WITH_GMP
6612 	#ifdef mpir_version
6613 	   MSG_INFO1(spxout, spxout << " [rational: MPIR " << mpir_version << "]");
6614 	#else
6615 	   MSG_INFO1(spxout, spxout << " [rational: GMP " << gmp_version << "]");
6616 	#endif
6617 	#else
6618 	   MSG_INFO1(spxout, spxout << " [rational: long double]");
6619 	#endif
6620 	
6621 	
6622 	#ifdef SOPLEX_WITH_PAPILO
6623 	   MSG_INFO1(spxout, spxout << " [PaPILO  " << PAPILO_VERSION_MAJOR << "." << PAPILO_VERSION_MINOR  <<
6624 	             "." << PAPILO_VERSION_PATCH << " {" <<  PAPILO_GITHASH << "}]\n");
6625 	#else
6626 	   MSG_INFO1(spxout, spxout << " [PaPILO: not available]");
6627 	#endif
6628 	
6629 	   MSG_INFO1(spxout, spxout << " [githash: " << getGitHash() << "]\n");
6630 	}
6631 	
6632 	
6633 	/// checks if real LP and rational LP are in sync; dimensions will always be compared,
6634 	/// vector and matrix values only if the respective parameter is set to true.
6635 	/// If quiet is set to true the function will only display which vectors are different.
6636 	template <class R>
6637 	bool SoPlexBase<R>::areLPsInSync(const bool checkVecVals, const bool checkMatVals,
6638 	                                 const bool quiet) const
6639 	{
6640 	#ifndef SOPLEX_WITH_BOOST
6641 	   MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
6642 	   return false;
6643 	#else
6644 	   bool result = true;
6645 	   bool nRowsMatch = true;
6646 	   bool nColsMatch = true;
6647 	   bool rhsDimMatch = true;
6648 	   bool lhsDimMatch = true;
6649 	   bool maxObjDimMatch = true;
6650 	   bool upperDimMatch = true;
6651 	   bool lowerDimMatch = true;
6652 	
6653 	   // compare number of Rows
6654 	   if(_realLP->nRows() != _rationalLP->nRows())
6655 	   {
6656 	      MSG_INFO1(spxout, spxout <<
6657 	                "The number of Rows in the R LP does not match the one in the Rational LP."
6658 	                << " R LP: " << _realLP->nRows() << "  Rational LP: " << _rationalLP->nRows() << std::endl);
6659 	      result = false;
6660 	      nRowsMatch = false;
6661 	   }
6662 	
6663 	   // compare number of Columns
6664 	   if(_realLP->nCols() != _rationalLP->nCols())
6665 	   {
6666 	      MSG_INFO1(spxout, spxout <<
6667 	                "The number of Columns in the R LP does not match the one in the Rational LP."
6668 	                << " R LP: " << _realLP->nCols() << "  Rational LP: " << _rationalLP->nCols() << std::endl);
6669 	      result = false;
6670 	      nColsMatch = false;
6671 	   }
6672 	
6673 	   // compare number of nonZeros
6674 	   if(_realLP->nNzos() != _rationalLP->nNzos())
6675 	   {
6676 	      MSG_INFO1(spxout, spxout <<
6677 	                "The number of nonZeros in the R LP does not match the one in the Rational LP."
6678 	                << " R LP: " << _realLP->nNzos() << "  Rational LP: " << _rationalLP->nNzos() << std::endl);
6679 	      result = false;
6680 	   }
6681 	
6682 	   // compare the dimensions of the right hand side vectors
6683 	   if(_realLP->rhs().dim() != _rationalLP->rhs().dim())
6684 	   {
6685 	      MSG_INFO1(spxout, spxout <<
6686 	                "The dimension of the right hand side vector of the R LP does not match the one of the Rational LP."
6687 	                << " R LP: " << _realLP->rhs().dim() << "  Rational LP: " << _rationalLP->rhs().dim() << std::endl);
6688 	      result = false;
6689 	      rhsDimMatch = false;
6690 	
6691 	   }
6692 	
6693 	   // compare the dimensions of the left hand side vectors
6694 	   if(_realLP->lhs().dim() != _rationalLP->lhs().dim())
6695 	   {
6696 	      MSG_INFO1(spxout, spxout <<
6697 	                "The dimension of the left hand side vector of the R LP does not match the one of the Rational LP."
6698 	                << " R LP: " << _realLP->lhs().dim() << "  Rational LP: " << _rationalLP->lhs().dim() << std::endl);
6699 	      result = false;
6700 	      lhsDimMatch = false;
6701 	   }
6702 	
6703 	   // compare the dimensions of the objective function vectors
6704 	   if(_realLP->maxObj().dim() != _rationalLP->maxObj().dim())
6705 	   {
6706 	      MSG_INFO1(spxout, spxout <<
6707 	                "The dimension of the objective function vector of the R LP does not match the one of the Rational LP."
6708 	                << " R LP: " << _realLP->maxObj().dim() << "  Rational LP: " << _rationalLP->maxObj().dim() <<
6709 	                std::endl);
6710 	      result = false;
6711 	      maxObjDimMatch = false;
6712 	   }
6713 	
6714 	   // compare the sense
6715 	   if((int)_realLP->spxSense() != (int)_rationalLP->spxSense())
6716 	   {
6717 	      MSG_INFO1(spxout, spxout <<
6718 	                "The objective function sense of the R LP does not match the one of the Rational LP."
6719 	                << " Real LP: " << (_realLP->spxSense() == SPxLPBase<R>::MINIMIZE ? "MIN" : "MAX")
6720 	                << "  Rational LP: " << (_rationalLP->spxSense() == SPxLPRational::MINIMIZE ? "MIN" : "MAX") <<
6721 	                std::endl);
6722 	      result = false;
6723 	   }
6724 	
6725 	   // compare the dimensions of upper bound vectors
6726 	   if(_realLP->upper().dim() != _rationalLP->upper().dim())
6727 	   {
6728 	      MSG_INFO1(spxout, spxout <<
6729 	                "The dimension of the upper bound vector of the R LP does not match the one of the Rational LP."
6730 	                << " R LP: " << _realLP->upper().dim() << "  Rational LP: " << _rationalLP->upper().dim() <<
6731 	                std::endl);
6732 	      result = false;
6733 	      upperDimMatch = false;
6734 	   }
6735 	
6736 	   // compare the dimensions of the objective function vectors
6737 	   if(_realLP->lower().dim() != _rationalLP->lower().dim())
6738 	   {
6739 	      MSG_INFO1(spxout, spxout <<
6740 	                "The dimension of the lower bound vector of the R LP does not match the one of the Rational LP."
6741 	                << " R LP: " << _realLP->lower().dim() << "  Rational LP: " << _rationalLP->lower().dim() <<
6742 	                std::endl);
6743 	      result = false;
6744 	      lowerDimMatch = false;
6745 	   }
6746 	
6747 	   // compares the values of the rhs, lhs, maxObj, upper, lower vectors
6748 	   if(checkVecVals)
6749 	   {
6750 	      bool rhsValMatch = true;
6751 	      bool lhsValMatch = true;
6752 	      bool maxObjValMatch = true;
6753 	      bool upperValMatch = true;
6754 	      bool lowerValMatch = true;
6755 	
6756 	      // compares the values of the right hand side vectors
6757 	      if(rhsDimMatch)
6758 	      {
6759 	         for(int i = 0; i < _realLP->rhs().dim(); i++)
6760 	         {
6761 	            if((GE(_realLP->rhs()[i], R(realParam(SoPlexBase<R>::INFTY))) != (_rationalLP->rhs()[i] >=
6762 	                  _rationalPosInfty))
6763 	                  || (LT(_realLP->rhs()[i], R(realParam(SoPlexBase<R>::INFTY)))
6764 	                      && _rationalLP->rhs()[i] < _rationalPosInfty
6765 	                      && !isAdjacentTo(_rationalLP->rhs()[i], (double)_realLP->rhs()[i])))
6766 	            {
6767 	               if(!quiet)
6768 	               {
6769 	                  MSG_INFO1(spxout, spxout << "Entries number " << i << " of the right hand side vectors don't match."
6770 	                            << " R LP: " << _realLP->rhs()[i] << "  Rational LP: " << _rationalLP->rhs()[i] << std::endl);
6771 	               }
6772 	
6773 	               rhsValMatch = false;
6774 	               result = false;
6775 	            }
6776 	         }
6777 	
6778 	         if(!rhsValMatch && quiet)
6779 	         {
6780 	            MSG_INFO1(spxout, spxout << "The values of the right hand side vectors don't match." << std::endl);
6781 	         }
6782 	      }
6783 	
6784 	      // compares the values of the left hand side vectors
6785 	      if(lhsDimMatch)
6786 	      {
6787 	         for(int i = 0; i < _realLP->lhs().dim(); i++)
6788 	         {
6789 	            if((LE(_realLP->lhs()[i], R(-realParam(SoPlexBase<R>::INFTY))) != (_rationalLP->lhs()[i] <=
6790 	                  _rationalNegInfty))
6791 	                  || (GT(_realLP->lhs()[i], R(-realParam(SoPlexBase<R>::INFTY)))
6792 	                      && _rationalLP->lhs()[i] > _rationalNegInfty
6793 	                      && !isAdjacentTo(_rationalLP->lhs()[i], (double)_realLP->lhs()[i])))
6794 	            {
6795 	               if(!quiet)
6796 	               {
6797 	                  MSG_INFO1(spxout, spxout << "Entries number " << i << " of the left hand side vectors don't match."
6798 	                            << " R LP: " << _realLP->lhs()[i] << "  Rational LP: " << _rationalLP->lhs()[i] << std::endl);
6799 	               }
6800 	
6801 	               lhsValMatch = false;
6802 	               result = false;
6803 	            }
6804 	         }
6805 	
6806 	         if(!lhsValMatch && quiet)
6807 	         {
6808 	            MSG_INFO1(spxout, spxout << "The values of the left hand side vectors don't match." << std::endl);
6809 	         }
6810 	      }
6811 	
6812 	      // compares the values of the objective function vectors
6813 	      if(maxObjDimMatch)
6814 	      {
6815 	         for(int i = 0; i < _realLP->maxObj().dim(); i++)
6816 	         {
6817 	            if(!isAdjacentTo(_rationalLP->maxObj()[i], (double)_realLP->maxObj()[i]))
6818 	            {
6819 	               if(!quiet)
6820 	               {
6821 	                  MSG_INFO1(spxout, spxout << "Entries number " << i <<
6822 	                            " of the objective function vectors don't match."
6823 	                            << " R LP: " << _realLP->maxObj()[i] << "  Rational LP: " << _rationalLP->maxObj()[i] << std::endl);
6824 	               }
6825 	
6826 	               maxObjValMatch = false;
6827 	               result = false;
6828 	            }
6829 	         }
6830 	
6831 	         if(!maxObjValMatch && quiet)
6832 	         {
6833 	            MSG_INFO1(spxout, spxout << "The values of the objective function vectors don't match." <<
6834 	                      std::endl);
6835 	         }
6836 	      }
6837 	
6838 	      // compares the values of the upper bound vectors
6839 	      if(upperDimMatch)
6840 	      {
6841 	         for(int i = 0; i < _realLP->upper().dim(); i++)
6842 	         {
6843 	            if((GE(_realLP->upper()[i], R(realParam(SoPlexBase<R>::INFTY))) != (_rationalLP->upper()[i] >=
6844 	                  _rationalPosInfty))
6845 	                  || (LT(_realLP->upper()[i], R(realParam(SoPlexBase<R>::INFTY)))
6846 	                      && _rationalLP->upper()[i] < _rationalPosInfty
6847 	                      && !isAdjacentTo(_rationalLP->upper()[i], (double)_realLP->upper()[i])))
6848 	            {
6849 	               if(!quiet)
6850 	               {
6851 	                  MSG_INFO1(spxout, spxout << "Entries number " << i << " of the upper bound vectors don't match."
6852 	                            << " R LP: " << _realLP->upper()[i] << "  Rational LP: " << _rationalLP->upper()[i] << std::endl);
6853 	               }
6854 	
6855 	               upperValMatch = false;
6856 	               result = false;
6857 	            }
6858 	         }
6859 	
6860 	         if(!upperValMatch && quiet)
6861 	         {
6862 	            MSG_INFO1(spxout, spxout << "The values of the upper bound vectors don't match." << std::endl);
6863 	         }
6864 	      }
6865 	
6866 	      // compares the values of the lower bound vectors
6867 	      if(lowerDimMatch)
6868 	      {
6869 	         for(int i = 0; i < _realLP->lower().dim(); i++)
6870 	         {
6871 	            if((LE(_realLP->lower()[i], R(-realParam(SoPlexBase<R>::INFTY))) != (_rationalLP->lower()[i] <=
6872 	                  _rationalNegInfty))
6873 	                  || (GT(_realLP->lower()[i], R(-realParam(SoPlexBase<R>::INFTY)))
6874 	                      && _rationalLP->lower()[i] > _rationalNegInfty
6875 	                      && !isAdjacentTo(_rationalLP->lower()[i], (double)_realLP->lower()[i])))
6876 	            {
6877 	               if(!quiet)
6878 	               {
6879 	                  MSG_INFO1(spxout, spxout << "Entries number " << i << " of the lower bound vectors don't match."
6880 	                            << " R LP: " << _realLP->lower()[i] << "  Rational LP: " << _rationalLP->lower()[i] << std::endl);
6881 	               }
6882 	
6883 	               lowerValMatch = false;
6884 	               result = false;
6885 	            }
6886 	         }
6887 	
6888 	         if(!lowerValMatch && quiet)
6889 	         {
6890 	            MSG_INFO1(spxout, spxout << "The values of the lower bound vectors don't match." << std::endl);
6891 	         }
6892 	      }
6893 	   }
6894 	
6895 	   // compare the values of the matrix
6896 	   if(checkMatVals && nRowsMatch && nColsMatch)
6897 	   {
6898 	      bool matrixValMatch = true;
6899 	
6900 	      for(int i = 0; i < _realLP->nCols() ; i++)
6901 	      {
6902 	         for(int j = 0; j < _realLP->nRows() ; j++)
6903 	         {
6904 	            if(!isAdjacentTo(_rationalLP->colVector(i)[j], (double)_realLP->colVector(i)[j]))
6905 	            {
6906 	               if(!quiet)
6907 	               {
6908 	                  MSG_INFO1(spxout, spxout << "Entries number " << j << " of column number " << i << " don't match."
6909 	                            << " R LP: " << _realLP->colVector(i)[j] << "  Rational LP: " << _rationalLP->colVector(
6910 	                               i)[j] << std::endl);
6911 	               }
6912 	
6913 	               matrixValMatch = false;
6914 	               result = false;
6915 	            }
6916 	         }
6917 	      }
6918 	
6919 	      if(!matrixValMatch && quiet)
6920 	      {
6921 	         MSG_INFO1(spxout, spxout << "The values of the matrices don't match." << std::endl);
6922 	      }
6923 	   }
6924 	
6925 	   return result;
6926 	#endif
6927 	}
6928 	
6929 	
6930 	
6931 	/// set the random seed of the solver instance
6932 	template <class R>
6933 	void SoPlexBase<R>::setRandomSeed(unsigned int seed)
6934 	{
6935 	   _solver.random.setSeed(seed);
6936 	}
6937 	
6938 	
6939 	
6940 	/// returns the current random seed of the solver instance or the one stored in the settings
6941 	template <class R>
6942 	unsigned int  SoPlexBase<R>::randomSeed() const
6943 	{
6944 	   return _solver.random.getSeed();
6945 	}
6946 	
6947 	
6948 	
6949 	/// extends sparse vector to hold newmax entries if and only if it holds no more free entries
6950 	template <class R>
6951 	void SoPlexBase<R>::_ensureDSVectorRationalMemory(DSVectorRational& vec, const int newmax) const
6952 	{
6953 	   assert(newmax > vec.size());
6954 	
6955 	   if(vec.size() >= vec.max())
6956 	      vec.setMax(newmax);
6957 	}
6958 	
6959 	
6960 	
6961 	/// creates a permutation for removing rows/columns from an array of indices
6962 	template <class R>
6963 	void SoPlexBase<R>::_idxToPerm(int* idx, int idxSize, int* perm, int permSize) const
6964 	{
6965 	   assert(idx != 0);
6966 	   assert(idxSize >= 0);
6967 	   assert(perm != 0);
6968 	   assert(permSize >= 0);
6969 	
6970 	   for(int i = 0; i < permSize; i++)
6971 	      perm[i] = i;
6972 	
6973 	   for(int i = 0; i < idxSize; i++)
6974 	   {
6975 	      assert(idx[i] >= 0);
6976 	      assert(idx[i] < permSize);
6977 	      perm[idx[i]] = -1;
6978 	   }
6979 	}
6980 	
6981 	
6982 	
6983 	/// creates a permutation for removing rows/columns from a range of indices
6984 	template <class R>
6985 	void SoPlexBase<R>::_rangeToPerm(int start, int end, int* perm, int permSize) const
6986 	{
6987 	   assert(perm != 0);
6988 	   assert(permSize >= 0);
6989 	
6990 	   for(int i = 0; i < permSize; i++)
6991 	      perm[i] = (i < start || i > end) ? i : -1;
6992 	}
6993 	
6994 	
6995 	
6996 	/// checks consistency
6997 	template <class R>
6998 	bool SoPlexBase<R>::_isConsistent() const
6999 	{
7000 	   assert(_statistics != 0);
7001 	   assert(_currentSettings != 0);
7002 	
7003 	   assert(_realLP != 0);
7004 	   assert(_rationalLP != 0 || intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL);
7005 	
7006 	   assert(_realLP != &_solver || _isRealLPLoaded);
7007 	   assert(_realLP == &_solver || !_isRealLPLoaded);
7008 	
7009 	   assert(!_hasBasis || _isRealLPLoaded || _basisStatusRows.size() == numRows());
7010 	   assert(!_hasBasis || _isRealLPLoaded || _basisStatusCols.size() == numCols());
7011 	   assert(_rationalLUSolver.status() == SLinSolverRational::UNLOADED || _hasBasis);
7012 	   assert(_rationalLUSolver.status() == SLinSolverRational::UNLOADED
7013 	          || _rationalLUSolver.dim() == _rationalLUSolverBind.size());
7014 	   assert(_rationalLUSolver.status() == SLinSolverRational::UNLOADED
7015 	          || _rationalLUSolver.dim() == numRowsRational());
7016 	
7017 	   assert(_rationalLP == 0 || _colTypes.size() == numColsRational());
7018 	   assert(_rationalLP == 0 || _rowTypes.size() == numRowsRational());
7019 	
7020 	   return true;
7021 	}
7022 	
7023 	
7024 	
7025 	/// should solving process be stopped?
7026 	template <class R>
7027 	bool SoPlexBase<R>::_isSolveStopped(bool& stoppedTime, bool& stoppedIter) const
7028 	{
7029 	   assert(_statistics != 0);
7030 	
7031 	   stoppedTime = (realParam(TIMELIMIT) < realParam(INFTY)
7032 	                  && _statistics->solvingTime->time() >= realParam(TIMELIMIT));
7033 	   stoppedIter = (intParam(ITERLIMIT) >= 0 && _statistics->iterations >= intParam(ITERLIMIT))
7034 	                 || (intParam(REFLIMIT) >= 0 && _statistics->refinements >= intParam(REFLIMIT))
7035 	                 || (intParam(STALLREFLIMIT) >= 0 && _statistics->stallRefinements >= intParam(STALLREFLIMIT));
7036 	
7037 	   return stoppedTime || stoppedIter;
7038 	}
7039 	
7040 	
7041 	
7042 	/// determines RangeType from real bounds
7043 	template <class R>
7044 	typename SoPlexBase<R>::RangeType SoPlexBase<R>::_rangeTypeReal(const R& lower,
7045 	      const R& upper) const
7046 	{
7047 	   assert(lower <= upper);
7048 	
7049 	   if(lower <= R(-infinity))
7050 	   {
7051 	      if(upper >= R(infinity))
7052 	         return RANGETYPE_FREE;
7053 	      else
7054 	         return RANGETYPE_UPPER;
7055 	   }
7056 	   else
7057 	   {
7058 	      if(upper >= R(infinity))
7059 	         return RANGETYPE_LOWER;
7060 	      else if(lower == upper)
7061 	         return RANGETYPE_FIXED;
7062 	      else
7063 	         return RANGETYPE_BOXED;
7064 	   }
7065 	}
7066 	
7067 	
7068 	
7069 	/// determines RangeType from rational bounds
7070 	template <class R>
7071 	typename SoPlexBase<R>::RangeType SoPlexBase<R>::_rangeTypeRational(const Rational& lower,
7072 	      const Rational& upper) const
7073 	{
7074 	   assert(lower <= upper);
7075 	
7076 	   if(lower <= _rationalNegInfty)
7077 	   {
7078 	      if(upper >= _rationalPosInfty)
7079 	         return RANGETYPE_FREE;
7080 	      else
7081 	         return RANGETYPE_UPPER;
7082 	   }
7083 	   else
7084 	   {
7085 	      if(upper >= _rationalPosInfty)
7086 	         return RANGETYPE_LOWER;
7087 	      else if(lower == upper)
7088 	         return RANGETYPE_FIXED;
7089 	      else
7090 	         return RANGETYPE_BOXED;
7091 	   }
7092 	}
7093 	
7094 	
7095 	
7096 	/// switches RANGETYPE_LOWER to RANGETYPE_UPPER and vice versa
7097 	template <class R>
7098 	typename SoPlexBase<R>::RangeType SoPlexBase<R>::_switchRangeType(const typename
7099 	      SoPlexBase<R>::RangeType&
7100 	      rangeType) const
7101 	{
7102 	   if(rangeType == RANGETYPE_LOWER)
7103 	      return RANGETYPE_UPPER;
7104 	   else if(rangeType == RANGETYPE_UPPER)
7105 	      return RANGETYPE_LOWER;
7106 	   else
7107 	      return rangeType;
7108 	}
7109 	
7110 	
7111 	
7112 	/// checks whether RangeType corresponds to finite lower bound
7113 	template <class R>
7114 	bool SoPlexBase<R>::_lowerFinite(const RangeType& rangeType) const
7115 	{
7116 	   return (rangeType == RANGETYPE_LOWER || rangeType == RANGETYPE_BOXED
7117 	           || rangeType == RANGETYPE_FIXED);
7118 	}
7119 	
7120 	
7121 	
7122 	/// checks whether RangeType corresponds to finite upper bound
7123 	template <class R>
7124 	bool SoPlexBase<R>::_upperFinite(const RangeType& rangeType) const
7125 	{
7126 	   return (rangeType == RANGETYPE_UPPER || rangeType == RANGETYPE_BOXED
7127 	           || rangeType == RANGETYPE_FIXED);
7128 	}
7129 	
7130 	
7131 	
7132 	/// adds a single row to the R LP and adjusts basis
7133 	template <class R>
7134 	void SoPlexBase<R>::_addRowReal(const LPRowBase<R>& lprow)
7135 	{
7136 	   assert(_realLP != 0);
7137 	
7138 	   bool scale = _realLP->isScaled();
7139 	   _realLP->addRow(lprow, scale);
7140 	
7141 	   if(_isRealLPLoaded)
7142 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7143 	   else if(_hasBasis)
7144 	      _basisStatusRows.append(SPxSolverBase<R>::BASIC);
7145 	
7146 	   _rationalLUSolver.clear();
7147 	}
7148 	
7149 	
7150 	
7151 	/// adds a single row to the R LP and adjusts basis
7152 	template <class R>
7153 	void SoPlexBase<R>::_addRowReal(R lhs, const SVectorBase<R>& lprow, R rhs)
7154 	{
7155 	   assert(_realLP != 0);
7156 	
7157 	   bool scale = _realLP->isScaled();
7158 	   _realLP->addRow(lhs, lprow, rhs, scale);
7159 	
7160 	   if(_isRealLPLoaded)
7161 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7162 	   else if(_hasBasis)
7163 	      _basisStatusRows.append(SPxSolverBase<R>::BASIC);
7164 	
7165 	   _rationalLUSolver.clear();
7166 	}
7167 	
7168 	
7169 	
7170 	/// adds multiple rows to the R LP and adjusts basis
7171 	template <class R>
7172 	void SoPlexBase<R>::_addRowsReal(const LPRowSetBase<R>& lprowset)
7173 	{
7174 	   assert(_realLP != 0);
7175 	
7176 	   bool scale = _realLP->isScaled();
7177 	   _realLP->addRows(lprowset, scale);
7178 	
7179 	   if(_isRealLPLoaded)
7180 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7181 	   else if(_hasBasis)
7182 	      _basisStatusRows.append(lprowset.num(), SPxSolverBase<R>::BASIC);
7183 	
7184 	   _rationalLUSolver.clear();
7185 	}
7186 	
7187 	
7188 	/// adds a single column to the R LP and adjusts basis
7189 	template <class R>
7190 	void SoPlexBase<R>::_addColReal(const LPColReal& lpcol)
7191 	{
7192 	   assert(_realLP != 0);
7193 	
7194 	   bool scale = _realLP->isScaled();
7195 	   _realLP->addCol(lpcol, scale);
7196 	
7197 	   if(_isRealLPLoaded)
7198 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7199 	   else if(_hasBasis)
7200 	   {
7201 	      if(lpcol.lower() > -realParam(SoPlexBase<R>::INFTY))
7202 	         _basisStatusCols.append(SPxSolverBase<R>::ON_LOWER);
7203 	      else if(lpcol.upper() < realParam(SoPlexBase<R>::INFTY))
7204 	         _basisStatusCols.append(SPxSolverBase<R>::ON_UPPER);
7205 	      else
7206 	         _basisStatusCols.append(SPxSolverBase<R>::ZERO);
7207 	   }
7208 	
7209 	   _rationalLUSolver.clear();
7210 	}
7211 	
7212 	
7213 	
7214 	/// adds a single column to the R LP and adjusts basis
7215 	template <class R>
7216 	void SoPlexBase<R>::_addColReal(R obj, R lower, const SVectorBase<R>& lpcol, R upper)
7217 	{
7218 	   assert(_realLP != 0);
7219 	
7220 	   bool scale = _realLP->isScaled();
7221 	   _realLP->addCol(obj, lower, lpcol, upper, scale);
7222 	
7223 	   if(_isRealLPLoaded)
7224 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7225 	   else if(_hasBasis)
7226 	      _basisStatusRows.append(SPxSolverBase<R>::BASIC);
7227 	
7228 	   _rationalLUSolver.clear();
7229 	}
7230 	
7231 	
7232 	/// adds multiple columns to the R LP and adjusts basis
7233 	template <class R>
7234 	void SoPlexBase<R>::_addColsReal(const LPColSetReal& lpcolset)
7235 	{
7236 	   assert(_realLP != 0);
7237 	
7238 	   bool scale = _realLP->isScaled();
7239 	   _realLP->addCols(lpcolset, scale);
7240 	
7241 	   if(_isRealLPLoaded)
7242 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7243 	   else if(_hasBasis)
7244 	   {
7245 	      for(int i = 0; i < lpcolset.num(); i++)
7246 	      {
7247 	         if(lpcolset.lower(i) > -realParam(SoPlexBase<R>::INFTY))
7248 	            _basisStatusCols.append(SPxSolverBase<R>::ON_LOWER);
7249 	         else if(lpcolset.upper(i) < realParam(SoPlexBase<R>::INFTY))
7250 	            _basisStatusCols.append(SPxSolverBase<R>::ON_UPPER);
7251 	         else
7252 	            _basisStatusCols.append(SPxSolverBase<R>::ZERO);
7253 	      }
7254 	   }
7255 	
7256 	   _rationalLUSolver.clear();
7257 	}
7258 	
7259 	
7260 	/// replaces row \p i with \p lprow and adjusts basis
7261 	template <class R>
7262 	void SoPlexBase<R>::_changeRowReal(int i, const LPRowBase<R>& lprow)
7263 	{
7264 	   assert(_realLP != 0);
7265 	
7266 	   bool scale = _realLP->isScaled();
7267 	   _realLP->changeRow(i, lprow, scale);
7268 	
7269 	   if(_isRealLPLoaded)
7270 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7271 	   else if(_hasBasis)
7272 	   {
7273 	      if(_basisStatusRows[i] != SPxSolverBase<R>::BASIC)
7274 	         _hasBasis = false;
7275 	      else if(_basisStatusRows[i] == SPxSolverBase<R>::ON_LOWER
7276 	              && lprow.lhs() <= -realParam(SoPlexBase<R>::INFTY))
7277 	         _basisStatusRows[i] = (lprow.rhs() < realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_UPPER :
7278 	                               SPxSolverBase<R>::ZERO;
7279 	      else if(_basisStatusRows[i] == SPxSolverBase<R>::ON_UPPER
7280 	              && lprow.rhs() >= realParam(SoPlexBase<R>::INFTY))
7281 	         _basisStatusRows[i] = (lprow.lhs() > -realParam(SoPlexBase<R>::INFTY)) ?
7282 	                               SPxSolverBase<R>::ON_LOWER : SPxSolverBase<R>::ZERO;
7283 	   }
7284 	
7285 	   _rationalLUSolver.clear();
7286 	}
7287 	
7288 	
7289 	
7290 	/// changes left-hand side vector for constraints to \p lhs and adjusts basis
7291 	template <class R>
7292 	void SoPlexBase<R>::_changeLhsReal(const VectorBase<R>& lhs)
7293 	{
7294 	   assert(_realLP != 0);
7295 	
7296 	   bool scale = _realLP->isScaled();
7297 	   _realLP->changeLhs(lhs, scale);
7298 	
7299 	   if(_isRealLPLoaded)
7300 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7301 	   else if(_hasBasis)
7302 	   {
7303 	      for(int i = numRows() - 1; i >= 0; i--)
7304 	      {
7305 	         if(_basisStatusRows[i] == SPxSolverBase<R>::ON_LOWER && lhs[i] <= -realParam(SoPlexBase<R>::INFTY))
7306 	            _basisStatusRows[i] = (rhsReal(i) < realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_UPPER :
7307 	                                  SPxSolverBase<R>::ZERO;
7308 	      }
7309 	   }
7310 	
7311 	   _rationalLUSolver.clear();
7312 	}
7313 	
7314 	/// changes left-hand side of row \p i to \p lhs and adjusts basis
7315 	template <class R>
7316 	void SoPlexBase<R>::_changeLhsReal(int i, const R& lhs)
7317 	{
7318 	   assert(_realLP != 0);
7319 	
7320 	   bool scale = _realLP->isScaled();
7321 	   _realLP->changeLhs(i, lhs, scale);
7322 	
7323 	   if(_isRealLPLoaded)
7324 	   {
7325 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7326 	   }
7327 	   else if(_hasBasis && _basisStatusRows[i] == SPxSolverBase<R>::ON_LOWER
7328 	           && lhs <= -realParam(SoPlexBase<R>::INFTY))
7329 	      _basisStatusRows[i] = (rhsReal(i) < realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_UPPER :
7330 	                            SPxSolverBase<R>::ZERO;
7331 	
7332 	   _rationalLUSolver.clear();
7333 	}
7334 	
7335 	
7336 	
7337 	/// changes right-hand side vector to \p rhs and adjusts basis
7338 	template <class R>
7339 	void SoPlexBase<R>::_changeRhsReal(const VectorBase<R>& rhs)
7340 	{
7341 	   assert(_realLP != 0);
7342 	
7343 	   bool scale = _realLP->isScaled();
7344 	   _realLP->changeRhs(rhs, scale);
7345 	
7346 	   if(_isRealLPLoaded)
7347 	   {
7348 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7349 	   }
7350 	   else if(_hasBasis)
7351 	   {
7352 	      for(int i = numRows() - 1; i >= 0; i--)
7353 	      {
7354 	         if(_basisStatusRows[i] == SPxSolverBase<R>::ON_UPPER && rhs[i] >= realParam(SoPlexBase<R>::INFTY))
7355 	            _basisStatusRows[i] = (lhsReal(i) > -realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_LOWER :
7356 	                                  SPxSolverBase<R>::ZERO;
7357 	      }
7358 	   }
7359 	
7360 	   _rationalLUSolver.clear();
7361 	}
7362 	
7363 	
7364 	
7365 	/// changes right-hand side of row \p i to \p rhs and adjusts basis
7366 	template <class R>
7367 	void SoPlexBase<R>::_changeRhsReal(int i, const R& rhs)
7368 	{
7369 	   assert(_realLP != 0);
7370 	
7371 	   bool scale = _realLP->isScaled();
7372 	   _realLP->changeRhs(i, rhs, scale);
7373 	
7374 	   if(_isRealLPLoaded)
7375 	   {
7376 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7377 	   }
7378 	   else if(_hasBasis && _basisStatusRows[i] == SPxSolverBase<R>::ON_UPPER
7379 	           && rhs >= realParam(SoPlexBase<R>::INFTY))
7380 	      _basisStatusRows[i] = (lhsReal(i) > -realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_LOWER :
7381 	                            SPxSolverBase<R>::ZERO;
7382 	
7383 	   _rationalLUSolver.clear();
7384 	}
7385 	
7386 	
7387 	
7388 	/// changes left- and right-hand side vectors and adjusts basis
7389 	template <class R>
7390 	void SoPlexBase<R>::_changeRangeReal(const VectorBase<R>& lhs, const VectorBase<R>& rhs)
7391 	{
7392 	   assert(_realLP != 0);
7393 	
7394 	   bool scale = _realLP->isScaled();
7395 	   _realLP->changeRange(lhs, rhs, scale);
7396 	
7397 	   if(_isRealLPLoaded)
7398 	   {
7399 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7400 	   }
7401 	   else if(_hasBasis)
7402 	   {
7403 	      for(int i = numRows() - 1; i >= 0; i--)
7404 	      {
7405 	         if(_basisStatusRows[i] == SPxSolverBase<R>::ON_LOWER && lhs[i] <= -realParam(SoPlexBase<R>::INFTY))
7406 	            _basisStatusRows[i] = (rhs[i] < realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_UPPER :
7407 	                                  SPxSolverBase<R>::ZERO;
7408 	         else if(_basisStatusRows[i] == SPxSolverBase<R>::ON_UPPER
7409 	                 && rhs[i] >= realParam(SoPlexBase<R>::INFTY))
7410 	            _basisStatusRows[i] = (lhs[i] > -realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_LOWER :
7411 	                                  SPxSolverBase<R>::ZERO;
7412 	      }
7413 	   }
7414 	
7415 	   _rationalLUSolver.clear();
7416 	}
7417 	
7418 	
7419 	
7420 	/// changes left- and right-hand side of row \p i and adjusts basis
7421 	template <class R>
7422 	void SoPlexBase<R>::_changeRangeReal(int i, const R& lhs, const R& rhs)
7423 	{
7424 	   assert(_realLP != 0);
7425 	
7426 	   bool scale = _realLP->isScaled();
7427 	   _realLP->changeRange(i, lhs, rhs, scale);
7428 	
7429 	   if(_isRealLPLoaded)
7430 	   {
7431 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7432 	   }
7433 	   else if(_hasBasis)
7434 	   {
7435 	      if(_basisStatusRows[i] == SPxSolverBase<R>::ON_LOWER && lhs <= -realParam(SoPlexBase<R>::INFTY))
7436 	         _basisStatusRows[i] = (rhs < realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_UPPER :
7437 	                               SPxSolverBase<R>::ZERO;
7438 	      else if(_basisStatusRows[i] == SPxSolverBase<R>::ON_UPPER && rhs >= realParam(SoPlexBase<R>::INFTY))
7439 	         _basisStatusRows[i] = (lhs > -realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_LOWER :
7440 	                               SPxSolverBase<R>::ZERO;
7441 	   }
7442 	
7443 	   _rationalLUSolver.clear();
7444 	}
7445 	
7446 	
7447 	
7448 	/// replaces column \p i with \p lpcol and adjusts basis
7449 	template <class R>
7450 	void SoPlexBase<R>::_changeColReal(int i, const LPColReal& lpcol)
7451 	{
7452 	   assert(_realLP != 0);
7453 	
7454 	   bool scale = _realLP->isScaled();
7455 	   _realLP->changeCol(i, lpcol, scale);
7456 	
7457 	   if(_isRealLPLoaded)
7458 	   {
7459 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7460 	   }
7461 	   else if(_hasBasis)
7462 	   {
7463 	      if(_basisStatusCols[i] == SPxSolverBase<R>::BASIC)
7464 	         _hasBasis = false;
7465 	      else if(_basisStatusCols[i] == SPxSolverBase<R>::ON_LOWER
7466 	              && lpcol.lower() <= -realParam(SoPlexBase<R>::INFTY))
7467 	         _basisStatusCols[i] = (lpcol.upper() < realParam(SoPlexBase<R>::INFTY)) ?
7468 	                               SPxSolverBase<R>::ON_UPPER : SPxSolverBase<R>::ZERO;
7469 	      else if(_basisStatusCols[i] == SPxSolverBase<R>::ON_UPPER
7470 	              && lpcol.upper() >= realParam(SoPlexBase<R>::INFTY))
7471 	         _basisStatusCols[i] = (lpcol.lower() > -realParam(SoPlexBase<R>::INFTY)) ?
7472 	                               SPxSolverBase<R>::ON_LOWER : SPxSolverBase<R>::ZERO;
7473 	   }
7474 	
7475 	   _rationalLUSolver.clear();
7476 	}
7477 	
7478 	
7479 	
7480 	/// changes vector of lower bounds to \p lower and adjusts basis
7481 	template <class R>
7482 	void SoPlexBase<R>::_changeLowerReal(const VectorBase<R>& lower)
7483 	{
7484 	   assert(_realLP != 0);
7485 	
7486 	   bool scale = _realLP->isScaled();
7487 	   _realLP->changeLower(lower, scale);
7488 	
7489 	   if(_isRealLPLoaded)
7490 	   {
7491 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7492 	   }
7493 	   else if(_hasBasis)
7494 	   {
7495 	      for(int i = numCols() - 1; i >= 0; i--)
7496 	      {
7497 	         if(_basisStatusCols[i] == SPxSolverBase<R>::ON_LOWER
7498 	               && lower[i] <= -realParam(SoPlexBase<R>::INFTY))
7499 	            _basisStatusCols[i] = (upperReal(i) < realParam(SoPlexBase<R>::INFTY)) ?
7500 	                                  SPxSolverBase<R>::ON_UPPER : SPxSolverBase<R>::ZERO;
7501 	      }
7502 	   }
7503 	
7504 	   _rationalLUSolver.clear();
7505 	}
7506 	
7507 	
7508 	
7509 	/// changes lower bound of column i to \p lower and adjusts basis
7510 	template <class R>
7511 	void SoPlexBase<R>::_changeLowerReal(int i, const R& lower)
7512 	{
7513 	   assert(_realLP != 0);
7514 	
7515 	   bool scale = _realLP->isScaled();
7516 	   _realLP->changeLower(i, lower, scale);
7517 	
7518 	   if(_isRealLPLoaded)
7519 	   {
7520 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7521 	   }
7522 	   else if(_hasBasis && _basisStatusCols[i] == SPxSolverBase<R>::ON_LOWER
7523 	           && lower <= -realParam(SoPlexBase<R>::INFTY))
7524 	      _basisStatusCols[i] = (upperReal(i) < realParam(SoPlexBase<R>::INFTY)) ?
7525 	                            SPxSolverBase<R>::ON_UPPER : SPxSolverBase<R>::ZERO;
7526 	
7527 	   _rationalLUSolver.clear();
7528 	}
7529 	
7530 	
7531 	
7532 	/// changes vector of upper bounds to \p upper and adjusts basis
7533 	template <class R>
7534 	void SoPlexBase<R>::_changeUpperReal(const VectorBase<R>& upper)
7535 	{
7536 	   assert(_realLP != 0);
7537 	
7538 	   bool scale = _realLP->isScaled();
7539 	   _realLP->changeUpper(upper, scale);
7540 	
7541 	   if(_isRealLPLoaded)
7542 	   {
7543 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7544 	   }
7545 	   else if(_hasBasis)
7546 	   {
7547 	      for(int i = numCols() - 1; i >= 0; i--)
7548 	      {
7549 	         if(_basisStatusCols[i] == SPxSolverBase<R>::ON_UPPER && upper[i] >= realParam(SoPlexBase<R>::INFTY))
7550 	            _basisStatusCols[i] = (lowerReal(i) > -realParam(SoPlexBase<R>::INFTY)) ?
7551 	                                  SPxSolverBase<R>::ON_LOWER : SPxSolverBase<R>::ZERO;
7552 	      }
7553 	   }
7554 	
7555 	   _rationalLUSolver.clear();
7556 	}
7557 	
7558 	
7559 	
7560 	/// changes \p i 'th upper bound to \p upper and adjusts basis
7561 	template <class R>
7562 	void SoPlexBase<R>::_changeUpperReal(int i, const R& upper)
7563 	{
7564 	   assert(_realLP != 0);
7565 	
7566 	   bool scale = _realLP->isScaled();
7567 	   _realLP->changeUpper(i, upper, scale);
7568 	
7569 	   if(_isRealLPLoaded)
7570 	   {
7571 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7572 	   }
7573 	   else if(_hasBasis &&  _basisStatusCols[i] == SPxSolverBase<R>::ON_UPPER
7574 	           && upper >= realParam(SoPlexBase<R>::INFTY))
7575 	      _basisStatusCols[i] = (lowerReal(i) > -realParam(SoPlexBase<R>::INFTY)) ?
7576 	                            SPxSolverBase<R>::ON_LOWER : SPxSolverBase<R>::ZERO;
7577 	
7578 	   _rationalLUSolver.clear();
7579 	}
7580 	
7581 	
7582 	
7583 	/// changes vectors of column bounds to \p lower and \p upper and adjusts basis
7584 	template <class R>
7585 	void SoPlexBase<R>::_changeBoundsReal(const VectorBase<R>& lower, const VectorBase<R>& upper)
7586 	{
7587 	   assert(_realLP != 0);
7588 	
7589 	   bool scale = _realLP->isScaled();
7590 	   _realLP->changeBounds(lower, upper, scale);
7591 	
7592 	   if(_isRealLPLoaded)
7593 	   {
7594 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7595 	   }
7596 	   else if(_hasBasis)
7597 	   {
7598 	      for(int i = numCols() - 1; i >= 0; i--)
7599 	      {
7600 	         if(_basisStatusCols[i] == SPxSolverBase<R>::ON_LOWER
7601 	               && lower[i] <= -realParam(SoPlexBase<R>::INFTY))
7602 	            _basisStatusCols[i] = (upper[i] < realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_UPPER :
7603 	                                  SPxSolverBase<R>::ZERO;
7604 	         else if(_basisStatusCols[i] == SPxSolverBase<R>::ON_UPPER
7605 	                 && upper[i] >= realParam(SoPlexBase<R>::INFTY))
7606 	            _basisStatusCols[i] = (lower[i] > -realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_LOWER :
7607 	                                  SPxSolverBase<R>::ZERO;
7608 	      }
7609 	   }
7610 	
7611 	   _rationalLUSolver.clear();
7612 	}
7613 	
7614 	
7615 	
7616 	/// changes bounds of column \p i to \p lower and \p upper and adjusts basis
7617 	template <class R>
7618 	void SoPlexBase<R>::_changeBoundsReal(int i, const R& lower, const R& upper)
7619 	{
7620 	   assert(_realLP != 0);
7621 	
7622 	   bool scale = _realLP->isScaled();
7623 	   _realLP->changeBounds(i, lower, upper, scale);
7624 	
7625 	   if(_isRealLPLoaded)
7626 	   {
7627 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7628 	   }
7629 	   else if(_hasBasis)
7630 	   {
7631 	      if(_basisStatusCols[i] == SPxSolverBase<R>::ON_LOWER && lower <= -realParam(SoPlexBase<R>::INFTY))
7632 	         _basisStatusCols[i] = (upper < realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_UPPER :
7633 	                               SPxSolverBase<R>::ZERO;
7634 	      else if(_basisStatusCols[i] == SPxSolverBase<R>::ON_UPPER
7635 	              && upper >= realParam(SoPlexBase<R>::INFTY))
7636 	         _basisStatusCols[i] = (lower > -realParam(SoPlexBase<R>::INFTY)) ? SPxSolverBase<R>::ON_LOWER :
7637 	                               SPxSolverBase<R>::ZERO;
7638 	   }
7639 	
7640 	   _rationalLUSolver.clear();
7641 	}
7642 	
7643 	
7644 	
7645 	/// changes matrix entry in row \p i and column \p j to \p val and adjusts basis
7646 	template <class R>
7647 	void SoPlexBase<R>::_changeElementReal(int i, int j, const R& val)
7648 	{
7649 	   assert(_realLP != 0);
7650 	
7651 	   bool scale = _realLP->isScaled();
7652 	   _realLP->changeElement(i, j, val, scale);
7653 	
7654 	   if(_isRealLPLoaded)
7655 	   {
7656 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7657 	   }
7658 	   else if(_hasBasis)
7659 	   {
7660 	      if(_basisStatusRows[i] != SPxSolverBase<R>::BASIC && _basisStatusCols[i] == SPxSolverBase<R>::BASIC)
7661 	         _hasBasis = false;
7662 	   }
7663 	
7664 	   _rationalLUSolver.clear();
7665 	}
7666 	
7667 	
7668 	
7669 	/// removes row \p i and adjusts basis
7670 	template <class R>
7671 	void SoPlexBase<R>::_removeRowReal(int i)
7672 	{
7673 	   assert(_realLP != 0);
7674 	
7675 	   _realLP->removeRow(i);
7676 	
7677 	   if(_isRealLPLoaded)
7678 	   {
7679 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7680 	   }
7681 	   else if(_hasBasis)
7682 	   {
7683 	      if(_basisStatusRows[i] != SPxSolverBase<R>::BASIC)
7684 	         _hasBasis = false;
7685 	      else
7686 	      {
7687 	         _basisStatusRows[i] = _basisStatusRows[_basisStatusRows.size() - 1];
7688 	         _basisStatusRows.removeLast();
7689 	      }
7690 	   }
7691 	
7692 	   _rationalLUSolver.clear();
7693 	}
7694 	
7695 	
7696 	
7697 	/// removes all rows with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
7698 	/// new index where row \p i has been moved to; note that \p perm must point to an array of size at least
7699 	/// #numRows()
7700 	template <class R>
7701 	void SoPlexBase<R>::_removeRowsReal(int perm[])
7702 	{
7703 	   assert(_realLP != 0);
7704 	
7705 	   _realLP->removeRows(perm);
7706 	
7707 	   if(_isRealLPLoaded)
7708 	   {
7709 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7710 	   }
7711 	   else if(_hasBasis)
7712 	   {
7713 	      for(int i = numRows() - 1; i >= 0 && _hasBasis; i--)
7714 	      {
7715 	         if(perm[i] < 0 && _basisStatusRows[i] != SPxSolverBase<R>::BASIC)
7716 	            _hasBasis = false;
7717 	         else if(perm[i] >= 0 && perm[i] != i)
7718 	         {
7719 	            assert(perm[i] < numRows());
7720 	            assert(perm[perm[i]] < 0);
7721 	
7722 	            _basisStatusRows[perm[i]] = _basisStatusRows[i];
7723 	         }
7724 	      }
7725 	
7726 	      if(_hasBasis)
7727 	         _basisStatusRows.reSize(numRows());
7728 	   }
7729 	
7730 	   _rationalLUSolver.clear();
7731 	}
7732 	
7733 	
7734 	
7735 	/// removes column i
7736 	template <class R>
7737 	void SoPlexBase<R>::_removeColReal(int i)
7738 	{
7739 	   assert(_realLP != 0);
7740 	
7741 	   _realLP->removeCol(i);
7742 	
7743 	   if(_isRealLPLoaded)
7744 	   {
7745 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7746 	   }
7747 	   else if(_hasBasis)
7748 	   {
7749 	      if(_basisStatusCols[i] == SPxSolverBase<R>::BASIC)
7750 	         _hasBasis = false;
7751 	      else
7752 	      {
7753 	         _basisStatusCols[i] = _basisStatusCols[_basisStatusCols.size() - 1];
7754 	         _basisStatusCols.removeLast();
7755 	      }
7756 	   }
7757 	
7758 	   _rationalLUSolver.clear();
7759 	}
7760 	
7761 	
7762 	
7763 	/// removes all columns with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
7764 	/// new index where column \p i has been moved to; note that \p perm must point to an array of size at least
7765 	/// #numCols()
7766 	template <class R>
7767 	void SoPlexBase<R>::_removeColsReal(int perm[])
7768 	{
7769 	   assert(_realLP != 0);
7770 	
7771 	   _realLP->removeCols(perm);
7772 	
7773 	   if(_isRealLPLoaded)
7774 	   {
7775 	      _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7776 	   }
7777 	   else if(_hasBasis)
7778 	   {
7779 	      for(int i = numCols() - 1; i >= 0 && _hasBasis; i--)
7780 	      {
7781 	         if(perm[i] < 0 && _basisStatusCols[i] == SPxSolverBase<R>::BASIC)
7782 	            _hasBasis = false;
7783 	         else if(perm[i] >= 0 && perm[i] != i)
7784 	         {
7785 	            assert(perm[i] < numCols());
7786 	            assert(perm[perm[i]] < 0);
7787 	
7788 	            _basisStatusCols[perm[i]] = _basisStatusCols[i];
7789 	         }
7790 	      }
7791 	
7792 	      if(_hasBasis)
7793 	         _basisStatusCols.reSize(numCols());
7794 	   }
7795 	
7796 	   _rationalLUSolver.clear();
7797 	}
7798 	
7799 	
7800 	
7801 	/// invalidates solution
7802 	template <class R>
7803 	void SoPlexBase<R>::_invalidateSolution()
7804 	{
7805 	   ///@todo maybe this should be done individually at the places when this method is called
7806 	   _status = SPxSolverBase<R>::UNKNOWN;
7807 	
7808 	   _solReal.invalidate();
7809 	   _hasSolReal = false;
7810 	
7811 	   _solRational.invalidate();
7812 	   _hasSolRational = false;
7813 	}
7814 	
7815 	
7816 	
7817 	/// enables simplifier and scaler
7818 	template <class R>
7819 	void SoPlexBase<R>::_enableSimplifierAndScaler()
7820 	{
7821 	   // type of simplifier
7822 	   switch(intParam(SoPlexBase<R>::SIMPLIFIER))
7823 	   {
7824 	   case SIMPLIFIER_OFF:
7825 	      _simplifier = 0;
7826 	      break;
7827 	
7828 	   case SIMPLIFIER_AUTO:
7829 	   case SIMPLIFIER_INTERNAL:
7830 	      _simplifier = &_simplifierMainSM;
7831 	      assert(_simplifier != 0);
7832 	      _simplifier->setMinReduction(realParam(MINRED));
7833 	      break;
7834 	
7835 	   case SIMPLIFIER_PAPILO:
7836 	#ifdef SOPLEX_WITH_PAPILO
7837 	      _simplifier = &_simplifierPaPILO;
7838 	      assert(_simplifier != 0);
7839 	#else
7840 	      _simplifier = &_simplifierMainSM;
7841 	      assert(_simplifier != 0);
7842 	      _simplifier->setMinReduction(realParam(MINRED));
7843 	#endif
7844 	      break;
7845 	
7846 	   default:
7847 	      break;
7848 	   }
7849 	
7850 	   // type of scaler
7851 	   switch(intParam(SoPlexBase<R>::SCALER))
7852 	   {
7853 	   case SCALER_OFF:
7854 	      _scaler = 0;
7855 	      break;
7856 	
7857 	   case SCALER_UNIEQUI:
7858 	      _scaler = &_scalerUniequi;
7859 	      break;
7860 	
7861 	   case SCALER_BIEQUI:
7862 	      _scaler = &_scalerBiequi;
7863 	      break;
7864 	
7865 	   case SCALER_GEO1:
7866 	      _scaler = &_scalerGeo1;
7867 	      break;
7868 	
7869 	   case SCALER_GEO8:
7870 	      _scaler = &_scalerGeo8;
7871 	      break;
7872 	
7873 	   case SCALER_LEASTSQ:
7874 	      _scaler = &_scalerLeastsq;
7875 	      break;
7876 	
7877 	   case SCALER_GEOEQUI:
7878 	      _scaler = &_scalerGeoequi;
7879 	      break;
7880 	
7881 	   default:
7882 	      break;
7883 	   }
7884 	}
7885 	
7886 	
7887 	
7888 	/// disables simplifier and scaler
7889 	template <class R>
7890 	void SoPlexBase<R>::_disableSimplifierAndScaler()
7891 	{
7892 	   _simplifier = 0;
7893 	
7894 	   // preserve scaler when persistent scaling is used
7895 	   if(!_isRealLPScaled)
7896 	      _scaler = 0;
7897 	   else
7898 	      assert(boolParam(SoPlexBase<R>::PERSISTENTSCALING));
7899 	}
7900 	
7901 	
7902 	
7903 	/// ensures that the rational LP is available; performs no sync
7904 	template <class R>
7905 	void SoPlexBase<R>::_ensureRationalLP()
7906 	{
7907 	   if(_rationalLP == 0)
7908 	   {
7909 	      spx_alloc(_rationalLP);
7910 	      _rationalLP = new(_rationalLP) SPxLPRational();
7911 	      _rationalLP->setOutstream(spxout);
7912 	   }
7913 	}
7914 	
7915 	
7916 	
7917 	/// ensures that the R LP and the basis are loaded in the solver; performs no sync
7918 	template <class R>
7919 	void SoPlexBase<R>::_ensureRealLPLoaded()
7920 	{
7921 	   if(!_isRealLPLoaded)
7922 	   {
7923 	      assert(_realLP != &_solver);
7924 	
7925 	      _solver.loadLP(*_realLP);
7926 	      _realLP->~SPxLPBase<R>();
7927 	      spx_free(_realLP);
7928 	      _realLP = &_solver;
7929 	      _isRealLPLoaded = true;
7930 	
7931 	      if(_hasBasis)
7932 	      {
7933 	         ///@todo this should not fail even if the basis is invalid (wrong dimension or wrong number of basic
7934 	         ///      entries); fix either in SPxSolverBase or in SPxBasisBase
7935 	         assert(_basisStatusRows.size() == numRows());
7936 	         assert(_basisStatusCols.size() == numCols());
7937 	         _solver.setBasis(_basisStatusRows.get_const_ptr(), _basisStatusCols.get_const_ptr());
7938 	         _hasBasis = (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM);
7939 	      }
7940 	   }
7941 	}
7942 	
7943 	
7944 	
7945 	/// call floating-point solver and update statistics on iterations etc.
7946 	template <class R>
7947 	void SoPlexBase<R>::_solveRealLPAndRecordStatistics(volatile bool* interrupt)
7948 	{
7949 	   bool _hadBasis = _hasBasis;
7950 	
7951 	   // set time and iteration limit
7952 	   if(intParam(SoPlexBase<R>::ITERLIMIT) < realParam(SoPlexBase<R>::INFTY))
7953 	      _solver.setTerminationIter(intParam(SoPlexBase<R>::ITERLIMIT) - _statistics->iterations);
7954 	   else
7955 	      _solver.setTerminationIter(-1);
7956 	
7957 	   if(realParam(SoPlexBase<R>::TIMELIMIT) < realParam(SoPlexBase<R>::INFTY))
7958 	      _solver.setTerminationTime(Real(realParam(SoPlexBase<R>::TIMELIMIT)) -
7959 	                                 _statistics->solvingTime->time());
7960 	   else
7961 	      _solver.setTerminationTime(Real(realParam(SoPlexBase<R>::INFTY)));
7962 	
7963 	   // ensure that tolerances are not too small
7964 	   if(_solver.feastol() < 1e-12)
7965 	      _solver.setFeastol(1e-12);
7966 	
7967 	   if(_solver.opttol() < 1e-12)
7968 	      _solver.setOpttol(1e-12);
7969 	
7970 	   // set correct representation
7971 	   if((intParam(SoPlexBase<R>::REPRESENTATION) == SoPlexBase<R>::REPRESENTATION_COLUMN
7972 	         || (intParam(SoPlexBase<R>::REPRESENTATION) == SoPlexBase<R>::REPRESENTATION_AUTO
7973 	             && (_solver.nCols() + 1) * realParam(SoPlexBase<R>::REPRESENTATION_SWITCH) >=
7974 	             (_solver.nRows() + 1)))
7975 	         && _solver.rep() != SPxSolverBase<R>::COLUMN)
7976 	   {
7977 	      _solver.setRep(SPxSolverBase<R>::COLUMN);
7978 	   }
7979 	   else if((intParam(SoPlexBase<R>::REPRESENTATION) == SoPlexBase<R>::REPRESENTATION_ROW
7980 	            || (intParam(SoPlexBase<R>::REPRESENTATION) == SoPlexBase<R>::REPRESENTATION_AUTO
7981 	                && (_solver.nCols() + 1) * realParam(SoPlexBase<R>::REPRESENTATION_SWITCH) < (_solver.nRows() + 1)))
7982 	           && _solver.rep() != SPxSolverBase<R>::ROW)
7983 	   {
7984 	      _solver.setRep(SPxSolverBase<R>::ROW);
7985 	   }
7986 	
7987 	   // set correct type
7988 	   if(((intParam(ALGORITHM) == SoPlexBase<R>::ALGORITHM_PRIMAL
7989 	         && _solver.rep() == SPxSolverBase<R>::COLUMN)
7990 	         || (intParam(ALGORITHM) == SoPlexBase<R>::ALGORITHM_DUAL && _solver.rep() == SPxSolverBase<R>::ROW))
7991 	         && _solver.type() != SPxSolverBase<R>::ENTER)
7992 	   {
7993 	      _solver.setType(SPxSolverBase<R>::ENTER);
7994 	   }
7995 	   else if(((intParam(ALGORITHM) == SoPlexBase<R>::ALGORITHM_DUAL
7996 	             && _solver.rep() == SPxSolverBase<R>::COLUMN)
7997 	            || (intParam(ALGORITHM) == SoPlexBase<R>::ALGORITHM_PRIMAL
7998 	                && _solver.rep() == SPxSolverBase<R>::ROW))
7999 	           && _solver.type() != SPxSolverBase<R>::LEAVE)
8000 	   {
8001 	      _solver.setType(SPxSolverBase<R>::LEAVE);
8002 	   }
8003 	
8004 	   // set pricing modes
8005 	   _solver.setSparsePricingFactor(realParam(SoPlexBase<R>::SPARSITY_THRESHOLD));
8006 	
8007 	   if((intParam(SoPlexBase<R>::HYPER_PRICING) == SoPlexBase<R>::HYPER_PRICING_ON)
8008 	         || ((intParam(SoPlexBase<R>::HYPER_PRICING) == SoPlexBase<R>::HYPER_PRICING_AUTO)
8009 	             && (_solver.nRows() + _solver.nCols() > HYPERPRICINGTHRESHOLD)))
8010 	      _solver.hyperPricing(true);
8011 	   else if(intParam(SoPlexBase<R>::HYPER_PRICING) == SoPlexBase<R>::HYPER_PRICING_OFF)
8012 	      _solver.hyperPricing(false);
8013 	
8014 	   _solver.setNonzeroFactor(realParam(SoPlexBase<R>::REFAC_BASIS_NNZ));
8015 	   _solver.setFillFactor(realParam(SoPlexBase<R>::REFAC_UPDATE_FILL));
8016 	   _solver.setMemFactor(realParam(SoPlexBase<R>::REFAC_MEM_FACTOR));
8017 	
8018 	   // call floating-point solver and catch exceptions
8019 	   _statistics->simplexTime->start();
8020 	
8021 	   try
8022 	   {
8023 	      _solver.solve(interrupt);
8024 	   }
8025 	   catch(const SPxException& E)
8026 	   {
8027 	      MSG_INFO1(spxout, spxout << "Caught exception <" << E.what() << "> while solving Real LP.\n");
8028 	      _status = SPxSolverBase<R>::ERROR;
8029 	   }
8030 	   catch(...)
8031 	   {
8032 	      MSG_INFO1(spxout, spxout << "Caught unknown exception while solving Real LP.\n");
8033 	      _status = SPxSolverBase<R>::ERROR;
8034 	   }
8035 	
8036 	   _statistics->simplexTime->stop();
8037 	
8038 	   // invalidate rational factorization of basis if pivots have been performed
8039 	   if(_solver.iterations() > 0)
8040 	      _rationalLUSolver.clear();
8041 	
8042 	   // record statistics
8043 	   _statistics->iterations += _solver.iterations();
8044 	   _statistics->iterationsPrimal += _solver.primalIterations();
8045 	   _statistics->iterationsFromBasis += _hadBasis ? _solver.iterations() : 0;
8046 	   _statistics->iterationsPolish += _solver.polishIterations();
8047 	   _statistics->boundflips += _solver.boundFlips();
8048 	   _statistics->multTimeSparse += _solver.multTimeSparse->time();
8049 	   _statistics->multTimeFull += _solver.multTimeFull->time();
8050 	   _statistics->multTimeColwise += _solver.multTimeColwise->time();
8051 	   _statistics->multTimeUnsetup += _solver.multTimeUnsetup->time();
8052 	   _statistics->multSparseCalls += _solver.multSparseCalls;
8053 	   _statistics->multFullCalls += _solver.multFullCalls;
8054 	   _statistics->multColwiseCalls += _solver.multColwiseCalls;
8055 	   _statistics->multUnsetupCalls += _solver.multUnsetupCalls;
8056 	   _statistics->luFactorizationTimeReal += _slufactor.getFactorTime();
8057 	   _statistics->luSolveTimeReal += _slufactor.getSolveTime();
8058 	   _statistics->luFactorizationsReal += _slufactor.getFactorCount();
8059 	   _statistics->luSolvesReal += _slufactor.getSolveCount();
8060 	   _slufactor.resetCounters();
8061 	
8062 	   _statistics->degenPivotsPrimal += _solver.primalDegeneratePivots();
8063 	   _statistics->degenPivotsDual += _solver.dualDegeneratePivots();
8064 	   _statistics->sumDualDegen += _solver.sumDualDegeneracy();
8065 	   _statistics->sumPrimalDegen += _solver.sumPrimalDegeneracy();
8066 	}
8067 	
8068 	
8069 	
8070 	/// reads R LP in LP or MPS format from file and returns true on success; gets row names, column names, and
8071 	/// integer variables if desired
8072 	template <class R>
8073 	bool SoPlexBase<R>::_readFileReal(const char* filename, NameSet* rowNames, NameSet* colNames,
8074 	                                  DIdxSet* intVars)
8075 	{
8076 	   assert(_realLP != 0);
8077 	
8078 	   // clear statistics
8079 	   _statistics->clearAllData();
8080 	
8081 	   // update status
8082 	   clearBasis();
8083 	   _invalidateSolution();
8084 	   _status = SPxSolverBase<R>::UNKNOWN;
8085 	
8086 	   // start timing
8087 	   _statistics->readingTime->start();
8088 	
8089 	   // read
8090 	   bool success = _realLP->readFile(filename, rowNames, colNames, intVars);
8091 	
8092 	   // stop timing
8093 	   _statistics->readingTime->stop();
8094 	
8095 	   if(success)
8096 	   {
8097 	      setIntParam(SoPlexBase<R>::OBJSENSE,
8098 	                  (_realLP->spxSense() == SPxLPBase<R>::MAXIMIZE ? SoPlexBase<R>::OBJSENSE_MAXIMIZE :
8099 	                   SoPlexBase<R>::OBJSENSE_MINIMIZE), true);
8100 	      _realLP->changeObjOffset(realParam(SoPlexBase<R>::OBJ_OFFSET));
8101 	
8102 	      // if sync mode is auto, we have to copy the (rounded) R LP to the rational LP; this is counted to sync time
8103 	      // and not to reading time
8104 	      if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
8105 	         _syncLPRational();
8106 	   }
8107 	   else
8108 	      clearLPReal();
8109 	
8110 	   return success;
8111 	}
8112 	
8113 	
8114 	
8115 	/// reads rational LP in LP or MPS format from file and returns true on success; gets row names, column names, and
8116 	/// integer variables if desired
8117 	template <class R>
8118 	bool SoPlexBase<R>::_readFileRational(const char* filename, NameSet* rowNames, NameSet* colNames,
8119 	                                      DIdxSet* intVars)
8120 	{
8121 	   // clear statistics
8122 	   _statistics->clearAllData();
8123 	
8124 	   // start timing
8125 	   _statistics->readingTime->start();
8126 	
8127 	   // update status
8128 	   clearBasis();
8129 	   _invalidateSolution();
8130 	   _status = SPxSolverBase<R>::UNKNOWN;
8131 	
8132 	   // read
8133 	   _ensureRationalLP();
8134 	   bool success = _rationalLP->readFile(filename, rowNames, colNames, intVars);
8135 	
8136 	   // stop timing
8137 	   _statistics->readingTime->stop();
8138 	
8139 	   if(success)
8140 	   {
8141 	      setIntParam(SoPlexBase<R>::OBJSENSE,
8142 	                  (_rationalLP->spxSense() == SPxLPRational::MAXIMIZE ? SoPlexBase<R>::OBJSENSE_MAXIMIZE :
8143 	                   SoPlexBase<R>::OBJSENSE_MINIMIZE), true);
8144 	      _rationalLP->changeObjOffset(realParam(SoPlexBase<R>::OBJ_OFFSET));
8145 	      _recomputeRangeTypesRational();
8146 	
8147 	      // if sync mode is auto, we have to copy the (rounded) R LP to the rational LP; this is counted to sync time
8148 	      // and not to reading time
8149 	      if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_AUTO)
8150 	         _syncLPReal();
8151 	      // if a rational LP file is read, but only the (rounded) R LP should be kept, we have to free the rational LP
8152 	      else if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
8153 	      {
8154 	         _syncLPReal();
8155 	         _rationalLP->~SPxLPRational();
8156 	         spx_free(_rationalLP);
8157 	      }
8158 	   }
8159 	   else
8160 	      clearLPRational();
8161 	
8162 	   return success;
8163 	}
8164 	
8165 	
8166 	
8167 	/// completes range type arrays after adding columns and/or rows
8168 	template <class R>
8169 	void SoPlexBase<R>::_completeRangeTypesRational()
8170 	{
8171 	   // we use one method for bot columns and rows, because during column/row addition, rows/columns can be added
8172 	   // implicitly
8173 	   for(int i = _colTypes.size(); i < numColsRational(); i++)
8174 	      _colTypes.append(_rangeTypeRational(_rationalLP->lower(i), _rationalLP->upper(i)));
8175 	
8176 	   for(int i = _rowTypes.size(); i < numRowsRational(); i++)
8177 	      _rowTypes.append(_rangeTypeRational(_rationalLP->lhs(i), _rationalLP->rhs(i)));
8178 	}
8179 	
8180 	
8181 	
8182 	/// recomputes range types from scratch using R LP
8183 	template <class R>
8184 	void SoPlexBase<R>::_recomputeRangeTypesReal()
8185 	{
8186 	   _rowTypes.reSize(numRows());
8187 	
8188 	   for(int i = 0; i < numRows(); i++)
8189 	      _rowTypes[i] = _rangeTypeReal(_realLP->lhs(i), _realLP->rhs(i));
8190 	
8191 	   _colTypes.reSize(numCols());
8192 	
8193 	   for(int i = 0; i < numCols(); i++)
8194 	      _colTypes[i] = _rangeTypeReal(_realLP->lower(i), _realLP->upper(i));
8195 	}
8196 	
8197 	
8198 	
8199 	/// recomputes range types from scratch using rational LP
8200 	template <class R>
8201 	void SoPlexBase<R>::_recomputeRangeTypesRational()
8202 	{
8203 	   _rowTypes.reSize(numRowsRational());
8204 	
8205 	   for(int i = 0; i < numRowsRational(); i++)
8206 	      _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), _rationalLP->rhs(i));
8207 	
8208 	   _colTypes.reSize(numColsRational());
8209 	
8210 	   for(int i = 0; i < numColsRational(); i++)
8211 	      _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), _rationalLP->upper(i));
8212 	}
8213 	
8214 	
8215 	
8216 	/// synchronizes R LP with rational LP, i.e., copies (rounded) rational LP into R LP, without looking at the sync mode
8217 	template <class R>
8218 	void SoPlexBase<R>::_syncLPReal(bool time)
8219 	{
8220 	   // start timing
8221 	   if(time)
8222 	      _statistics->syncTime->start();
8223 	
8224 	   // copy LP
8225 	   if(_isRealLPLoaded)
8226 	      _solver.loadLP((SPxLPBase<R>)(*_rationalLP));
8227 	   else
8228 	      *_realLP = *_rationalLP;
8229 	
8230 	   ///@todo try loading old basis
8231 	   _hasBasis = false;
8232 	   _rationalLUSolver.clear();
8233 	
8234 	   // stop timing
8235 	   if(time)
8236 	      _statistics->syncTime->stop();
8237 	}
8238 	
8239 	
8240 	
8241 	/// synchronizes rational LP with R LP, i.e., copies R LP to rational LP, without looking at the sync mode
8242 	template <class R>
8243 	void SoPlexBase<R>::_syncLPRational(bool time)
8244 	{
8245 	   // start timing
8246 	   if(time)
8247 	      _statistics->syncTime->start();
8248 	
8249 	   // copy LP
8250 	   _ensureRationalLP();
8251 	   *_rationalLP = *_realLP;
8252 	   _recomputeRangeTypesRational();
8253 	
8254 	   // stop timing
8255 	   if(time)
8256 	      _statistics->syncTime->stop();
8257 	}
8258 	
8259 	
8260 	
8261 	/// synchronizes rational solution with R solution, i.e., copies (rounded) rational solution to R solution
8262 	template <class R>
8263 	void SoPlexBase<R>::_syncRealSolution()
8264 	{
8265 	   if(_hasSolRational && !_hasSolReal)
8266 	   {
8267 	      _solReal = _solRational;
8268 	      _hasSolReal = true;
8269 	   }
8270 	}
8271 	
8272 	
8273 	
8274 	/// synchronizes R solution with rational solution, i.e., copies R solution to rational solution
8275 	template <class R>
8276 	void SoPlexBase<R>::_syncRationalSolution()
8277 	{
8278 	   if(_hasSolReal && !_hasSolRational)
8279 	   {
8280 	      _solRational = _solReal;
8281 	      _hasSolRational = true;
8282 	   }
8283 	}
8284 	
8285 	
8286 	
8287 	/// returns pointer to a constant unit vector available until destruction of the SoPlexBase class
8288 	template <class R>
8289 	const UnitVectorRational* SoPlexBase<R>::_unitVectorRational(const int i)
8290 	{
8291 	   assert(i >= 0);
8292 	
8293 	   if(i < 0)
8294 	      return 0;
8295 	   else if(i >= _unitMatrixRational.size())
8296 	      _unitMatrixRational.append(i + 1 - _unitMatrixRational.size(), (UnitVectorRational*)0);
8297 	
8298 	   assert(i < _unitMatrixRational.size());
8299 	
8300 	   if(_unitMatrixRational[i] == 0)
8301 	   {
8302 	      spx_alloc(_unitMatrixRational[i]);
8303 	      new(_unitMatrixRational[i]) UnitVectorRational(i);
8304 	   }
8305 	
8306 	   assert(_unitMatrixRational[i] != 0);
8307 	
8308 	   return _unitMatrixRational[i];
8309 	}
8310 	
8311 	
8312 	
8313 	/// parses one line in a settings file and returns true on success; note that the string is modified
8314 	template <class R>
8315 	bool SoPlexBase<R>::_parseSettingsLine(char* line, const int lineNumber)
8316 	{
8317 	   assert(line != 0);
8318 	
8319 	   // find the start of the parameter type
8320 	   while(*line == ' ' || *line == '\t' || *line == '\r')
8321 	      line++;
8322 	
8323 	   if(*line == '\0' || *line == '\n' || *line == '#')
8324 	      return true;
8325 	
8326 	   char* paramTypeString = line;
8327 	
8328 	   // find the end of the parameter type
8329 	   while(*line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#'
8330 	         && *line != '\0' && *line != ':')
8331 	      line++;
8332 	
8333 	   if(*line == ':')
8334 	   {
8335 	      *line = '\0';
8336 	      line++;
8337 	   }
8338 	   else
8339 	   {
8340 	      *line = '\0';
8341 	      line++;
8342 	
8343 	      // search for the ':' char in the line
8344 	      while(*line == ' ' || *line == '\t' || *line == '\r')
8345 	         line++;
8346 	
8347 	      if(*line != ':')
8348 	      {
8349 	         MSG_INFO1(spxout, spxout <<
8350 	                   "Error parsing settings file: no ':' separating parameter type and name in line " << lineNumber <<
8351 	                   ".\n");
8352 	         return false;
8353 	      }
8354 	
8355 	      line++;
8356 	   }
8357 	
8358 	   // find the start of the parameter name
8359 	   while(*line == ' ' || *line == '\t' || *line == '\r')
8360 	      line++;
8361 	
8362 	   if(*line == '\0' || *line == '\n' || *line == '#')
8363 	   {
8364 	      MSG_INFO1(spxout, spxout << "Error parsing settings file: no parameter name in line " << lineNumber
8365 	                << ".\n");
8366 	      return false;
8367 	   }
8368 	
8369 	   char* paramName = line;
8370 	
8371 	   // find the end of the parameter name
8372 	   while(*line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#'
8373 	         && *line != '\0' && *line != '=')
8374 	      line++;
8375 	
8376 	   if(*line == '=')
8377 	   {
8378 	      *line = '\0';
8379 	      line++;
8380 	   }
8381 	   else
8382 	   {
8383 	      *line = '\0';
8384 	      line++;
8385 	
8386 	      // search for the '=' char in the line
8387 	      while(*line == ' ' || *line == '\t' || *line == '\r')
8388 	         line++;
8389 	
8390 	      if(*line != '=')
8391 	      {
8392 	         MSG_INFO1(spxout, spxout << "Error parsing settings file: no '=' after parameter name in line " <<
8393 	                   lineNumber << ".\n");
8394 	         return false;
8395 	      }
8396 	
8397 	      line++;
8398 	   }
8399 	
8400 	   // find the start of the parameter value string
8401 	   while(*line == ' ' || *line == '\t' || *line == '\r')
8402 	      line++;
8403 	
8404 	   if(*line == '\0' || *line == '\n' || *line == '#')
8405 	   {
8406 	      MSG_INFO1(spxout, spxout << "Error parsing settings file: no parameter value in line " << lineNumber
8407 	                << ".\n");
8408 	      return false;
8409 	   }
8410 	
8411 	   char* paramValueString = line;
8412 	
8413 	   // find the end of the parameter value string
8414 	   while(*line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#'
8415 	         && *line != '\0')
8416 	      line++;
8417 	
8418 	   if(*line != '\0')
8419 	   {
8420 	      // check, if the rest of the line is clean
8421 	      *line = '\0';
8422 	      line++;
8423 	
8424 	      while(*line == ' ' || *line == '\t' || *line == '\r')
8425 	         line++;
8426 	
8427 	      if(*line != '\0' && *line != '\n' && *line != '#')
8428 	      {
8429 	         MSG_INFO1(spxout, spxout << "Error parsing settings file: additional character '" << *line <<
8430 	                   "' after parameter value in line " << lineNumber << ".\n");
8431 	         return false;
8432 	      }
8433 	   }
8434 	
8435 	   // check whether we have a bool parameter
8436 	   if(strncmp(paramTypeString, "bool", 4) == 0)
8437 	   {
8438 	      for(int param = 0; ; param++)
8439 	      {
8440 	         if(param >= SoPlexBase<R>::BOOLPARAM_COUNT)
8441 	         {
8442 	            MSG_INFO1(spxout, spxout << "Error parsing settings file: unknown parameter name <" << paramName <<
8443 	                      "> in line " << lineNumber << ".\n");
8444 	            return false;
8445 	         }
8446 	         else if(strncmp(paramName, _currentSettings->boolParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0)
8447 	         {
8448 	            if(strncasecmp(paramValueString, "true", 4) == 0
8449 	                  || strncasecmp(paramValueString, "TRUE", 4) == 0
8450 	                  || strncasecmp(paramValueString, "t", 4) == 0
8451 	                  || strncasecmp(paramValueString, "T", 4) == 0
8452 	                  || strtol(paramValueString, NULL, 4) == 1)
8453 	            {
8454 	               setBoolParam((SoPlexBase<R>::BoolParam)param, true);
8455 	               break;
8456 	            }
8457 	            else if(strncasecmp(paramValueString, "false", 5) == 0
8458 	                    || strncasecmp(paramValueString, "FALSE", 5) == 0
8459 	                    || strncasecmp(paramValueString, "f", 5) == 0
8460 	                    || strncasecmp(paramValueString, "F", 5) == 0
8461 	                    || strtol(paramValueString, NULL, 5) == 0)
8462 	            {
8463 	               setBoolParam((SoPlexBase<R>::BoolParam)param, false);
8464 	               break;
8465 	            }
8466 	            else
8467 	            {
8468 	               MSG_INFO1(spxout, spxout << "Error parsing settings file: invalid value <" << paramValueString <<
8469 	                         "> for bool parameter <" << paramName << "> in line " << lineNumber << ".\n");
8470 	               return false;
8471 	            }
8472 	         }
8473 	      }
8474 	
8475 	      return true;
8476 	   }
8477 	
8478 	   // check whether we have an integer parameter
8479 	   if(strncmp(paramTypeString, "int", 3) == 0)
8480 	   {
8481 	      for(int param = 0; ; param++)
8482 	      {
8483 	         if(param >= SoPlexBase<R>::INTPARAM_COUNT)
8484 	         {
8485 	            MSG_INFO1(spxout, spxout << "Error parsing settings file: unknown parameter name <" << paramName <<
8486 	                      "> in line " << lineNumber << ".\n");
8487 	            return false;
8488 	         }
8489 	         else if(strncmp(paramName, _currentSettings->intParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0)
8490 	         {
8491 	            int value;
8492 	            value = std::stoi(paramValueString);
8493 	
8494 	            if(setIntParam((SoPlexBase<R>::IntParam)param, value, false))
8495 	               break;
8496 	            else
8497 	            {
8498 	               MSG_INFO1(spxout, spxout << "Error parsing settings file: invalid value <" << paramValueString <<
8499 	                         "> for int parameter <" << paramName << "> in line " << lineNumber << ".\n");
8500 	               return false;
8501 	            }
8502 	         }
8503 	      }
8504 	
8505 	      return true;
8506 	   }
8507 	
8508 	   // check whether we have a R parameter
8509 	   if(strncmp(paramTypeString, "real", 4) == 0)
8510 	   {
8511 	      for(int param = 0; ; param++)
8512 	      {
8513 	         if(param >= SoPlexBase<R>::REALPARAM_COUNT)
8514 	         {
8515 	            MSG_INFO1(spxout, spxout << "Error parsing settings file: unknown parameter name <" << paramName <<
8516 	                      "> in line " << lineNumber << ".\n");
8517 	            return false;
8518 	         }
8519 	         else if(strncmp(paramName, _currentSettings->realParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0)
8520 	         {
8521 	            Real value;
8522 	
8523 	#ifdef WITH_LONG_DOUBLE
8524 	            value = std::stold(paramValueString);
8525 	#else
8526 	#ifdef WITH_FLOAT
8527 	            value = std::stof(paramValueString);
8528 	#else
8529 	            value = std::stod(paramValueString);
8530 	#endif
8531 	#endif
8532 	
8533 	            if(setRealParam((SoPlexBase<R>::RealParam)param, value))
8534 	               break;
8535 	            else
8536 	            {
8537 	               MSG_INFO1(spxout, spxout << "Error parsing settings file: invalid value <" << paramValueString <<
8538 	                         "> for R parameter <" << paramName << "> in line " << lineNumber << ".\n");
8539 	               return false;
8540 	            }
8541 	         }
8542 	      }
8543 	
8544 	      return true;
8545 	   }
8546 	
8547 	#ifdef SOPLEX_WITH_RATIONALPARAM
8548 	
8549 	   // check whether we have a rational parameter
8550 	   if(strncmp(paramTypeString, "rational", 8) == 0)
8551 	   {
8552 	      for(int param = 0; ; param++)
8553 	      {
8554 	         if(param >= SoPlexBase<R>::RATIONALPARAM_COUNT)
8555 	         {
8556 	            MSG_INFO1(spxout, spxout << "Error parsing settings file: unknown parameter name <" << paramName <<
8557 	                      "> in line " << lineNumber << ".\n");
8558 	            return false;
8559 	         }
8560 	         else if(strncmp(paramName, _currentSettings->rationalParam.name[param].c_str(),
8561 	                         SET_MAX_LINE_LEN) == 0)
8562 	         {
8563 	            Rational value;
8564 	
8565 	            if(readStringRational(paramValueString, value)
8566 	                  && setRationalParam((SoPlexBase<R>::RationalParam)param, value))
8567 	               break;
8568 	            else
8569 	            {
8570 	               MSG_INFO1(spxout, spxout << "Error parsing settings file: invalid value <" << paramValueString <<
8571 	                         "> for rational parameter <" << paramName << "> in line " << lineNumber << ".\n");
8572 	               return false;
8573 	            }
8574 	         }
8575 	      }
8576 	
8577 	      return true;
8578 	   }
8579 	
8580 	#endif
8581 	
8582 	   // check whether we have the random seed
8583 	   if(strncmp(paramTypeString, "uint", 4) == 0)
8584 	   {
8585 	      if(strncmp(paramName, "random_seed", 11) == 0)
8586 	      {
8587 	         unsigned int value;
8588 	         unsigned long parseval;
8589 	
8590 	         parseval = std::stoul(paramValueString);
8591 	
8592 	         if(parseval > UINT_MAX)
8593 	         {
8594 	            value = UINT_MAX;
8595 	            MSG_WARNING(spxout, spxout << "Converting number greater than UINT_MAX to uint.\n");
8596 	         }
8597 	         else
8598 	            value = (unsigned int) parseval;
8599 	
8600 	         setRandomSeed(value);
8601 	         return true;
8602 	      }
8603 	
8604 	      MSG_INFO1(spxout, spxout << "Error parsing settings file for uint parameter <random_seed>.\n");
8605 	      return false;
8606 	   }
8607 	
8608 	   MSG_INFO1(spxout, spxout << "Error parsing settings file: invalid parameter type <" <<
8609 	             paramTypeString << "> for parameter <" << paramName << "> in line " << lineNumber << ".\n");
8610 	
8611 	   return false;
8612 	}
8613 	
8614 	/// default constructor
8615 	template <class R>
8616 	SoPlexBase<R>::SoPlexBase()
8617 	   : _statistics(0)
8618 	   , _currentSettings(0)
8619 	   , _scalerUniequi(false)
8620 	   , _scalerBiequi(true)
8621 	   , _scalerGeo1(false, 1)
8622 	   , _scalerGeo8(false, 8)
8623 	   , _scalerGeoequi(true)
8624 	   , _scalerLeastsq()
8625 	   , _simplifier(0)
8626 	   , _scaler(nullptr)
8627 	   , _starter(0)
8628 	   , _rationalLP(0)
8629 	   , _unitMatrixRational(0)
8630 	   , _status(SPxSolverBase<R>::UNKNOWN)
8631 	   , _hasBasis(false)
8632 	   , _hasSolReal(false)
8633 	   , _hasSolRational(false)
8634 	   , _rationalPosone(1)
8635 	   , _rationalNegone(-1)
8636 	   , _rationalZero(0)
8637 	{
8638 	   // transfer message handler
8639 	   _solver.setOutstream(spxout);
8640 	   _scalerUniequi.setOutstream(spxout);
8641 	   _scalerBiequi.setOutstream(spxout);
8642 	   _scalerGeo1.setOutstream(spxout);
8643 	   _scalerGeo8.setOutstream(spxout);
8644 	   _scalerGeoequi.setOutstream(spxout);
8645 	   _scalerLeastsq.setOutstream(spxout);
8646 	
8647 	   // give lu factorization to solver
8648 	   _solver.setBasisSolver(&_slufactor);
8649 	
8650 	   // the R LP is initially stored in the solver; the rational LP is constructed, when the parameter SYNCMODE is
8651 	   // initialized in setSettings() below
8652 	   _realLP = &_solver;
8653 	   _isRealLPLoaded = true;
8654 	   _isRealLPScaled = false;
8655 	   _applyPolishing = false;
8656 	   _optimizeCalls = 0;
8657 	   _unscaleCalls = 0;
8658 	   _realLP->setOutstream(spxout);
8659 	   _currentProb = DECOMP_ORIG;
8660 	
8661 	   // initialize statistics
8662 	   spx_alloc(_statistics);
8663 	   _statistics = new(_statistics) Statistics();
8664 	
8665 	   // initialize parameter settings to default
8666 	   spx_alloc(_currentSettings);
8667 	   _currentSettings = new(_currentSettings) Settings();
8668 	   setSettings(*_currentSettings, true);
8669 	
8670 	   _lastSolveMode = intParam(SoPlexBase<R>::SOLVEMODE);
8671 	
8672 	   _simplifierPaPILO.setOutstream(spxout);
8673 	
8674 	   assert(_isConsistent());
8675 	}
8676 	
8677 	
8678 	
8679 	/// reads settings file; returns true on success
8680 	template <class R>
8681 	bool SoPlexBase<R>::loadSettingsFile(const char* filename)
8682 	{
8683 	   assert(filename != 0);
8684 	
8685 	   // start timing
8686 	   _statistics->readingTime->start();
8687 	
8688 	   MSG_INFO1(spxout, spxout << "Loading settings file <" << filename << "> . . .\n");
8689 	
8690 	   // open file
8691 	   spxifstream file(filename);
8692 	
8693 	   if(!file)
8694 	   {
8695 	      MSG_INFO1(spxout, spxout << "Error opening settings file.\n");
8696 	      return false;
8697 	   }
8698 	
8699 	   // read file
8700 	   char line[SET_MAX_LINE_LEN];
8701 	   int lineNumber = 0;
8702 	   bool readError = false;
8703 	   bool parseError = false;
8704 	
8705 	   while(!readError && !parseError)
8706 	   {
8707 	      lineNumber++;
8708 	      readError = !file.getline(line, sizeof(line));
8709 	
8710 	      if(!readError)
8711 	         parseError = !_parseSettingsLine(line, lineNumber);
8712 	   }
8713 	
8714 	   readError = readError && !file.eof();
8715 	
8716 	   if(readError && strlen(line) == SET_MAX_LINE_LEN - 1)
8717 	   {
8718 	      MSG_INFO1(spxout, spxout << "Error reading settings file: line " << lineNumber <<
8719 	                " in settings file exceeds " << SET_MAX_LINE_LEN - 2 << " characters.\n");
8720 	   }
8721 	   else if(readError)
8722 	   {
8723 	      MSG_INFO1(spxout, spxout << "Error reading settings file: line " << lineNumber << ".\n");
8724 	   }
8725 	
8726 	   // stop timing
8727 	   _statistics->readingTime->stop();
8728 	
8729 	   return !readError;
8730 	}
8731 	
8732 	
8733 	/// parses one setting string and returns true on success
8734 	template <class R>
8735 	bool SoPlexBase<R>::parseSettingsString(char* string)
8736 	{
8737 	   assert(string != 0);
8738 	
8739 	   if(string == 0)
8740 	      return false;
8741 	
8742 	   char parseString[SET_MAX_LINE_LEN];
8743 	   spxSnprintf(parseString, SET_MAX_LINE_LEN - 1, "%s", string);
8744 	
8745 	   char* line = parseString;
8746 	
8747 	   // find the start of the parameter type
8748 	   while(*line == ' ' || *line == '\t' || *line == '\r')
8749 	      line++;
8750 	
8751 	   if(*line == '\0' || *line == '\n' || *line == '#')
8752 	      return true;
8753 	
8754 	   char* paramTypeString = line;
8755 	
8756 	   // find the end of the parameter type
8757 	   while(*line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#'
8758 	         && *line != '\0' && *line != ':')
8759 	      line++;
8760 	
8761 	   if(*line == ':')
8762 	   {
8763 	      *line = '\0';
8764 	      line++;
8765 	   }
8766 	   else
8767 	   {
8768 	      *line = '\0';
8769 	      line++;
8770 	
8771 	      // search for the ':' char in the line
8772 	      while(*line == ' ' || *line == '\t' || *line == '\r')
8773 	         line++;
8774 	
8775 	      if(*line != ':')
8776 	      {
8777 	         MSG_INFO1(spxout, spxout <<
8778 	                   "Error parsing setting string: no ':' separating parameter type and name.\n");
8779 	         return false;
8780 	      }
8781 	
8782 	      line++;
8783 	   }
8784 	
8785 	   // find the start of the parameter name
8786 	   while(*line == ' ' || *line == '\t' || *line == '\r')
8787 	      line++;
8788 	
8789 	   if(*line == '\0' || *line == '\n' || *line == '#')
8790 	   {
8791 	      MSG_INFO1(spxout, spxout << "Error parsing setting string: no parameter name.\n");
8792 	      return false;
8793 	   }
8794 	
8795 	   char* paramName = line;
8796 	
8797 	   // find the end of the parameter name
8798 	   while(*line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#'
8799 	         && *line != '\0' && *line != '=')
8800 	      line++;
8801 	
8802 	   if(*line == '=')
8803 	   {
8804 	      *line = '\0';
8805 	      line++;
8806 	   }
8807 	   else
8808 	   {
8809 	      *line = '\0';
8810 	      line++;
8811 	
8812 	      // search for the '=' char in the line
8813 	      while(*line == ' ' || *line == '\t' || *line == '\r')
8814 	         line++;
8815 	
8816 	      if(*line != '=')
8817 	      {
8818 	         MSG_INFO1(spxout, spxout << "Error parsing setting string: no '=' after parameter name.\n");
8819 	         return false;
8820 	      }
8821 	
8822 	      line++;
8823 	   }
8824 	
8825 	   // find the start of the parameter value string
8826 	   while(*line == ' ' || *line == '\t' || *line == '\r')
8827 	      line++;
8828 	
8829 	   if(*line == '\0' || *line == '\n' || *line == '#')
8830 	   {
8831 	      MSG_INFO1(spxout, spxout << "Error parsing setting string: no parameter value.\n");
8832 	      return false;
8833 	   }
8834 	
8835 	   char* paramValueString = line;
8836 	
8837 	   // find the end of the parameter value string
8838 	   while(*line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#'
8839 	         && *line != '\0')
8840 	      line++;
8841 	
8842 	   if(*line != '\0')
8843 	   {
8844 	      // check, if the rest of the line is clean
8845 	      *line = '\0';
8846 	      line++;
8847 	
8848 	      while(*line == ' ' || *line == '\t' || *line == '\r')
8849 	         line++;
8850 	
8851 	      if(*line != '\0' && *line != '\n' && *line != '#')
8852 	      {
8853 	         MSG_INFO1(spxout, spxout << "Error parsing setting string: additional character '" << *line <<
8854 	                   "' after parameter value.\n");
8855 	         return false;
8856 	      }
8857 	   }
8858 	
8859 	   // check whether we have a bool parameter
8860 	   if(strncmp(paramTypeString, "bool", 4) == 0)
8861 	   {
8862 	      for(int param = 0; ; param++)
8863 	      {
8864 	         if(param >= SoPlexBase<R>::BOOLPARAM_COUNT)
8865 	         {
8866 	            MSG_INFO1(spxout, spxout << "Error parsing setting string: unknown parameter name <" << paramName <<
8867 	                      ">.\n");
8868 	            return false;
8869 	         }
8870 	         else if(strncmp(paramName, _currentSettings->boolParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0)
8871 	         {
8872 	            if(strncasecmp(paramValueString, "true", 4) == 0
8873 	                  || strncasecmp(paramValueString, "TRUE", 4) == 0
8874 	                  || strncasecmp(paramValueString, "t", 4) == 0
8875 	                  || strncasecmp(paramValueString, "T", 4) == 0
8876 	                  || strtol(paramValueString, NULL, 4) == 1)
8877 	            {
8878 	               setBoolParam((SoPlexBase<R>::BoolParam)param, true);
8879 	               break;
8880 	            }
8881 	            else if(strncasecmp(paramValueString, "false", 5) == 0
8882 	                    || strncasecmp(paramValueString, "FALSE", 5) == 0
8883 	                    || strncasecmp(paramValueString, "f", 5) == 0
8884 	                    || strncasecmp(paramValueString, "F", 5) == 0
8885 	                    || strtol(paramValueString, NULL, 5) == 0)
8886 	            {
8887 	               setBoolParam((SoPlexBase<R>::BoolParam)param, false);
8888 	               break;
8889 	            }
8890 	            else
8891 	            {
8892 	               MSG_INFO1(spxout, spxout << "Error parsing setting string: invalid value <" << paramValueString <<
8893 	                         "> for bool parameter <" << paramName << ">.\n");
8894 	               return false;
8895 	            }
8896 	         }
8897 	      }
8898 	
8899 	      return true;
8900 	   }
8901 	
8902 	   // check whether we have an integer parameter
8903 	   if(strncmp(paramTypeString, "int", 3) == 0)
8904 	   {
8905 	      for(int param = 0; ; param++)
8906 	      {
8907 	         if(param >= SoPlexBase<R>::INTPARAM_COUNT)
8908 	         {
8909 	            MSG_INFO1(spxout, spxout << "Error parsing setting string: unknown parameter name <" << paramName <<
8910 	                      ">.\n");
8911 	            return false;
8912 	         }
8913 	         else if(strncmp(paramName, _currentSettings->intParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0)
8914 	         {
8915 	            int value;
8916 	            value = std::stoi(paramValueString);
8917 	
8918 	            if(setIntParam((SoPlexBase<R>::IntParam)param, value, false))
8919 	               break;
8920 	            else
8921 	            {
8922 	               MSG_INFO1(spxout, spxout << "Error parsing setting string: invalid value <" << paramValueString <<
8923 	                         "> for int parameter <" << paramName << ">.\n");
8924 	               return false;
8925 	            }
8926 	         }
8927 	      }
8928 	
8929 	      return true;
8930 	   }
8931 	
8932 	   // check whether we have a real parameter
8933 	   if(strncmp(paramTypeString, "real", 4) == 0)
8934 	   {
8935 	      for(int param = 0; ; param++)
8936 	      {
8937 	         if(param >= SoPlexBase<R>::REALPARAM_COUNT)
8938 	         {
8939 	            MSG_INFO1(spxout, spxout << "Error parsing setting string: unknown parameter name <" << paramName <<
8940 	                      ">.\n");
8941 	            return false;
8942 	         }
8943 	         else if(strncmp(paramName, _currentSettings->realParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0)
8944 	         {
8945 	            Real value;
8946 	#ifdef WITH_LONG_DOUBLE
8947 	            value = std::stold(paramValueString);
8948 	#else
8949 	#ifdef WITH_FLOAT
8950 	            value = std::stof(paramValueString);
8951 	#else
8952 	            value = std::stod(paramValueString);
8953 	#endif
8954 	#endif
8955 	
8956 	            if(setRealParam((SoPlexBase<R>::RealParam)param, value))
8957 	               break;
8958 	            else
8959 	            {
8960 	               MSG_INFO1(spxout, spxout << "Error parsing setting string: invalid value <" << paramValueString <<
8961 	                         "> for real parameter <" << paramName << ">.\n");
8962 	               return false;
8963 	            }
8964 	         }
8965 	      }
8966 	
8967 	      return true;
8968 	   }
8969 	
8970 	#ifdef SOPLEX_WITH_RATIONALPARAM
8971 	
8972 	   // check whether we have a rational parameter
8973 	   if(strncmp(paramTypeString, "rational", 8) == 0)
8974 	   {
8975 	      for(int param = 0; ; param++)
8976 	      {
8977 	         if(param >= SoPlexBase<R>::RATIONALPARAM_COUNT)
8978 	         {
8979 	            MSG_INFO1(spxout, spxout << "Error parsing setting string: unknown parameter name <" << paramName <<
8980 	                      ">.\n");
8981 	            return false;
8982 	         }
8983 	         else if(strncmp(paramName, _currentSettings->rationalParam.name[param].c_str(),
8984 	                         SET_MAX_LINE_LEN) == 0)
8985 	         {
8986 	            Rational value;
8987 	
8988 	            if(readStringRational(paramValueString, value)
8989 	                  && setRationalParam((SoPlexBase<R>::RationalParam)param, value))
8990 	               break;
8991 	            else
8992 	            {
8993 	               MSG_INFO1(spxout, spxout << "Error parsing setting string: invalid value <" << paramValueString <<
8994 	                         "> for rational parameter <" << paramName << ">.\n");
8995 	               return false;
8996 	            }
8997 	         }
8998 	      }
8999 	
9000 	      return true;
9001 	   }
9002 	
9003 	#endif
9004 	
9005 	   // check whether we have the random seed
9006 	   if(strncmp(paramTypeString, "uint", 4) == 0)
9007 	   {
9008 	      if(strncmp(paramName, "random_seed", 11) == 0)
9009 	      {
9010 	         unsigned int value;
9011 	         unsigned long parseval;
9012 	
9013 	         parseval = std::stoul(paramValueString);
9014 	
9015 	         if(parseval > UINT_MAX)
9016 	         {
9017 	            value = UINT_MAX;
9018 	            MSG_WARNING(spxout, spxout << "Converting number greater than UINT_MAX to uint.\n");
9019 	         }
9020 	         else
9021 	            value = (unsigned int) parseval;
9022 	
9023 	         setRandomSeed(value);
9024 	         return true;
9025 	      }
9026 	
9027 	      MSG_INFO1(spxout, spxout << "Error parsing setting string for uint parameter <random_seed>.\n");
9028 	      return false;
9029 	   }
9030 	
9031 	   MSG_INFO1(spxout, spxout << "Error parsing setting string: invalid parameter type <" <<
9032 	             paramTypeString << "> for parameter <" << paramName << ">.\n");
9033 	
9034 	   return false;
9035 	}
9036 	
9037 	/// writes settings file; returns true on success
9038 	template <class R>
9039 	bool SoPlexBase<R>::saveSettingsFile(const char* filename, const bool onlyChanged,
9040 	                                     int solvemode) const
9041 	{
9042 	   assert(filename != 0);
9043 	
9044 	   std::ofstream file(filename);
9045 	   SPxOut::setScientific(file, 16);
9046 	
9047 	   if(!file.good())
9048 	      return false;
9049 	
9050 	   file.setf(std::ios::left);
9051 	
9052 	   SPxOut::setFixed(file);
9053 	
9054 	   file << "# SoPlexBase version " << SOPLEX_VERSION / 100 << "." << (SOPLEX_VERSION / 10) % 10 << "."
9055 	        << SOPLEX_VERSION % 10;
9056 	#if SOPLEX_SUBVERSION > 0
9057 	   file << "." << SOPLEX_SUBVERSION;
9058 	#endif
9059 	   file << "\n";
9060 	
9061 	   // Additional parameter solvemode is written
9062 	   file << "\n# solving mode (0 - floating-point solve, 1 - auto, 2 - force iterative refinement, 3 - multi precision solve)\n";
9063 	   file << "solvemode = " << solvemode << "\n";
9064 	
9065 	   for(int i = 0; i < SoPlexBase<R>::BOOLPARAM_COUNT; i++)
9066 	   {
9067 	      if(onlyChanged
9068 	            && _currentSettings->_boolParamValues[i] == _currentSettings->boolParam.defaultValue[i])
9069 	         continue;
9070 	
9071 	      file << "\n";
9072 	      file << "# " << _currentSettings->boolParam.description[i] << "\n";
9073 	      file << "# range {true, false}, default " << (_currentSettings->boolParam.defaultValue[i] ?
9074 	            "true\n" : "false\n");
9075 	      file << "bool:" << _currentSettings->boolParam.name[i] << " = " <<
9076 	           (_currentSettings->_boolParamValues[i] ? "true\n" : "false\n");
9077 	   }
9078 	
9079 	   for(int i = 0; i < SoPlexBase<R>::INTPARAM_COUNT; i++)
9080 	   {
9081 	      if(onlyChanged
9082 	            && _currentSettings->_intParamValues[i] == _currentSettings->intParam.defaultValue[i])
9083 	         continue;
9084 	
9085 	      file << "\n";
9086 	      file << "# " << _currentSettings->intParam.description[i] << "\n";
9087 	      file << "# range [" << _currentSettings->intParam.lower[i] << "," <<
9088 	           _currentSettings->intParam.upper[i]
9089 	           << "], default " << _currentSettings->intParam.defaultValue[i] << "\n";
9090 	      file << "int:" << _currentSettings->intParam.name[i] << " = " <<
9091 	           _currentSettings->_intParamValues[i] << "\n";
9092 	   }
9093 	
9094 	   SPxOut::setScientific(file);
9095 	
9096 	   for(int i = 0; i < SoPlexBase<R>::REALPARAM_COUNT; i++)
9097 	   {
9098 	      if(onlyChanged
9099 	            && _currentSettings->_realParamValues[i] == _currentSettings->realParam.defaultValue[i])
9100 	         continue;
9101 	
9102 	      file << "\n";
9103 	      file << "# " << _currentSettings->realParam.description[i] << "\n";
9104 	      file << "# range [" << _currentSettings->realParam.lower[i] << "," <<
9105 	           _currentSettings->realParam.upper[i]
9106 	           << "], default " << _currentSettings->realParam.defaultValue[i] << "\n";
9107 	      file << "real:" << _currentSettings->realParam.name[i] << " = " <<
9108 	           _currentSettings->_realParamValues[i] << "\n";
9109 	   }
9110 	
9111 	#ifdef SOPLEX_WITH_RATIONALPARAM
9112 	
9113 	   for(int i = 0; i < SoPlexBase<R>::RATIONALPARAM_COUNT; i++)
9114 	   {
9115 	      if(onlyChanged
9116 	            && _currentSettings->_rationalParamValues[i] == _currentSettings->rationalParam.defaultValue[i])
9117 	         continue;
9118 	
9119 	      file << "\n";
9120 	      file << "# " << _currentSettings->rationalParam.description[i] << "\n";
9121 	      file << "# range [" << _currentSettings->rationalParam.lower[i] << "," <<
9122 	           _currentSettings->rationalParam.upper[i]
9123 	           << "], default " << _currentSettings->rationalParam.defaultValue[i] << "\n";
9124 	      file << "rational:" << _currentSettings->rationalParam.name[i] << " = " <<
9125 	           _currentSettings->_rationalParamValues[i] << "\n";
9126 	   }
9127 	
9128 	#endif
9129 	
9130 	   if(!onlyChanged || _solver.random.getSeed() != DEFAULT_RANDOM_SEED)
9131 	   {
9132 	      file << "\n";
9133 	      file << "# initial random seed used for perturbation\n";
9134 	      file << "# range [0, " << UINT_MAX << "], default " << DEFAULT_RANDOM_SEED << "\n";
9135 	      file << "uint:random_seed = " << _solver.random.getSeed() << "\n";
9136 	   }
9137 	
9138 	   return true;
9139 	}
9140 	
9141 	
9142 	
9143 	/// reads LP file in LP or MPS format according to READMODE parameter; gets row names, column names, and
9144 	/// integer variables if desired; returns true on success
9145 	
9146 	template <class R>
9147 	bool SoPlexBase<R>::readFile(const char* filename, NameSet* rowNames, NameSet* colNames,
9148 	                             DIdxSet* intVars)
9149 	{
9150 	   bool success = false;
9151 	
9152 	   if(intParam(SoPlexBase<R>::READMODE) == READMODE_REAL)
9153 	      success = _readFileReal(filename, rowNames, colNames, intVars);
9154 	   else
9155 	      success = _readFileRational(filename, rowNames, colNames, intVars);
9156 	
9157 	   // storing the row and column names for use in the DBDS print basis methods
9158 	   _rowNames = rowNames;
9159 	   _colNames = colNames;
9160 	
9161 	   return success;
9162 	}
9163 	
9164 	
9165 	
9166 	/// writes R LP to file; LP or MPS format is chosen from the extension in \p filename; if \p rowNames and \p
9167 	/// colNames are \c NULL, default names are used; if \p intVars is not \c NULL, the variables contained in it are
9168 	/// marked as integer; returns true on success
9169 	template <class R>
9170 	bool SoPlexBase<R>::writeFile(const char* filename, const NameSet* rowNames,
9171 	                              const NameSet* colNames, const DIdxSet* intVars, const bool unscale) const
9172 	{
9173 	   ///@todo implement return value
9174 	   if(unscale && _realLP->isScaled())
9175 	   {
9176 	      MSG_INFO3(spxout, spxout << "copy LP to write unscaled original problem" << std::endl;)
9177 	      SPxLPBase<R>* origLP;
9178 	      origLP = nullptr;
9179 	      spx_alloc(origLP);
9180 	      origLP = new(origLP) SPxLPBase<R>(*_realLP);
9181 	      origLP->unscaleLP();
9182 	      origLP->writeFileLPBase(filename, rowNames, colNames, intVars);
9183 	      origLP->~SPxLPBase<R>();
9184 	      spx_free(origLP);
9185 	   }
9186 	   else
9187 	      _realLP->writeFileLPBase(filename, rowNames, colNames, intVars);
9188 	
9189 	   return true;
9190 	}
9191 	
9192 	
9193 	/// writes the dual of the R LP to file; LP or MPS format is chosen from the extension in \p filename;
9194 	/// if \p rowNames and \p colNames are \c NULL, default names are used; if \p intVars is not \c NULL,
9195 	/// the variables contained in it are marked as integer; returns true on success
9196 	template <class R>
9197 	bool SoPlexBase<R>::writeDualFileReal(const char* filename, const NameSet* rowNames,
9198 	                                      const NameSet* colNames, const DIdxSet* intVars) const
9199 	{
9200 	   SPxLPBase<R> dualLP;
9201 	   _realLP->buildDualProblem(dualLP);
9202 	   dualLP.setOutstream(spxout);
9203 	
9204 	   // swap colnames and rownames
9205 	   dualLP.writeFileLPBase(filename, colNames, rowNames);
9206 	   return true;
9207 	}
9208 	
9209 	
9210 	
9211 	/// reads basis information from \p filename and returns true on success; if \p rowNames and \p colNames are \c NULL,
9212 	/// default names are assumed; returns true on success
9213 	template <class R>
9214 	bool SoPlexBase<R>::readBasisFile(const char* filename, const NameSet* rowNames,
9215 	                                  const NameSet* colNames)
9216 	{
9217 	   clearBasis();
9218 	   /// @todo can't we just remove the else code?
9219 	#if 1
9220 	   assert(filename != 0);
9221 	   assert(_realLP != 0);
9222 	
9223 	   // start timing
9224 	   _statistics->readingTime->start();
9225 	
9226 	   // read
9227 	   if(!_isRealLPLoaded)
9228 	   {
9229 	      assert(_realLP != &_solver);
9230 	
9231 	      _solver.loadLP(*_realLP);
9232 	      _realLP->~SPxLPBase<R>();
9233 	      spx_free(_realLP);
9234 	      _realLP = &_solver;
9235 	      _isRealLPLoaded = true;
9236 	   }
9237 	
9238 	   _hasBasis = _solver.readBasisFile(filename, rowNames, colNames);
9239 	   assert(_hasBasis == (_solver.basis().status() > SPxBasisBase<R>::NO_PROBLEM));
9240 	
9241 	   // stop timing
9242 	   _statistics->readingTime->stop();
9243 	
9244 	   return _hasBasis;
9245 	#else
9246 	   // this is alternative code for reading bases without the SPxSolverBase class
9247 	   assert(filename != 0);
9248 	
9249 	   // start timing
9250 	   _statistics->readingTime->start();
9251 	
9252 	   // read
9253 	   spxifstream file(filename);
9254 	
9255 	   if(!file)
9256 	      return false;
9257 	
9258 	   // get problem size
9259 	   int numRows = numRows();
9260 	   int numCols = numCols();
9261 	
9262 	   // prepare column names
9263 	   const NameSet* colNamesPtr = colNames;
9264 	   NameSet* tmpColNames = 0;
9265 	
9266 	   if(colNames == 0)
9267 	   {
9268 	      std::stringstream name;
9269 	
9270 	      spx_alloc(tmpColNames);
9271 	      tmpColNames = new(tmpColNames) NameSet();
9272 	      tmpColNames->reMax(numCols);
9273 	
9274 	      for(int j = 0; j < numCols; ++j)
9275 	      {
9276 	         name << "x" << j;
9277 	         tmpColNames->add(name.str().c_str());
9278 	      }
9279 	
9280 	      colNamesPtr = tmpColNames;
9281 	   }
9282 	
9283 	   // prepare row names
9284 	   const NameSet* rowNamesPtr = rowNames;
9285 	   NameSet* tmpRowNames = 0;
9286 	
9287 	   if(rowNamesPtr == 0)
9288 	   {
9289 	      std::stringstream name;
9290 	
9291 	      spx_alloc(tmpRowNames);
9292 	      tmpRowNames = new(tmpRowNames) NameSet();
9293 	      tmpRowNames->reMax(numRows);
9294 	
9295 	      for(int i = 0; i < numRows; ++i)
9296 	      {
9297 	         name << "C" << i;
9298 	         tmpRowNames->add(name.str().c_str());
9299 	      }
9300 	
9301 	      rowNamesPtr = tmpRowNames;
9302 	   }
9303 	
9304 	   // initialize with default slack basis
9305 	   _basisStatusRows.reSize(numRows);
9306 	   _basisStatusCols.reSize(numCols);
9307 	
9308 	   for(int i = 0; i < numRows; i++)
9309 	      _basisStatusRows[i] = SPxSolverBase<R>::BASIC;
9310 	
9311 	   for(int i = 0; i < numCols; i++)
9312 	   {
9313 	      if(lowerRealInternal(i) == upperRealInternal(i))
9314 	         _basisStatusCols[i] = SPxSolverBase<R>::FIXED;
9315 	      else if(lowerRealInternal(i) <= double(-realParam(SoPlexBase<R>::INFTY))
9316 	              && upperRealInternal(i) >= double(realParam(SoPlexBase<R>::INFTY)))
9317 	         _basisStatusCols[i] = SPxSolverBase<R>::ZERO;
9318 	      else if(lowerRealInternal(i) <= double(-realParam(SoPlexBase<R>::INFTY)))
9319 	         _basisStatusCols[i] = SPxSolverBase<R>::ON_UPPER;
9320 	      else
9321 	         _basisStatusCols[i] = SPxSolverBase<R>::ON_LOWER;
9322 	   }
9323 	
9324 	   // read basis
9325 	   MPSInput mps(file);
9326 	
9327 	   if(mps.readLine() && (mps.field0() != 0) && !strcmp(mps.field0(), "NAME"))
9328 	   {
9329 	      while(mps.readLine())
9330 	      {
9331 	         int c = -1;
9332 	         int r = -1;
9333 	
9334 	         if(mps.field0() != 0 && !strcmp(mps.field0(), "ENDATA"))
9335 	         {
9336 	            mps.setSection(MPSInput::ENDATA);
9337 	            break;
9338 	         }
9339 	
9340 	         if(mps.field1() == 0 || mps.field2() == 0)
9341 	            break;
9342 	
9343 	         if((c = colNamesPtr->number(mps.field2())) < 0)
9344 	            break;
9345 	
9346 	         if(*mps.field1() == 'X')
9347 	         {
9348 	            if(mps.field3() == 0 || (r = rowNamesPtr->number(mps.field3())) < 0)
9349 	               break;
9350 	         }
9351 	
9352 	         if(!strcmp(mps.field1(), "XU"))
9353 	         {
9354 	            _basisStatusCols[c] = SPxSolverBase<R>::BASIC;
9355 	
9356 	            if(_rowTypes[r] == SoPlexBase<R>::RANGETYPE_LOWER)
9357 	               _basisStatusRows[r] = SPxSolverBase<R>::ON_LOWER;
9358 	            else if(_rowTypes[r] == SoPlexBase<R>::RANGETYPE_FIXED)
9359 	               _basisStatusRows[r] = SPxSolverBase<R>::FIXED;
9360 	            else
9361 	               _basisStatusRows[r] = SPxSolverBase<R>::ON_UPPER;
9362 	         }
9363 	         else if(!strcmp(mps.field1(), "XL"))
9364 	         {
9365 	            _basisStatusCols[c] = SPxSolverBase<R>::BASIC;
9366 	
9367 	            if(_rowTypes[r] == SoPlexBase<R>::RANGETYPE_UPPER)
9368 	               _basisStatusRows[r] = SPxSolverBase<R>::ON_UPPER;
9369 	            else if(_rowTypes[r] == SoPlexBase<R>::RANGETYPE_FIXED)
9370 	               _basisStatusRows[r] = SPxSolverBase<R>::FIXED;
9371 	            else
9372 	               _basisStatusRows[r] = SPxSolverBase<R>::ON_LOWER;
9373 	         }
9374 	         else if(!strcmp(mps.field1(), "UL"))
9375 	         {
9376 	            _basisStatusCols[c] = SPxSolverBase<R>::ON_UPPER;
9377 	         }
9378 	         else if(!strcmp(mps.field1(), "LL"))
9379 	         {
9380 	            _basisStatusCols[c] = SPxSolverBase<R>::ON_LOWER;
9381 	         }
9382 	         else
9383 	         {
9384 	            mps.syntaxError();
9385 	            break;
9386 	         }
9387 	      }
9388 	   }
9389 	
9390 	   if(rowNames == 0)
9391 	   {
9392 	      tmpRowNames->~NameSet();
9393 	      spx_free(tmpRowNames);
9394 	   }
9395 	
9396 	   if(colNames == 0)
9397 	   {
9398 	      tmpColNames->~NameSet();
9399 	      spx_free(tmpColNames);
9400 	   }
9401 	
9402 	   _hasBasis = !mps.hasError();
9403 	
9404 	   // stop timing
9405 	   _statistics->readingTime->stop();
9406 	
9407 	   return _hasBasis;
9408 	#endif
9409 	}
9410 	
9411 	
9412 	/// solves the LP
9413 	/// R specialization of the optimize function
9414 	template <class R>
9415 	typename SPxSolverBase<R>::Status SoPlexBase<R>::optimize(volatile bool* interrupt)
9416 	{
9417 	   assert(_isConsistent());
9418 	
9419 	   // clear statistics
9420 	   _statistics->clearSolvingData();
9421 	
9422 	   // the solution is no longer valid
9423 	   _invalidateSolution();
9424 	
9425 	   // if the decomposition based dual simplex flag is set to true
9426 	   if(boolParam(SoPlexBase<R>::USEDECOMPDUALSIMPLEX))
9427 	   {
9428 	      setIntParam(SoPlexBase<R>::SOLVEMODE, SOLVEMODE_REAL);
9429 	      setIntParam(SoPlexBase<R>::REPRESENTATION, REPRESENTATION_ROW);
9430 	      setIntParam(SoPlexBase<R>::ALGORITHM, ALGORITHM_DUAL);
9431 	      //setBoolParam(SoPlexBase<R>::PERSISTENTSCALING, false);
9432 	
9433 	      _solver.setComputeDegenFlag(boolParam(COMPUTEDEGEN));
9434 	
9435 	      _solveDecompositionDualSimplex();
9436 	   }
9437 	   // decide whether to solve the rational LP with iterative refinement or call the standard floating-point solver
9438 	   else if(intParam(SoPlexBase<R>::SOLVEMODE) == SOLVEMODE_REAL
9439 	           || (intParam(SoPlexBase<R>::SOLVEMODE) == SOLVEMODE_AUTO
9440 	               && GE(realParam(SoPlexBase<R>::FEASTOL), 1e-9) && GE(realParam(SoPlexBase<R>::OPTTOL), 1e-9)))
9441 	   {
9442 	      // ensure that tolerances are reasonable for the floating-point solver
9443 	      if(realParam(SoPlexBase<R>::FEASTOL) < _currentSettings->realParam.lower[SoPlexBase<R>::FPFEASTOL])
9444 	      {
9445 	         MSG_WARNING(spxout, spxout << "Cannot call floating-point solver with feasibility tolerance below "
9446 	                     << _currentSettings->realParam.lower[SoPlexBase<R>::FPFEASTOL] << " - relaxing tolerance\n");
9447 	         _solver.setFeastol(_currentSettings->realParam.lower[SoPlexBase<R>::FPFEASTOL]);
9448 	      }
9449 	      else
9450 	         _solver.setFeastol(realParam(SoPlexBase<R>::FEASTOL));
9451 	
9452 	      if(realParam(SoPlexBase<R>::OPTTOL) < _currentSettings->realParam.lower[SoPlexBase<R>::FPOPTTOL])
9453 	      {
9454 	         MSG_WARNING(spxout, spxout << "Cannot call floating-point solver with optimality tolerance below "
9455 	                     << _currentSettings->realParam.lower[SoPlexBase<R>::FPOPTTOL] << " - relaxing tolerance\n");
9456 	         _solver.setOpttol(_currentSettings->realParam.lower[SoPlexBase<R>::FPOPTTOL]);
9457 	      }
9458 	      else
9459 	         _solver.setOpttol(realParam(SoPlexBase<R>::OPTTOL));
9460 	
9461 	      _solver.setComputeDegenFlag(boolParam(COMPUTEDEGEN));
9462 	
9463 	      _optimize(interrupt);
9464 	#ifdef SOPLEX_DEBUG // this check will remove scaling of the realLP
9465 	      _checkBasisScaling();
9466 	#endif
9467 	   }
9468 	   else if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_ONLYREAL)
9469 	   {
9470 	      _syncLPRational();
(5) Event template_instantiation_context: instantiation of "void soplex::SoPlexBase<R>::_optimizeRational(volatile bool *) [with R=soplex::Real]" at line 9471 of "/sapmnt/home1/d029903/my_work/SCIPSoPlex_coverity/scipoptsuite-v800-rc07/scipoptsuite-8.0.0/soplex/src/soplex.hpp"
Also see events: [switch_selector_expr_is_constant][caretline][template_instantiation_context][template_instantiation_context][template_instantiation_context]
9471 	      _optimizeRational(interrupt);
9472 	   }
9473 	   else if(intParam(SoPlexBase<R>::SYNCMODE) == SYNCMODE_MANUAL)
9474 	   {
9475 	#ifdef ENABLE_ADDITIONAL_CHECKS
9476 	      assert(areLPsInSync(true, true, false));
9477 	#else
9478 	      assert(areLPsInSync(true, false, false));
9479 	#endif
9480 	
9481 	      _optimizeRational(interrupt);
9482 	
9483 	#ifdef ENABLE_ADDITIONAL_CHECKS
9484 	      assert(areLPsInSync(true, true, false));
9485 	#else
9486 	      assert(areLPsInSync(true, false, false));
9487 	#endif
9488 	   }
9489 	   else
9490 	   {
9491 	#ifdef ENABLE_ADDITIONAL_CHECKS
9492 	      assert(areLPsInSync(true, true, false));
9493 	#else
9494 	      assert(areLPsInSync(true, false, false));
9495 	#endif
9496 	
9497 	      _optimizeRational(interrupt);
9498 	   }
9499 	
9500 	   MSG_INFO1(spxout, spxout << "\n";
9501 	             printShortStatistics(spxout.getStream(SPxOut::INFO1));
9502 	             spxout << "\n");
9503 	
9504 	
9505 	   return status();
9506 	}
9507 	
9508 	
9509 	// @todo: temporary fix. Needs to be looked later
9510 	/// prints complete statistics
9511 	template <class R>
9512 	void SoPlexBase<R>::printStatistics(std::ostream& os)
9513 	{
9514 	   SPxOut::setFixed(os, 2);
9515 	
9516 	   printStatus(os, _status);
9517 	
9518 	   os << "Original problem    : \n";
9519 	
9520 	   if(boolParam(SoPlexBase<R>::USEDECOMPDUALSIMPLEX))
9521 	      printOriginalProblemStatistics(os);
9522 	   else
9523 	   {
9524 	      if(intParam(SoPlexBase<R>::READMODE) == READMODE_REAL)
9525 	         _realLP->printProblemStatistics(os);
9526 	      else
9527 	         _rationalLP->printProblemStatistics(os);
9528 	   }
9529 	
9530 	   os << "Objective sense     : " << (intParam(SoPlexBase<R>::OBJSENSE) ==
9531 	                                      SoPlexBase<R>::OBJSENSE_MINIMIZE ? "minimize\n" : "maximize\n");
9532 	   printSolutionStatistics(os);
9533 	   printSolvingStatistics(os);
9534 	}
9535 	
9536 	// @todo temporary fix. Need to think about precision later
9537 	/// prints short statistics
9538 	template <class R>
9539 	void SoPlexBase<R>::printShortStatistics(std::ostream& os)
9540 	{
9541 	   printStatus(os, _status);
9542 	   SPxOut::setFixed(os, 2);
9543 	   os << "Solving time (sec)  : " << this->_statistics->solvingTime->time() << "\n"
9544 	      << "Iterations          : " << this->_statistics->iterations << "\n";
9545 	   SPxOut::setScientific(os);
9546 	   os << "Objective value     : " << objValueReal() << "\n";
9547 	}
9548 	// @todo: temporary fix need to worry about precision
9549 	/// writes basis information to \p filename; if \p rowNames and \p colNames are \c NULL, default names are used;
9550 	/// returns true on success
9551 	template <class R>
9552 	bool SoPlexBase<R>::writeBasisFile(const char* filename, const NameSet* rowNames,
9553 	                                   const NameSet* colNames, const bool cpxFormat) const
9554 	{
9555 	   assert(filename != 0);
9556 	
9557 	   if(_isRealLPLoaded)
9558 	      return _solver.writeBasisFile(filename, rowNames, colNames, cpxFormat);
9559 	   else
9560 	   {
9561 	      std::ofstream file(filename);
9562 	
9563 	      if(!file.good())
9564 	         return false;
9565 	
9566 	      file.setf(std::ios::left);
9567 	      file << "NAME  " << filename << "\n";
9568 	
9569 	      // do not write basis if there is none
9570 	      if(!_hasBasis)
9571 	      {
9572 	         file << "ENDATA\n";
9573 	         return true;
9574 	      }
9575 	
9576 	      // start writing
9577 	      int numRows = _basisStatusRows.size();
9578 	      int numCols = _basisStatusCols.size();
9579 	      int row = 0;
9580 	
9581 	      for(int col = 0; col < numCols; col++)
9582 	      {
9583 	         assert(_basisStatusCols[col] != SPxSolverBase<R>::UNDEFINED);
9584 	
9585 	         if(_basisStatusCols[col] == SPxSolverBase<R>::BASIC)
9586 	         {
9587 	            // find nonbasic row
9588 	            for(; row < numRows; row++)
9589 	            {
9590 	               assert(_basisStatusRows[row] != SPxSolverBase<R>::UNDEFINED);
9591 	
9592 	               if(_basisStatusRows[row] != SPxSolverBase<R>::BASIC)
9593 	                  break;
9594 	            }
9595 	
9596 	            assert(row != numRows);
9597 	
9598 	            if(_basisStatusRows[row] == SPxSolverBase<R>::ON_UPPER && (!cpxFormat
9599 	                  || _rowTypes[row] == SoPlexBase<R>::RANGETYPE_BOXED))
9600 	               file << " XU ";
9601 	            else
9602 	               file << " XL ";
9603 	
9604 	            file << std::setw(8);
9605 	
9606 	            if(colNames != 0 && colNames->has(col))
9607 	               file << (*colNames)[col];
9608 	            else
9609 	               file << "x" << col;
9610 	
9611 	            file << "       ";
9612 	
9613 	            if(rowNames != 0 && rowNames->has(row))
9614 	               file << (*rowNames)[row];
9615 	            else
9616 	               file << "C" << row;
9617 	
9618 	            file << "\n";
9619 	            row++;
9620 	         }
9621 	         else
9622 	         {
9623 	            if(_basisStatusCols[col] == SPxSolverBase<R>::ON_UPPER)
9624 	            {
9625 	               file << " UL ";
9626 	
9627 	               file << std::setw(8);
9628 	
9629 	               if(colNames != 0 && colNames->has(col))
9630 	                  file << (*colNames)[col];
9631 	               else
9632 	                  file << "x" << col;
9633 	
9634 	               file << "\n";
9635 	            }
9636 	         }
9637 	      }
9638 	
9639 	      file << "ENDATA\n";
9640 	
9641 	#ifndef NDEBUG
9642 	
9643 	      // check that the remaining rows are basic
9644 	      for(; row < numRows; row++)
9645 	      {
9646 	         assert(_basisStatusRows[row] == SPxSolverBase<R>::BASIC);
9647 	      }
9648 	
9649 	#endif
9650 	
9651 	      return true;
9652 	   }
9653 	}
9654 	
9655 	/// set statistic timers to a certain type, used to turn off statistic time measurement
9656 	template <class R>
9657 	void SoPlexBase<R>::setTimings(const Timer::TYPE ttype)
9658 	{
9659 	   _slufactor.changeTimer(ttype);
9660 	   _statistics->readingTime = TimerFactory::switchTimer(_statistics->readingTime, ttype);
9661 	   _statistics->simplexTime = TimerFactory::switchTimer(_statistics->simplexTime, ttype);
9662 	   _statistics->syncTime = TimerFactory::switchTimer(_statistics->syncTime, ttype);
9663 	   _statistics->solvingTime = TimerFactory::switchTimer(_statistics->solvingTime, ttype);
9664 	   _statistics->preprocessingTime = TimerFactory::switchTimer(_statistics->preprocessingTime, ttype);
9665 	   _statistics->rationalTime = TimerFactory::switchTimer(_statistics->rationalTime, ttype);
9666 	   _statistics->transformTime = TimerFactory::switchTimer(_statistics->transformTime, ttype);
9667 	   _statistics->reconstructionTime = TimerFactory::switchTimer(_statistics->reconstructionTime, ttype);
9668 	}
9669 	
9670 	/// prints solution statistics
9671 	template <class R>
9672 	void SoPlexBase<R>::printSolutionStatistics(std::ostream& os)
9673 	{
9674 	   SPxOut::setScientific(os);
9675 	
9676 	   if(_lastSolveMode == SOLVEMODE_REAL)
9677 	   {
9678 	      os << "Solution (real)     : \n"
9679 	         << "  Objective value   : " << objValueReal() << "\n";
9680 	   }
9681 	   else if(_lastSolveMode == SOLVEMODE_RATIONAL)
9682 	   {
9683 	      os << "Solution (rational) : \n"
9684 	         << "  Objective value   : " << objValueRational() << "\n";
9685 	      os << "Size (base 2/10)    : \n"
9686 	         << "  Total primal      : " << totalSizePrimalRational() << " / " << totalSizePrimalRational(
9687 	            10) << "\n"
9688 	         << "  Total dual        : " << totalSizeDualRational() << " / " << totalSizeDualRational(10) << "\n"
9689 	         << "  DLCM primal       : " << dlcmSizePrimalRational() << " / " << dlcmSizePrimalRational(
9690 	            10) << "\n"
9691 	         << "  DLCM dual         : " << dlcmSizeDualRational() << " / " << dlcmSizeDualRational(10) << "\n"
9692 	         << "  DMAX primal       : " << dmaxSizePrimalRational() << " / " << dmaxSizePrimalRational(
9693 	            10) << "\n"
9694 	         << "  DMAX dual         : " << dmaxSizeDualRational() << " / " << dmaxSizeDualRational(10) << "\n";
9695 	   }
9696 	   else
9697 	   {
9698 	      os << "Solution            : \n"
9699 	         << "  Objective value   : -\n";
9700 	   }
9701 	
9702 	   if(intParam(CHECKMODE) == CHECKMODE_RATIONAL
9703 	         || (intParam(CHECKMODE) == CHECKMODE_AUTO && intParam(READMODE) == READMODE_RATIONAL))
9704 	   {
9705 	      Rational maxviol;
9706 	      Rational sumviol;
9707 	
9708 	      os << "Violation (rational): \n";
9709 	
9710 	      if(getBoundViolationRational(maxviol, sumviol))
9711 	         os << "  Max/sum bound     : " << maxviol.str() << " / " << sumviol.str() << "\n";
9712 	      else
9713 	         os << "  Max/sum bound     : - / -\n";
9714 	
9715 	      if(getRowViolationRational(maxviol, sumviol))
9716 	         os << "  Max/sum row       : " << maxviol.str() << " / " << sumviol.str() << "\n";
9717 	      else
9718 	         os << "  Max/sum row       : - / -\n";
9719 	
9720 	      if(getRedCostViolationRational(maxviol, sumviol))
9721 	         os << "  Max/sum redcost   : " << maxviol.str() << " / " << sumviol.str() << "\n";
9722 	      else
9723 	         os << "  Max/sum redcost   : - / -\n";
9724 	
9725 	      if(getDualViolationRational(maxviol, sumviol))
9726 	         os << "  Max/sum dual      : " << maxviol.str() << " / " << sumviol.str() << "\n";
9727 	      else
9728 	         os << "  Max/sum dual      : - / -\n";
9729 	   }
9730 	   else
9731 	   {
9732 	      R maxviol;
9733 	      R sumviol;
9734 	
9735 	      os << "Violations (real)   : \n";
9736 	
9737 	      if(getBoundViolation(maxviol, sumviol))
9738 	         os << "  Max/sum bound     : " << maxviol << " / " << sumviol << "\n";
9739 	      else
9740 	         os << "  Max/sum bound     : - / -\n";
9741 	
9742 	      if(getRowViolation(maxviol, sumviol))
9743 	         os << "  Max/sum row       : " << maxviol << " / " << sumviol << "\n";
9744 	      else
9745 	         os << "  Max/sum row       : - / -\n";
9746 	
9747 	      if(getRedCostViolation(maxviol, sumviol))
9748 	         os << "  Max/sum redcost   : " << maxviol << " / " << sumviol << "\n";
9749 	      else
9750 	         os << "  Max/sum redcost   : - / -\n";
9751 	
9752 	      if(getDualViolation(maxviol, sumviol))
9753 	         os << "  Max/sum dual      : " << maxviol << " / " << sumviol << "\n";
9754 	      else
9755 	         os << "  Max/sum dual      : - / -\n";
9756 	   }
9757 	}
9758 	
9759 	
9760 	/// prints statistics on solving process
9761 	template <class R>
9762 	void SoPlexBase<R>::printSolvingStatistics(std::ostream& os)
9763 	{
9764 	   assert(_statistics != 0);
9765 	   _statistics->print(os);
9766 	}
9767 	
9768 	
9769 	
9770 	} // namespace soplex
9771