src/work/athos/lp/lin_expr.h
author athos
Thu, 07 Apr 2005 09:42:31 +0000
changeset 1314 9269c76551cf
parent 1259 11a09f1319b3
permissions -rw-r--r--
New functions in lp_glpk.cc. Sample file: lp_sample.cc.
alpar@1253
     1
/* -*- C++ -*-
alpar@1253
     2
 * src/lemon/lin_expr.h - Part of LEMON, a generic C++ optimization library
alpar@1253
     3
 *
alpar@1253
     4
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1253
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
alpar@1253
     6
 *
alpar@1253
     7
 * Permission to use, modify and distribute this software is granted
alpar@1253
     8
 * provided that this copyright notice appears in all copies. For
alpar@1253
     9
 * precise terms see the accompanying LICENSE file.
alpar@1253
    10
 *
alpar@1253
    11
 * This software is provided "AS IS" with no warranty of any kind,
alpar@1253
    12
 * express or implied, and with no claim as to its suitability for any
alpar@1253
    13
 * purpose.
alpar@1253
    14
 *
alpar@1253
    15
 */
alpar@1253
    16
alpar@1253
    17
#ifndef LEMON_LIN_EXPR_H
alpar@1253
    18
#define LEMON_LIN_EXPR_H
alpar@1253
    19
alpar@1253
    20
#include<vector>
alpar@1253
    21
#include<map>
alpar@1264
    22
#include<lemon/utility.h>
alpar@1253
    23
///\file
alpar@1253
    24
///\brief Classes to handle linear expressions
alpar@1253
    25
