29 #ifndef DOXYGEN_SHOULD_SKIP_THIS 31 # include <agrum/tools/core/math/variableLog2ParamComplexity.h> 32 # include <agrum/tools/core/math/gammaLog2.h> 41 template <
template <
typename >
class ALLOC >
42 INLINE
typename VariableLog2ParamComplexity< ALLOC >::allocator_type
43 VariableLog2ParamComplexity< ALLOC >::getAllocator()
const {
49 template <
template <
typename >
class ALLOC >
50 INLINE VariableLog2ParamComplexity< ALLOC >::VariableLog2ParamComplexity(
51 const allocator_type& alloc) :
52 VariableLog2ParamComplexity< ALLOC >::allocator_type(alloc),
54 GUM_CONSTRUCTOR(VariableLog2ParamComplexity);
59 template <
template <
typename >
class ALLOC >
60 INLINE VariableLog2ParamComplexity< ALLOC >::VariableLog2ParamComplexity(
61 const VariableLog2ParamComplexity< ALLOC >& from,
62 const typename VariableLog2ParamComplexity< ALLOC >::allocator_type& alloc) :
63 VariableLog2ParamComplexity< ALLOC >::allocator_type(alloc),
64 use_cache__(from.use_cache__), cache__(from.cache__) {
65 GUM_CONS_CPY(VariableLog2ParamComplexity);
70 template <
template <
typename >
class ALLOC >
71 INLINE VariableLog2ParamComplexity< ALLOC >::VariableLog2ParamComplexity(
72 const VariableLog2ParamComplexity< ALLOC >& from) :
73 VariableLog2ParamComplexity(from,
this->getAllocator()) {}
77 template <
template <
typename >
class ALLOC >
78 INLINE VariableLog2ParamComplexity< ALLOC >::VariableLog2ParamComplexity(
79 VariableLog2ParamComplexity< ALLOC >&& from,
80 const typename VariableLog2ParamComplexity< ALLOC >::allocator_type& alloc) :
81 VariableLog2ParamComplexity< ALLOC >::allocator_type(alloc),
82 use_cache__(from.use_cache__), cache__(std::move(from.cache__)) {
83 GUM_CONS_MOV(VariableLog2ParamComplexity);
88 template <
template <
typename >
class ALLOC >
89 INLINE VariableLog2ParamComplexity< ALLOC >::VariableLog2ParamComplexity(
90 VariableLog2ParamComplexity< ALLOC >&& from) :
91 VariableLog2ParamComplexity(std::move(from),
this->getAllocator()) {}
95 template <
template <
typename >
class ALLOC >
96 VariableLog2ParamComplexity< ALLOC >*
97 VariableLog2ParamComplexity< ALLOC >::clone(
98 const typename VariableLog2ParamComplexity< ALLOC >::allocator_type& alloc)
100 ALLOC< VariableLog2ParamComplexity< ALLOC > > allocator(alloc);
101 VariableLog2ParamComplexity< ALLOC >* table = allocator.allocate(1);
103 allocator.construct(table, *
this);
105 allocator.deallocate(table, 1);
113 template <
template <
typename >
class ALLOC >
114 VariableLog2ParamComplexity< ALLOC >*
115 VariableLog2ParamComplexity< ALLOC >::clone()
const {
116 return clone(
this->getAllocator());
121 template <
template <
typename >
class ALLOC >
122 INLINE VariableLog2ParamComplexity< ALLOC >::~VariableLog2ParamComplexity() {
123 GUM_DESTRUCTOR(VariableLog2ParamComplexity);
128 template <
template <
typename >
class ALLOC >
129 INLINE VariableLog2ParamComplexity< ALLOC >&
130 VariableLog2ParamComplexity< ALLOC >::operator=(
131 const VariableLog2ParamComplexity< ALLOC >& from) {
137 template <
template <
typename >
class ALLOC >
138 INLINE VariableLog2ParamComplexity< ALLOC >&
139 VariableLog2ParamComplexity< ALLOC >::operator=(
140 VariableLog2ParamComplexity< ALLOC >&& from) {
146 template <
template <
typename >
class ALLOC >
147 INLINE
void VariableLog2ParamComplexity< ALLOC >::useCache(
const bool on_off) {
148 use_cache__ = on_off;
153 template <
template <
typename >
class ALLOC >
154 INLINE
void VariableLog2ParamComplexity< ALLOC >::clearCache() {
160 template <
template <
typename >
class ALLOC >
161 double VariableLog2ParamComplexity< ALLOC >::log2Cnr(
const std::size_t r,
166 if (r == std::size_t(1))
return 0.0;
167 if (n == 0.0)
return 0.0;
168 if (n == 1.0)
return std::log2((
double)r);
171 GUM_ERROR(OutOfBounds,
172 "In the penalty of the fNML score, n must be greater " 173 <<
"than or equal to 0. But, here, n = " << n);
176 if (n < VariableLog2ParamComplexityCTableNSize) {
179 std::size_t xn = (std::size_t)n;
180 if (r - 2 < VariableLog2ParamComplexityCTableRSize) {
181 return VariableLog2ParamComplexityCTable[r - 2][xn];
186 return cache__[std::pair< std::size_t,
double >{r, n}];
187 }
catch (NotFound&) {}
206 double log2Cnr1 = VariableLog2ParamComplexityCTable[3][xn];
207 double log2Cnr2 = VariableLog2ParamComplexityCTable[2][xn];
208 double log2Cnr = 0.0;
209 double k_r = std::exp((log2Cnr2 - log2Cnr1) * M_LN2);
210 double q_r = 1.0 + k_r * n / (6.0 - 2.0);
211 for (std::size_t i = std::size_t(6); i <= r; ++i) {
212 log2Cnr = log2Cnr1 + std::log2(q_r);
215 q_r = 1.0 + k_r * (n / (i - 1.0));
220 cache__.insert(std::pair< std::size_t,
double >{r, n}, log2Cnr);
229 return cache__[std::pair< std::size_t,
double >{r, n}];
230 }
catch (NotFound&) {}
236 = 0.5 * std::log2(n) + cst1__ + cst2__ / std::sqrt(n) + cst3__ / n;
237 if (r == std::size_t(2))
return log2Cnr1;
240 double log2Cnr2 = 0.0;
244 double k_r = std::exp((log2Cnr2 - log2Cnr1) * M_LN2);
245 double q_r = 1.0 + k_r * n / (3.0 - 2.0);
246 double log2Cnr = 0.0;
247 for (std::size_t i = std::size_t(3); i <= r; ++i) {
248 log2Cnr = log2Cnr1 + std::log2(q_r);
251 q_r = 1.0 + k_r * (n / (i - 1.0));
256 cache__.insert(std::pair< std::size_t,
double >{r, n}, log2Cnr);
265 template <
template <
typename >
class ALLOC >
267 VariableLog2ParamComplexity< ALLOC >::CnrToFile(
const std::string& filename) {
269 std::vector<
long double > cn2_table(VariableLog2ParamComplexityCTableNSize);
275 GammaLog2 gamma_log2;
276 for (
double n = 2; n < VariableLog2ParamComplexityCTableNSize; ++n) {
284 for (
double h = 1; h < n; ++h) {
286 = (gamma_log2(n + 1) - gamma_log2(h + 1) - gamma_log2((n - h) + 1))
288 + h * std::log(h / n) + (n - h) * std::log((n - h) / n);
289 cn2 += std::exp(elt);
297 std::ofstream outfile(filename);
298 if (!outfile.is_open()) {
299 GUM_ERROR(IOError,
"It is impossible to open file " << filename);
301 outfile.precision(20);
302 outfile <<
"namespace gum {\n\n";
311 outfile <<
" // the CTable cache for log2(Cnr), n < " 312 << VariableLog2ParamComplexityCTableNSize <<
" and r in {2,3,4,5}\n";
313 outfile <<
" const double VariableLog2ParamComplexityCTable[4][" 314 << VariableLog2ParamComplexityCTableNSize <<
"] = {\n";
319 for (
const auto cn2: cn2_table) {
324 const double logCn2 = (
double)std::log2(cn2);
331 for (std::size_t i = std::size_t(0);
332 i < VariableLog2ParamComplexityCTableNSize;
334 if (i > std::size_t(0)) outfile <<
",\n ";
335 const double logCn3 = (
double)std::log2(cn2_table[i] + i);
342 for (std::size_t i = std::size_t(0);
343 i < VariableLog2ParamComplexityCTableNSize;
345 if (i > std::size_t(0)) outfile <<
",\n ";
346 const double logCn4 = (
double)std::log2(cn2_table[i] * (1.0 + i / 2.0) + i);
353 for (std::size_t i = std::size_t(0);
354 i < VariableLog2ParamComplexityCTableNSize;
356 if (i > std::size_t(0)) outfile <<
",\n ";
357 const double logCn5 = (
double)std::log2(cn2_table[i] * (1.0 + 5.0 * i / 6.0)
364 outfile <<
" };\n\n";
365 outfile <<
"} /* namespace gum */\n";