aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
rational.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Class template used to approximate decimal numbers by rationals
25  * @author Matthieu HOURBRACQ and Pierre-Henri WUILLEMIN(@LIP6)
26  */
27 
28 #ifndef GUM_RATIONAL_H
29 #define GUM_RATIONAL_H
30 
31 #include <iomanip>
32 #include <iostream>
33 #include <sstream>
34 #include <stdlib.h>
35 #include <vector>
36 #include <agrum/tools/core/math/math_utils.h>
37 
38 // 64 bits for windows (long is 32 bits)
39 #ifdef _MSC_VER
40 typedef __int64 int64_t;
41 typedef unsigned __int64 uint64_t;
42 #else
43 # include <stdint.h>
44 #endif
45 
46 namespace gum {
47 
48  /**
49  * @class Rational
50  * @headerfile rational.h <agrum/tools/core/math/rational.h>
51  * @brief Class template used to approximate decimal numbers by rationals.
52  * @ingroup math_group
53  *
54  * @tparam GUM_SCALAR The floating type ( float, double, long double ... ) of
55  * the number.
56  */
57  template < typename GUM_SCALAR >
58  class Rational {
59  public:
60  // ========================================================================
61  /// @name Real approximation by rational
62  // ========================================================================
63  /// @{
64 
65  /**
66  * @brief Find the rational close enough to a given ( decimal ) number in
67  * [-1,1] and whose denominator is not higher than a given integer number.
68  *
69  * Because of the double constraint on precision and size of the
70  * denominator, there is no guarantee on the precision of the approximation
71  * if \c den_max is low and \c zero is high. Prefer the use of continued
72  * fractions.
73  *
74  * @param numerator The numerator of the rational.
75  * @param denominator The denominator of the rational.
76  * @param number The constant number we want to approximate using rationals.
77  * @param den_max The constant highest authorized denominator. 1000000 by
78  * default.
79  * @param zero The positive value below which a number is considered zero.
80  * 1e-6 by default.
81  */
82  static void farey(int64_t& numerator,
83  int64_t& denominator,
84  const GUM_SCALAR& number,
85  const int64_t& den_max = 1000000L,
86  const GUM_SCALAR& zero = 1e-6);
87 
88  /**
89  * @brief Find the first best rational approximation.
90  *
91  * The one with the smallest denominator such that no other rational with
92  * smaller denominator is a better approx, within precision zero to a
93  * given ( decimal ) number ( ANY number).
94  *
95  * It gives the same answer than farey assuming \c zero is the same and
96  * den_max is infinite. Use this functions because you are sure to get an
97  * approx within \c zero of \c number.
98  *
99  * We look at the semi-convergents left of the last admissible convergent,
100  * if any. They may be within the same precision and have a smaller
101  * denominator.
102  *
103  * @param numerator The numerator of the rational.
104  * @param denominator The denominator of the rational.
105  * @param number The constant number we want to approximate using rationals.
106  * @param zero The positive value below which a number is considered zero.
107  * 1e-6 by default.
108  */
109  static void continuedFracFirst(int64_t& numerator,
110  int64_t& denominator,
111  const GUM_SCALAR& number,
112  const double& zero = 1e-6);
113 
114  /**
115  * @brief Find the best rational approximation.
116  *
117  * Not the first, to a given ( decimal) number ( ANY number ) and whose
118  * denominator is not higher than a given integer number.
119  *
120  * In this case, we look for semi-convergents at the right of the last
121  * admissible convergent, if any. They are better approximations, but have
122  * higher denominators.
123  *
124  * @param numerator The numerator of the rational.
125  * @param denominator The denominator of the rational.
126  * @param number The constant number we want to approximate using rationals.
127  * @param den_max The constant highest authorized denominator. 1000000 by
128  * default.
129  */
130  static void continuedFracBest(int64_t& numerator,
131  int64_t& denominator,
132  const GUM_SCALAR& number,
133  const int64_t& den_max = 1000000);
134 
135  /// @}
136  };
137 
138 } // namespace gum
139 
140 
141 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
142 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
143 extern template class gum::Rational< double >;
144 # endif
145 #endif
146 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
147 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
148 extern template class gum::Rational< long double >;
149 # endif
150 #endif
151 
152 
153 // Always include template implementation in header file
154 #include <agrum/tools/core/math/rational_tpl.h>
155 
156 #endif // GUM_RATIONAL_H
static void continuedFracBest(int64_t &numerator, int64_t &denominator, const GUM_SCALAR &number, const int64_t &den_max=1000000)
Find the best rational approximation.
Definition: rational_tpl.h:191
Class template used to approximate decimal numbers by rationals.
Definition: rational.h:58
static void farey(int64_t &numerator, int64_t &denominator, const GUM_SCALAR &number, const int64_t &den_max=1000000L, const GUM_SCALAR &zero=1e-6)
Find the rational close enough to a given ( decimal ) number in [-1,1] and whose denominator is not h...
Definition: rational_tpl.h:35
static void continuedFracFirst(int64_t &numerator, int64_t &denominator, const GUM_SCALAR &number, const double &zero=1e-6)
Find the first best rational approximation.
Definition: rational_tpl.h:94