namespace lemon {
alpar@1253
    26
  
alpar@1253
    27
  /// Class to handle sparse linear expressions
alpar@1259
    28
  template <class _V>
alpar@1259
    29
  class SparseLinExpr : public std::map<_V, typename _V::ExprValue>
alpar@1253
    30
  {
alpar@1253
    31
  public:
alpar@1253
    32
    typedef _V Var; 
alpar@1259
    33
    typedef typename _V::ExprValue Coeff;
alpar@1253
    34
    
alpar@1253
    35
  protected:
alpar@1259
    36
    typedef typename std::map<_V, typename _V::ExprValue> Base;
alpar@1253
    37
alpar@1253
    38
    Coeff const_comp;
alpar@1253
    39
  public:
alpar@1264
    40
    typedef True IsLinExpression;
alpar@1259
    41
    ///\e
alpar@1259
    42
    SparseLinExpr() : Base(), const_comp(0) { }
alpar@1259
    43
    ///\e
alpar@1259
    44
    SparseLinExpr(const Var &v) : const_comp(0) {
alpar@1253
    45
      Base::insert(std::make_pair(v, 1));
alpar@1253
    46
    }
alpar@1259
    47
    ///\e
alpar@1253
    48
    SparseLinExpr(const Coeff &v) : const_comp(v) {}
alpar@1253
    49
    
alpar@1259
    50
    ///\e
alpar@1253
    51
    void set(const Var &v,const Coeff &c) {
alpar@1253
    52
      return Base::insert(std::make_pair(v, c));
alpar@1253
    53
    }
alpar@1253
    54
//     Coeff &operator[](const Var &v) { return data[v]; }
alpar@1253
    55
//     const Coeff &operator[](const Var &v) const { return data[v]; }
alpar@1253
    56
alpar@1259
    57
    ///\e
alpar@1253
    58
    Coeff &constComp() { return const_comp; }
alpar@1259
    59
    ///\e
alpar@1253
    60
    const Coeff &constComp() const { return const_comp; }
alpar@1253
    61
alpar@1253
    62
    ///Removes the components with zero coefficient.
alpar@1253
    63
    void simplify() {
alpar@1253
    64
      for (typename Base::iterator i=Base::begin(); i!=Base::end();) {
alpar@1253
    65
	typename Base::iterator j=i;
alpar@1253
    66
	++j;
alpar@1253
    67
	if ((*i).second==0) Base::erase(i);
alpar@1253
    68
	j=i;
alpar@1253
    69
      }
alpar@1253
    70
    }
alpar@1253
    71
   
alpar@1259
    72
    ///\e
alpar@1259
    73
    SparseLinExpr &operator+=(const SparseLinExpr &e) {
alpar@1259
    74
      for (typename Base::const_iterator j=e.begin(); j!=e.end(); ++j)
alpar@1259
    75
	(*this)[j->first]+=j->second;
alpar@1259
    76
      ///\todo it might be speeded up using "hints"
alpar@1259
    77
      const_comp+=e.const_comp;
alpar@1259
    78
      return *this;
alpar@1259
    79
    }
alpar@1259
    80
    ///\e
alpar@1259
    81
    SparseLinExpr &operator-=(const SparseLinExpr &e) {
alpar@1259
    82
      for (typename Base::const_iterator j=e.begin(); j!=e.end(); ++j)
alpar@1259
    83
	(*this)[j->first]-=j->second;
alpar@1259
    84
      const_comp-=e.const_comp;
alpar@1259
    85
      return *this;
alpar@1259
    86
    }
alpar@1259
    87
    ///\e
alpar@1259
    88
    SparseLinExpr &operator*=(const Coeff &c) {
alpar@1259
    89
      for (typename Base::iterator j=Base::begin(); j!=Base::end(); ++j)
alpar@1259
    90
	j->second*=c;
alpar@1259
    91
      const_comp*=c;
alpar@1259
    92
      return *this;
alpar@1259
    93
    }
alpar@1259
    94
    ///\e
alpar@1259
    95
    SparseLinExpr &operator/=(const Coeff &c) {
alpar@1259
    96
      for (typename Base::iterator j=Base::begin(); j!=Base::end(); ++j)
alpar@1259
    97
	j->second/=c;
alpar@1259
    98
      const_comp/=c;
alpar@1259
    99
      return *this;
alpar@1259
   100
    }
alpar@1259
   101
    
alpar@1253
   102
  };
alpar@1253
   103
alpar@1259
   104
  ///\e
alpar@1259
   105
  
alpar@1259
   106
  ///\relates SparseLinExpr
alpar@1259
   107
  ///
alpar@1259
   108
  template <class V>
alpar@1259
   109
  SparseLinExpr<V> operator+(const SparseLinExpr<V> &a,
alpar@1259
   110
				const SparseLinExpr<V> &b) {
alpar@1259
   111
    SparseLinExpr<V> tmp(a);
alpar@1259
   112
    tmp+=b; ///\todo Don't STL have some special 'merge' algorithm?
alpar@1259
   113
    return tmp;
alpar@1259
   114
  }
alpar@1259
   115
  
alpar@1259
   116
  ///\e
alpar@1259
   117
  
alpar@1259
   118
  ///\relates SparseLinExpr
alpar@1259
   119
  ///
alpar@1259
   120
  template <class V>
alpar@1259
   121
  SparseLinExpr<V> operator-(const SparseLinExpr<V> &a,
alpar@1259
   122
				const SparseLinExpr<V> &b) {
alpar@1259
   123
    SparseLinExpr<V> tmp(a);
alpar@1259
   124
    tmp-=b; ///\todo Don't STL have some special 'merge' algorithm?
alpar@1259
   125
    return tmp;
alpar@1259
   126
  }
alpar@1259
   127
  
alpar@1259
   128
  ///\e
alpar@1259
   129
  
alpar@1259
   130
  ///\relates SparseLinExpr
alpar@1259
   131
  ///
alpar@1259
   132
  template <class V>
alpar@1259
   133
  SparseLinExpr<V> operator*(const typename V::ExprValue &c,
alpar@1259
   134
			       const SparseLinExpr<V> &e) {
alpar@1259
   135
    SparseLinExpr<V> tmp(e);
alpar@1259
   136
    tmp*=c;
alpar@1259
   137
    return tmp;
alpar@1259
   138
  }
alpar@1259
   139
  
alpar@1259
   140
  ///\e
alpar@1259
   141
  
alpar@1259
   142
  ///\relates SparseLinExpr
alpar@1259
   143
  ///
alpar@1259
   144
  template <class V>
alpar@1259
   145
  SparseLinExpr<V> operator*(const SparseLinExpr<V> &e,
alpar@1259
   146
			       const typename V::ExprValue &c) {
alpar@1259
   147
    SparseLinExpr<V> tmp(e);
alpar@1259
   148
    tmp*=c;
alpar@1259
   149
    return tmp;
alpar@1259
   150
  }
alpar@1259
   151
  
alpar@1259
   152
  
alpar@1259
   153
  ///\e
alpar@1259
   154
  
alpar@1259
   155
  ///\relates SparseLinExpr
alpar@1259
   156
  ///
alpar@1259
   157
  template <class V>
alpar@1259
   158
  SparseLinExpr<V> operator/(const SparseLinExpr<V> &e,
alpar@1259
   159
			       const typename V::ExprValue &c) {
alpar@1259
   160
    SparseLinExpr<V> tmp(e);
alpar@1259
   161
    tmp/=c;
alpar@1259
   162
    return tmp;
alpar@1259
   163
  }
alpar@1259
   164
  
alpar@1259
   165
  ///\e
alpar@1259
   166
  
alpar@1259
   167
  ///\relates SparseLinExpr
alpar@1259
   168
  ///
alpar@1259
   169
  template <class V>
alpar@1259
   170
  SparseLinExpr<V> operator+(const typename V::ExprValue &c,
alpar@1259
   171
			     const SparseLinExpr<V> &e) {
alpar@1259
   172
    SparseLinExpr<V> tmp(e);
alpar@1259
   173
    tmp.constComp()+=c;
alpar@1259
   174
    return tmp;
alpar@1259
   175
  }
alpar@1259
   176
alpar@1259
   177
  ///\e
alpar@1259
   178
  
alpar@1259
   179
  ///\relates SparseLinExpr
alpar@1259
   180
  ///
alpar@1259
   181
  template <class V>
alpar@1259
   182
  SparseLinExpr<V> operator+(const SparseLinExpr<V> &e,
alpar@1259
   183
			     const typename V::ExprValue &c) {
alpar@1259
   184
    SparseLinExpr<V> tmp(e);
alpar@1259
   185
    tmp.constComp()+=c;
alpar@1259
   186
    return tmp;
alpar@1259
   187
  }
alpar@1259
   188
alpar@1259
   189
  ///\e
alpar@1259
   190
  
alpar@1259
   191
  ///\relates SparseLinExpr
alpar@1259
   192
  ///
alpar@1259
   193
  template <class V>
alpar@1259
   194
  SparseLinExpr<V> operator+(const V &v,const SparseLinExpr<V> &e) {
alpar@1259
   195
    SparseLinExpr<V> tmp(e);
alpar@1259
   196
    tmp[v]+=1;
alpar@1259
   197
    return tmp;
alpar@1259
   198
  }
alpar@1259
   199
alpar@1259
   200
  ///\e
alpar@1259
   201
  
alpar@1259
   202
  ///\relates SparseLinExpr
alpar@1259
   203
  ///
alpar@1259
   204
  template <class V>
alpar@1259
   205
  SparseLinExpr<V> operator+(const SparseLinExpr<V> &e,const V &v) {
alpar@1259
   206
    SparseLinExpr<V> tmp(e);
alpar@1259
   207
    tmp[v]+=1;
alpar@1259
   208
    return tmp;
alpar@1259
   209
  }
alpar@1259
   210
alpar@1259
   211
  ///\e
alpar@1259
   212
  
alpar@1259
   213
  ///\relates SparseLinExpr
alpar@1259
   214
  ///
alpar@1259
   215
  template <class V>
alpar@1259
   216
  SparseLinExpr<V> operator-(const typename V::ExprValue &c,
alpar@1259
   217
			     const SparseLinExpr<V> &e) {
alpar@1259
   218
    SparseLinExpr<V> tmp(e);
alpar@1259
   219
    tmp*=-1;
alpar@1259
   220
    tmp.constComp()+=c;
alpar@1259
   221
    return tmp;
alpar@1259
   222
  }
alpar@1259
   223
alpar@1259
   224
  ///\e
alpar@1259
   225
  
alpar@1259
   226
  ///\relates SparseLinExpr
alpar@1259
   227
  ///
alpar@1259
   228
  template <class V>
alpar@1259
   229
  SparseLinExpr<V> operator-(const SparseLinExpr<V> &e,
alpar@1259
   230
			     const typename V::ExprValue &c) {
alpar@1259
   231
    SparseLinExpr<V> tmp(e);
alpar@1259
   232
    tmp.constComp()-=c;
alpar@1259
   233
    return tmp;
alpar@1259
   234
  }
alpar@1259
   235
alpar@1259
   236
  ///\e
alpar@1259
   237
  
alpar@1259
   238
  ///\relates SparseLinExpr
alpar@1259
   239
  ///
alpar@1259
   240
  template <class V>
alpar@1259
   241
  SparseLinExpr<V> operator-(const V &v,const SparseLinExpr<V> &e) {
alpar@1259
   242
    SparseLinExpr<V> tmp(e);
alpar@1259
   243
    tmp*=-1;
alpar@1259
   244
    tmp[v]+=1;
alpar@1259
   245
    return tmp;
alpar@1259
   246
  }
alpar@1259
   247
alpar@1259
   248
  ///\e
alpar@1259
   249
  
alpar@1259
   250
  ///\relates SparseLinExpr
alpar@1259
   251
  ///
alpar@1259
   252
  template <class V>
alpar@1259
   253
  SparseLinExpr<V> operator-(const SparseLinExpr<V> &e,const V &v) {
alpar@1259
   254
    SparseLinExpr<V> tmp(e);
alpar@1259
   255
    tmp[v]-=1;
alpar@1259
   256
    return tmp;
alpar@1259
   257
  }
alpar@1259
   258
alpar@1259
   259
  ///\e
alpar@1259
   260
  
alpar@1259
   261
  ///\relates SparseLinExpr
alpar@1259
   262
  ///
alpar@1259
   263
  template <class V>
alpar@1264
   264
  SparseLinExpr<V> operator+(const V &v,const typename V::ExprValue &c) {
alpar@1264
   265
    SparseLinExpr<V> tmp(v);
alpar@1264
   266
    tmp.constComp()=c;
alpar@1264
   267
    return tmp;
alpar@1264
   268
  }
alpar@1264
   269
alpar@1264
   270
  ///\e
alpar@1264
   271
  
alpar@1264
   272
  ///\relates SparseLinExpr
alpar@1264
   273
  ///
alpar@1264
   274
  template <class V>
alpar@1264
   275
  SparseLinExpr<V> operator-(const V &v,const typename V::ExprValue &c) {
alpar@1264
   276
    SparseLinExpr<V> tmp(v);
alpar@1264
   277
    tmp.constComp()=-c;
alpar@1264
   278
    return tmp;
alpar@1264
   279
  }
alpar@1264
   280
alpar@1264
   281
  ///\e
alpar@1264
   282
  
alpar@1264
   283
  ///\relates SparseLinExpr
alpar@1264
   284
  ///
alpar@1264
   285
  template <class V>
alpar@1264
   286
  SparseLinExpr<V> operator+(const typename V::ExprValue &c,const V &v) {
alpar@1264
   287
    SparseLinExpr<V> tmp(v);
alpar@1264
   288
    tmp.constComp()=c;
alpar@1264
   289
    return tmp;
alpar@1264
   290
  }
alpar@1264
   291
alpar@1264
   292
  ///\e
alpar@1264
   293
  
alpar@1264
   294
  ///\relates SparseLinExpr
alpar@1264
   295
  ///
alpar@1264
   296
  template <class V>
alpar@1264
   297
  SparseLinExpr<V> operator-(const typename V::ExprValue &c,const V &v) {
alpar@1264
   298
    SparseLinExpr<V> tmp(c);
alpar@1264
   299
    tmp[v]=-1;
alpar@1264
   300
    return tmp;
alpar@1264
   301
  }
alpar@1264
   302
alpar@1264
   303
  ///\e
alpar@1264
   304
  
alpar@1264
   305
  ///\relates SparseLinExpr
alpar@1264
   306
  ///
alpar@1264
   307
  template <class V>
alpar@1259
   308
  SparseLinExpr<V> operator+(const V &v1,const V &v2) {
alpar@1259
   309
    SparseLinExpr<V> tmp(v1);
alpar@1259
   310
    tmp[v2]+=1;
alpar@1259
   311
    return tmp;
alpar@1259
   312
  }
alpar@1259
   313
alpar@1259
   314
  ///\e
alpar@1259
   315
  
alpar@1259
   316
  ///\relates SparseLinExpr
alpar@1259
   317
  ///
alpar@1259
   318
  template <class V>
alpar@1259
   319
  SparseLinExpr<V> operator*(const V &v,const typename V::ExprValue &c) {
alpar@1259
   320
    SparseLinExpr<V> tmp;
alpar@1259
   321
    tmp[v]=c;
alpar@1259
   322
    return tmp;
alpar@1259
   323
  }
alpar@1259
   324
alpar@1259
   325
  ///\e
alpar@1259
   326
  
alpar@1259
   327
  ///\relates SparseLinExpr
alpar@1259
   328
  ///
alpar@1259
   329
  template <class V>
alpar@1259
   330
  SparseLinExpr<V> operator*(const typename V::ExprValue &c,const V &v) {
alpar@1259
   331
    SparseLinExpr<V> tmp;
alpar@1259
   332
    tmp[v]=c;
alpar@1259
   333
    return tmp;
alpar@1259
   334
  }
alpar@1259
   335
alpar@1259
   336
  ///\e
alpar@1259
   337
  
alpar@1259
   338
  ///\relates SparseLinExpr
alpar@1259
   339
  ///
alpar@1259
   340
  template <class V>
alpar@1259
   341
  SparseLinExpr<V> operator/(const V &v,const typename V::ExprValue &c) {
alpar@1259
   342
    SparseLinExpr<V> tmp;
alpar@1259
   343
    tmp[v]=1/c;
alpar@1259
   344
    return tmp;
alpar@1259
   345
  }
alpar@1259
   346
alpar@1259
   347
alpar@1264
   348
  //////////////////////////////////////////////////////////////////////
alpar@1264
   349
  /// Constraints
alpar@1264
   350
  //////////////////////////////////////////////////////////////////////
alpar@1264
   351
  
alpar@1264
   352
  template <class E>
alpar@1264
   353
  class LinConstr
alpar@1264
   354
  {
alpar@1264
   355
  public:
alpar@1264
   356
    typedef E Expr;
alpar@1264
   357
    typedef typename E::Var Var;
alpar@1264
   358
    typedef typename E::Coeff Coeff;
alpar@1264
   359
    
alpar@1264
   360
    static const Coeff INF;
alpar@1264
   361
    static const Coeff NaN;
alpar@1264
   362
//     static const Coeff INF=0;
alpar@1264
   363
//     static const Coeff NaN=1;
alpar@1264
   364
alpar@1264
   365
    Expr expr;
alpar@1264
   366
    Coeff lb,ub;
alpar@1264
   367
    
alpar@1264
   368
    LinConstr() : expr(), lb(NaN), ub(NaN) {}
alpar@1264
   369
    LinConstr(Coeff _lb,const Expr &e,Coeff _ub) :
alpar@1264
   370
      expr(e), lb(_lb), ub(_ub) {}
alpar@1264
   371
    LinConstr(const Expr &e,Coeff _ub) : 
alpar@1264
   372
      expr(e), lb(NaN), ub(_ub) {}
alpar@1264
   373
    LinConstr(Coeff _lb,const Expr &e) :
alpar@1264
   374
      expr(e), lb(_lb), ub(NaN) {}
alpar@1264
   375
  };
alpar@1264
   376
alpar@1264
   377
  template<class E>
alpar@1264
   378
  const typename LinConstr<E>::Coeff LinConstr<E>::INF=
alpar@1264
   379
    std::numeric_limits<Coeff>::infinity();
alpar@1264
   380
  template<class E>
alpar@1264
   381
  const typename LinConstr<E>::Coeff LinConstr<E>::NaN=
alpar@1264
   382
    std::numeric_limits<Coeff>::quiet_NaN();
alpar@1264
   383
alpar@1264
   384
  
alpar@1264
   385
  template<class E>
alpar@1264
   386
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   387
  operator<=(const E &e,const E &f) 
alpar@1264
   388
  {
alpar@1264
   389
    return LinConstr<E>(-LinConstr<E>::INF,e-f,0);
alpar@1264
   390
  }
alpar@1264
   391
alpar@1264
   392
  template<class E>
alpar@1264
   393
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   394
  operator>=(const E &e,const E &f) 
alpar@1264
   395
  {
alpar@1264
   396
    return LinConstr<E>(-LinConstr<E>::INF,f-e,0);
alpar@1264
   397
  }
alpar@1264
   398
alpar@1264
   399
  template<class E>
alpar@1264
   400
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   401
  operator==(const E &e,const E &f) 
alpar@1264
   402
  {
alpar@1264
   403
    return LinConstr<E>(0,e-f,0);
alpar@1264
   404
  }
alpar@1264
   405
  
alpar@1264
   406
  //////////////////////////////
alpar@1264
   407
alpar@1264
   408
  template<class E>
alpar@1264
   409
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   410
  operator<=(const E &e,const typename E::Coeff &n) 
alpar@1264
   411
  {
alpar@1264
   412
    return LinConstr<E>(e,n);
alpar@1264
   413
  }
alpar@1264
   414
alpar@1264
   415
  template<class E>
alpar@1264
   416
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   417
  operator>=(const E &e,const typename E::Coeff &n) 
alpar@1264
   418
  {
alpar@1264
   419
    return LinConstr<E>(n,e);
alpar@1264
   420
  }
alpar@1264
   421
alpar@1264
   422
  template<class E>
alpar@1264
   423
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   424
  operator==(const E &e,const typename E::Coeff &n) 
alpar@1264
   425
  {
alpar@1264
   426
    return LinConstr<E>(n,e,n);
alpar@1264
   427
  }
alpar@1264
   428
alpar@1264
   429
  //////////////////////////////
alpar@1264
   430
alpar@1264
   431
  template<class E>
alpar@1264
   432
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   433
  operator<=(const typename E::Coeff &n,const E &e) 
alpar@1264
   434
  {
alpar@1264
   435
    return LinConstr<E>(n,e);
alpar@1264
   436
  }
alpar@1264
   437
alpar@1264
   438
  template<class E>
alpar@1264
   439
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   440
  operator>=(const typename E::Coeff &n,const E &e) 
alpar@1264
   441
  {
alpar@1264
   442
    return LinConstr<E>(e,n);
alpar@1264
   443
  }
alpar@1264
   444
alpar@1264
   445
  template<class E>
alpar@1264
   446
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   447
  operator==(const typename E::Coeff &n,const E &e) 
alpar@1264
   448
  {
alpar@1264
   449
    return LinConstr<E>(n,e,n);
alpar@1264
   450
  }
alpar@1264
   451
alpar@1264
   452
  //////////////////////////////
alpar@1264
   453
alpar@1264
   454
  template<class E>
alpar@1264
   455
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   456
  operator<=(const typename E::Coeff &n,const LinConstr<E> &c) 
alpar@1264
   457
  {
alpar@1264
   458
    LinConstr<E> tmp(c);
alpar@1264
   459
    if(tmp.lb!=tmp.NaN) throw LogicError();
alpar@1264
   460
    else tmp.lb=n;
alpar@1264
   461
    return tmp;
alpar@1264
   462
  }
alpar@1264
   463
alpar@1264
   464
  template<class E>
alpar@1264
   465
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   466
  operator>=(const typename E::Coeff &n,const LinConstr<E> &c) 
alpar@1264
   467
  {
alpar@1264
   468
    LinConstr<E> tmp(c);
alpar@1264
   469
    if(tmp.ub!=tmp.NaN) throw LogicError();
alpar@1264
   470
    else tmp.ub=n;
alpar@1264
   471
    return tmp;
alpar@1264
   472
  }
alpar@1264
   473
alpar@1264
   474
  template<class E>
alpar@1264
   475
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   476
  operator<=(const LinConstr<E> &c,const typename E::Coeff &n) 
alpar@1264
   477
  {
alpar@1264
   478
    LinConstr<E> tmp(c);
alpar@1264
   479
    if(tmp.ub!=tmp.NaN) throw LogicError();
alpar@1264
   480
    else tmp.ub=n;
alpar@1264
   481
    return tmp;
alpar@1264
   482
  }
alpar@1264
   483
alpar@1264
   484
  template<class E>
alpar@1264
   485
  typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
alpar@1264
   486
  operator>=(const LinConstr<E> &c,const typename E::Coeff &n) 
alpar@1264
   487
  {
alpar@1264
   488
    LinConstr<E> tmp(c);
alpar@1264
   489
    if(tmp.lb!=tmp.NaN) throw LogicError();
alpar@1264
   490
    else tmp.lb=n;
alpar@1264
   491
    return tmp;
alpar@1264
   492
  }
alpar@1264
   493
alpar@1264
   494
  
alpar@1264
   495
alpar@1253
   496
} //namespace lemon
alpar@1253
   497
alpar@1253
   498
#endif //LEMON_LIN_EXPR_H