| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /** | ||
| 2 | * \file bezier_curve.h | ||
| 3 | * \brief class allowing to create a Bezier curve of dimension 1 <= n <= 3. | ||
| 4 | * \author Steve T. | ||
| 5 | * \version 0.1 | ||
| 6 | * \date 06/17/2013 | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef _CLASS_BERNSTEIN | ||
| 10 | #define _CLASS_BERNSTEIN | ||
| 11 | |||
| 12 | #include <math.h> | ||
| 13 | |||
| 14 | #include <stdexcept> | ||
| 15 | #include <vector> | ||
| 16 | |||
| 17 | #include "MathDefs.h" | ||
| 18 | #include "curve_abc.h" | ||
| 19 | |||
| 20 | namespace ndcurves { | ||
| 21 | /// \brief Computes a binomial coefficient . | ||
| 22 | /// \param n : an unsigned integer. | ||
| 23 | /// \param k : an unsigned integer. | ||
| 24 | /// \return \f$\binom{n}{k}f$ | ||
| 25 | /// | ||
| 26 | 50016 | inline unsigned int bin(const unsigned int n, const unsigned int k) { | |
| 27 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 50016 times.
|
50016 | if (k > n) |
| 28 | ✗ | throw std::runtime_error("binomial coefficient higher than degree"); | |
| 29 |
2/2✓ Branch 0 taken 22498 times.
✓ Branch 1 taken 27518 times.
|
50016 | if (k == 0) return 1; |
| 30 |
2/2✓ Branch 0 taken 10345 times.
✓ Branch 1 taken 17173 times.
|
27518 | if (k > n / 2) return bin(n, n - k); |
| 31 | 17173 | return n * bin(n - 1, k - 1) / k; | |
| 32 | } | ||
| 33 | |||
| 34 | /// \class Bernstein. | ||
| 35 | /// \brief Computes a Bernstein polynomial. | ||
| 36 | /// | ||
| 37 | template <typename Numeric = double> | ||
| 38 | struct Bern { | ||
| 39 | 92 | Bern() {} | |
| 40 | 22192 | Bern(const unsigned int m, const unsigned int i) | |
| 41 | 22192 | : m_minus_i(m - i), i_(i), bin_m_i_(bin(m, i)) {} | |
| 42 | |||
| 43 | 139182 | virtual ~Bern() {} | |
| 44 | |||
| 45 | /// \brief Evaluation of Bernstein polynomial at value u. | ||
| 46 | /// \param u : value between 0 and 1. | ||
| 47 | /// \return Evaluation corresponding at value u. | ||
| 48 | 1200070 | Numeric operator()(const Numeric u) const { | |
| 49 |
2/4✓ Branch 0 taken 1200070 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1200070 times.
|
1200070 | if (!(u >= 0. && u <= 1.)) { |
| 50 | ✗ | throw std::invalid_argument("u needs to be betwen 0 and 1."); | |
| 51 | } | ||
| 52 | 1200070 | return bin_m_i_ * (pow(u, i_))*pow((1 - u), m_minus_i); | |
| 53 | } | ||
| 54 | |||
| 55 | /// \brief Check if actual Bernstein polynomial and other are approximately | ||
| 56 | /// equal. \param other : the other Bernstein polynomial to check. \return | ||
| 57 | /// true if the two Bernstein polynomials are approximately equals. | ||
| 58 | 110 | virtual bool operator==(const Bern& other) const { | |
| 59 |
1/2✓ Branch 1 taken 110 times.
✗ Branch 2 not taken.
|
220 | return ndcurves::isApprox<Numeric>(m_minus_i, other.m_minus_i) && |
| 60 |
2/4✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 110 times.
✗ Branch 4 not taken.
|
220 | ndcurves::isApprox<Numeric>(i_, other.i_) && |
| 61 | 220 | ndcurves::isApprox<Numeric>(bin_m_i_, other.bin_m_i_); | |
| 62 | } | ||
| 63 | |||
| 64 | /// \brief Check if actual Bernstein polynomial and other are different. | ||
| 65 | /// \param other : the other Bernstein polynomial to check. | ||
| 66 | /// \return true if the two Bernstein polynomials are different. | ||
| 67 | ✗ | virtual bool operator!=(const Bern& other) const { return !(*this == other); } | |
| 68 | |||
| 69 | /* Attributes */ | ||
| 70 | Numeric m_minus_i; | ||
| 71 | Numeric i_; | ||
| 72 | Numeric bin_m_i_; | ||
| 73 | /* Attributes */ | ||
| 74 | |||
| 75 | // Serialization of the class | ||
| 76 | friend class boost::serialization::access; | ||
| 77 | template <class Archive> | ||
| 78 | 368 | void serialize(Archive& ar, const unsigned int version) { | |
| 79 | if (version) { | ||
| 80 | // Do something depending on version ? | ||
| 81 | } | ||
| 82 |
1/2✓ Branch 2 taken 184 times.
✗ Branch 3 not taken.
|
368 | ar& boost::serialization::make_nvp("m_minus_i", m_minus_i); |
| 83 |
1/2✓ Branch 2 taken 184 times.
✗ Branch 3 not taken.
|
368 | ar& boost::serialization::make_nvp("i", i_); |
| 84 |
1/2✓ Branch 2 taken 184 times.
✗ Branch 3 not taken.
|
368 | ar& boost::serialization::make_nvp("bin_m_i", bin_m_i_); |
| 85 | 368 | } | |
| 86 | }; // End struct Bern | ||
| 87 | |||
| 88 | /// \brief Computes all Bernstein polynomes for a certain degree. | ||
| 89 | /// | ||
| 90 | template <typename Numeric> | ||
| 91 | 6045 | std::vector<Bern<Numeric> > makeBernstein(const unsigned int n) { | |
| 92 | 6045 | std::vector<Bern<Numeric> > res; | |
| 93 |
2/2✓ Branch 0 taken 22192 times.
✓ Branch 1 taken 6045 times.
|
28237 | for (unsigned int i = 0; i <= n; ++i) { |
| 94 |
2/4✓ Branch 1 taken 22192 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 22192 times.
✗ Branch 5 not taken.
|
22192 | res.push_back(Bern<Numeric>(n, i)); |
| 95 | } | ||
| 96 | 6045 | return res; | |
| 97 | ✗ | } | |
| 98 | } // namespace ndcurves | ||
| 99 | |||
| 100 | DEFINE_CLASS_TEMPLATE_VERSION(typename Numeric, ndcurves::Bern<Numeric>) | ||
| 101 | |||
| 102 | #endif //_CLASS_BERNSTEIN | ||
| 103 |