lemon/polynomial.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2199 1229af45cc69
child 2386 81b47fc5c444
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
alpar@2086
     1
/* -*- C++ -*-
alpar@2086
     2
 *
alpar@2086
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@2086
     4
 *
alpar@2086
     5
 * Copyright (C) 2003-2006
alpar@2086
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@2086
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@2086
     8
 *
alpar@2086
     9
 * Permission to use, modify and distribute this software is granted
alpar@2086
    10
 * provided that this copyright notice appears in all copies. For
alpar@2086
    11
 * precise terms see the accompanying LICENSE file.
alpar@2086
    12
 *
alpar@2086
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@2086
    14
 * express or implied, and with no claim as to its suitability for any
alpar@2086
    15
 * purpose.
alpar@2086
    16
 *
alpar@2086
    17
 */
alpar@2086
    18
alpar@2086
    19
#ifndef LEMON_BEZIER_H
alpar@2086
    20
#define LEMON_BEZIER_H
alpar@2086
    21
alpar@2086
    22
///\ingroup misc
alpar@2086
    23
///\file
alpar@2086
    24
///\brief A simple class implementing polynomials.
alpar@2086
    25
///
alpar@2086
    26
///\author Alpar Juttner
alpar@2086
    27
alpar@2086
    28
#include<vector>
alpar@2086
    29
alpar@2086
    30
