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