bernstein.h 2.3 KB
Newer Older
1
/**
Guilhem Saurel's avatar
Guilhem Saurel committed
2
3
4
5
6
7
 * \file bezier_curve.h
 * \brief class allowing to create a Bezier curve of dimension 1 <= n <= 3.
 * \author Steve T.
 * \version 0.1
 * \date 06/17/2013
 */
8
9
10
11
12
13
14
15
16
17
18
19

#ifndef _CLASS_BERNSTEIN
#define _CLASS_BERNSTEIN

#include "curve_abc.h"

#include "MathDefs.h"

#include <math.h>
#include <vector>
#include <stdexcept>

Guilhem Saurel's avatar
Guilhem Saurel committed
20
21
22
23
24
25
26
27
28
29
30
31
namespace curves {
/// \brief Computes a binomial coefficient  .
/// \param n : an unsigned integer.
/// \param k : an unsigned integer.
/// \return \f$\binom{n}{k}f$
///
inline unsigned int bin(const unsigned int n, const unsigned int k) {
  if (k > n) throw std::runtime_error("binomial coefficient higher than degree");
  if (k == 0) return 1;
  if (k > n / 2) return bin(n, n - k);
  return n * bin(n - 1, k - 1) / k;
}
32

Guilhem Saurel's avatar
Guilhem Saurel committed
33
34
35
36
37
38
39
/// \class Bernstein.
/// \brief Computes a Bernstein polynome.
///
template <typename Numeric = double>
struct Bern {
  Bern() {}
  Bern(const unsigned int m, const unsigned int i) : m_minus_i(m - i), i_(i), bin_m_i_(bin(m, i)) {}
40

Guilhem Saurel's avatar
Guilhem Saurel committed
41
  ~Bern() {}
42

Guilhem Saurel's avatar
Guilhem Saurel committed
43
44
45
46
  Numeric operator()(const Numeric u) const {
    assert(u >= 0. && u <= 1.);
    return bin_m_i_ * (pow(u, i_)) * pow((1 - u), m_minus_i);
  }
47

48
49
50
51
52
53
54
55
56
57
58
  virtual bool operator== (const Bern& other) const{
    return m_minus_i == other.m_minus_i
        && i_ == other.i_
        && bin_m_i_ == other.bin_m_i_;
  }

  virtual bool operator!=(const Bern& other) const {
    return !(*this == other);
  }


Guilhem Saurel's avatar
Guilhem Saurel committed
59
60
61
62
63
  /* Attributes */
  Numeric m_minus_i;
  Numeric i_;
  Numeric bin_m_i_;
  /* Attributes */
64

Guilhem Saurel's avatar
Guilhem Saurel committed
65
66
67
68
69
  // Serialization of the class
  friend class boost::serialization::access;
  template <class Archive>
  void serialize(Archive& ar, const unsigned int version) {
    if (version) {
70
      // Do something depending on version ?
71
    }
Guilhem Saurel's avatar
Guilhem Saurel committed
72
73
74
    ar& boost::serialization::make_nvp("m_minus_i", m_minus_i);
    ar& boost::serialization::make_nvp("i", i_);
    ar& boost::serialization::make_nvp("bin_m_i", bin_m_i_);
75
  }
Guilhem Saurel's avatar
Guilhem Saurel committed
76
};  // End struct Bern
77

Guilhem Saurel's avatar
Guilhem Saurel committed
78
79
80
81
82
83
84
85
86
87
88
89
/// \brief Computes all Bernstein polynomes for a certain degree.
///
template <typename Numeric>
std::vector<Bern<Numeric> > makeBernstein(const unsigned int n) {
  std::vector<Bern<Numeric> > res;
  for (unsigned int i = 0; i <= n; ++i) {
    res.push_back(Bern<Numeric>(n, i));
  }
  return res;
}
}  // namespace curves
#endif  //_CLASS_BERNSTEIN