namespace lemon {
alpar@2086
    31
alpar@2086
    32
  /// \addtogroup misc
alpar@2086
    33
  /// @{
alpar@2086
    34
alpar@2086
    35
  ///Simple polinomial class
alpar@2086
    36
alpar@2086
    37
  ///This class implements a polynomial where the coefficients are of
alpar@2086
    38
  ///type \c T.
alpar@2086
    39
  ///
alpar@2086
    40
  ///The coefficients are stored in an std::vector.
alpar@2086
    41
  template<class T>
alpar@2086
    42
  class Polynomial
alpar@2086
    43
  {
alpar@2086
    44
    std::vector<T> _coeff;
alpar@2086
    45
  public:
alpar@2086
    46
    ///Construct a polynomial of degree \c d.
alpar@2086
    47
    explicit Polynomial(int d=0) : _coeff(d+1) {}
alpar@2086
    48
    ///\e
alpar@2086
    49
    template<class U> Polynomial(const U &u) : _coeff(1,u) {}
alpar@2086
    50
    ///\e
alpar@2086
    51
    template<class U> Polynomial(const Polynomial<U> &u) : _coeff(u.deg()+1)
alpar@2086
    52
    {
alpar@2086
    53
      for(int i=0;i<(int)_coeff.size();i++) _coeff[i]=u[i];
alpar@2086
    54
    }
alpar@2086
    55
    ///Query the degree of the polynomial.
alpar@2086
    56
    
alpar@2086
    57
    ///Query the degree of the polynomial.
alpar@2086
    58
    ///\warning This number differs from real degree of the polinomial if
alpar@2086
    59
    ///the coefficient of highest degree is 0.
alpar@2086
    60
    int deg() const { return _coeff.size()-1; }
alpar@2086
    61
    ///Set the degree of the polynomial.
alpar@2086
    62
alpar@2086
    63
    ///Set the degree of the polynomial. In fact it resizes the
alpar@2086
    64
    ///coefficient vector.
alpar@2086
    65
    void deg(int d) { _coeff.resize(d+1);}
alpar@2086
    66
alpar@2086
    67
    ///Returns (as a reference) the coefficient of degree \c d.
alpar@2086
    68
    typename std::vector<T>::reference operator[](int d) { return _coeff[d]; }
alpar@2086
    69
    ///Returns (as a const reference) the coefficient of degree \c d.
alpar@2086
    70
    typename std::vector<T>::const_reference
alpar@2086
    71
    operator[](int d) const {return _coeff[d];}
alpar@2086
    72
    
alpar@2086
    73
    ///Substitute the value u into the polinomial.
alpar@2086
    74
alpar@2086
    75
    ///Substitute the value u into the polinomial.
alpar@2086
    76
    ///The calculation will be done using type \c R.
alpar@2086
    77
    ///The following examples shows the usage of the template parameter \c R.
alpar@2086
    78
    ///\code
alpar@2207
    79
    ///  Polynomial<dim2::Point<double> > line(1);
alpar@2207
    80
    ///  line[0]=dim2::Point<double>(12,25);
alpar@2207
    81
    ///  line[1]=dim2::Point<double>(2,7);
alpar@2086
    82
    ///  ...
alpar@2207
    83
    ///  dim2::Point<double> d = line.subst<dim2::Point<double> >(23.2);
alpar@2086
    84
    ///\endcode
alpar@2086
    85
    ///
alpar@2086
    86
    ///\code
alpar@2086
    87
    ///  Polynomial<double> p;
alpar@2086
    88
    ///  Polynomial<double> q;
alpar@2086
    89
    ///  ...
alpar@2086
    90
    ///  Polynomial<double> s = p.subst<Polynomial<double> >(q);
alpar@2086
    91
    ///\endcode
alpar@2086
    92
    template<class R,class U>
alpar@2086
    93
    R subst(const U &u) const
alpar@2086
    94
    {
alpar@2086
    95
      typename std::vector<T>::const_reverse_iterator i=_coeff.rbegin();
alpar@2086
    96
      R v=*i;
alpar@2086
    97
      for(++i;i!=_coeff.rend();++i) v=v*u+*i;
alpar@2086
    98
      return v;
alpar@2086
    99
    }
alpar@2086
   100
    ///Substitute the value u into the polinomial.
alpar@2086
   101
alpar@2086
   102
    ///Substitute the value u into the polinomial.
alpar@2086
   103
    ///The calculation will be done using type \c T
alpar@2086
   104
    ///(i.e. using the type of the coefficients.)
alpar@2086
   105
    template<class U>
alpar@2086
   106
    T operator()(const U &u) const 
alpar@2086
   107
    {
alpar@2086
   108
      return subst<T>(u);
alpar@2086
   109
    }
alpar@2086
   110
    
alpar@2086
   111
    ///Derivate the polynomial (in place)
alpar@2086
   112
    Polynomial &derivateMyself()
alpar@2086
   113
    {
alpar@2086
   114
      for(int i=1;i<(int)_coeff.size();i++) _coeff[i-1]=i*_coeff[i];
alpar@2086
   115
      _coeff.pop_back();
alpar@2086
   116
      return *this;
alpar@2086
   117
    }
alpar@2086
   118
    
alpar@2086
   119
    ///Return the derivate of the polynomial
alpar@2086
   120
    Polynomial derivate() const
alpar@2086
   121
    {
alpar@2086
   122
      Polynomial tmp(deg()-1);
alpar@2086
   123
      for(int i=1;i<(int)_coeff.size();i++) tmp[i-1]=i*_coeff[i];
alpar@2086
   124
      return tmp;
alpar@2086
   125
    }
alpar@2086
   126
alpar@2086
   127
    ///Integrate the polynomial (in place)
alpar@2086
   128
    Polynomial &integrateMyself()
alpar@2086
   129
    {
alpar@2086
   130
      _coeff.push_back(T());
deba@2199
   131
      for(int i=_coeff.size()-1;i>0;i--) _coeff[i]=_coeff[i-1]/i;
alpar@2086
   132
      _coeff[0]=0;
alpar@2086
   133
      return *this;
alpar@2086
   134
    }
alpar@2086
   135
    
alpar@2086
   136
    ///Return the integrate of the polynomial
alpar@2086
   137
    Polynomial integrate() const
alpar@2086
   138
    {
alpar@2086
   139
      Polynomial tmp(deg()+1);
alpar@2086
   140
      tmp[0]=0;
alpar@2086
   141
      for(int i=0;i<(int)_coeff.size();i++) tmp[i+1]=_coeff[i]/(i+1);
alpar@2086
   142
      return tmp;
alpar@2086
   143
    }
alpar@2086
   144
alpar@2086
   145
    ///\e
alpar@2086
   146
    template<class U>
alpar@2086
   147
    Polynomial &operator+=(const Polynomial<U> &p)
alpar@2086
   148
    {
alpar@2086
   149
      if(p.deg()>deg()) _coeff.resize(p.deg()+1);
alpar@2086
   150
      for(int i=0;i<=(int)std::min(deg(),p.deg());i++)
alpar@2086
   151
	_coeff[i]+=p[i];
alpar@2086
   152
      return *this;
alpar@2086
   153
    }
alpar@2086
   154
    ///\e
alpar@2086
   155
    template<class U>
alpar@2086
   156
    Polynomial &operator-=(const Polynomial<U> &p)
alpar@2086
   157
    {
alpar@2086
   158
      if(p.deg()>deg()) _coeff.resize(p.deg()+1);
alpar@2086
   159
      for(int i=0;i<=std::min(deg(),p.deg());i++) _coeff[i]-=p[i];
alpar@2086
   160
      return *this;
alpar@2086
   161
    }
alpar@2086
   162
    ///\e
alpar@2086
   163
    template<class U>
alpar@2086
   164
    Polynomial &operator+=(const U &u)
alpar@2086
   165
    {
alpar@2086
   166
      _coeff[0]+=u;
alpar@2086
   167
      return *this;
alpar@2086
   168
    }
alpar@2086
   169
    ///\e
alpar@2086
   170
    template<class U>
alpar@2086
   171
    Polynomial &operator-=(const U &u)
alpar@2086
   172
    {
alpar@2086
   173
      _coeff[0]+=u;
alpar@2086
   174
      return *this;
alpar@2086
   175
    }
alpar@2086
   176
    ///\e
alpar@2086
   177
    template<class U>
alpar@2086
   178
    Polynomial &operator*=(const U &u)
alpar@2086
   179
    {
alpar@2086
   180
      for(typename std::vector<T>::iterator i=_coeff.begin();i!=_coeff.end();++i)
alpar@2086
   181
	*i*=u;
alpar@2086
   182
      return *this;
alpar@2086
   183
    }
alpar@2086
   184
    ///\e
alpar@2086
   185
    template<class U>
alpar@2086
   186
    Polynomial &operator/=(const U &u)
alpar@2086
   187
    {
alpar@2086
   188
      for(typename std::vector<T>::iterator i=_coeff.begin();i!=_coeff.end();++i)
alpar@2086
   189
	*i/=u;
alpar@2086
   190
      return *this;
alpar@2086
   191
    }
alpar@2086
   192
alpar@2086
   193
  };
alpar@2086
   194
  
alpar@2086
   195
  ///Equality comparison
alpar@2086
   196
alpar@2086
   197
  ///\relates Polynomial
alpar@2086
   198
  ///\warning Two polynomials are defined to be unequal if their degrees differ,
alpar@2086
   199
  ///even if the non-zero coefficients are the same.
alpar@2086
   200
  template<class U,class V>
alpar@2086
   201
  bool operator==(const Polynomial<U> &u,const Polynomial<V> &v)
alpar@2086
   202
  {
alpar@2086
   203
    if(u.deg()!=v.deg()) return false;
alpar@2086
   204
    for(int i=0;i<=u.deg();i++) if(u[i]!=v[i]) return false;
alpar@2086
   205
    return true;
alpar@2086
   206
  }
alpar@2086
   207
alpar@2086
   208
  ///Non-equality comparison
alpar@2086
   209
alpar@2086
   210
  ///\relates Polynomial
alpar@2086
   211
  ///\warning Two polynomials are defined to be unequal if their degrees differ,
alpar@2086
   212
  ///even if the non-zero coefficients are the same.
alpar@2086
   213
  template<class U,class V>
alpar@2086
   214
  bool operator!=(const Polynomial<U> &u,const Polynomial<V> &v)
alpar@2086
   215
  {
alpar@2086
   216
    return !(u==v);
alpar@2086
   217
  }
alpar@2086
   218
alpar@2086
   219
  ///\e
alpar@2086
   220
alpar@2086
   221
  ///\relates Polynomial
alpar@2086
   222
  ///
alpar@2086
   223
  template<class U,class V>
alpar@2086
   224
  Polynomial<U> operator+(const Polynomial<U> &u,const Polynomial<V> &v)
alpar@2086
   225
  {
alpar@2086
   226
    Polynomial<U> tmp=u;
alpar@2086
   227
    tmp+=v;
alpar@2086
   228
    return tmp;
alpar@2086
   229
  }
alpar@2086
   230
alpar@2086
   231
  ///\e
alpar@2086
   232
alpar@2086
   233
  ///\relates Polynomial
alpar@2086
   234
  ///
alpar@2086
   235
  template<class U,class V>
alpar@2086
   236
  Polynomial<U> operator-(const Polynomial<U> &u,const Polynomial<V> &v)
alpar@2086
   237
  {
alpar@2086
   238
    Polynomial<U> tmp=u;
alpar@2086
   239
    tmp-=v;
alpar@2086
   240
    return tmp;
alpar@2086
   241
  }
alpar@2086
   242
alpar@2086
   243
  ///\e
alpar@2086
   244
alpar@2086
   245
  ///\relates Polynomial
alpar@2086
   246
  ///
alpar@2086
   247
  template<class U,class V>
alpar@2086
   248
  Polynomial<U> operator*(const Polynomial<U> &u,const Polynomial<V> &v)
alpar@2086
   249
  {
alpar@2086
   250
    Polynomial<U> tmp(u.deg()+v.deg());
alpar@2086
   251
    for(int i=0;i<=v.deg();i++)
alpar@2086
   252
      for(int j=0;j<=u.deg();j++)
alpar@2086
   253
	tmp[i+j]+=v[i]*u[j];
alpar@2086
   254
    return tmp;
alpar@2086
   255
  }
alpar@2086
   256
  ///\e
alpar@2086
   257
alpar@2086
   258
  ///\relates Polynomial
alpar@2086
   259
  ///
alpar@2086
   260
  template<class U,class V>
alpar@2086
   261
  Polynomial<U> operator+(const Polynomial<U> &u,const V &v)
alpar@2086
   262
  {
alpar@2086
   263
    Polynomial<U> tmp=u;
alpar@2086
   264
    tmp+=v;
alpar@2086
   265
    return tmp;
alpar@2086
   266
  }
alpar@2086
   267
  ///\e
alpar@2086
   268
alpar@2086
   269
  ///\relates Polynomial
alpar@2086
   270
  ///
alpar@2086
   271
  template<class U,class V>
alpar@2086
   272
  Polynomial<U> operator+(const V &v,const Polynomial<U> &u)
alpar@2086
   273
  {
alpar@2086
   274
    Polynomial<U> tmp=u;
alpar@2086
   275
    tmp+=v;
alpar@2086
   276
    return tmp;
alpar@2086
   277
  }
alpar@2086
   278
  ///\e
alpar@2086
   279
alpar@2086
   280
  ///\relates Polynomial
alpar@2086
   281
  ///
alpar@2086
   282
  template<class U,class V>
alpar@2086
   283
  Polynomial<U> operator-(const Polynomial<U> &u,const V &v)
alpar@2086
   284
  {
alpar@2086
   285
    Polynomial<U> tmp=u;
alpar@2086
   286
    tmp-=v;
alpar@2086
   287
    return tmp;
alpar@2086
   288
  }
alpar@2086
   289
  ///\e
alpar@2086
   290
alpar@2086
   291
  ///\relates Polynomial
alpar@2086
   292
  ///
alpar@2086
   293
  template<class U>
alpar@2086
   294
  Polynomial<U> operator-(const Polynomial<U> &u)
alpar@2086
   295
  {
alpar@2086
   296
    Polynomial<U> tmp(u.deg());
alpar@2086
   297
    for(int i=0;i<=u.deg();i++) tmp[i]=-u[i];
alpar@2086
   298
    return tmp;
alpar@2086
   299
  }
alpar@2086
   300
  ///\e
alpar@2086
   301
alpar@2086
   302
  ///\relates Polynomial
alpar@2086
   303
  ///
alpar@2086
   304
  template<class U,class V>
alpar@2086
   305
  Polynomial<U> operator-(const V &v,const Polynomial<U> &u)
alpar@2086
   306
  {
alpar@2086
   307
    Polynomial<U> tmp=-u;
alpar@2086
   308
    tmp+=v;
alpar@2086
   309
    return tmp;
alpar@2086
   310
  }
alpar@2086
   311
  ///\e
alpar@2086
   312
alpar@2086
   313
  ///\relates Polynomial
alpar@2086
   314
  ///
alpar@2086
   315
  template<class U,class V>
alpar@2086
   316
  Polynomial<U> operator*(const Polynomial<U> &u,const V &v)
alpar@2086
   317
  {
alpar@2086
   318
    Polynomial<U> tmp=u;
alpar@2086
   319
    tmp*=v;
alpar@2086
   320
    return tmp;
alpar@2086
   321
  }
alpar@2086
   322
  ///\e
alpar@2086
   323
alpar@2086
   324
  ///\relates Polynomial
alpar@2086
   325
  ///
alpar@2086
   326
  template<class U,class V>
alpar@2086
   327
  Polynomial<U> operator*(const V &v,const Polynomial<U> &u)
alpar@2086
   328
  {
alpar@2086
   329
    Polynomial<U> tmp=u;
alpar@2086
   330
    tmp*=v;
alpar@2086
   331
    return tmp;
alpar@2086
   332
  }
alpar@2086
   333
  ///\e
alpar@2086
   334
alpar@2086
   335
  ///\relates Polynomial
alpar@2086
   336
  ///
alpar@2086
   337
  template<class U,class V>
alpar@2086
   338
  Polynomial<U> operator/(const Polynomial<U> &u,const V &v)
alpar@2086
   339
  {
alpar@2086
   340
    Polynomial<U> tmp=u;
alpar@2086
   341
    tmp/=v;
alpar@2086
   342
    return tmp;
alpar@2086
   343
  }
alpar@2086
   344
    
alpar@2086
   345
  /// @}
alpar@2086
   346
alpar@2086
   347
} //END OF NAMESPACE LEMON
alpar@2086
   348
alpar@2086
   349
#endif // LEMON_POLYNOMIAL_H