Commit 883ce108 by Christophe Gonzales

learning: changed the ordering of values in variables: by default, increasing…

learning: changed the ordering of values in variables: by default, increasing order if they are numbers, else lexicographic order + fixed an incorrect computation of kNML score
parent 63151011
Pipeline #20721115 failed with stages
in 69 minutes 14 seconds
......@@ -499,6 +499,8 @@ namespace gum {
DatabaseTable<> database ( translator_set );
database.setVariableNames( initializer.variableNames () );
initializer.fillDatabase ( database );
database.reorder ();
return database;
}
......
......@@ -287,8 +287,16 @@ namespace gum {
/// sets/unset the editable dictionary mode
virtual void setEditableDictionaryMode ( bool new_mode );
/// indicates whether the translations should be reordered
/** When constructing dynamically its dictionary, the translator may
/** @brief indicates whether a reordering is needed to make the
* translations sorted
*
* If the strings represented by the translations are only numbers,
* translations are considered to be sorted if and only if they are sorted
* by increasing number. If the strings do not only represent numbers, then
* translations are considered to be sorted if and only if they are sorted
* lexicographically.
*
* When constructing dynamically its dictionary, the translator may
* assign wrong DBTranslatedValue values to strings. For instance, a
* translator reading sequentially integer strings 4, 1, 3, may map
* 4 into DBTranslatedValue{std::size_t(0)},
......@@ -299,7 +307,7 @@ namespace gum {
* reordering. Method needsReodering() returns a Boolean indicating
* whether such a reordering should be performed or whether the current
* order is OK. */
virtual bool needsReordering () = 0;
virtual bool needsReordering () const = 0;
/** @brief performs a reordering of the dictionary and returns a mapping
* from the old translated values to the new ones.
......@@ -310,7 +318,9 @@ namespace gum {
* that enables changing the old dictionary values into the new ones.
* Note that the hash table returned is expressed in terms of std::size_t
* because only the translations for discrete random variables need be
* reordered, those for continuous random variables are identity mappings. */
* reordered, those for continuous random variables are identity mappings.
* @warning If there is no reordering to perform, the method returns
* an empty hashtable. */
virtual HashTable<std::size_t,std::size_t,
ALLOC<std::pair<std::size_t,std::size_t>>> reorder () = 0;
......
......@@ -316,7 +316,7 @@ namespace gum {
virtual std::size_t domainSize () const final;
/// indicates that the translations should never be reordered
virtual bool needsReordering () final;
virtual bool needsReordering () const final;
/** @brief returns an empty mapping, indicating that old tanslations
* are equal to the newly reordered ones. */
......
......@@ -429,7 +429,7 @@ namespace gum {
/// indicates whether the translations should be reordered
template <template<typename> class ALLOC>
INLINE bool
DBTranslator4ContinuousVariable<ALLOC>::needsReordering () {
DBTranslator4ContinuousVariable<ALLOC>::needsReordering () const {
return false;
}
......
......@@ -267,15 +267,10 @@ namespace gum {
virtual void setEditableDictionaryMode ( bool new_mode ) final;
/// indicates that the translations should never be reordered
virtual bool needsReordering () final;
virtual bool needsReordering () const final;
/** @brief performs a reordering of the dictionary and returns a mapping
* from the old translated values to the new ones.
*
* When a reordering is needed, i.e., string values must be translated
* differently. Method reorder() computes how the translations should be
* changed. It updates accordingly the dictionary and returns the mapping
* that enables changing the old dictionary values into the new ones. */
/** @brief returns an empty HashTable to indicate that no reordering
* is needed. */
virtual HashTable<std::size_t,std::size_t,
ALLOC<std::pair<std::size_t,std::size_t>>>
reorder () final;
......
......@@ -310,7 +310,7 @@ namespace gum {
/// indicates whether the translations should be reordered
template <template<typename> class ALLOC>
bool DBTranslator4DiscretizedVariable<ALLOC>::needsReordering () {
bool DBTranslator4DiscretizedVariable<ALLOC>::needsReordering () const {
return false;
}
......@@ -320,15 +320,10 @@ namespace gum {
INLINE HashTable<std::size_t,std::size_t,
ALLOC<std::pair<std::size_t,std::size_t>>>
DBTranslator4DiscretizedVariable<ALLOC>::reorder () {
const std::size_t size = __variable.domainSize ();
HashTable<std::size_t,std::size_t,
ALLOC<std::pair<std::size_t,std::size_t>>>
mapping ( (Size) size );
for ( std::size_t i = std::size_t (0); i < size; ++i )
mapping.insert ( i,i );
return mapping;
return HashTable<std::size_t,std::size_t,
ALLOC<std::pair<std::size_t,std::size_t>>> ();
}
/// returns the domain size of a variable corresponding to the translations
template <template<typename> class ALLOC>
......
......@@ -337,8 +337,16 @@ namespace gum {
* sizes. */
virtual std::size_t domainSize () const final;
/// indicates whether the translations should be reordered
/** When constructing dynamically its dictionary, the translator may
/** @brief indicates whether a reordering is needed to make the
* translations sorted
*
* If the strings represented by the translations are only numbers,
* translations are considered to be sorted if and only if they are sorted
* by increasing number. If the strings do not only represent numbers, then
* translations are considered to be sorted if and only if they are sorted
* lexicographically.
*
* When constructing dynamically its dictionary, the translator may
* assign wrong DBTranslatedValue values to strings. For instance, a
* translator reading sequentially integer strings 4, 1, 3, may map
* 4 into DBTranslatedValue{std::size_t(0)},
......@@ -349,7 +357,7 @@ namespace gum {
* reordering. Method needsReodering() returns a Boolean indicating
* whether such a reordering should be performed or whether the current
* order is OK. */
virtual bool needsReordering () final;
virtual bool needsReordering () const final;
/** @brief performs a reordering of the dictionary and returns a mapping
* from the old translated values to the new ones.
......@@ -357,7 +365,9 @@ namespace gum {
* When a reordering is needed, i.e., string values must be translated
* differently. Method reorder() computes how the translations should be
* changed. It updates accordingly the dictionary and returns the mapping
* that enables changing the old dictionary values into the new ones. */
* that enables changing the old dictionary values into the new ones.
* @warning If there is no reordering to perform, the method returns
* an empty hashtable. */
virtual HashTable<std::size_t,std::size_t,
ALLOC<std::pair<std::size_t,std::size_t>>>
reorder () final;
......
......@@ -292,17 +292,30 @@ namespace gum {
/// indicates whether the translations should be reordered
template <template<typename> class ALLOC>
bool DBTranslator4LabelizedVariable<ALLOC>::needsReordering () {
bool DBTranslator4LabelizedVariable<ALLOC>::needsReordering () const {
// if the variable contains only numbers, they should be increasing
const auto& labels = __variable.labels ();
float last_number = std::numeric_limits<float>::lowest ();
float number;
bool only_numbers = true;
for ( const auto& label : labels ) {
if ( ! DBCell::isReal ( label ) ) return false;
if ( ! DBCell::isReal ( label ) ) {
only_numbers = false;
break;
}
number = std::stof( label );
if ( number < last_number ) return true;
last_number = number;
}
if ( ! only_numbers ) {
// here we shall examine whether the strings are sorted by
// lexicographical order
const std::size_t size = labels.size ();
for ( std::size_t i = 1; i < size; ++i ) {
if ( labels[i] < labels[i-1] ) return true;
}
}
return false;
}
......@@ -310,12 +323,22 @@ namespace gum {
/// returns a mapping to reorder the current dictionary and updates it
template <template<typename> class ALLOC>
INLINE HashTable<std::size_t,std::size_t,
ALLOC<std::pair<std::size_t,std::size_t>>>
HashTable<std::size_t,std::size_t,ALLOC<std::pair<std::size_t,std::size_t>>>
DBTranslator4LabelizedVariable<ALLOC>::reorder () {
// assign to each label its current index
// check whether the variable contains only numeric values. In this
// case, we have to sort the values by increasing number
const auto& labels = __variable.labels ();
const std::size_t size = labels.size ();
bool only_numbers = true;
for ( const auto& label : labels ) {
if ( ! DBCell::isReal ( label ) ) {
only_numbers = false;
break;
}
}
// assign to each label its current index
std::vector<std::pair<std::size_t,std::string>,
ALLOC<std::pair<std::size_t,std::string>>> xlabels;
xlabels.reserve ( size );
......@@ -323,10 +346,31 @@ namespace gum {
xlabels.push_back ( std::make_pair ( i, labels[i] ) );
// reorder by increasing order
std::sort( xlabels.begin(), xlabels.end(),
[]( const std::pair<std::size_t,std::string>& a,
const std::pair<std::size_t,std::string>& b) -> bool
{ return std::stof( a.second ) < std::stof( b.second ); } );
if ( only_numbers )
std::sort( xlabels.begin(), xlabels.end(),
[]( const std::pair<std::size_t,std::string>& a,
const std::pair<std::size_t,std::string>& b) -> bool
{ return std::stof( a.second ) < std::stof( b.second ); } );
else
std::sort( xlabels.begin(), xlabels.end(),
[]( const std::pair<std::size_t,std::string>& a,
const std::pair<std::size_t,std::string>& b) -> bool
{ return a.second < b.second; } );
// check whether there were any modification
bool modifications = false;
for ( std::size_t i = std::size_t(0); i < size; ++i ) {
if ( xlabels[i].first != i ) {
modifications = true;
break;
}
}
// if there were no modification, return an empty update hashtable
if ( ! modifications ) {
return HashTable<std::size_t,std::size_t,
ALLOC<std::pair<std::size_t,std::size_t>>> ();
}
// recreate the variable so that the labels correspond to the
// new ordering
......
......@@ -343,8 +343,10 @@ namespace gum {
/** Returns the size of the range of the variable. */
virtual std::size_t domainSize () const final;
/// indicates whether the translations should be reordered
/** When constructing dynamically its dictionary, the translator may
/** @brief indicates whether a reordering is needed to make the
* translations sorted by increasing numbers
*
* When constructing dynamically its dictionary, the translator may
* assign wrong DBTranslatedValue values to strings. For instance, a
* translator reading sequentially integer strings 2, 1, 3, may map
* 2 into DBTranslatedValue{std::size_t(0)},
......@@ -356,7 +358,7 @@ namespace gum {
* whether such a reordering should be performed or whether the current
* order is OK.
*/
virtual bool needsReordering () final;
virtual bool needsReordering () const final;
/** @brief performs a reordering of the dictionary and returns a mapping
* from the old translated values to the new ones.
......
......@@ -484,7 +484,7 @@ namespace gum {
/// indicates whether the translations should be reordered
template <template<typename> class ALLOC>
bool DBTranslator4RangeVariable<ALLOC>::needsReordering () {
bool DBTranslator4RangeVariable<ALLOC>::needsReordering () const {
// if the variable contains only numbers, they should be increasing
const auto& labels = __variable.labels ();
std::size_t last_number = std::numeric_limits<std::size_t>::lowest ();
......@@ -510,9 +510,19 @@ namespace gum {
std::vector<std::pair<std::size_t,std::string>,
ALLOC<std::pair<std::size_t,std::string>>> xlabels;
xlabels.reserve ( size );
for ( std::size_t i = std::size_t(0); i < size; ++i )
xlabels.push_back ( std::make_pair ( this->_back_dico.first( labels[i] ),
labels[i] ) );
bool modifications = false;
for ( std::size_t i = std::size_t(0); i < size; ++i ) {
const std::size_t new_val = this->_back_dico.first( labels[i] );
xlabels.push_back ( std::make_pair ( new_val, labels[i] ) );
if ( new_val != i ) modifications = true;
}
// if there were no modification, return an empty update hashtable
if ( ! modifications ) {
return HashTable<std::size_t,std::size_t,
ALLOC<std::pair<std::size_t,std::size_t>>> ();
}
// create the hashTable corresponding to the mapping from the old
// indices to the new one
......
......@@ -365,6 +365,58 @@ namespace gum {
* translators in the translator set. */
const Variable& variableSafe ( const std::size_t k ) const;
/** @brief indicates whether a reordering is needed to make the kth
* translator sorted
*
* For a given translator, if the strings represented by the translations
* are only numbers, the translations are considered to be sorted if and
* only if they are sorted by increasing number. If the strings do not
* only represent numbers, then translations are considered to be sorted
* if and only if they are sorted lexicographically.
*
* When constructing dynamically its dictionary, the translator may
* assign wrong DBTranslatedValue values to strings. For instance, a
* translator reading sequentially integer strings 4, 1, 3, may map
* 4 into DBTranslatedValue{std::size_t(0)},
* 1 into DBTranslatedValue{std::size_t(1)} and
* 3 into DBTranslatedValue{std::size_t(2)}, resulting in random variables
* having domain {4,1,3}. The user may prefer having domain {1,3,4}, i.e.,
* a domain specified with increasing values. This requires a
* reordering. Method needsReodering() returns a Boolean indicating
* whether such a reordering should be performed or whether the current
* order is OK.
* @warning this method assumes that there are at least k translators.
* So, it won't check that the kth translator actually exists. If unsure,
* use method needsReorderingSafe that performs this check. */
bool needsReordering ( const std::size_t k ) const;
/// same as method needsReordering but checks that the kth translator exists
/** @throw UndefinedElement is raised if there are fewer than k
* translators in the translator set. */
bool needsReorderingSafe ( const std::size_t k ) const;
/** @brief performs a reordering of the dictionary and returns a mapping
* from the old translated values to the new ones.
*
* When a reordering is needed, i.e., string values must be translated
* differently, Method reorder() computes how the translations should be
* changed. It updates accordingly the dictionary and returns the mapping
* that enables changing the old dictionary values into the new ones.
* Note that the hash table returned is expressed in terms of std::size_t
* because only the translations for discrete random variables need be
* reordered, those for continuous random variables are identity mappings.
* @warning this method assumes that there are at least k translators.
* So, it won't check that the kth translator actually exists. If unsure,
* use method reorderSafe that performs this check. */
HashTable<std::size_t,std::size_t,ALLOC<std::pair<std::size_t,std::size_t>>>
reorder ( const std::size_t k );
/// same as method reorder but checks that the kth translator exists
/** @throw UndefinedElement is raised if there are fewer than k
* translators in the translator set. */
HashTable<std::size_t,std::size_t,ALLOC<std::pair<std::size_t,std::size_t>>>
reorderSafe ( const std::size_t k );
/** @brief returns the column of the input database that will be read
* by the kth translator
*
......
......@@ -478,6 +478,48 @@ namespace gum {
}
// indicates whether a reordering is needed to make the kth translator
// sorted by lexicographical order
template <template<typename> class ALLOC>
INLINE bool
DBTranslatorSet<ALLOC>::needsReordering ( const std::size_t k ) const {
return __translators[k]->needsReordering ();
}
// indicates whether a reordering is needed to make the kth translator
// sorted by lexicographical order
template <template<typename> class ALLOC>
INLINE bool
DBTranslatorSet<ALLOC>::needsReorderingSafe ( const std::size_t k ) const {
if ( __translators.size () <= k )
GUM_ERROR ( UndefinedElement, "the variable could not be found" );
return __translators[k]->needsReordering ();
}
// performs a reordering of the dictionary and returns a mapping
// from the old translated values to the new ones.
template <template<typename> class ALLOC>
INLINE
HashTable<std::size_t,std::size_t,ALLOC<std::pair<std::size_t,std::size_t>>>
DBTranslatorSet<ALLOC>::reorder ( const std::size_t k ) {
return __translators[k]->reorder();
}
// performs a reordering of the dictionary and returns a mapping
// from the old translated values to the new ones.
template <template<typename> class ALLOC>
INLINE
HashTable<std::size_t,std::size_t,ALLOC<std::pair<std::size_t,std::size_t>>>
DBTranslatorSet<ALLOC>::reorderSafe ( const std::size_t k ) {
if ( __translators.size () <= k )
GUM_ERROR ( UndefinedElement, "the variable could not be found" );
return __translators[k]->reorder();
}
/** @brief returns the column of the input database that will be written
* in the kth column of the DatabaseTable */
template <template<typename> class ALLOC>
......
......@@ -33,6 +33,7 @@
#include <agrum/agrum.h>
#include <agrum/core/set.h>
#include <agrum/core/thread.h>
#include <agrum/learning/database/DBCell.h>
#include <agrum/learning/database/DBRow.h>
#include <agrum/learning/database/DBTranslatedValue.h>
......@@ -468,6 +469,70 @@ namespace gum {
/// returns the domain sizes of all the variables in the database table
DBVector<std::size_t> domainSizes () const;
/** @brief indicates whether a reordering is needed to make the kth
* translator sorted
*
* For a given translator, if the strings represented by the translations
* are only numbers, the translations are considered to be sorted if and
* only if they are sorted by increasing number. If the strings do not
* only represent numbers, then translations are considered to be sorted
* if and only if they are sorted lexicographically.
*
* When constructing dynamically its dictionary, the translator may
* assign wrong DBTranslatedValue values to strings. For instance, a
* translator reading sequentially integer strings 4, 1, 3, may map
* 4 into DBTranslatedValue{std::size_t(0)},
* 1 into DBTranslatedValue{std::size_t(1)} and
* 3 into DBTranslatedValue{std::size_t(2)}, resulting in random variables
* having domain {4,1,3}. The user may prefer having domain {1,3,4}, i.e.,
* a domain specified with increasing values. This requires a
* reordering. Method needsReodering() returns a Boolean indicating
* whether such a reordering should be performed or whether the current
* order is OK.
*
* Translators read an input dataset that is not necessarily the same as
* the content of the DatabaseTable. For instance, a CSV may contain 10
* columns, but if a DatabaseTable only contains two translators reading
* columns 3 and 5 respectively, then the DatabaseTable only contains 2
* columns. When k_is_input_col is set to false, Parameter k passed in
* argument corresponds to either 0 or 1, i.e., the index of one of these
* two columns. When k_is_input_col is set to true, the translator to be
* reordered is that which parses the kth column of the input database.
* @throw UndefinedElement is raised if there is no translator
* corresponding to k. */
bool needsReordering ( const std::size_t k,
const bool k_is_input_col = false ) const;
/** @brief performs a reordering of the kth translator or
* of the translator corresponding to the kth column of the input database
*
* For a given translator, if the strings represented by the translations
* are only numbers, the translations are considered to be sorted if and
* only if they are sorted by increasing number. If the strings do not
* only represent numbers, then translations are considered to be sorted
* if and only if they are sorted lexicographically.
*
* Translators read an input dataset that is not necessarily the same as
* the content of the DatabaseTable. For instance, a CSV may contain 10
* columns, but if a DatabaseTable only contains two translators reading
* columns 3 and 5 respectively, then the DatabaseTable only contains 2
* columns. When k_is_input_col is set to false, Parameter k passed in
* argument corresponds to either 0 or 1, i.e., the index of one of these
* two columns. When k_is_input_col is set to true, the translator to be
* reordered is that which parses the kth column of the input database.
* @throw UndefinedElement is raised if there is no translator
* corresponding to k. */
void reorder ( const std::size_t k,
const bool k_is_input_col = false );
/// performs a reordering of all the columns
/** For a given translator, if the strings represented by the translations
* are only numbers, the translations are considered to be sorted if and
* only if they are sorted by increasing number. If the strings do not
* only represent numbers, then translations are considered to be sorted
* if and only if they are sorted lexicographically. */
void reorder ();
/// insert a new row at the end of the database
using IDatabaseTable<DBTranslatedValue,ALLOC>::insertRow;
......
......@@ -530,6 +530,70 @@ namespace gum {
return dom;
}
// indicates whether a reordering is needed to make the kth
// translator sorted by lexicographical order
template <template<typename> class ALLOC>
INLINE bool
DatabaseTable<ALLOC>::needsReordering ( const std::size_t k,
const bool k_is_input_col ) const {
// find the position kk of the translator that contains the variable
const std::size_t nb_trans = __translators.size ();
const std::size_t kk = __getKthIndex ( k, k_is_input_col );
// check if the translator exists
if ( nb_trans <= kk )
GUM_ERROR ( UndefinedElement,
"the translator could not be found in the database table" );
return __translators.needsReordering ( kk );
}
// performs a a lexicographic reordering of the kth translator or
// of the translator corresponding to the kth column of the input database
template <template<typename> class ALLOC>
void DatabaseTable<ALLOC>::reorder ( const std::size_t k,
const bool k_is_input_col ) {
// find the position kk of the translator that contains the variable
const std::size_t nb_trans = __translators.size ();
const std::size_t kk = __getKthIndex ( k, k_is_input_col );
// check if the translator exists
if ( nb_trans <= kk )
GUM_ERROR ( UndefinedElement,
"the translator could not be found in the database table" );
// get the translation to perform
auto updates = __translators.reorder ( kk );
if ( updates.empty () ) return;
const std::size_t size = updates.size ();
std::vector<std::size_t,ALLOC<std::size_t>> new_values ( size );
for ( const auto& update : updates ) {
if ( update.first >= size )
new_values.resize ( update.first + 1 );
new_values[update.first] = update.second;
}
// apply the translations
//auto nb_threads = thread::getMaxNumberOfThreads();
for ( auto& xrow : this->_content () ) {
auto& elt = xrow.row()[kk].discr_val;
if ( elt != std::numeric_limits<std::size_t>::max () )
elt = new_values[elt];
}
}
/// performs a reordering of all the columns
template <template<typename> class ALLOC>
INLINE void DatabaseTable<ALLOC>::reorder () {
const std::size_t nb_trans = __translators.size ();
for ( std::size_t i = std::size_t(0); i < nb_trans; ++i )
reorder ( i, false );
}
/// insert a new row at the end of the database
template <template<typename> class ALLOC>
......
......@@ -70,18 +70,20 @@ namespace gum {
// create a bn with dummy parameters corresponding to the dag
for (const auto id : dag) {
// create the labelized variable
/*
std::vector< std::string > labels;
auto& translator = translators.translator ( id );
for (Idx i = 0; i < modal[id]; ++i) {
labels.push_back(translator.translateBack(DBTranslatedValue{std::size_t(i)}));
}
sort(labels.begin(), labels.end());
LabelizedVariable variable(names[id], "", 0);
for (auto s : labels) {
variable.addLabel(s);
}
bn.add(variable, id);
*/
bn.add(dynamic_cast<const DiscreteVariable&> (translators.variable(id)), id);
}
// add the arcs
......
......@@ -282,12 +282,22 @@ namespace gum {
const std::vector< double, CountAlloc >& Nz =
this->_getConditioningCounts(nodeset_index + 1);
const auto Z_size = Size(Nz.size());
const auto Y_size = Size(modals[all_nodes[all_nodes.size() - 2]]);
const auto X_size = Size(modals[all_nodes[all_nodes.size() - 1]]);
double score = 0.0;
for ( auto n_zx : Nzx )
score += std::log(this->_C(Y_size, n_zx));
for ( auto n_zy : Nzy )
score += std::log(this->_C(X_size, n_zy));
for ( auto n_z : Nz ) {
score -= std::log(this->_C(X_size, n_z));
score -= std::log(this->_C(Y_size, n_z));
}
/*
for (Idx z = 0, beg_zx = 0, beg_zy = 0; z < Z_size;
++z, beg_zx += X_size, beg_zy += Y_size) {
double sumX = 0.0, sumY = 0.0;
......@@ -300,6 +310,7 @@ namespace gum {
}
score += sumY - std::log(this->_C(X_size, Nz[z]));
}
*/
score *= 0.5;
// shall we put the score into the cache?
......
......@@ -709,8 +709,9 @@ namespace gum_tests {
learner.useLocalSearchWithTabuList();
gum::BayesNet< double > bn = learner.learnBN();
//std::cout << bn.dag () << std::endl;
TS_ASSERT_DELTA(listen.getNbr(), gum::Size(13), 1); // 75 ?
TS_ASSERT_DELTA(listen.getNbr(), gum::Size(15), 1); // 75 ?
TS_ASSERT_EQUALS(listen.getMess(), "stopped on request");
TS_ASSERT_EQUALS(learner.messageApproximationScheme(),
"stopped on request");
......
......@@ -520,9 +520,7 @@ namespace gum_tests {
TS_ASSERT ( translator.needsReordering () == false);
auto new_order = translator.reorder ();
TS_ASSERT ( new_order[0] == 0 );
TS_ASSERT ( new_order[1] == 1 );
TS_ASSERT ( new_order[2] == 2 );
TS_ASSERT ( new_order.size () == 0 );
}
......
......@@ -703,9 +703,7 @@ namespace gum_tests {
TS_ASSERT ( translator2.missingSymbols () == missing_kept2 );
auto new_order2 = translator2.reorder ();
TS_ASSERT ( new_order2[0] == 0 );
TS_ASSERT ( new_order2[1] == 1 );
TS_ASSERT ( new_order2[2] == 2 );
TS_ASSERT ( new_order2.size () == 0 );
}
......
......@@ -125,9 +125,7 @@ namespace gum_tests {
( gum::learning::DBTranslatedValue{std::numeric_limits<std::size_t>::max ()} ) ) );
TS_ASSERT( translator2.needsReordering () == false );
const auto new_order = translator2.reorder ();
TS_ASSERT( new_order[0] == 0 );
TS_ASSERT( new_order[1] == 1 );
TS_ASSERT( new_order[2] == 2 );
TS_ASSERT( new_order.size() == 0 );
gum::RangeVariable var ( "X2", "", 2, 3 );
gum::learning::DBTranslator4RangeVariable<>
......@@ -285,9 +283,7 @@ namespace gum_tests {
TS_ASSERT( possible_translated_miss.exists ( translator2.translateBack ( gum::learning::DBTranslatedValue{std::numeric_limits<std::size_t>::max ()} ) ) );
TS_ASSERT( translator2.needsReordering () == false );
const auto new_order = translator2.reorder ();
TS_ASSERT( new_order[0] == 0 );
TS_ASSERT( new_order[1] == 1 );
TS_ASSERT( new_order[2] == 2 );
TS_ASSERT( new_order.size() == 0 );
gum::RangeVariable var ( "X2", "", 2, 3 );
gum::learning::DBTranslator4RangeVariable<MyAlloc>
......