lemon/polynomial.h
author kpeter
Sun, 05 Oct 2008 13:46:07 +0000
changeset 2621 814ba94d9989
parent 2391 14a343be7a5a
permissions -rw-r--r--
Bug fix in min_cost_flow_test.cc
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@2553
     5
 * Copyright (C) 2003-2008
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
    {
deba@2386
    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
    {
deba@2386
   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);
deba@2386
   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;
deba@2386
   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);
deba@2386
   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