1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the class library                   */
4    	/*       SoPlex --- the Sequential object-oriented simPlex.                  */
5    	/*                                                                           */
6    	/*    Copyright (C) 1996-2022 Konrad-Zuse-Zentrum                            */
7    	/*                            fuer Informationstechnik Berlin                */
8    	/*                                                                           */
9    	/*  SoPlex is distributed under the terms of the ZIB Academic Licence.       */
10   	/*                                                                           */
11   	/*  You should have received a copy of the ZIB Academic License              */
12   	/*  along with SoPlex; see the file COPYING. If not email to soplex@zib.de.  */
13   	/*                                                                           */
14   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15   	
16   	/**@file  lprowbase.h
17   	 * @brief (In)equality for LPs.
18   	 */
19   	#ifndef _LPROWBASE_H_
20   	#define _LPROWBASE_H_
21   	
22   	#include <assert.h>
23   	
24   	#include "soplex/spxdefines.h"
25   	#include "soplex/basevectors.h"
26   	
27   	namespace soplex
28   	{
29   	/**@brief   (In)equality for LPs.
30   	 * @ingroup Algo
31   	 *
32   	 *  Class LPRowBase provides constraints for linear programs in the form \f[ l \le a^Tx \le r, \f] where \em a is a
33   	 *  DSVector. \em l is referred to as %left hand side, \em r as %right hand side and \em a as \em row \em vector or the
34   	 *  constraint vector. \em l and \em r may also take values \f$\pm\f$ #R(infinity).  This static member is predefined, but
35   	 *  may be overridden to meet the needs of the LP solver to be used.
36   	 *
37   	 *  LPRowBases allow to specify regular inequalities of the form \f[ a^Tx \sim \alpha, \f] where \f$\sim\f$ can take any
38   	 *  value of \f$\le, =, \ge\f$, by setting rhs and lhs to the same value or setting one of them to \f$\infty\f$.
39   	 *
40   	 *  Since constraints in the regular form occur often, LPRowBases offers methods type() and value() for retreiving
41   	 *  \f$\sim\f$ and \f$\alpha\f$ of an LPRowBase in this form, respectively. Also, a constructor for LPRowBases given in
42   	 *  regular form is provided.
43   	 */
44   	template < class R >
(1) Event copy_without_assign: Class "soplex::LPRowBase<double>" has a user-written copy constructor "soplex::LPRowBase<double>::LPRowBase(soplex::LPRowBase<double> const &)" but no corresponding user-written assignment operator.
Also see events: [copy_ctor]
45   	class LPRowBase
46   	{
47   	   template < class S > friend class LPRowBase;
48   	
49   	private:
50   	
51   	   // ------------------------------------------------------------------------------------------------------------------
52   	   /**@name Data */
53   	   ///@{
54   	
55   	   R left;                 ///< left-hand side of the constraint
56   	   R right;                ///< right-hand side of the constraint
57   	   R object;               ///< objective coefficient of corresponding slack variable s = vec times primal
58   	   DSVectorBase<R> vec;    ///< the row vector
59   	
60   	   ///@}
61   	
62   	public:
63   	
64   	   // ------------------------------------------------------------------------------------------------------------------
65   	   /**@name Types */
66   	   ///@{
67   	
68   	   /// (In)Equality type of an LP row.
69   	   /** #LPRowBase%s may be of one of the following Types. This datatype may be used for constructing new #LPRowBase%s in the
70   	    *  regular form.
71   	    */
72   	   enum Type
73   	   {
74   	      LESS_EQUAL,          ///< \f$a^Tx \le \alpha\f$.
75   	      EQUAL,               ///< \f$a^Tx = \alpha\f$.
76   	      GREATER_EQUAL,       ///< \f$a^Tx \ge \alpha\f$.
77   	      RANGE                ///< \f$\lambda \le a^Tx \le \rho\f$.
78   	   };
79   	
80   	   ///@}
81   	
82   	   // ------------------------------------------------------------------------------------------------------------------
83   	   /**@name Construction / destruction */
84   	   ///@{
85   	
86   	   /// Constructs LPRowBase with a vector ready to hold \p defDim nonzeros.
87   	   explicit LPRowBase<R>(int defDim = 0)
88   	      : left(0), right(R(infinity)), object(0), vec(defDim)
89   	   {
90   	      assert(isConsistent());
91   	   }
92   	
93   	   /// Copy constructor.
(2) Event copy_ctor: User-written copy constructor.
Also see events: [copy_without_assign]
94   	   LPRowBase<R>(const LPRowBase<R>& row)
95   	      : left(row.left), right(row.right), object(row.object), vec(row.vec)
96   	   {
97   	      assert(isConsistent());
98   	   }
99   	
100  	   /// Copy constructor.
101  	   template < class S >
102  	   LPRowBase<R>(const LPRowBase<S>& row)
103  	      : left(row.left), right(row.right), object(row.object), vec(row.vec)
104  	   {
105  	      assert(isConsistent());
106  	   }
107  	
108  	   /// Constructs LPRowBase with the given left-hand side, right-hand side and rowVector.
109  	   LPRowBase<R>(const R& p_lhs, const SVectorBase<R>& p_rowVector, const R& p_rhs, const R& p_obj = 0)
110  	      : left(p_lhs), right(p_rhs), object(p_obj), vec(p_rowVector)
111  	   {
112  	      assert(isConsistent());
113  	   }
114  	
115  	   /// Constructs LPRowBase from passed \p rowVector, \p type and \p value.
116  	   LPRowBase<R>(const SVectorBase<R>& p_rowVector, Type p_type, const R& p_value, const R& p_obj = 0)
117  	      : object(p_obj), vec(p_rowVector)
118  	   {
119  	      switch(p_type)
120  	      {
121  	      case LESS_EQUAL:
122  	         left = R(-infinity);
123  	         right = p_value;
124  	         break;
125  	
126  	      case EQUAL:
127  	         left = p_value;
128  	         right = p_value;
129  	         break;
130  	
131  	      case GREATER_EQUAL:
132  	         left = p_value;
133  	         right = R(infinity);
134  	         break;
135  	
136  	      default:
137  	         throw SPxInternalCodeException("XLPROW03 This should never happen.");
138  	      }
139  	
140  	      assert(isConsistent());
141  	   }
142  	
143  	   /// Destructor.
144  	   ~LPRowBase()
145  	   {}
146  	
147  	   ///@}
148  	
149  	   // ------------------------------------------------------------------------------------------------------------------
150  	   /**@name Access / modification */
151  	   ///@{
152  	
153  	   /// Gets type of row.
154  	   Type type() const
155  	   {
156  	      if(rhs() >= R(infinity))
157  	         return GREATER_EQUAL;
158  	
159  	      if(lhs() <= R(-infinity))
160  	         return LESS_EQUAL;
161  	
162  	      if(lhs() == rhs())
163  	         return EQUAL;
164  	
165  	      return RANGE;
166  	   }
167  	
168  	   /// Sets type of (in)equality.
169  	   void setType(Type p_type)
170  	   {
171  	      switch(p_type)
172  	      {
173  	      case LESS_EQUAL:
174  	         left = R(-infinity);
175  	         break;
176  	
177  	      case EQUAL:
178  	         if(lhs() > R(-infinity))
179  	            right = lhs();
180  	         else
181  	            left = rhs();
182  	
183  	         break;
184  	
185  	      case GREATER_EQUAL:
186  	         right = R(infinity);
187  	         break;
188  	
189  	      case RANGE:
190  	         MSG_ERROR(std::cerr << "ELPROW01 RANGE not supported in LPRow::setType()"
191  	                   << std::endl;)
192  	         throw SPxInternalCodeException("XLPROW01 This should never happen.");
193  	
194  	      default:
195  	         throw SPxInternalCodeException("XLPROW02 This should never happen.");
196  	      }
197  	   }
198  	
199  	   /// Right hand side value of (in)equality.
200  	   /** This method returns \f$\alpha\f$ for a LPRowBase in regular form.  However, value() may only be called for
201  	    *  LPRowBase%s with type() != \c RANGE.
202  	    */
203  	   R value() const
204  	   {
205  	      assert(type() != RANGE);
206  	
207  	      return (rhs() < R(infinity)) ? rhs() : lhs();
208  	   }
209  	
210  	   /// Left-hand side value.
211  	   R lhs() const
212  	   {
213  	      return left;
214  	   }
215  	
216  	   /// Sets left-hand side value.
217  	   void setLhs(const R& p_left)
218  	   {
219  	      left = p_left;
220  	   }
221  	
222  	   /// Right-hand side value.
223  	   R rhs() const
224  	   {
225  	      return right;
226  	   }
227  	
228  	   /// Sets right-hand side value.
229  	   void setRhs(const R& p_right)
230  	   {
231  	      right = p_right;
232  	   }
233  	
234  	   /// Objective coefficient value.
235  	   R obj() const
236  	   {
237  	      return object;
238  	   }
239  	
240  	   /// Sets objective coefficient value.
241  	   void setObj(const R& p_obj)
242  	   {
243  	      object = p_obj;
244  	   }
245  	
246  	   /// Constraint row vector.
247  	   const SVectorBase<R>& rowVector() const
248  	   {
249  	      return vec;
250  	   }
251  	
252  	   /// access constraint row vector.
253  	   void setRowVector(const DSVectorBase<R>& p_vec)
254  	   {
255  	      vec = p_vec;
256  	   }
257  	
258  	   ///@}
259  	
260  	   // ------------------------------------------------------------------------------------------------------------------
261  	   /**@name Consistency check */
262  	   ///@{
263  	
264  	   /// Checks consistency.
265  	   bool isConsistent() const
266  	   {
267  	#ifdef ENABLE_CONSISTENCY_CHECKS
268  	      return vec.isConsistent();
269  	#else
270  	      return true;
271  	#endif
272  	   }
273  	
274  	   ///@}
275  	};
276  	
277  	} // namespace soplex
278  	#endif // _LPROWBASE_H_
279