50#ifndef DOXYGEN_SHOULD_SKIP_THIS
63 _translators_(translators) {
64 if (translators.size()) {
66 std::vector< std::string > var_names(translators.size());
67 for (std::size_t i = std::size_t(0), size = translators.size(); i < size; ++i) {
68 var_names[i] = _translators_.translator(i).variable()->name();
70 setVariableNames(var_names,
false);
73 GUM_CONSTRUCTOR(DatabaseTable);
77 DatabaseTable::DatabaseTable(
const DBTranslatorSet& translators) :
78 IDatabaseTable< DBTranslatedValue >(
std::vector<
std::string >(),
79 std::vector<
std::string >()),
80 _translators_(translators) {
81 if (translators.size()) {
83 std::vector< std::string > var_names(translators.size());
84 for (std::size_t i = std::size_t(0), size = translators.size(); i < size; ++i) {
85 var_names[i] = _translators_.translator(i).variable()->name();
87 setVariableNames(var_names,
false);
90 GUM_CONSTRUCTOR(DatabaseTable);
94 DatabaseTable* DatabaseTable::clone()
const {
return new DatabaseTable(*
this); }
97 DatabaseTable& DatabaseTable::operator=(
const DatabaseTable& from) {
99 IDatabaseTable< DBTranslatedValue >::operator=(from);
100 _translators_ = from._translators_;
101 _ignored_cols_ = from._ignored_cols_;
108 DatabaseTable& DatabaseTable::operator=(DatabaseTable&& from)
noexcept {
110 IDatabaseTable< DBTranslatedValue >::operator=(std::move(from));
111 _translators_ = std::move(from._translators_);
112 _ignored_cols_ = std::move(from._ignored_cols_);
119 std::size_t DatabaseTable::insertTranslator(
const DBTranslator& translator,
120 const std::size_t input_column,
121 const bool unique_column) {
123 if (_ignored_cols_.exists(input_column))
125 "Column " << input_column <<
" is marked as being ignored. "
126 <<
"So it is forbidden to create a translator for that column.")
129 const
std::
size_t new_size = this->nbVariables() + 1;
134 auto reserve_lambda = [this, new_size](
std::
size_t begin,
std::
size_t end,
std::
size_t index) {
135 for (std::size_t i = begin; i < end; ++i) {
136 this->rows_[i].row().reserve(new_size);
140 auto undo_reserve_lambda = [](std::size_t begin, std::size_t end, std::size_t index) {};
143 this->_threadProcessDatabase_(reserve_lambda, undo_reserve_lambda);
146 const std::size_t pos = _translators_.insertTranslator(translator, input_column, unique_column);
150 this->variable_names_.push_back(translator.variable()->name());
152 _translators_.eraseTranslator(pos);
158 if (!IDatabaseTable< DBTranslatedValue >::empty()) {
159 const DBTranslatedValue missing = _translators_[pos].missingValue();
162 auto fill_lambda = [
this, missing](std::size_t begin, std::size_t end, std::size_t index) {
163 std::size_t i = begin;
165 for (; i < end; ++i) {
166 this->rows_[i].row().push_back(missing);
169 for (std::size_t j = begin; j < i; ++j) {
170 this->rows_[j].row().pop_back();
175 for (i = begin; i < end; ++i) {
176 this->has_row_missing_val_[i] = IsMissing::True;
180 auto undo_fill_lambda = [
this](std::size_t begin, std::size_t end, std::size_t index) {
181 for (std::size_t i = begin; i < end; ++i) {
182 auto& row = this->rows_[i].row();
186 bool has_missing_value =
false;
187 for (std::size_t j = 0, endj = row.size(); j < endj; ++j) {
188 if (_translators_[j].isMissingValue(row[j])) {
189 has_missing_value =
true;
193 this->has_row_missing_val_[i] = has_missing_value ? IsMissing::True : IsMissing::False;
198 this->_threadProcessDatabase_(fill_lambda, undo_fill_lambda);
205 std::size_t DatabaseTable::insertTranslator(
const Variable& var,
206 const std::size_t input_column,
207 const bool unique_column) {
209 if (_ignored_cols_.exists(input_column))
211 "Column " << input_column <<
" is marked as being ignored. "
212 <<
"So it is forbidden to create a translator for that column.")
218 if (!IDatabaseTable< DBTranslatedValue >::empty()) {
220 "inserting a new translator into a database creates a new column "
221 <<
"with missing values. However, you did not define any symbol for "
226 const std::size_t new_size = this->nbVariables() + 1;
231 auto reserve_lambda = [
this, new_size](std::size_t begin, std::size_t end, std::size_t index) {
232 for (std::size_t i = begin; i < end; ++i)
233 this->rows_[i].row().reserve(new_size);
236 auto undo_reserve_lambda = [](std::size_t begin, std::size_t end, std::size_t index) {};
239 this->_threadProcessDatabase_(reserve_lambda, undo_reserve_lambda);
242 const std::size_t pos = _translators_.insertTranslator(var, input_column, unique_column);
246 this->variable_names_.push_back(var.name());
248 _translators_.eraseTranslator(pos);
256 std::size_t DatabaseTable::insertTranslator(
const Variable& var,
257 const std::size_t input_column,
258 const std::vector< std::string >& missing_symbols,
259 const bool unique_column) {
261 if (_ignored_cols_.exists(input_column))
263 "Column " << input_column <<
" is marked as being ignored. "
264 <<
"So it is forbidden to create a translator for that column.")
267 const
std::
size_t new_size = this->nbVariables() + 1;
273 = [this, new_size](
std::
size_t begin,
std::
size_t end,
std::
size_t index) ->
void {
274 for (std::size_t i = begin; i < end; ++i)
275 this->rows_[i].row().reserve(new_size);
278 auto undo_reserve_lambda = [](std::size_t begin, std::size_t end, std::size_t index) ->
void {};
281 this->_threadProcessDatabase_(reserve_lambda, undo_reserve_lambda);
284 const std::size_t pos
285 = _translators_.insertTranslator(var, input_column, missing_symbols, unique_column);
289 this->variable_names_.push_back(var.name());
291 _translators_.eraseTranslator(pos);
297 if (!IDatabaseTable< DBTranslatedValue >::empty()) {
298 const DBTranslatedValue missing = _translators_[pos].missingValue();
302 = [
this, missing](std::size_t begin, std::size_t end, std::size_t index) ->
void {
303 std::size_t i = begin;
305 for (; i < end; ++i) {
306 this->rows_[i].row().push_back(missing);
309 for (std::size_t j = begin; j < i; ++j) {
310 this->rows_[j].row().pop_back();
315 for (i = begin; i < end; ++i) {
316 this->has_row_missing_val_[i] = IsMissing::True;
320 auto undo_fill_lambda
321 = [
this](std::size_t begin, std::size_t end, std::size_t index) ->
void {
322 for (std::size_t i = begin; i < end; ++i) {
323 auto& row = this->rows_[i].row();
327 bool has_missing_value =
false;
328 for (std::size_t j = 0, endj = row.size(); j < endj; ++j) {
329 if (_translators_[j].isMissingValue(row[j])) {
330 has_missing_value =
true;
334 this->has_row_missing_val_[i] = has_missing_value ? IsMissing::True : IsMissing::False;
339 this->_threadProcessDatabase_(fill_lambda, undo_fill_lambda);
347 void DatabaseTable::eraseTranslators(
const std::size_t k,
const bool k_is_input_col) {
348 for (
const auto kk: _getKthIndices_(k, k_is_input_col)) {
352 this->variable_names_.erase(this->variable_names_.begin() + kk);
353 if (this->variable_names_.empty()) {
354 IDatabaseTable< DBTranslatedValue >::eraseAllRows();
356 const std::size_t nb_trans = _translators_.size();
359 = [
this, nb_trans, kk](std::size_t begin, std::size_t end, std::size_t index) ->
void {
360 for (std::size_t i = begin; i < end; ++i) {
361 auto& row = this->rows_[i].row();
362 if (this->_translators_.isMissingValue(row[kk], kk)) {
363 bool has_missing_val =
false;
364 for (std::size_t j = std::size_t(0); j < nb_trans; ++j) {
365 if ((j != kk) && this->_translators_.isMissingValue(row[j], j)) {
366 has_missing_val =
true;
370 if (!has_missing_val) this->has_row_missing_val_[i] = IsMissing::False;
372 row.erase(row.begin() + kk);
376 auto undo_erase_lambda
377 = [](std::size_t begin, std::size_t end, std::size_t index) ->
void {};
380 this->_threadProcessDatabase_(erase_lambda, undo_erase_lambda);
382 _translators_.eraseTranslator(kk);
387 void DatabaseTable::changeTranslator(DBTranslator& new_translator,
389 const bool k_is_input_col) {
392 const auto db_k = _getKthIndices_(k, k_is_input_col);
396 const std::size_t kk = db_k[db_k.size() - 1];
397 if (kk >= _translators_.size()) {
406 this->variable_names_[kk] = new_translator.variable()->name();
409 _translators_.changeTranslator(new_translator, kk);
417 DBTranslator& old_translator = _translators_[kk];
418 if (!old_translator.isLossless()) {
423 "Lossy translators cannot yet be substituted by other translators");
426 const std::size_t nb_threads = this->nbProcessingThreads_();
429 std::pair< DBTranslatedValue, DBTranslatedValue > miss_mapping(old_translator.missingValue(),
430 new_translator.missingValue());
453 if (!this->empty()) {
456 bool has_missing_value =
false;
458 std::vector< int > missing_values(nb_threads, 0);
461 auto get_lambda = [
this, kk, &missing_values](std::size_t begin,
463 std::size_t index) ->
void {
464 for (std::size_t i = begin; i < end; ++i) {
465 auto& row = this->rows_[i].row();
466 if (this->_translators_.isMissingValue(row[kk], kk)) {
467 missing_values[index] = 1;
473 auto undo_get_lambda = [](std::size_t begin, std::size_t end, std::size_t index) ->
void {};
476 this->_threadProcessDatabase_(get_lambda, undo_get_lambda);
479 for (
const auto x: missing_values) {
481 has_missing_value =
true;
488 const auto old_missing_symbols = old_translator.missingSymbols();
489 const auto new_missing_symbols = new_translator.missingSymbols();
490 const bool multiple_missing_symbols = old_missing_symbols.size() > 1;
491 const bool old_miss_included = old_missing_symbols.isSubsetOrEqual(new_missing_symbols);
492 if (has_missing_value && multiple_missing_symbols && !old_miss_included) {
496 "it is impossible to substitute the translator because "
497 "the database contains some missing values that cannot be "
498 "substituted unambiguously");
510 if (has_missing_value && !old_miss_included) {
512 new_translator.translate(*(old_translator.missingSymbols().begin()));
513 }
catch (Exception
const&) {
515 "it is impossible to substitute the translator because "
516 "the database contains some missing values that cannot be "
523 if (has_missing_value && !old_miss_included) {
524 miss_mapping.second = new_translator.translate(*(old_translator.missingSymbols().begin()));
532 std::vector< int > unmapped(nb_threads, 0);
536 = [
this, kk, &old_translator, &new_translator, &unmapped](std::size_t begin,
538 std::size_t index) ->
void {
539 const auto old_miss = old_translator.missingValue().discr_val;
540 for (std::size_t i = begin; i < end; ++i) {
541 const auto& row = this->rows_[i].row();
542 if (row[kk].discr_val != old_miss) {
544 new_translator.translate(old_translator.translateBack(row[kk]));
545 }
catch (Exception
const&) {
554 auto undo_check_lambda = [](std::size_t begin, std::size_t end, std::size_t index) ->
void {};
557 this->_threadProcessDatabase_(check_lambda, undo_check_lambda);
561 for (
const auto x: unmapped) {
564 "The database contains some values that cannot be translated "
565 "using the new translator");
573 = [
this, kk, &old_translator, &new_translator, miss_mapping](std::size_t begin,
575 std::size_t index) ->
void {
576 const auto old_miss = old_translator.missingValue().discr_val;
577 for (std::size_t i = begin; i < end; ++i) {
578 auto& row = this->rows_[i].row();
579 if (row[kk].discr_val == old_miss) {
580 row[kk] = miss_mapping.second;
582 row[kk] = new_translator.translate(old_translator.translateBack(row[kk]));
587 auto undo_change_lambda = [](std::size_t begin, std::size_t end, std::size_t index) ->
void {};
590 this->_threadProcessDatabase_(change_lambda, undo_change_lambda);
593 this->variable_names_[kk] = new_translator.variable()->name();
596 _translators_.changeTranslator(new_translator, kk);
600 void DatabaseTable::changeTranslator(
const Variable& var,
602 const bool k_is_input_col,
603 const std::vector< std::string >& missing_symbols,
604 const bool editable_dictionary,
605 const std::size_t max_dico_entries) {
607 std::vector< std::string > missing;
608 if (missing_symbols.empty()) {
610 const auto db_k = _getKthIndices_(k, k_is_input_col);
614 const std::size_t kk = db_k[db_k.size() - 1];
615 if (kk >= _translators_.size()) {
619 const auto& miss = _translators_[kk].missingSymbols();
620 missing.reserve(miss.size());
621 for (
const auto& m: miss) {
622 missing.push_back(m);
625 missing = missing_symbols;
629 DBTranslator* new_translator
630 = DBTranslators::create(var, missing, editable_dictionary, max_dico_entries);
633 changeTranslator(*new_translator, k, k_is_input_col);
636 delete new_translator;
641 delete new_translator;
645 std::vector< std::pair< Idx, std::shared_ptr< DBTranslator > > >
646 DatabaseTable::betterTranslators()
const {
647 std::vector< std::pair< Idx, std::shared_ptr< DBTranslator > > > better;
649 for (Idx i = 0, size = _translators_.size(); i < size; ++i) {
650 switch (_translators_[i].variable()->varType()) {
653 case VarType::CONTINUOUS :
654 case VarType::NUMERICAL :
655 case VarType::DISCRETIZED :
656 case VarType::RANGE :
break;
660 case VarType::INTEGER : {
661 const auto& var =
dynamic_cast< const IntegerVariable&
>(*(_translators_[i].variable()));
664 const auto& domain = var.integerDomain();
665 if (domain.empty())
break;
666 int prev = domain[0] - 1;
668 for (
const auto elt: domain) {
669 if (elt != prev + 1) {
680 RangeVariable new_var(var.name(),
683 domain[domain.size() - 1]);
686 const auto& missing = _translators_[i].missingSymbols();
687 std::vector< std::string > new_missing;
688 new_missing.reserve(missing.size());
689 for (
const auto& miss: missing) {
690 new_missing.push_back(miss);
692 auto new_trans =
new DBTranslator4RangeVariable(new_var, new_missing);
693 better.push_back(std::pair< Idx, std::shared_ptr< DBTranslator > >(
695 std::shared_ptr< DBTranslator >(new_trans)));
705 case VarType::LABELIZED : {
707 =
dynamic_cast< const LabelizedVariable&
>(*(_translators_[i].variable()));
708 if (!var.domainSize())
break;
711 Set< int > int_values;
712 Set< float > real_values;
714 for (Idx j = 0, s = var.domainSize(); j < s; ++j) {
715 const auto& val = var.label(j);
716 if (DBCell::isReal(val)) {
717 if (DBCell::isInteger(val)) {
718 int_values.insert(std::stoi(val));
720 real_values.insert(std::stof(val));
731 if (real_values.empty()) {
733 std::vector< int > values;
734 values.reserve(int_values.size());
735 for (
const auto val: int_values)
736 values.push_back(val);
737 std::sort(values.begin(), values.end());
741 int prev = values[0] - 1;
742 bool consecutive =
true;
743 for (
const auto elt: values) {
744 if (elt != prev + 1) {
755 RangeVariable new_var(var.name(), var.description(), values[0], values.back());
758 const auto& missing = _translators_[i].missingSymbols();
759 std::vector< std::string > new_missing;
760 new_missing.reserve(missing.size());
761 for (
const auto& miss: missing) {
762 new_missing.push_back(miss);
764 auto new_trans =
new DBTranslator4RangeVariable(new_var, new_missing);
765 better.emplace_back(i, std::shared_ptr< DBTranslator >(new_trans));
769 IntegerVariable new_var(var.name(), var.description(), values);
772 const auto& missing = _translators_[i].missingSymbols();
773 std::vector< std::string > new_missing;
774 new_missing.reserve(missing.size());
775 for (
const auto& miss: missing) {
776 new_missing.push_back(miss);
778 auto new_trans =
new DBTranslator4IntegerVariable(new_var, new_missing);
779 better.emplace_back(i, std::shared_ptr< DBTranslator >(new_trans));
783 ContinuousVariable new_var(var.name(), var.description());
786 const auto& missing = _translators_[i].missingSymbols();
787 std::vector< std::string > new_missing;
788 new_missing.reserve(missing.size());
789 for (
const auto& miss: missing) {
790 new_missing.push_back(miss);
792 auto new_trans =
new DBTranslator4ContinuousVariable(new_var, new_missing);
793 better.emplace_back(i, std::shared_ptr< DBTranslator >(new_trans));
805 const DBTranslator& DatabaseTable::translator(
const std::size_t k,
806 const bool k_is_input_col)
const {
809 const std::size_t nb_trans = _translators_.size();
810 const std::size_t kk = _getKthIndex_(k, k_is_input_col);
813 if (nb_trans <= kk) {
814 if (k_is_input_col) {
816 "there is no translator in the database table that " <<
"parses Column " << k)
819 "the database has " << nb_trans <<
" translators, so Translator #" << k
820 <<
" does not exist")
824 return _translators_.translator(kk);
828 const Variable& DatabaseTable::variable(
const std::size_t k,
const bool k_is_input_col)
const {
831 const std::size_t nb_trans = _translators_.size();
832 const std::size_t kk = _getKthIndex_(k, k_is_input_col);
835 if (nb_trans <= kk) {
836 if (k_is_input_col) {
838 "there is no variable in the database table that " <<
"corresponds to Column "
842 "the database has " << nb_trans <<
" variables, so Variable #" << k
843 <<
" does not exist")
847 return _translators_.variable(kk);
851 void DatabaseTable::setVariableNames(
const std::vector< std::string >& names,
852 const bool from_external_object) {
853 const std::size_t size = names.size();
854 const std::size_t nb_trans = _translators_.size();
855 if (!from_external_object) {
856 if (nb_trans != size) {
858 "the number of variable's names (i.e., "
859 << size <<
") does not correspond to the number of columns of the "
860 <<
"database table (i.e.," << nb_trans <<
")")
864 for (std::size_t i = std::size_t(0); i < size; ++i) {
865 _translators_.translator(i).setVariableName(names[i]);
868 if (nb_trans && (_translators_.highestInputColumn() >= size)) {
870 "the names vector has " << size <<
" elements whereas it should have at least "
871 << (_translators_.highestInputColumn() + 1)
872 <<
"elements so that each translator is assigned a name")
876 for (std::size_t i = std::size_t(0); i < nb_trans; ++i) {
877 _translators_.translator(i).setVariableName(names[_translators_.inputColumn(i)]);
882 this->variable_names_.resize(nb_trans);
883 for (std::size_t i = std::size_t(0); i < nb_trans; ++i) {
884 this->variable_names_[i] = _translators_.variable(i).name();
890 void DatabaseTable::ignoreColumn(
const std::size_t k,
const bool k_is_input_col) {
894 const std::size_t nb_trans = _translators_.size();
895 if (k_is_input_col) {
896 if (_ignored_cols_.exists(k))
return;
897 _ignored_cols_.insert(k);
900 _ignored_cols_.insert(_translators_.inputColumn(k));
903 "It is impossible to ignore the column parsed by Translator #"
904 << k <<
"because there exist only " << nb_trans <<
" translators")
909 eraseTranslators(k, k_is_input_col);
913 const typename DatabaseTable::template DBVector< std::size_t >
914 DatabaseTable::ignoredColumns()
const {
915 const std::size_t nb_trans = _translators_.size();
917 if (nb_trans == std::size_t(0)) {
return DBVector< std::size_t >{std::size_t(0)}; }
920 DBVector< std::size_t > cols(nb_trans);
921 for (std::size_t i = std::size_t(0); i < nb_trans; ++i) {
922 cols[i] = _translators_.inputColumn(i);
924 std::sort(cols.begin(), cols.end());
927 const std::size_t highest = _translators_.highestInputColumn() + 1;
928 DBVector< std::size_t > ignored_cols(highest);
929 std::iota(ignored_cols.begin(), ignored_cols.end(), 0);
932 for (std::size_t i = std::size_t(0), ii = highest - 1, k = std::size_t(0), kk = nb_trans - 1;
935 if (cols[kk] == ii) {
936 ignored_cols.erase(ignored_cols.begin() + ii);
937 while ((k < nb_trans) && (cols[kk] == ii)) {
941 if (k == nb_trans)
break;
946 ignored_cols.push_back(highest);
952 const typename DatabaseTable::template DBVector< std::size_t >
953 DatabaseTable::inputColumns()
const {
954 const std::size_t nb_trans = _translators_.size();
955 if (nb_trans == std::size_t(0)) {
return DBVector< std::size_t >(); }
957 DBVector< std::size_t > input_cols(nb_trans);
958 for (std::size_t i = std::size_t(0); i < nb_trans; ++i) {
959 input_cols[i] = _translators_.inputColumn(i);
965 std::size_t DatabaseTable::domainSize(
const std::size_t k,
const bool k_is_input_col)
const {
967 const std::size_t nb_trans = _translators_.size();
968 const std::size_t kk = _getKthIndex_(k, k_is_input_col);
971 if (nb_trans <= kk) {
972 if (k_is_input_col) {
974 "there is no variable in the database table that " <<
"corresponds to Column "
978 "the database has " << nb_trans <<
" variables, so Variable #" << k
979 <<
" does not exist")
983 return _translators_.domainSize(kk);
988 bool DatabaseTable::needsReordering(
const std::size_t k,
const bool k_is_input_col)
const {
990 const std::size_t nb_trans = _translators_.size();
991 const std::size_t kk = _getKthIndex_(k, k_is_input_col);
994 if (nb_trans <= kk) {
995 if (k_is_input_col) {
997 "there is no translator in the database table that " <<
"parses Column " << k)
1000 "the database has " << nb_trans <<
" translators, so Translator #" << k
1001 <<
" does not exist")
1005 return _translators_.needsReordering(kk);
1010 void DatabaseTable::reorder(
const std::size_t k,
const bool k_is_input_col) {
1012 const std::size_t nb_trans = _translators_.size();
1013 const std::size_t kk = _getKthIndex_(k, k_is_input_col);
1016 if (nb_trans <= kk) {
1017 if (k_is_input_col) {
1019 "there is no translator in the database table that " <<
"parses Column " << k)
1022 "the database has " << nb_trans <<
" translators, so Translator #" << k
1023 <<
" does not exist")
1029 if (_translators_.translator(kk).getValType() != DBTranslatedValueType::DISCRETE)
return;
1032 auto updates = _translators_.reorder(kk);
1033 if (updates.empty())
return;
1035 std::size_t size = updates.size();
1036 std::vector< std::size_t > new_values(size);
1037 for (
const auto& update: updates) {
1038 if (update.first >= size) {
1039 size = update.first + 1;
1040 new_values.resize(size);
1042 new_values[update.first] = update.second;
1046 auto newtrans_lambda
1047 = [
this, kk, &new_values](std::size_t begin, std::size_t end, std::size_t index) ->
void {
1048 for (std::size_t i = begin; i < end; ++i) {
1049 auto& elt = this->rows_[i][kk].discr_val;
1050 if (elt != std::numeric_limits< std::size_t >::max()) elt = new_values[elt];
1054 auto undo_newtrans_lambda
1055 = [](std::size_t begin, std::size_t end, std::size_t index) ->
void {};
1058 this->_threadProcessDatabase_(newtrans_lambda, undo_newtrans_lambda);
1062 void DatabaseTable::insertRow(
const std::vector< std::string >& new_row) {
1065 const std::size_t row_size = new_row.size();
1066 if (row_size == std::size_t(0))
return;
1068 if (_translators_.highestInputColumn() >= row_size) {
1070 "the row #" << 1 + size() <<
" has " << row_size
1071 <<
" columns whereas the database requires at least "
1072 << (_translators_.highestInputColumn() + 1) <<
" columns")
1076 const std::size_t nb_trans = _translators_.size();
1077 Row< DBTranslatedValue > dbrow;
1078 dbrow.reserve(nb_trans);
1079 bool has_missing_val =
false;
1080 for (std::size_t i = std::size_t(0); i < nb_trans; ++i) {
1081 const DBTranslatedValue new_val(_translators_.translate(new_row, i));
1082 if (_translators_.isMissingValue(new_val, i)) has_missing_val =
true;
1083 dbrow.pushBack(std::move(new_val));
1086 this->insertRow(std::move(dbrow), has_missing_val ? IsMissing::True : IsMissing::False);
1091 bool DatabaseTable::_isRowCompatible_(
1092 const typename DatabaseTable::template Row< DBTranslatedValue >& row)
const {
1094 const std::size_t row_size = row.size();
1095 if (row_size != _translators_.size())
return false;
1097 const auto& translators = _translators_.translators();
1098 for (std::size_t i = std::size_t(0); i < row_size; ++i) {
1099 switch (translators[i]->getValType()) {
1100 case DBTranslatedValueType::DISCRETE :
1101 if ((row[i].discr_val >= translators[i]->domainSize())
1102 && (row[i].discr_val != std::numeric_limits< std::size_t >::max()))
1106 case DBTranslatedValueType::CONTINUOUS : {
1107 const IContinuousVariable& var
1108 =
static_cast< const IContinuousVariable&
>(*(translators[i]->variable()));
1109 if (((var.lowerBoundAsDouble() > (
double)row[i].cont_val)
1110 || (var.upperBoundAsDouble() < (
double)row[i].cont_val))
1111 && (row[i].cont_val != std::numeric_limits< float >::max()))
1124 void DatabaseTable::insertRow(
const typename DatabaseTable::template Row< DBCell >& new_row) {
1129 void DatabaseTable::insertRow(
typename DatabaseTable::template Row< DBCell >&& new_row) {
1134 void DatabaseTable::insertRows(
1139 for (
const auto& new_row: rows) {
1140 if (!_isRowCompatible_(new_row)) {
1141 if (new_row.size() != _translators_.size()) {
1143 "The new row has " << new_row.size()
1144 <<
" elements whereas the database table has "
1145 << _translators_.size() <<
" columns")
1152 IDatabaseTable< DBTranslatedValue >::insertRows(std::move(rows), rows_have_missing_vals);
1156 void DatabaseTable::insertRows(
1161 for (
const auto& new_row: new_rows) {
1162 if (!_isRowCompatible_(new_row)) {
1163 if (new_row.size() != _translators_.size()) {
1165 "The new row has " << new_row.size()
1166 <<
" elements whereas the database table has "
1167 << _translators_.size() <<
" columns")
1174 IDatabaseTable< DBTranslatedValue >::insertRows(new_rows, rows_have_missing_vals);
1178 void DatabaseTable::insertRows(
typename DatabaseTable::template
Matrix< DBCell >&& new_rows) {
1184 DatabaseTable::insertRows(
const typename DatabaseTable::template
Matrix< DBCell >& new_rows) {
1189 void DatabaseTable::clear() {
1190 _translators_.clear();
1191 _ignored_cols_.clear();
1192 IDatabaseTable< DBTranslatedValue >::clear();
1195 std::size_t DatabaseTable::_getKthIndex_(
const std::size_t k,
const bool k_is_input_col)
const {
1196 if (k_is_input_col) {
1197 const std::size_t nb_trans = _translators_.size();
1198 for (std::size_t i = std::size_t(0); i < nb_trans; ++i) {
1199 if (_translators_.inputColumn(i) == k) {
return i; }
1201 return nb_trans + 1;
1207 void DatabaseTable::insertRow(
typename DatabaseTable::template Row< DBTranslatedValue >&& new_row,
1208 const typename DatabaseTable::IsMissing contains_missing_data) {
1211 if (!_isRowCompatible_(new_row)) {
1212 if (new_row.size() != _translators_.size()) {
1214 "The new row has " << new_row.size()
1215 <<
" elements whereas the database table has "
1216 << _translators_.size() <<
" columns")
1222 IDatabaseTable< DBTranslatedValue >::insertRow(std::move(new_row), contains_missing_data);
1225 void DatabaseTable::insertRow(
1226 const typename DatabaseTable::template Row< DBTranslatedValue >& new_row,
1227 const typename DatabaseTable::IsMissing contains_missing_data) {
1230 if (!_isRowCompatible_(new_row)) {
1231 if (new_row.size() != _translators_.size()) {
1233 "The new row has " << new_row.size()
1234 <<
" elements whereas the database table has "
1235 << _translators_.size() <<
" columns")
1241 IDatabaseTable< DBTranslatedValue >::insertRow(new_row, contains_missing_data);
Exception: at least one argument passed to a function is not what was expected.
Error: The database contains some missing values.
Exception : there is something wrong with an implementation.
Exception : operation not allowed.
Exception : out of bound.
Exception : problem with size.
Exception : a looked-for element could not be found.
the class for packing together the translators used to preprocess the datasets
DatabaseTable(const MissingValType &missing_symbols, const DBTranslatorSet &translators=DBTranslatorSet())
default constructor
std::vector< std::string > MissingValType
The common class for the tabular database tables.
The class representing a tabular database stored in RAM.
#define GUM_ERROR(type, msg)
include the inlined functions if necessary
The union class for storing the translated values in learning databases.