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