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