diff --git a/CMakeLists.txt b/CMakeLists.txt index 355d5b1704ff8e0aa011ca73bd8a948ef3cbe14e..f0a2125b67d083e2eead75d5fffba45100fe7075 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,14 +63,15 @@ if(EXTERNAL_BOOST) message(STATUS "Using external boost") set(EXTERNAL_BOOST TRUE) else(EXTERNAL_BOOST) - if(NOT DEFINED EXTERNAL_BUILD_N_PROCS) - set(EXTERNAL_BUILD_N_PROCS 1 CACHE STRING "Number of processes to use when building Boost") - endif() message(STATUS "Building boost wth ${EXTERNAL_BUILD_N_PROCS} process(es)") include( ExternalProject ) set(EXTERNAL_BOOST FALSE) endif() +if(NOT DEFINED EXTERNAL_BUILD_N_PROCS) + set(EXTERNAL_BUILD_N_PROCS 1 CACHE STRING "Number of processes to use when building Boost") +endif() + # Check for FindOpenMP find_package(OpenMP REQUIRED) if (OPENMP_FOUND) diff --git a/src/feature_creation/feature_space/FeatureSpace.cpp b/src/feature_creation/feature_space/FeatureSpace.cpp index f210241c05cde87ca98a8ec63ebacc14b0943552..10d3022f4c2c01a1844fd158166a2302d27b0419 100644 --- a/src/feature_creation/feature_space/FeatureSpace.cpp +++ b/src/feature_creation/feature_space/FeatureSpace.cpp @@ -573,6 +573,110 @@ void FeatureSpace::generate_non_param_feats( } } +#ifdef PARAMETERIZE +int FeatureSpace::reorder_by_n_params(std::vector<node_ptr>& feat_set, int start) +{ + std::vector<int> feat_n_params(feat_set.size() - start); + std::transform( + feat_set.begin() + start, + feat_set.end(), + feat_n_params.begin(), + [](node_ptr feat){return feat->n_params();} + ); + std::vector<int> inds = util_funcs::argsort<int>(feat_n_params); + std::vector<node_ptr> feat_set_copy(feat_n_params.size()); + std::copy_n(feat_set.begin() + start, feat_n_params.size(), feat_set_copy.begin()); + + std::transform( + inds.begin(), + inds.end(), + feat_set.begin() + start, + [&feat_set_copy](int ind){return feat_set_copy[ind];} + ); + + for(int ff = start; ff < feat_set.size(); ++ff) + { + feat_set[ff]->reindex(ff); + } + + // Set how many features have no parameters + return start + std::count_if( + feat_n_params.begin(), + feat_n_params.end(), + [](int n_param){return n_param == 0;} + ); +} +#endif +void FeatureSpace::remove_duplicate_features(std::vector<node_ptr>& feat_set, int start) +{ + std::vector<double> scores(feat_set.size(), 0.0); + project_funcs::project_r(_prop_train.data(), scores.data(), feat_set, _task_sizes_train, 1); + + scores.erase(scores.begin(), scores.begin() + start); + if(scores.size() == 0) + { + throw std::logic_error("No features created during this rung (" + std::to_string(feat_set.back()->rung() + 1) + ")"); + } + std::vector<int> inds = util_funcs::argsort<double>(scores); + + std::vector<int> del_inds; + node_value_arrs::clear_temp_reg(); + for(int sc = 0; sc < scores.size() - 1; ++sc) + { + #ifdef PARAMETERIZE + if(feat_set[inds[sc] + start]->n_params() > 0) + { + continue; + } + #endif + + double* val_ptr = feat_set[start + inds[sc]]->stand_value_ptr(); + double base_val = std::abs( + std::inner_product( + val_ptr, + val_ptr + _n_samp_train, + val_ptr, + 0.0 + ) + ); + + int sc2 = sc + 1; + while((sc2 < scores.size()) && (scores[inds[sc2]] - scores[inds[sc]] < 1e-7)) + { + double comp = std::abs( + base_val - + std::abs( + std::inner_product( + val_ptr, + val_ptr + _n_samp_train, + feat_set[start + inds[sc2]]->stand_value_ptr(true), + 0.0 + ) + ) + ); + + if(comp / static_cast<double>(_n_samp_train) < 1e-10) + { + del_inds.push_back(-1 * (inds[sc] + start)); + break; + } + ++sc2; + } + } + + inds = util_funcs::argsort<int>(del_inds); + for(int ii = 0; ii < inds.size(); ++ii) + { + feat_set.erase(feat_set.begin() - del_inds[inds[ii]]); + } + + // Reindex + for(int ff = start; ff < feat_set.size(); ++ff) + { + feat_set[ff]->reindex(ff); + } +} + void FeatureSpace::generate_feature_space( std::vector<node_ptr>& feat_set, std::vector<int>& start_rung, @@ -669,7 +773,6 @@ void FeatureSpace::generate_feature_space( if((nn < _max_rung) || (nn <= _n_rung_store) || (_mpi_comm->size() == 1)) { int new_phi_size; - int phi_size_start = feat_set.size(); if(_mpi_comm->rank() == 0) { std::vector<std::vector<node_ptr>> next_phi_gathered; @@ -679,7 +782,6 @@ void FeatureSpace::generate_feature_space( { feat_set.insert(feat_set.end(), next_phi_vec.begin(), next_phi_vec.end()); } - new_phi_size = feat_set.size(); // Sort the features to ensure consistent feature spaces for all MPI/OpenMP configurations std::sort( @@ -694,118 +796,44 @@ void FeatureSpace::generate_feature_space( feat_set.end(), [&feat_ind](node_ptr n){n->reindex(feat_ind); ++feat_ind;} ); - - mpi::broadcast(*_mpi_comm, new_phi_size, 0); - - for(int bb = 0; bb <= (new_phi_size - phi_size_start) / 10000; ++bb) + if(nn < _max_rung) + { + remove_duplicate_features(feat_set, start_rung.back()); + } + #ifdef PARAMETERIZE + if(!reparam) { - mpi::broadcast(*_mpi_comm, &feat_set[phi_size_start + bb * 10000], std::min(10000, new_phi_size - phi_size_start - bb * 10000), 0); + int no_param_sz = reorder_by_n_params(feat_set, start_rung.back()); + mpi::broadcast(*_mpi_comm, no_param_sz, 0); + _end_no_params.push_back(no_param_sz); } + #endif + new_phi_size = feat_set.size(); + mpi::broadcast(*_mpi_comm, new_phi_size, 0); + mpi::broadcast(*_mpi_comm, &feat_set[start_rung.back()], new_phi_size - start_rung.back(), 0); } else { mpi::gather(*_mpi_comm, next_phi, 0); - mpi::broadcast(*_mpi_comm, new_phi_size, 0); - feat_set.resize(new_phi_size); - for(int bb = 0; bb <= (new_phi_size - phi_size_start) / 10000; ++bb) + #ifdef PARAMETERIZE + if(!reparam) { - mpi::broadcast(*_mpi_comm, &feat_set[phi_size_start + bb * 10000], std::min(10000, new_phi_size - phi_size_start - bb * 10000), 0); + int no_param_sz; + mpi::broadcast(*_mpi_comm, no_param_sz, 0); + _end_no_params.push_back(no_param_sz); } - } + #endif - if(phi_size_start == new_phi_size) + mpi::broadcast(*_mpi_comm, new_phi_size, 0); + feat_set.resize(new_phi_size); + mpi::broadcast(*_mpi_comm, &feat_set[start_rung.back()], new_phi_size - start_rung.back(), 0); + } + if(start_rung.back() == feat_set.size()) { throw std::logic_error("No features created during this rung (" + std::to_string(nn) + ")"); } - node_value_arrs::clear_temp_reg(); - if(nn < _max_rung) - { - // Remove identical features - _scores.resize(feat_set.size()); - _mpi_comm->barrier(); - project_funcs::project_r(_prop_train.data(), _scores.data(), feat_set, _task_sizes_train, 1); - _scores.erase(_scores.begin(), _scores.begin() + start_rung[start_rung.size() - 1]); - inds = util_funcs::argsort<double>(_scores); - - std::vector<int> del_inds; - - _mpi_comm->barrier(); - node_value_arrs::clear_temp_reg(); - for(int sc = 0; sc < _scores.size() - 1; ++sc) - { - #ifdef PARAMETERIZE - if(feat_set[inds[sc] + start_rung.back()]->n_params() > 0) - { - continue; - } - #endif - - if(_scores[inds[sc]] > -1e-10) - { - double base_val = std::abs( - util_funcs::r( - feat_set[start_rung.back() + inds[sc]]->value_ptr(), - feat_set[start_rung.back() + inds[sc]]->value_ptr(), - _n_samp_train - ) - ); - for(int sc2 = sc + 1; sc2 < _scores.size(); ++sc2) - { - double comp = std::abs( - base_val - std::abs( - util_funcs::r( - feat_set[start_rung.back() + inds[sc]]->value_ptr(), - feat_set[start_rung.back() + inds[sc2]]->value_ptr(0, true), - _n_samp_train - ) - ) - ); - if(comp < 1e-10) - { - del_inds.push_back(-1 * (inds[sc] + start_rung.back())); - break; - } - } - } - else if(_scores[inds[sc + 1]] - _scores[inds[sc]] < 1e-10) - { - double base_val = std::abs( - util_funcs::r( - feat_set[start_rung.back() + inds[sc]]->value_ptr(), - feat_set[start_rung.back() + inds[sc]]->value_ptr(), - _n_samp_train - ) - ); - double comp = std::abs( - base_val - std::abs( - util_funcs::r( - feat_set[start_rung.back() + inds[sc]]->value_ptr(), - feat_set[start_rung.back() + inds[sc + 1]]->value_ptr(0, true), - _n_samp_train - ) - ) - ); - if(comp < 1e-10) - { - del_inds.push_back(-1 * (inds[sc] + start_rung.back())); - } - } - } - - inds = util_funcs::argsort<int>(del_inds); - for(int ii = 0; ii < inds.size(); ++ii) - { - feat_set.erase(feat_set.begin() - del_inds[inds[ii]]); - } - - // Reindex - for(int ff = start_rung.back(); ff < feat_set.size(); ++ff) - { - feat_set[ff]->reindex(ff); - } - } node_value_arrs::clear_temp_reg(); if(!reparam) { @@ -960,49 +988,19 @@ void FeatureSpace::generate_feature_space( } } } - - #pragma omp parallel for for(int ff = start_rung.back(); ff < feat_set.size(); ++ff) { feat_set[ff]->reindex(ff + n_feat_below_rank, ff); - feat_set[ff]->set_value(); - feat_set[ff]->set_test_value(); } - } - #ifdef PARAMETERIZE - if(!reparam) - { - // Reorder features based on the number of parameters they have (none goes first) - std::vector<int> feat_n_params(feat_set.size() - start_rung.back()); - std::transform( - feat_set.begin() + start_rung.back(), - feat_set.end(), - feat_n_params.begin(), - [](node_ptr feat){return feat->n_params();} - ); - inds = util_funcs::argsort<int>(feat_n_params); - next_phi.resize(feat_n_params.size()); - std::copy_n(feat_set.begin() + start_rung.back(), feat_n_params.size(), next_phi.begin()); - std::transform( - inds.begin(), - inds.end(), - feat_set.begin() + start_rung.back(), - [&next_phi](int ind){return next_phi[ind];} - ); - for(int ff = start_rung.back(); ff < feat_set.size(); ++ff) + #ifdef PARAMETERIZE + if(!reparam) { - feat_set[ff]->reindex(ff); - feat_set[ff]->set_value(); + int no_param_sz = reorder_by_n_params(feat_set, start_rung.back()); + _end_no_params.push_back(no_param_sz); } - - // Set how many features have no parameters - _end_no_params.push_back( - start_rung.back() + - std::count_if(feat_n_params.begin(), feat_n_params.end(), [](int n_param){return n_param == 0;}) - ); + #endif } - #endif } } @@ -1019,12 +1017,14 @@ void FeatureSpace::generate_and_project(std::shared_ptr<LossFunction> loss, std: int worst_score_ind = std::max_element(scores_sel.begin(), scores_sel.end()) - scores_sel.begin(); double worst_score = scores_sel[worst_score_ind]; + int num_valid_feats = phi_sel.size(); #pragma omp parallel firstprivate(worst_score, worst_score_ind, scores_sel_all) { std::shared_ptr<LossFunction> loss_copy = loss_function_util::copy(loss); std::vector<node_ptr> phi_sel_private(phi_sel); std::vector<double> scores_sel_private(scores_sel); - int index_base = _phi.size() + _n_sis_select * (omp_get_thread_num() + _mpi_comm->size()); + int index_base = _phi.size() + 2 * _n_sis_select * (omp_get_thread_num() + _mpi_comm->size()); + int num_valid_feats_private = num_valid_feats; #ifdef PARAMETERIZE std::shared_ptr<NLOptimizer> optimizer; @@ -1044,14 +1044,15 @@ void FeatureSpace::generate_and_project(std::shared_ptr<LossFunction> loss, std: } #endif + auto start = _phi.begin() + _start_rung.back() + _mpi_comm->rank(); #ifdef OMP45 #pragma omp for schedule(monotonic: dynamic) #else #pragma omp for schedule(dynamic) #endif - for(auto feat = _phi.begin() + _start_rung.back() + _mpi_comm->rank(); feat < _phi.end(); feat += _mpi_comm->size()) + for(auto feat = start; feat < _phi.end(); feat += _mpi_comm->size()) { - unsigned long int feat_ind = _phi.size() + _n_sis_select * (omp_get_num_threads() + _mpi_comm->size()); + unsigned long int feat_ind = _phi.size() + 2 * _n_sis_select * (omp_get_num_threads() + _mpi_comm->size()); node_value_arrs::clear_temp_reg_thread(); std::vector<node_ptr> generated_phi; @@ -1089,9 +1090,10 @@ void FeatureSpace::generate_and_project(std::shared_ptr<LossFunction> loss, std: while((ii < inds.size()) && ((scores[inds[ii]] < worst_score) || (phi_sel_private.size() < _n_sis_select))) { + node_value_arrs::clear_temp_reg_thread(); double cur_score = scores[inds[ii]]; - bool valid_feat = _is_valid( - generated_phi[inds[ii]]->value_ptr(0), + int valid_feat = _is_valid( + generated_phi[inds[ii]]->stand_value_ptr(), _n_samp_train, _cross_cor_max, scores_sel_all, @@ -1099,27 +1101,27 @@ void FeatureSpace::generate_and_project(std::shared_ptr<LossFunction> loss, std: node_value_arrs::N_SELECTED - _n_sis_select, 0 ); - valid_feat = valid_feat && _is_valid_feat_list( - generated_phi[inds[ii]]->value_ptr(0), - _n_samp_train, - _cross_cor_max, - phi_sel_private, - scores_sel_private, - cur_score - ); - if(valid_feat) + if(valid_feat > 0) { - if(scores_sel_private.size() == _n_sis_select) + valid_feat = _is_valid_feat_list( + generated_phi[inds[ii]]->stand_value_ptr(), + _n_samp_train, + _cross_cor_max, + phi_sel_private, + scores_sel_private, + cur_score + ); + + if((valid_feat > 0) && (num_valid_feats_private >= _n_sis_select)) { generated_phi[inds[ii]]->reindex(index_base + worst_score_ind); - generated_phi[inds[ii]]->set_value(); phi_sel_private[worst_score_ind] = generated_phi[inds[ii]]; scores_sel_private[worst_score_ind] = cur_score; } - else + else if(valid_feat != 0) { + num_valid_feats_private += valid_feat > 0; generated_phi[inds[ii]]->reindex(index_base + scores_sel_private.size()); - generated_phi[inds[ii]]->set_value(); phi_sel_private.push_back(generated_phi[inds[ii]]); scores_sel_private.push_back(cur_score); } @@ -1132,38 +1134,88 @@ void FeatureSpace::generate_and_project(std::shared_ptr<LossFunction> loss, std: #pragma omp critical { - index_base = _phi.size() + _n_sis_select * _mpi_comm->rank(); + index_base = _phi.size() + 2 * _n_sis_select * _mpi_comm->rank(); worst_score_ind = std::max_element(scores_sel.begin(), scores_sel.end()) - scores_sel.begin(); for(int sc = 0; sc < scores_sel_private.size(); ++sc) { - if( - ((phi_sel.size() < _n_sis_select) || (scores_sel_private[sc] < scores_sel[worst_score_ind])) && - _is_valid_feat_list(phi_sel_private[sc]->value_ptr(), _n_samp_train, _cross_cor_max, phi_sel, scores_sel, scores_sel_private[sc]) - ) + node_value_arrs::clear_temp_reg_thread(); + if(scores_sel_private[sc] > scores_sel[worst_score_ind]) { - if(phi_sel.size() == _n_sis_select) + continue; + } + int valid_feat = _is_valid_feat_list( + phi_sel_private[sc]->stand_value_ptr(), + _n_samp_train, + _cross_cor_max, + phi_sel, + scores_sel, + scores_sel_private[sc] + ); + if((valid_feat > 0) && (num_valid_feats >= _n_sis_select)) + { + scores_sel[worst_score_ind] = scores_sel_private[sc]; + phi_sel[worst_score_ind] = phi_sel_private[sc]; + if(phi_sel[worst_score_ind]->rung() == _max_rung) { - scores_sel[worst_score_ind] = scores_sel_private[sc]; - phi_sel[worst_score_ind] = phi_sel_private[sc]; - if(phi_sel[worst_score_ind]->rung() == _max_rung) - { - phi_sel[worst_score_ind]->reindex(index_base + worst_score_ind); - } + phi_sel[worst_score_ind]->reindex(index_base + worst_score_ind); } - else + worst_score_ind = std::max_element(scores_sel.begin(), scores_sel.end()) - scores_sel.begin(); + } + else if(valid_feat != 0) + { + num_valid_feats += (valid_feat > 0); + scores_sel.push_back(scores_sel_private[sc]); + phi_sel.push_back(phi_sel_private[sc]); + if(phi_sel.back()->rung() == _max_rung) { - scores_sel.push_back(scores_sel_private[sc]); - phi_sel.push_back(phi_sel_private[sc]); - if(phi_sel.back()->rung() == _max_rung) - { - phi_sel.back()->reindex(index_base + phi_sel.size()); - } + phi_sel.back()->reindex(index_base + phi_sel.size()); } worst_score_ind = std::max_element(scores_sel.begin(), scores_sel.end()) - scores_sel.begin(); } } } } + + // Go through all features and remove any that were valid, but no longer are due to new better features appearing. If _cross_cor_max == 1.0 then this is not necessary + if(_cross_cor_max < 0.99999) + { + int index_base = _phi.size() + 2 * _n_sis_select + _mpi_comm->rank(); + std::vector<int> inds = util_funcs::argsort(scores_sel); + + std::vector<node_ptr> phi_sel_copy(phi_sel); + phi_sel.clear(); + + std::vector<double> scores_sel_copy(scores_sel); + scores_sel.clear(); + + phi_sel.push_back(phi_sel_copy[inds[0]]); + scores_sel.push_back(scores_sel_copy[inds[0]]); + + int ii = 1; + while((ii < inds.size()) && (phi_sel.size() < _n_sis_select)) + { + node_value_arrs::clear_temp_reg_thread(); + if( + _is_valid_feat_list( + phi_sel_copy[inds[ii]]->stand_value_ptr(), + _n_samp_train, + _cross_cor_max, + phi_sel, + scores_sel, + scores_sel_copy[inds[ii]] + ) > 0 + ) + { + scores_sel.push_back(scores_sel_copy[inds[ii]]); + phi_sel.push_back(phi_sel_copy[inds[ii]]); + if(phi_sel.back()->rung() == _max_rung) + { + phi_sel.back()->reindex(index_base + phi_sel.size()); + } + } + ++ii; + } + } } void FeatureSpace::sis(const std::vector<double>& prop) @@ -1200,6 +1252,7 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) _scores.resize(_phi.size()); } #endif + // Create output directories if needed boost::filesystem::path p(_feature_space_file.c_str()); boost::filesystem::create_directories(p.remove_filename()); @@ -1252,7 +1305,17 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) start_time = omp_get_wtime(); while((cur_feat_local != _n_sis_select) && (ii < _scores.size())) { - if(_is_valid(_phi[inds[ii]]->value_ptr(), _n_samp_train, _cross_cor_max, scores_sel_all, _scores[inds[ii]], cur_feat + cur_feat_local, 0)) + if( + _is_valid( + _phi[inds[ii]]->stand_value_ptr(), + _n_samp_train, + _cross_cor_max, + scores_sel_all, + _scores[inds[ii]], + cur_feat + cur_feat_local, + 0 + ) + ) { scores_sel[cur_feat_local] = _scores[inds[ii]]; scores_sel_all[cur_feat + cur_feat_local] = _scores[inds[ii]]; @@ -1260,7 +1323,7 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) phi_sel.back()->set_selected(true); phi_sel.back()->set_d_mat_ind(cur_feat + cur_feat_local); phi_sel.back()->set_value(); - + phi_sel.back()->set_standardized_value(); ++cur_feat_local; } ++ii; @@ -1308,11 +1371,15 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) if(_mpi_comm->size() > 1) { // Collect the best features from all ranks - std::vector<node_sc_pair> local_sel(_n_sis_select, std::make_tuple<node_ptr, double>(nullptr, std::numeric_limits<double>::max())); - for(int ff = 0; ff < phi_sel.size(); ++ff) - { - local_sel[ff] = mpi_reduce_op::make_node_sc_pair(phi_sel[ff], scores_sel[ff]); - } + std::vector<node_sc_pair> local_sel(_n_sis_select); + std::transform( + phi_sel.begin(), + phi_sel.end(), + scores_sel.begin(), + local_sel.begin(), + [](node_ptr feat, double sc){return node_sc_pair(feat, sc);} + ); + std::vector<node_sc_pair> selected(_n_sis_select); mpi::all_reduce( *_mpi_comm, @@ -1326,10 +1393,11 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) cur_feat_local = 0; for(auto& sel : selected) { - _phi_selected.push_back(std::get<0>(sel)); + _phi_selected.push_back(sel._feat); _phi_selected.back()->set_selected(true); _phi_selected.back()->set_d_mat_ind(cur_feat); _phi_selected.back()->set_value(); + _phi_selected.back()->set_standardized_value(); ++cur_feat_local; ++cur_feat; } @@ -1342,7 +1410,7 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) for(auto& sel : selected) { out_file_stream << std::setw(14) <<std::left << cur_feat << _phi_selected[cur_feat]->postfix_expr() << std::endl; - sum_file_stream << std::setw(14) <<std::left << cur_feat << std::setw(24) << std::setprecision(18) << std::left << prefact * std::get<1>(sel); + sum_file_stream << std::setw(14) <<std::left << cur_feat << std::setw(24) << std::setprecision(18) << std::left << prefact * sel._score; sum_file_stream << _phi_selected[cur_feat]->expr() << std::endl; ++cur_feat; @@ -1380,6 +1448,7 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) double prefact = std::pow(-1, (_project_type != "classification")); for(auto& ind : inds) { + node_value_arrs::clear_temp_reg(); out_file_stream << std::setw(14) <<std::left << cur_feat << phi_sel[ind]->postfix_expr() << std::endl; sum_file_stream << std::setw(14) <<std::left << cur_feat << std::setw(24) << std::setprecision(18) << std::left << prefact * scores_sel[ind]; @@ -1389,6 +1458,7 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) _phi_selected.back()->set_selected(true); _phi_selected.back()->set_d_mat_ind(cur_feat); _phi_selected.back()->set_value(); + _phi_selected.back()->set_standardized_value(); ++cur_feat; ++cur_feat_local; @@ -1397,7 +1467,13 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) if(cur_feat != node_value_arrs::N_SELECTED) { - throw std::logic_error("SIS went through all features and did not select enough."); + throw std::logic_error( + "SIS went through all features and did not select enough (" + + std::to_string(cur_feat) + + " not " + + std::to_string(_n_sis_select) + + ")." + ); } if(_mpi_comm->rank() == 0) diff --git a/src/feature_creation/feature_space/FeatureSpace.hpp b/src/feature_creation/feature_space/FeatureSpace.hpp index 8000451e789187ef41f62b66e3449a10c0ed5aa3..0b2f7e305374c904e711ce091a1174ffa3bcedbb 100644 --- a/src/feature_creation/feature_space/FeatureSpace.hpp +++ b/src/feature_creation/feature_space/FeatureSpace.hpp @@ -79,7 +79,7 @@ class FeatureSpace const std::string _phi_out_file; //!< Filename of the file to output the feature set to std::function<bool(const double*, const int, const double, const std::vector<double>&, const double, const int, const int)> _is_valid; //!< Function used to determine of a feature is too correlated to previously selected features - std::function<bool(const double*, const int, const double, const std::vector<node_ptr>&, const std::vector<double>&, const double)> _is_valid_feat_list; //!< Function used to determine of a feature is too correlated to previously selected features within a given list + std::function<int(const double*, const int, const double, const std::vector<node_ptr>&, const std::vector<double>&, const double)> _is_valid_feat_list; //!< Function used to determine of a feature is too correlated to previously selected features within a given list std::shared_ptr<MPI_Interface> _mpi_comm; //!< the MPI communicator for the calculation @@ -146,6 +146,24 @@ public: */ void initialize_fs_output_files() const; + /** + * @brief Remove duplicate features from the feature space + * + * @param feat_set Feature space to remove the duplicates from + * @param start The index to start the removal from + */ + void remove_duplicate_features(std::vector<node_ptr>& feat_set, int start); + + #ifdef PARAMETERIZE + /** + * @brief Reorder features based on the number of parameters they have (smallest to largest) + * + * @param feat_set Feature space to remove the duplicates from + * @param start The index to start the removal from + */ + int reorder_by_n_params(std::vector<node_ptr>& feat_set, int start); + #endif + /** * @brief Populate _phi using _phi_0 and the allowed operators up to (_max_rung - _n_rung_generate)^th rung */ diff --git a/src/feature_creation/node/Node.cpp b/src/feature_creation/node/Node.cpp index 92c85b669238b946de9ed8ad172cb2e93fb66da1..8b4f4905d5f58b33975204ad17c799fff1f5a9b7 100644 --- a/src/feature_creation/node/Node.cpp +++ b/src/feature_creation/node/Node.cpp @@ -48,3 +48,49 @@ std::map<std::string, int> Node::primary_feature_decomp() const } BOOST_SERIALIZATION_ASSUME_ABSTRACT(Node) +void Node::set_standardized_value(const bool for_comp) const +{ + double* stand_val_ptr; + if(_selected) + { + stand_val_ptr = node_value_arrs::get_stand_d_matrix_ptr(_d_mat_ind); + } + else + { + stand_val_ptr = node_value_arrs::access_temp_stand_storage(_arr_ind, for_comp); + } + + util_funcs::standardize(value_ptr(-1, for_comp), _n_samp, stand_val_ptr); +} + +void Node::set_standardized_test_value(const bool for_comp) const +{ + double* val_ptr = value_ptr(-1, for_comp); + double* test_val_ptr = test_value_ptr(-1, for_comp); + double* stand_val_ptr = node_value_arrs::access_temp_stand_storage_test(_arr_ind, for_comp); + + double mean = util_funcs::mean(val_ptr, _n_samp); + double stand_dev = util_funcs::stand_dev(val_ptr, _n_samp, mean); + std::transform( + test_val_ptr, + test_val_ptr + _n_samp_test, + stand_val_ptr, + [&](double val){return (val - mean) / stand_dev;} + ); +} + +double* Node::stand_value_ptr(const bool for_comp) const +{ + if(_selected) + { + return node_value_arrs::get_stand_d_matrix_ptr(_d_mat_ind); + } + set_standardized_value(for_comp); + return node_value_arrs::access_temp_stand_storage(_arr_ind, for_comp); +} + +double* Node::stand_test_value_ptr(const bool for_comp) const +{ + set_standardized_test_value(for_comp); + return node_value_arrs::access_temp_stand_storage_test(_arr_ind, for_comp); +} diff --git a/src/feature_creation/node/Node.hpp b/src/feature_creation/node/Node.hpp index 6b752818b9d02c00c1c4a4372f00b3e1a4cabbc4..83aafbf725709a80d493b7cd09ba8684b9fd895d 100644 --- a/src/feature_creation/node/Node.hpp +++ b/src/feature_creation/node/Node.hpp @@ -279,6 +279,15 @@ public: */ virtual void set_value(int offset=-1, const bool for_comp=false) const = 0; + // DocString: node_set_stand_value + /** + * @brief Set the value of all training samples to the standardized values for the feature inside the central data storage arrays + * + * @param offset (int) Where the current node is in the binary expression tree relative to other nodes at the same depth + * @param for_comp (bool) If true then the evaluation is used for comparing features + */ + void set_standardized_value(const bool for_comp=false) const; + /** * @brief The pointer to where the feature's training data is stored * @@ -289,6 +298,16 @@ public: */ virtual double* value_ptr(int offset=-1, const bool for_comp=false) const = 0; + /** + * @brief The pointer to where the feature's standardized training data is stored + * + * @param offset (int) Where the current node is in the binary expression tree relative to other nodes at the same depth + * @param for_comp (bool) If true then the evaluation is used for comparing features + * + * @return pointer to the feature's training value + */ + double* stand_value_ptr(const bool for_comp=false) const; + // DocString: node_set_test_value /** * @brief Set the value of all test samples for the feature inside the central data storage array @@ -298,6 +317,15 @@ public: */ virtual void set_test_value(int offset=-1, const bool for_comp=false) const = 0; + // DocString: node_set_stand_test_value + /** + * @brief Set the value of all test samples to the standardized values for the feature inside the central data storage array + * + * @param offset (int) Where the current node is in the binary expression tree relative to other nodes at the same depth + * @param for_comp (bool) If true then the evaluation is used for comparing features + */ + void set_standardized_test_value(const bool for_comp=false) const; + /** * @brief The pointer to where the feature's test data is stored * @@ -308,6 +336,16 @@ public: */ virtual double* test_value_ptr(int offset=-1, const bool for_comp=false) const = 0; + /** + * @brief The pointer to where the feature's standardized test data is stored + * + * @param offset (int) Where the current node is in the binary expression tree relative to other nodes at the same depth + * @param for_comp (bool) If true then the evaluation is used for comparing features + * + * @return pointer to the feature's test values + */ + double* stand_test_value_ptr(const bool for_comp=false) const; + // DocString: node_is_nan /** * @brief Check if the feature has a NaN value in it diff --git a/src/feature_creation/node/value_storage/nodes_value_containers.cpp b/src/feature_creation/node/value_storage/nodes_value_containers.cpp index 55f5d705f9eb11398c655b40cdaccde5425b0eba..bb4bafa520ceb6f5814e0791a9712d0fbb0253f5 100644 --- a/src/feature_creation/node/value_storage/nodes_value_containers.cpp +++ b/src/feature_creation/node/value_storage/nodes_value_containers.cpp @@ -47,6 +47,10 @@ std::vector<double> node_value_arrs::TEST_VALUES_ARR; std::vector<double> node_value_arrs::TEMP_STORAGE_ARR; std::vector<double> node_value_arrs::TEMP_STORAGE_TEST_ARR; +std::vector<double> node_value_arrs::STANDARDIZED_D_MATRIX; +std::vector<double> node_value_arrs::STANDARDIZED_STORAGE_ARR; +std::vector<double> node_value_arrs::STANDARDIZED_TEST_STORAGE_ARR; + void node_value_arrs::initialize_values_arr( const int n_samples, const int n_samples_test, @@ -61,6 +65,8 @@ void node_value_arrs::initialize_values_arr( VALUES_ARR = std::vector<double>(N_STORE_FEATURES * N_SAMPLES); TEST_VALUES_ARR = std::vector<double>(N_STORE_FEATURES * N_SAMPLES_TEST); + STANDARDIZED_STORAGE_ARR = std::vector<double>(2 * (N_PRIMARY_FEATURES + 1) * N_SAMPLES * MAX_N_THREADS); + STANDARDIZED_TEST_STORAGE_ARR = std::vector<double>(2 * (N_PRIMARY_FEATURES + 1) * N_SAMPLES_TEST * MAX_N_THREADS); } void node_value_arrs::initialize_values_arr( @@ -174,6 +180,9 @@ void node_value_arrs::resize_values_arr(const int n_dims, const int n_feat) { N_PRIMARY_FEATURES = N_STORE_FEATURES; + STANDARDIZED_STORAGE_ARR = std::vector<double>(2 * (N_PRIMARY_FEATURES + 1) * N_SAMPLES * MAX_N_THREADS); + STANDARDIZED_TEST_STORAGE_ARR = std::vector<double>(2 * (N_PRIMARY_FEATURES + 1) * N_SAMPLES_TEST * MAX_N_THREADS); + TEMP_STORAGE_ARR.resize(MAX_N_THREADS * (N_OP_SLOTS * N_PRIMARY_FEATURES + 1) * N_SAMPLES); TEMP_STORAGE_ARR.shrink_to_fit(); @@ -236,6 +245,7 @@ void node_value_arrs::initialize_d_matrix_arr() { N_SELECTED = 0; D_MATRIX = std::vector<double>(0); + STANDARDIZED_D_MATRIX = std::vector<double>(0); } void node_value_arrs::resize_d_matrix_arr(const int n_select) @@ -243,6 +253,9 @@ void node_value_arrs::resize_d_matrix_arr(const int n_select) N_SELECTED += n_select; D_MATRIX.resize(N_SELECTED * N_SAMPLES, 0.0); D_MATRIX.shrink_to_fit(); + + STANDARDIZED_D_MATRIX.resize(N_SELECTED * N_SAMPLES, 0.0); + STANDARDIZED_D_MATRIX.shrink_to_fit(); } void node_value_arrs::finalize_values_arr() @@ -265,11 +278,18 @@ void node_value_arrs::finalize_values_arr() TASK_START_TRAIN.resize(0); TASK_SZ_TEST.resize(0); - PARAM_STORAGE_ARR.resize(0); - PARAM_STORAGE_TEST_ARR.resize(0); D_MATRIX.resize(0); + VALUES_ARR.resize(0); TEST_VALUES_ARR.resize(0); + TEMP_STORAGE_ARR.resize(0); TEMP_STORAGE_TEST_ARR.resize(0); + + PARAM_STORAGE_ARR.resize(0); + PARAM_STORAGE_TEST_ARR.resize(0); + + STANDARDIZED_D_MATRIX.resize(0); + STANDARDIZED_STORAGE_ARR.resize(0); + STANDARDIZED_TEST_STORAGE_ARR.resize(0); } diff --git a/src/feature_creation/node/value_storage/nodes_value_containers.hpp b/src/feature_creation/node/value_storage/nodes_value_containers.hpp index 0b793bfe4d2668c5d7f8581956ff2b784423de21..ac9188697f0ddd716807172c97b93e4bb3216aa4 100644 --- a/src/feature_creation/node/value_storage/nodes_value_containers.hpp +++ b/src/feature_creation/node/value_storage/nodes_value_containers.hpp @@ -58,6 +58,10 @@ namespace node_value_arrs extern std::vector<int> TASK_START_TRAIN; //!< The starting point for each task in the training data extern std::vector<int> TASK_SZ_TEST; //!< Number of test sample per task + extern std::vector<double> STANDARDIZED_D_MATRIX; //!< The descriptor matrix filled with standardized feature values (Central storage for the selected feature space) + extern std::vector<double> STANDARDIZED_STORAGE_ARR; //!< //!< The vector used to temporarily store the values of the standardized feature training values + extern std::vector<double> STANDARDIZED_TEST_STORAGE_ARR; //!< //!< The vector used to temporarily store the values of the standardized feature test values + extern int N_SELECTED; //!< Number of selected features extern int N_SAMPLES; //!< Number of training samples for each feature (Sum of all elements in TASK_SZ_TRAIN) @@ -290,6 +294,38 @@ namespace node_value_arrs */ inline double* access_temp_storage_test(const unsigned long int slot){return &TEMP_STORAGE_TEST_ARR[slot*N_SAMPLES_TEST];} + /** + * @brief Access element of temporary standardized storage array for the training data + * + * @param arr_ind The array index of the feature + * @param for_comp True if used for a comparison + * + * @return pointer to the data stored in the specified slot + */ + inline double* access_temp_stand_storage(const unsigned long int arr_ind, const bool for_comp) + { + return &STANDARDIZED_STORAGE_ARR[ + ((arr_ind % N_PRIMARY_FEATURES) + for_comp * N_PRIMARY_FEATURES) * N_SAMPLES + + omp_get_thread_num() * 2 * (N_PRIMARY_FEATURES + 1) * N_SAMPLES + ]; + } + + /** + * @brief Access element of temporary standardized storage array for the test data + * + * @param arr_ind The array index of the feature + * @param for_comp True if used for a comparison + * + * @return pointer to the data stored in the specified slot + */ + inline double* access_temp_stand_storage_test(const unsigned long int arr_ind, const bool for_comp) + { + return &STANDARDIZED_TEST_STORAGE_ARR[ + ((arr_ind % N_PRIMARY_FEATURES) + for_comp * N_PRIMARY_FEATURES) * N_SAMPLES_TEST + + omp_get_thread_num() * 2 * (N_PRIMARY_FEATURES + 1) * N_SAMPLES_TEST + ]; + } + /** * @brief Access the param storage array * @@ -367,7 +403,7 @@ namespace node_value_arrs ); /** - * @brief Get the pointer to a particular selected Node from sis + * @brief Get the pointer to a particular selected Node's data from sis * * @param ind Index of the data in the descriptor matrix * @return The pointer to the descriptor matrix's data @@ -375,7 +411,7 @@ namespace node_value_arrs inline double* get_d_matrix_ptr(const int ind){return &D_MATRIX[ind * N_SAMPLES];} /** - * @brief Get the pointer to a particular selected Node from sis + * @brief Get the pointer to a particular selected Node's data from sis * * @param ind Index of the data in the descriptor matrix * @param taskind The index for the given task @@ -383,6 +419,23 @@ namespace node_value_arrs */ inline double* get_d_matrix_ptr(const int ind, const int taskind){return &D_MATRIX[ind * N_SAMPLES + TASK_START_TRAIN[taskind]];} + /** + * @brief Get the pointer to a particular selected Node's standardized from sis + * + * @param ind Index of the data in the descriptor matrix + * @return The pointer to the descriptor matrix's standardized data + */ + inline double* get_stand_d_matrix_ptr(const int ind){return &STANDARDIZED_D_MATRIX[ind * N_SAMPLES];} + + /** + * @brief Get the pointer to a particular selected Node's standardized from sis + * + * @param ind Index of the data in the descriptor matrix + * @param taskind The index for the given task + * @return The pointer to the descriptor matrix's standardized data + */ + inline double* get_stand_d_matrix_ptr(const int ind, const int taskind){return &STANDARDIZED_D_MATRIX[ind * N_SAMPLES + TASK_START_TRAIN[taskind]];} + /** * @brief Flush the temporary storage register (training data) * @details Reset all slots in the register to -1 diff --git a/src/mpi_interface/MPI_Ops.cpp b/src/mpi_interface/MPI_Ops.cpp index f2b71fed1c239de944218a534ad5633cf4eba24f..93dc1f9d4ecec371443981518158fa68e6f586b0 100644 --- a/src/mpi_interface/MPI_Ops.cpp +++ b/src/mpi_interface/MPI_Ops.cpp @@ -65,20 +65,20 @@ std::vector<node_sc_pair> mpi_reduce_op::select_top_feats(std::vector<node_sc_pa // Merge input vectors and sort in_vec_2.insert(in_vec_2.end(), in_vec_1.begin(), in_vec_1.end()); - std::sort(in_vec_2.begin(), in_vec_2.end(), my_sorter); + std::sort(in_vec_2.begin(), in_vec_2.end()); // Populate the output vector int ff = 0; int out_ind = 0; while((out_ind < N_SIS_SELECT) && (ff < in_vec_2.size())) { - const node_ptr cur_node = std::get<0>(in_vec_2[ff]); - if(cur_node && IS_VALID(cur_node->value_ptr(), cur_node->n_samp(), CROSS_COR_MAX, out_vec, std::get<1>(in_vec_2[ff]))) + if(in_vec_2[ff]._feat && IS_VALID(in_vec_2[ff]._feat->stand_value_ptr(), in_vec_2[ff]._feat->n_samp(), CROSS_COR_MAX, out_vec, in_vec_2[ff]._score)) { out_vec.push_back(in_vec_2[ff]); ++out_ind; } ++ff; } + return out_vec; } diff --git a/src/mpi_interface/MPI_Ops.hpp b/src/mpi_interface/MPI_Ops.hpp index cfa62b5ba648f3f60a4609dd9069cd5c1d9b93ca..37d4758c2a2cfc38fb8f681dcad686c8c273b27e 100644 --- a/src/mpi_interface/MPI_Ops.hpp +++ b/src/mpi_interface/MPI_Ops.hpp @@ -35,26 +35,6 @@ namespace mpi_reduce_op extern double CROSS_COR_MAX; //!< The maximum cross correlation between features extern int N_SIS_SELECT; //!< The number of features to select - /** - * @brief Create a node_sc pair from a node_ptr and a score value - * - * @param feat the node_ptr for the pair - * @param sc the score for the pair - * - * @return The resulting pair - */ - inline node_sc_pair make_node_sc_pair(node_ptr feat, double sc){return std::make_tuple(feat, sc);} - - /** - * @brief The function for sorting different node_sc pointers - * - * @param node_1 first node to compare - * @param node_2 second node to compare - * - * @return True if the score of node_1 is less then the score of node_2 - */ - inline bool my_sorter(node_sc_pair node_1, node_sc_pair node_2){ return (std::get<1>(node_1) < std::get<1>(node_2)); } - /** * @brief Get the top features of the combined input vectors * diff --git a/src/utils/compare_features.cpp b/src/utils/compare_features.cpp index fa5d96602c77448e5f126a48e72a412de6e58015..dd6fc36d419bbff14ed530c50ac9d991ecb15905 100644 --- a/src/utils/compare_features.cpp +++ b/src/utils/compare_features.cpp @@ -21,6 +21,7 @@ #include "utils/compare_features.hpp" #include <iomanip> +std::vector<double> comp_feats::DGEMV_OUT; std::vector<double> comp_feats::RANK; std::vector<int> comp_feats::INDEX; @@ -29,13 +30,14 @@ void comp_feats::set_is_valid_fxn( const double max_corr, const int n_samp, std::function<bool(const double*, const int, const double, const std::vector<double>&, const double, const int, const int)>& is_valid, - std::function<bool(const double*, const int, const double, const std::vector<node_ptr>&, const std::vector<double>&, const double)>& is_valid_feat_list + std::function<int(const double*, const int, const double, const std::vector<node_ptr>&, const std::vector<double>&, const double)>& is_valid_feat_list ) { if(project_type.compare("classification") != 0) { if(max_corr < 0.99999) { + DGEMV_OUT.resize(n_samp); is_valid = valid_feature_against_selected_pearson; is_valid_feat_list = valid_feature_against_selected_pearson_feat_list; } @@ -79,9 +81,7 @@ bool comp_feats::valid_feature_against_selected_pearson_max_corr_1( const int start_sel ) { - double mean = util_funcs::mean<double>(val_ptr, n_samp); - double stand_dev = util_funcs::stand_dev(val_ptr, n_samp, mean); - double base_val = util_funcs::r(val_ptr, val_ptr, n_samp, mean, stand_dev, mean, stand_dev); + double base_val = std::inner_product(val_ptr, val_ptr + n_samp, val_ptr, 0.0); for(int dd = start_sel; dd < end_sel; ++dd) { @@ -90,9 +90,18 @@ bool comp_feats::valid_feature_against_selected_pearson_max_corr_1( continue; } - double comp_value = ( - base_val - std::abs(util_funcs::r(val_ptr, node_value_arrs::get_d_matrix_ptr(dd), n_samp, mean, stand_dev)) + double comp_value = 1.0 / static_cast<double>(n_samp) * ( + base_val - + std::abs( + std::inner_product( + val_ptr, + val_ptr + n_samp, + node_value_arrs::get_stand_d_matrix_ptr(dd), + 0.0 + ) + ) ); + if(std::abs(comp_value) < 5.0e-9) { return false; @@ -101,7 +110,7 @@ bool comp_feats::valid_feature_against_selected_pearson_max_corr_1( return true; } -bool comp_feats::valid_feature_against_selected_pearson_max_corr_1_feat_list( +int comp_feats::valid_feature_against_selected_pearson_max_corr_1_feat_list( const double* val_ptr, const int n_samp, const double cross_cor_max, @@ -110,9 +119,7 @@ bool comp_feats::valid_feature_against_selected_pearson_max_corr_1_feat_list( const double cur_score ) { - double mean = util_funcs::mean<double>(val_ptr, n_samp); - double stand_dev = util_funcs::stand_dev(val_ptr, n_samp, mean); - double base_val = util_funcs::r(val_ptr, val_ptr, n_samp, mean, stand_dev, mean, stand_dev); + double base_val = std::inner_product(val_ptr, val_ptr + n_samp, val_ptr, 0.0); for(int ff = 0; ff < selected.size(); ++ff) { @@ -121,15 +128,24 @@ bool comp_feats::valid_feature_against_selected_pearson_max_corr_1_feat_list( continue; } - double comp_value = ( - base_val - std::abs(util_funcs::r(val_ptr, selected[ff]->value_ptr(-1, true), n_samp, mean, stand_dev)) + double comp_value = 1.0 / static_cast<double>(n_samp) * ( + base_val - + std::abs( + std::inner_product( + val_ptr, + val_ptr + n_samp, + selected[ff]->stand_value_ptr(true), + 0.0 + ) + ) ); + if(std::abs(comp_value) < 5.0e-9) { - return false; + return 0; } } - return true; + return 1; } bool comp_feats::valid_feature_against_selected_pearson_max_corr_1_mpi_op( @@ -140,20 +156,27 @@ bool comp_feats::valid_feature_against_selected_pearson_max_corr_1_mpi_op( const double cur_score ) { - double mean = util_funcs::mean<double>(val_ptr, n_samp); - double stand_dev = util_funcs::stand_dev(val_ptr, n_samp, mean); - double base_val = util_funcs::r(val_ptr, val_ptr, n_samp, mean, stand_dev, mean, stand_dev); + double base_val = std::inner_product(val_ptr, val_ptr + n_samp, val_ptr, 0.0); for(auto& feat_sc : out_vec) { - if(abs(cur_score - std::get<1>(feat_sc)) > 1e-5) + if(abs(cur_score - feat_sc._score) > 1e-5) { continue; } - double comp_value = ( - base_val - std::abs(util_funcs::r(val_ptr, std::get<0>(feat_sc)->value_ptr(-1, true), n_samp, mean, stand_dev)) + double comp_value = 1.0 / static_cast<double>(n_samp) * ( + base_val - + std::abs( + std::inner_product( + val_ptr, + val_ptr + n_samp, + feat_sc._feat->stand_value_ptr(true), + 0.0 + ) + ) ); + if(std::abs(comp_value) < 5.0e-9) { return false; @@ -173,32 +196,30 @@ bool comp_feats::valid_feature_against_selected_pearson( const int start_sel ) { - double mean = util_funcs::mean<double>(val_ptr, n_samp); - double stand_dev = util_funcs::stand_dev(val_ptr, n_samp, mean); - double base_val = util_funcs::r(val_ptr, val_ptr, n_samp, mean, stand_dev, mean, stand_dev); - - volatile bool is_valid = true; - - #pragma omp parallel for schedule(dynamic) - for(int dd = start_sel; dd < end_sel; ++dd) + if(end_sel <= start_sel) { - if(!is_valid) - { - continue; - } - - double comp_value = ( - base_val - std::abs(util_funcs::r(val_ptr, node_value_arrs::get_d_matrix_ptr(dd), n_samp, mean, stand_dev)) - ); - if(std::abs(comp_value) < (1.0 - cross_cor_max + 5.0e-9)) - { - is_valid = false; - } + return true; } - return is_valid; + + DGEMV_OUT.resize(end_sel - start_sel); + dgemv_( + 'N', + DGEMV_OUT.size(), + n_samp, + 1.0 / static_cast<double>(n_samp), + node_value_arrs::get_stand_d_matrix_ptr(start_sel), + DGEMV_OUT.size(), + val_ptr, + 1, + 0.0, + DGEMV_OUT.data(), + 1 + ); + + return std::abs(DGEMV_OUT[idamax_(DGEMV_OUT.size(), DGEMV_OUT.data(), 1) - 1]) <= cross_cor_max; } -bool comp_feats::valid_feature_against_selected_pearson_feat_list( +int comp_feats::valid_feature_against_selected_pearson_feat_list( const double* val_ptr, const int n_samp, const double cross_cor_max, @@ -207,21 +228,21 @@ bool comp_feats::valid_feature_against_selected_pearson_feat_list( const double cur_score ) { - double mean = util_funcs::mean<double>(val_ptr, n_samp); - double stand_dev = util_funcs::stand_dev(val_ptr, n_samp, mean); - double base_val = util_funcs::r(val_ptr, val_ptr, n_samp, mean, stand_dev, mean, stand_dev); - - for(auto& feat : selected) + int is_valid = 1; + double comp_value = 1.0; + for(int ff = 0; ff < selected.size(); ++ff) { - double comp_value = ( - base_val - std::abs(util_funcs::r(val_ptr, feat->value_ptr(-1, true), n_samp, mean, stand_dev)) + comp_value = 1.0 / static_cast<double>(n_samp) * std::abs( + std::inner_product(val_ptr, val_ptr + n_samp, selected[ff]->stand_value_ptr(true), 0.0) ); - if(std::abs(comp_value) < (1.0 - cross_cor_max + 5.0e-9)) + + if((comp_value > cross_cor_max) && (cur_score > scores_sel[ff])) { - return false; + return 0; } + is_valid -= 2 * (comp_value > cross_cor_max); } - return true; + return is_valid / std::abs(is_valid); } bool comp_feats::valid_feature_against_selected_pearson_mpi_op( @@ -232,16 +253,13 @@ bool comp_feats::valid_feature_against_selected_pearson_mpi_op( const double cur_score ) { - double mean = util_funcs::mean<double>(val_ptr, n_samp); - double stand_dev = util_funcs::stand_dev(val_ptr, n_samp, mean); - double base_val = util_funcs::r(val_ptr, val_ptr, n_samp, mean, stand_dev, mean, stand_dev); - for(auto& feat_sc : out_vec) { - double comp_value = ( - base_val - std::abs(util_funcs::r(val_ptr, std::get<0>(feat_sc)->value_ptr(-1, true), n_samp, mean, stand_dev)) + double comp_value = 1.0 / static_cast<double>(n_samp) * std::abs( + std::inner_product(val_ptr, val_ptr + n_samp, feat_sc._feat->stand_value_ptr(true), 0.0) ); - if(std::abs(comp_value) < (1.0 - cross_cor_max + 5.0e-9)) + + if(comp_value > cross_cor_max) { return false; } @@ -291,7 +309,7 @@ bool comp_feats::valid_feature_against_selected_spearman_max_corr_1( return true; } -bool comp_feats::valid_feature_against_selected_spearman_max_corr_1_feat_list( +int comp_feats::valid_feature_against_selected_spearman_max_corr_1_feat_list( const double* val_ptr, const int n_samp, const double cross_cor_max, @@ -325,10 +343,10 @@ bool comp_feats::valid_feature_against_selected_spearman_max_corr_1_feat_list( ); if(std::abs(comp_value) < 5.0e-9) { - return false; + return 0; } } - return true; + return 1; } bool comp_feats::valid_feature_against_selected_spearman_max_corr_1_mpi_op( @@ -352,13 +370,13 @@ bool comp_feats::valid_feature_against_selected_spearman_max_corr_1_mpi_op( for(auto& feat_sc : out_vec) { - if(abs(std::floor(cur_score) - std::floor(std::get<1>(feat_sc))) > 1e-5) + if(abs(std::floor(cur_score) - std::floor(feat_sc._score)) > 1e-5) { continue; } util_funcs::rank( - std::get<0>(feat_sc)->value_ptr(-1, true), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp + feat_sc._feat->value_ptr(-1, true), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp ); double comp_value = ( base_val - std::abs(util_funcs::r(&RANK[omp_get_thread_num() * 4 * n_samp], &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], n_samp)) @@ -381,39 +399,23 @@ bool comp_feats::valid_feature_against_selected_spearman( const int start_sel ) { - double base_val = std::abs( - util_funcs::spearman_r( - val_ptr, - val_ptr, - &RANK[omp_get_thread_num() * 4 * n_samp], - &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], - &INDEX[omp_get_thread_num() * 2 * n_samp], - n_samp - ) - ); - volatile bool is_valid = true; - + util_funcs::rank(val_ptr, &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp); + for(int dd = start_sel; dd < end_sel; ++dd) { - for(int dd = start_sel; dd < end_sel; ++dd) + // Rank the new variable and take the Pearson correlation of the rank variables (val_ptr rank still in &RANK[(omp_get_thread_num() * 4 + 2) * n_samp]) + util_funcs::rank(node_value_arrs::get_d_matrix_ptr(dd), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp); + double comp_value = std::abs( + util_funcs::r(&RANK[omp_get_thread_num() * 4 * n_samp], &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], n_samp) + ); + if(comp_value > cross_cor_max) { - if(!is_valid) - continue; - - // Rank the new variable and take the Pearson correlation of the rank variables (val_ptr rank still in &RANK[(omp_get_thread_num() * 4 + 2) * n_samp]) - util_funcs::rank(node_value_arrs::get_d_matrix_ptr(dd), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp); - double comp_value = ( - base_val - std::abs(util_funcs::r(&RANK[omp_get_thread_num() * 4 * n_samp], &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], n_samp)) - ); - if(std::abs(comp_value) < 1.0 -cross_cor_max + 5.0e-9) - { - is_valid = false; - } + return false; } } - return is_valid; + return true; } -bool comp_feats::valid_feature_against_selected_spearman_feat_list( +int comp_feats::valid_feature_against_selected_spearman_feat_list( const double* val_ptr, const int n_samp, const double cross_cor_max, @@ -422,30 +424,22 @@ bool comp_feats::valid_feature_against_selected_spearman_feat_list( const double cur_score ) { - double base_val = std::abs( - util_funcs::spearman_r( - val_ptr, - val_ptr, - &RANK[omp_get_thread_num() * 4 * n_samp], - &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], - &INDEX[omp_get_thread_num() * 2 * n_samp], - n_samp - ) - ); - - for(auto& feat : selected) + util_funcs::rank(val_ptr, &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp); + int is_valid = 1; + for(int ff = 0; ff < selected.size(); ++ff) { // Rank the new variable and take the Pearson correlation of the rank variables (val_ptr rank still in &RANK[(omp_get_thread_num() * 4 + 2) * n_samp]) - util_funcs::rank(feat->value_ptr(-1, true), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp); - double comp_value = ( - base_val - std::abs(util_funcs::r(&RANK[omp_get_thread_num() * 4 * n_samp], &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], n_samp)) + util_funcs::rank(selected[ff]->value_ptr(-1, true), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp); + double comp_value = std::abs( + util_funcs::r(&RANK[omp_get_thread_num() * 4 * n_samp], &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], n_samp) ); - if(std::abs(comp_value) < 1.0 - cross_cor_max + 5.0e-9) + if((comp_value > cross_cor_max) && (cur_score > scores_sel[ff])) { - return false; + return 0; } + is_valid -= 2 * (std::abs(comp_value) > cross_cor_max); } - return true; + return is_valid / std::abs(is_valid); } bool comp_feats::valid_feature_against_selected_spearman_mpi_op( @@ -456,26 +450,16 @@ bool comp_feats::valid_feature_against_selected_spearman_mpi_op( const double cur_score ) { - double base_val = std::abs( - util_funcs::spearman_r( - val_ptr, - val_ptr, - &RANK[omp_get_thread_num() * 4 * n_samp], - &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], - &INDEX[omp_get_thread_num() * 2 * n_samp], - n_samp - ) - ); - + util_funcs::rank(val_ptr, &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp); for(auto& feat_sc : out_vec) { util_funcs::rank( - std::get<0>(feat_sc)->value_ptr(-1, true), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp + feat_sc._feat->value_ptr(-1, true), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp ); - double comp_value = ( - base_val - std::abs(util_funcs::r(&RANK[omp_get_thread_num() * 4 * n_samp], &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], n_samp)) + double comp_value = std::abs( + util_funcs::r(&RANK[omp_get_thread_num() * 4 * n_samp], &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], n_samp) ); - if(std::abs(comp_value) < 1.0 - cross_cor_max + 5.0e-9) + if(comp_value > cross_cor_max) { return false; } diff --git a/src/utils/compare_features.hpp b/src/utils/compare_features.hpp index b0084cb22fafbc17cbbd58c2069b418541b483bf..16a059e3a56e1ab152c5901d20a818f30a4cc32a 100644 --- a/src/utils/compare_features.hpp +++ b/src/utils/compare_features.hpp @@ -26,10 +26,102 @@ #include "feature_creation/node/Node.hpp" -typedef std::tuple<node_ptr, double> node_sc_pair; +struct node_sc_pair +{ + /** + * @brief Serialization function to send over MPI + * + * @param ar Archive representation of node + */ + template <typename Archive> + void serialize(Archive& ar, const unsigned int version) + { + ar & _feat; + ar & _score; + } + node_ptr _feat; //!< The feature + double _score; //!< The score + + /** + * @brief Default Constructor + */ + node_sc_pair(): + _feat(nullptr), + _score(0.0) + {} + + /** + * @brief Constructor + * + * @param feat The feature + * @param score The score + */ + node_sc_pair(node_ptr feat, double score): + _feat(feat), + _score(score) + {} + + /** + * @brief Copy Constructor + * + * @param o Node to be copied + */ + node_sc_pair(const node_sc_pair& o) = default; + + /** + * @brief Move Constructor + * + * @param o Node to be copied + */ + node_sc_pair(node_sc_pair&& o) = default; + + /** + * @brief Copy Assignment operator + * + * @param o Node to be copied + */ + node_sc_pair& operator= (const node_sc_pair& o) = default; + + /** + * @brief Move Assignment operator + * + * @param o Node to be moved + */ + node_sc_pair& operator= (node_sc_pair&& o) = default; + + /** + * @brief Less than operator + * + * @param pair_2 node_sc_pair to compare against + * @return True if _score is less than pair_2.score + */ + inline bool operator<(node_sc_pair pair_2){return _score < pair_2._score;} + /** + * @brief Greater than operator + * + * @param pair_2 node_sc_pair to compare against + * @return True if _score is greater than pair_2.score + */ + inline bool operator>(node_sc_pair pair_2){return _score > pair_2._score;} + /** + * @brief Less than or equal to operator + * + * @param pair_2 node_sc_pair to compare against + * @return True if _score is less than or equal to pair_2.score + */ + inline bool operator<=(node_sc_pair pair_2){return _score <= pair_2._score;} + /** + * @brief Greater than or equal to operator + * + * @param pair_2 node_sc_pair to compare against + * @return True if _score is greater than or equal to pair_2.score + */ + inline bool operator>=(node_sc_pair pair_2){return _score >= pair_2._score;} +}; namespace comp_feats { + extern std::vector<double> DGEMV_OUT; //!< Function used to store the output of DGEMV extern std::vector<double> RANK; //!< Global variable used to store the rank variables for Spearman correlation extern std::vector<int> INDEX; //!< Global variable used to store the sorting indexes for Spearman correlation @@ -47,7 +139,7 @@ namespace comp_feats const double max_corr, const int n_samp, std::function<bool(const double*, const int, const double, const std::vector<double>&, const double, const int, const int)>& is_valid, - std::function<bool(const double*, const int, const double, const std::vector<node_ptr>&, const std::vector<double>&, const double)>& is_valid_feat_list + std::function<int(const double*, const int, const double, const std::vector<node_ptr>&, const std::vector<double>&, const double)>& is_valid_feat_list ); /** @@ -88,9 +180,9 @@ namespace comp_feats * @param scores_sel The projection scores for the selected feature * @param cur_score The score of the current candidate feature * - * @return True if the feature is still valid + * @return 1 if the feature is valid, 0 if the feature is invalid, -1 if the feature is invalid but has a higher score than the conflicting features */ - bool valid_feature_against_selected_pearson_max_corr_1_feat_list( + int valid_feature_against_selected_pearson_max_corr_1_feat_list( const double* val_ptr, const int n_samp, const double cross_cor_max, @@ -151,9 +243,9 @@ namespace comp_feats * @param scores_sel The projection scores for the selected feature * @param cur_score The score of the current candidate feature * - * @return True if the feature is still valid + * @return 1 if the feature is valid, -1 if the feature is invalid, 0 if the feature is invalid but has a higher score than the conflicting features */ - bool valid_feature_against_selected_pearson_feat_list( + int valid_feature_against_selected_pearson_feat_list( const double* val_ptr, const int n_samp, const double cross_cor_max, @@ -214,9 +306,9 @@ namespace comp_feats * @param scores_sel The projection scores for the selected feature * @param cur_score The score of the current candidate feature * - * @return True if the feature is still valid + * @return 1 if the feature is valid, -1 if the feature is invalid, 0 if the feature is invalid but has a higher score than the conflicting features */ - bool valid_feature_against_selected_spearman_max_corr_1_feat_list( + int valid_feature_against_selected_spearman_max_corr_1_feat_list( const double* val_ptr, const int n_samp, const double cross_cor_max, @@ -277,9 +369,9 @@ namespace comp_feats * @param scores_sel The projection scores for the selected feature * @param cur_score The score of the current candidate feature * - * @return True if the feature is still valid + * @return 1 if the feature is valid, -1 if the feature is invalid, 0 if the feature is invalid but has a higher score than the conflicting features */ - bool valid_feature_against_selected_spearman_feat_list( + int valid_feature_against_selected_spearman_feat_list( const double* val_ptr, const int n_samp, const double cross_cor_max, diff --git a/src/utils/math_funcs.cpp b/src/utils/math_funcs.cpp index 247a90ed2733ab611fde97a1ad8daa9212b0b2f4..8b53f0b9e5cc60352c59b4bafdd9ee347da3e939 100644 --- a/src/utils/math_funcs.cpp +++ b/src/utils/math_funcs.cpp @@ -41,6 +41,18 @@ bool util_funcs::iterate(std::vector<int>& inds, int size, int incriment) return cont; } +void util_funcs::standardize(const double* val, const int sz, double* stand_val) +{ + double avg = mean(val, sz); + double std = stand_dev(val, sz, avg); + std::transform( + val, + val + sz, + stand_val, + [&](double vv){return (vv - avg) / std;} + ); +} + double util_funcs::log_r2(const double* a, const double* b, double* log_a, const int size) { std::transform(a, a + size, log_a, [](double aa){return std::log(aa);}); diff --git a/src/utils/math_funcs.hpp b/src/utils/math_funcs.hpp index 58878ca0e0554a0a5121c7d76c00222e356fcc29..fa3e3ad378e7a3945ed5c4f974cba5c6ad994e04 100644 --- a/src/utils/math_funcs.hpp +++ b/src/utils/math_funcs.hpp @@ -143,6 +143,15 @@ namespace util_funcs return std::sqrt(std::accumulate(start, start+size, 0.0, [&vec_mean](double total, double val){return total + std::pow(val - vec_mean, 2.0);}) / size); }; + /** + * @brief Standardize a vector + * + * @param val pointer to the head of the vector to standardize + * @param sz size of the vector + * @param stand_val vector to the output vector + */ + void standardize(const double* val, int sz, double* stand_val); + /** * @brief Find the norm of a vector * diff --git a/tests/exec_test/classification_max_corr_gen_proj/sisso.json b/tests/exec_test/classification_max_corr_gen_proj/sisso.json index 7f978c23d974a3d8bf07c2710cac52494716e103..2ca3dab025898649d7569b0c686d9c97c6eee98c 100644 --- a/tests/exec_test/classification_max_corr_gen_proj/sisso.json +++ b/tests/exec_test/classification_max_corr_gen_proj/sisso.json @@ -5,7 +5,7 @@ "n_residual": 1, "data_file": "data.csv", "data_file_relatice_to_json": true, - "max_feat_cross_correlation": 0.99, + "max_feat_cross_correlation": 0.9, "property_key": "prop", "leave_out_frac": 0.2, "n_models_store": 1, diff --git a/tests/exec_test/default/feature_space/phi.txt b/tests/exec_test/default/feature_space/phi.txt deleted file mode 100644 index cca393a6211387286058db79cd189cf7171af6bb..0000000000000000000000000000000000000000 --- a/tests/exec_test/default/feature_space/phi.txt +++ /dev/null @@ -1,3468 +0,0 @@ -# Number of Features: 3466 -# Maximum Rung of the Calculation: 2 -0 -1 -2 -3 -3|sp -2|abs -2|sin -2|cos -2|1|mult -2|1|div -2|3|div -3|0|mult -3|0|div -3|exp -3|inv -3|sq -3|cb -2|cbrt -3|cbrt -3|abs -3|sin -3|cos -3|1|mult -3|1|div -3|2|add -3|2|sub -3|2|abd -3|2|mult -3|2|div -1|cb -0|sq -0|cb -0|sp -0|cbrt -0|abs -0|1|div -0|2|div -0|3|div -1|0|mult -1|0|div -1|inv -1|sq -0|inv -1|sp -1|sqrt -1|cbrt -1|2|div -1|3|div -2|0|mult -2|0|div -2|inv -2|sq -2|cb -2|sp -0|3|div|cb -0|2|div|0|abs|mult -0|2|div|0|abs|div -0|2|div|1|sq|div -0|2|div|1|sp|div -0|2|div|1|sqrt|div -0|2|div|1|cbrt|div -0|2|div|2|sq|div -0|2|div|2|cb|div -0|3|div|0|add -0|3|div|0|sub -0|3|div|0|abd -0|3|div|0|mult -0|3|div|sq -0|2|div|0|abs|abd -0|3|div|sp -0|3|div|cbrt -0|3|div|abs -0|3|div|1|mult -0|3|div|1|div -0|3|div|2|mult -0|3|div|2|div -0|3|div|3|div -0|3|div|2|abs|mult -0|3|div|2|abs|div -0|3|div|2|sin|mult -0|3|div|2|sin|div -0|2|div|3|2|sub|mult -0|2|div|2|cbrt|div -0|2|div|3|cbrt|mult -0|2|div|3|cbrt|div -0|2|div|3|abs|mult -0|2|div|3|abs|div -0|2|div|3|sin|mult -0|2|div|3|sin|div -0|2|div|3|cos|mult -0|2|div|3|cos|div -0|2|div|3|1|mult|mult -0|2|div|3|1|mult|div -0|2|div|3|2|add|mult -0|2|div|3|2|add|div -0|3|div|2|cos|mult -0|2|div|3|2|sub|div -0|2|div|3|2|abd|mult -0|2|div|3|2|abd|div -0|2|div|3|2|mult|div -0|2|div|1|cb|mult -0|2|div|1|cb|div -0|2|div|0|sq|mult -0|2|div|0|cb|mult -0|2|div|0|sp|mult -0|2|div|0|cbrt|mult -0|2|div|0|abs|add -0|2|div|0|abs|sub -0|3|div|1|sq|div -0|3|div|1|cb|div -0|3|div|0|sq|mult -0|3|div|0|cb|mult -0|3|div|0|sp|mult -0|3|div|0|cbrt|mult -0|3|div|0|abs|add -0|3|div|0|abs|sub -0|3|div|0|abs|abd -0|3|div|0|abs|mult -0|3|div|0|abs|div -0|3|div|0|2|div|add -0|3|div|0|2|div|sub -0|3|div|0|2|div|abd -0|3|div|1|cb|mult -0|3|div|1|sp|div -0|3|div|1|sqrt|div -0|3|div|1|cbrt|div -0|3|div|2|sq|div -0|3|div|2|cb|div -1|0|mult|0|mult -1|0|mult|inv -1|0|mult|sq -1|0|mult|cb -1|0|mult|sp -1|0|mult|cbrt -1|0|mult|abs -0|3|div|3|abs|div -0|3|div|2|cos|div -0|3|div|2|1|mult|mult -0|3|div|2|1|mult|div -0|3|div|3|0|mult|add -0|3|div|3|0|mult|sub -0|3|div|3|0|mult|abd -0|3|div|3|sq|div -0|3|div|3|cb|div -0|3|div|2|cbrt|mult -0|3|div|2|cbrt|div -0|3|div|3|cbrt|div -0|3|div|3|abs|mult -0|2|div|3|cb|div -0|3|div|3|sin|mult -0|3|div|3|sin|div -0|3|div|3|cos|mult -0|3|div|3|cos|div -0|3|div|3|1|mult|div -0|3|div|3|2|add|mult -0|3|div|3|2|add|div -0|3|div|3|2|sub|mult -0|3|div|3|2|sub|div -0|3|div|3|2|abd|mult -0|3|div|3|2|abd|div -0|3|div|3|2|mult|div -0|1|div|3|0|mult|mult -0|1|div|1|div -0|1|div|2|mult -0|1|div|2|div -0|1|div|3|mult -0|1|div|3|div -0|1|div|3|sp|mult -0|1|div|2|abs|mult -0|1|div|2|abs|div -0|1|div|2|sin|mult -0|1|div|2|sin|div -0|1|div|2|cos|mult -0|1|div|2|cos|div -0|1|div|2|1|mult|div -0|1|div|abs -0|1|div|3|sq|mult -0|1|div|3|sq|div -0|1|div|3|cb|mult -0|1|div|3|cb|div -0|1|div|2|cbrt|mult -0|1|div|2|cbrt|div -0|1|div|3|cbrt|mult -0|1|div|3|cbrt|div -0|1|div|3|abs|mult -0|1|div|3|abs|div -0|1|div|3|sin|mult -0|1|div|3|sin|div -0|abs|1|0|mult|div -0|abs|3|2|abd|div -0|abs|3|2|mult|mult -0|abs|3|2|mult|div -0|abs|3|2|div|mult -0|abs|1|cb|mult -0|abs|1|cb|div -0|abs|0|sq|mult -0|abs|0|sq|div -0|abs|0|cb|mult -0|abs|0|cb|div -0|abs|0|sp|mult -0|abs|0|cbrt|mult -0|abs|0|cbrt|div -0|1|div|3|cos|mult -0|abs|1|sq|div -0|abs|1|sp|div -0|abs|1|sqrt|div -0|abs|1|cbrt|div -0|abs|2|0|mult|div -0|abs|2|sq|div -0|abs|2|cb|div -0|1|div|0|mult -0|1|div|sq -0|1|div|cb -0|1|div|sp -0|1|div|cbrt -0|2|div|2|abs|div -0|2|div|0|mult -0|2|div|sq -0|2|div|cb -0|2|div|sp -0|2|div|cbrt -0|2|div|abs -0|2|div|1|mult -0|2|div|1|div -0|2|div|2|div -0|2|div|3|mult -0|2|div|3|div -0|2|div|3|sp|mult -0|2|div|2|abs|mult -0|2|div|0|abd -0|2|div|2|sin|mult -0|2|div|2|sin|div -0|2|div|2|cos|mult -0|2|div|2|cos|div -0|2|div|2|1|mult|div -0|2|div|3|0|mult|add -0|2|div|3|0|mult|sub -0|2|div|3|0|mult|abd -0|2|div|3|0|mult|mult -0|2|div|3|sq|mult -0|2|div|3|sq|div -0|2|div|3|cb|mult -0|1|div|0|cb|mult -0|1|div|3|cos|div -0|1|div|3|1|mult|div -0|1|div|3|2|add|mult -0|1|div|3|2|add|div -0|1|div|3|2|sub|mult -0|1|div|3|2|sub|div -0|1|div|3|2|abd|mult -0|1|div|3|2|abd|div -0|1|div|3|2|mult|mult -0|1|div|3|2|mult|div -0|1|div|1|cb|div -0|1|div|0|sq|mult -1|0|mult|1|mult -0|1|div|0|sp|mult -0|1|div|0|cbrt|mult -0|1|div|0|abs|mult -0|1|div|0|abs|div -0|1|div|1|sq|div -0|1|div|1|sp|div -0|1|div|1|sqrt|div -0|1|div|1|cbrt|div -0|1|div|2|sq|div -0|1|div|2|cb|div -0|2|div|0|add -0|2|div|0|sub -1|sq|3|2|mult|div -1|sq|3|abs|div -1|sq|3|sin|mult -1|sq|3|sin|div -1|sq|3|cos|mult -1|sq|3|cos|div -1|sq|3|1|mult|mult -1|sq|3|2|add|mult -1|sq|3|2|add|div -1|sq|3|2|sub|mult -1|sq|3|2|sub|div -1|sq|3|2|abd|mult -1|sq|3|2|abd|div -1|sq|3|2|mult|mult -1|sq|3|abs|mult -1|sq|3|2|div|mult -1|sq|0|sq|div -1|sq|0|cb|mult -1|sq|0|cb|div -1|sq|0|sp|mult -1|sq|0|cbrt|mult -1|sq|0|cbrt|div -1|sq|0|abs|mult -1|sq|0|abs|div -1|sq|0|2|div|mult -1|sq|0|3|div|mult -1|sq|1|0|mult|mult -1|sq|2|cos|mult -1|sq|0|mult -1|sq|0|div -1|sq|inv -1|sq|sq -1|sq|2|mult -1|sq|2|div -1|sq|3|mult -1|sq|3|div -1|sq|3|sp|mult -1|sq|2|abs|mult -1|sq|2|abs|div -1|sq|2|sin|mult -1|sq|2|sin|div -1|sq|1|0|div|mult -1|sq|2|cos|div -1|sq|2|1|mult|mult -1|sq|2|3|div|mult -1|sq|3|0|mult|mult -1|sq|3|0|mult|div -1|sq|3|0|div|mult -1|sq|3|cb|mult -1|sq|3|cb|div -1|sq|2|cbrt|mult -1|sq|2|cbrt|div -1|sq|3|cbrt|mult -1|sq|3|cbrt|div -1|sp|3|cos|div -1|sp|3|sq|mult -1|sp|3|sq|div -1|sp|3|cb|mult -1|sp|3|cb|div -1|sp|2|cbrt|mult -1|sp|2|cbrt|div -1|sp|3|cbrt|mult -1|sp|3|cbrt|div -1|sp|3|abs|mult -1|sp|3|abs|div -1|sp|3|sin|mult -1|sp|3|sin|div -1|sp|3|cos|mult -1|sp|3|0|div|mult -1|sp|3|1|mult|mult -1|sp|3|2|add|mult -1|sp|3|2|add|div -1|sp|3|2|sub|mult -1|sp|3|2|sub|div -1|sp|3|2|abd|mult -1|sp|3|2|abd|div -1|sp|3|2|mult|mult -1|sp|3|2|mult|div -1|sp|3|2|div|mult -1|sp|0|sq|mult -1|sp|0|sq|div -1|sp|2|div -1|sq|2|0|mult|div -1|sq|2|cb|div -0|inv|abs -0|inv|3|0|div|add -0|inv|3|0|div|sub -0|inv|3|0|div|abd -1|sp|0|mult -1|sp|0|div -1|sp|inv -1|sp|sq -1|sp|cb -1|sp|2|mult -1|inv|3|1|div|sub -1|sp|3|mult -1|sp|3|div -1|sp|2|abs|mult -1|sp|2|abs|div -1|sp|2|sin|mult -1|sp|2|sin|div -1|sp|2|cos|mult -1|sp|2|cos|div -1|sp|2|1|mult|mult -1|sp|2|3|div|mult -1|sp|3|0|mult|mult -1|sp|3|0|mult|div -1|0|mult|1|cb|mult -1|0|mult|3|sin|div -1|0|mult|3|cos|mult -1|0|mult|3|cos|div -1|0|mult|3|1|mult|mult -1|0|mult|3|2|add|mult -1|0|mult|3|2|add|div -1|0|mult|3|2|sub|mult -1|0|mult|3|2|sub|div -1|0|mult|3|2|abd|mult -1|0|mult|3|2|abd|div -1|0|mult|3|2|mult|mult -1|0|mult|3|2|mult|div -1|0|mult|3|2|div|mult -1|0|mult|3|sin|mult -1|0|mult|0|sq|mult -1|0|mult|0|cb|mult -1|0|mult|0|sp|mult -1|0|mult|0|cbrt|mult -1|0|mult|0|abs|mult -1|0|mult|0|abs|div -1|0|mult|0|2|div|mult -1|0|mult|0|3|div|mult -1|0|mult|2|sq|div -1|0|mult|2|cb|div -1|0|div|0|div -1|0|div|sq -1|0|mult|2|1|mult|mult -1|0|mult|2|mult -1|0|mult|2|div -1|0|mult|3|mult -1|0|mult|3|div -1|0|mult|3|sp|mult -1|0|mult|3|sp|div -1|0|mult|2|abs|mult -1|0|mult|2|abs|div -1|0|mult|2|sin|mult -1|0|mult|2|sin|div -1|0|mult|2|cos|mult -1|0|mult|2|cos|div -1|0|div|cb -1|0|mult|2|3|div|mult -1|0|mult|3|0|mult|mult -1|0|mult|3|sq|mult -1|0|mult|3|sq|div -1|0|mult|3|cb|mult -1|0|mult|3|cb|div -1|0|mult|2|cbrt|mult -1|0|mult|2|cbrt|div -1|0|mult|3|cbrt|mult -1|0|mult|3|cbrt|div -1|0|mult|3|abs|mult -1|0|mult|3|abs|div -1|0|div|3|2|mult|div -1|0|div|3|abs|div -1|0|div|3|sin|mult -1|0|div|3|sin|div -1|0|div|3|cos|mult -1|0|div|3|cos|div -1|0|div|3|1|mult|mult -1|0|div|3|2|add|mult -1|0|div|3|2|add|div -1|0|div|3|2|sub|mult -1|0|div|3|2|sub|div -1|0|div|3|2|abd|mult -1|0|div|3|2|abd|div -1|0|div|3|2|mult|mult -1|0|div|3|abs|mult -1|0|div|1|cb|mult -1|0|div|0|sq|div -1|0|div|0|cb|div -1|0|div|0|cbrt|div -1|0|div|0|abs|mult -1|0|div|0|abs|div -1|0|div|2|0|mult|div -1|0|div|2|sq|div -1|inv|2|1|div|add -1|inv|2|1|div|sub -1|inv|2|1|div|abd -1|inv|3|1|div|add -1|0|div|2|sin|div -1|0|div|sp -1|0|div|cbrt -1|0|div|abs -1|0|div|1|mult -1|0|div|2|mult -1|0|div|2|div -1|0|div|3|mult -1|0|div|3|div -1|0|div|3|sp|mult -1|0|div|2|abs|mult -1|0|div|2|abs|div -1|0|div|2|sin|mult -0|abs|3|2|abd|mult -1|0|div|2|cos|mult -1|0|div|2|cos|div -1|0|div|2|1|mult|mult -1|0|div|3|0|mult|div -1|0|div|3|sq|mult -1|0|div|3|sq|div -1|0|div|3|cb|mult -1|0|div|3|cb|div -1|0|div|2|cbrt|mult -1|0|div|2|cbrt|div -1|0|div|3|cbrt|mult -1|0|div|3|cbrt|div -1|cb|3|2|mult|mult -1|cb|3|abs|mult -1|cb|3|abs|div -1|cb|3|sin|mult -1|cb|3|sin|div -1|cb|3|cos|mult -1|cb|3|cos|div -1|cb|3|1|mult|mult -1|cb|3|2|add|mult -1|cb|3|2|add|div -1|cb|3|2|sub|mult -1|cb|3|2|sub|div -1|cb|3|2|abd|mult -1|cb|3|2|abd|div -1|cb|3|cbrt|div -1|cb|3|2|mult|div -1|cb|3|2|div|mult -1|cb|0|sq|div -1|cb|0|cb|div -1|cb|0|sp|div -1|cb|0|cbrt|div -1|cb|0|abs|div -1|cb|2|0|mult|div -1|cb|2|sq|div -0|sq|inv -0|sq|sq -0|sq|1|mult -1|cb|2|sin|div -1|cb|0|div -1|cb|inv -1|cb|sq -1|cb|cb -1|cb|2|mult -1|cb|2|div -1|cb|3|mult -1|cb|3|div -1|cb|3|sp|mult -1|cb|3|sp|div -1|cb|2|abs|mult -1|cb|2|abs|div -1|cb|2|sin|mult -0|sq|1|div -1|cb|2|cos|mult -1|cb|2|cos|div -1|cb|2|1|mult|mult -1|cb|2|3|div|mult -1|cb|3|0|mult|mult -1|cb|3|0|mult|div -1|cb|3|0|div|mult -1|cb|3|sq|mult -1|cb|3|sq|div -1|cb|2|cbrt|mult -1|cb|2|cbrt|div -1|cb|3|cbrt|mult -0|sq|3|2|mult|div -0|sq|3|sin|div -0|sq|3|cos|mult -0|sq|3|cos|div -0|sq|3|1|mult|mult -0|sq|3|1|mult|div -0|sq|3|1|div|mult -0|sq|3|2|add|mult -0|sq|3|2|add|div -0|sq|3|2|sub|mult -0|sq|3|2|sub|div -0|sq|3|2|abd|mult -0|sq|3|2|abd|div -0|sq|3|2|mult|mult -0|sq|3|sin|mult -0|sq|3|2|div|mult -0|sq|1|cb|mult -0|sq|1|cb|div -0|sq|0|abs|div -0|sq|1|sp|div -0|sq|1|sqrt|div -0|sq|1|cbrt|div -0|sq|2|cb|div -0|sq|2|sp|div -0|cb|inv -0|cb|sq -0|cb|cb -0|sq|2|1|mult|mult -0|sq|2|mult -0|sq|2|div -0|sq|3|mult -0|sq|3|div -0|sq|3|sp|mult -0|sq|3|sp|div -0|sq|2|abs|mult -0|sq|2|abs|div -0|sq|2|sin|mult -0|sq|2|sin|div -0|sq|2|cos|mult -0|sq|2|cos|div -1|cb|0|mult -0|sq|2|1|mult|div -0|sq|2|1|div|mult -0|sq|2|3|div|mult -0|sq|3|0|mult|mult -0|sq|3|cb|mult -0|sq|3|cb|div -0|sq|2|cbrt|mult -0|sq|2|cbrt|div -0|sq|3|cbrt|mult -0|sq|3|cbrt|div -0|sq|3|abs|mult -0|sq|3|abs|div -3|2|div|3|exp|sub -3|2|div|2|sin|mult -3|2|div|2|sin|div -3|2|div|2|cos|add -3|2|div|2|cos|sub -3|2|div|2|cos|abd -3|2|div|2|cos|mult -3|2|div|2|cos|div -3|2|div|2|1|mult|div -3|2|div|2|3|div|add -3|2|div|2|3|div|sub -3|2|div|2|3|div|abd -3|2|div|3|0|mult|mult -3|2|div|3|exp|add -3|2|div|2|sin|abd -3|2|div|3|exp|abd -3|2|div|3|inv|add -3|2|div|3|inv|sub -3|2|div|3|inv|abd -3|2|div|3|sq|add -3|2|div|3|sq|sub -3|2|div|3|sq|abd -3|2|div|3|sq|mult -3|2|div|3|cb|add -3|2|div|3|cb|sub -3|2|div|3|cb|mult -3|2|div|2|cbrt|add -3|2|div|3|sub -3|2|div|sp -3|2|div|cbrt -3|2|div|abs -3|2|div|sin -3|2|div|cos -3|2|div|1|mult -3|2|div|1|div -3|2|div|2|add -3|2|div|2|sub -3|2|div|2|abd -3|2|div|2|div -3|2|div|3|add -3|2|div|2|cbrt|sub -3|2|div|3|mult -3|2|div|3|sp|add -3|2|div|3|sp|sub -3|2|div|3|sp|abd -3|2|div|3|sp|mult -3|2|div|2|abs|add -3|2|div|2|abs|sub -3|2|div|2|abs|abd -3|2|div|2|abs|mult -3|2|div|2|abs|div -3|2|div|2|sin|add -3|2|div|2|sin|sub -3|2|div|1|cb|div -3|2|div|3|2|sub|add -3|2|div|3|2|sub|sub -3|2|div|3|2|sub|abd -3|2|div|3|2|sub|mult -3|2|div|3|2|sub|div -3|2|div|3|2|abd|add -3|2|div|3|2|abd|sub -3|2|div|3|2|abd|abd -3|2|div|3|2|abd|mult -3|2|div|3|2|abd|div -3|2|div|3|2|mult|add -3|2|div|3|2|mult|sub -3|2|div|3|2|mult|abd -3|2|div|3|2|add|div -3|2|div|0|sq|div -3|2|div|0|cb|div -3|2|div|0|cbrt|div -3|2|div|0|abs|div -3|2|div|1|0|mult|div -3|2|div|1|sq|div -3|2|div|1|sp|div -3|2|div|1|sqrt|div -3|2|div|1|cbrt|div -3|2|div|2|0|mult|div -3|2|div|2|sq|div -3|2|div|2|cb|div -3|2|div|3|sin|abd -3|2|div|2|cbrt|abd -3|2|div|2|cbrt|div -3|2|div|3|cbrt|add -3|2|div|3|cbrt|sub -3|2|div|3|cbrt|mult -3|2|div|3|abs|add -3|2|div|3|abs|sub -3|2|div|3|abs|abd -3|2|div|3|abs|mult -3|2|div|3|abs|div -3|2|div|3|sin|add -3|2|div|3|sin|sub -0|cb|abs -3|2|div|3|sin|mult -3|2|div|3|sin|div -3|2|div|3|cos|add -3|2|div|3|cos|sub -3|2|div|3|cos|abd -3|2|div|3|cos|mult -3|2|div|3|cos|div -3|2|div|3|1|mult|mult -3|2|div|3|2|add|add -3|2|div|3|2|add|sub -3|2|div|3|2|add|abd -3|2|div|3|2|add|mult -0|cbrt|3|2|mult|div -0|cbrt|3|sin|div -0|cbrt|3|cos|mult -0|cbrt|3|cos|div -0|cbrt|3|1|mult|mult -0|cbrt|3|1|mult|div -0|cbrt|3|1|div|mult -0|cbrt|3|2|add|mult -0|cbrt|3|2|add|div -0|cbrt|3|2|sub|mult -0|cbrt|3|2|sub|div -0|cbrt|3|2|abd|mult -0|cbrt|3|2|abd|div -0|cbrt|3|2|mult|mult -0|cbrt|3|sin|mult -0|cbrt|3|2|div|mult -0|cbrt|1|cb|mult -0|cbrt|1|cb|div -0|cbrt|0|abs|div -0|cbrt|1|sq|div -0|cbrt|1|sp|div -0|cbrt|1|sqrt|div -0|cbrt|2|sq|div -0|cbrt|2|cb|div -0|abs|0|add -0|abs|0|sub -0|abs|0|abd -0|cbrt|2|1|mult|mult -0|cbrt|1|mult -0|cbrt|1|div -0|cbrt|2|mult -0|cbrt|2|div -0|cbrt|3|mult -0|cbrt|3|div -0|cbrt|3|sp|mult -0|cbrt|2|abs|mult -0|cbrt|2|abs|div -0|cbrt|2|sin|mult -0|cbrt|2|sin|div -0|cbrt|2|cos|mult -0|cbrt|2|cos|div -0|abs|0|mult -0|cbrt|2|1|mult|div -0|cbrt|2|1|div|mult -0|cbrt|2|3|div|mult -0|cbrt|3|0|mult|mult -0|cbrt|3|sq|mult -0|cbrt|3|sq|div -0|cbrt|3|cb|mult -0|cbrt|3|cb|div -0|cbrt|2|cbrt|mult -0|cbrt|3|cbrt|mult -0|cbrt|3|abs|mult -0|cbrt|3|abs|div -0|abs|3|abs|mult -0|abs|3|0|mult|sub -0|abs|3|0|mult|abd -0|abs|3|0|mult|mult -0|abs|3|0|mult|div -0|abs|3|0|div|mult -0|abs|3|sq|mult -0|abs|3|sq|div -0|abs|3|cb|mult -0|abs|3|cb|div -0|abs|2|cbrt|mult -0|abs|2|cbrt|div -0|abs|3|cbrt|mult -0|abs|3|cbrt|div -0|abs|3|0|mult|add -0|abs|3|abs|div -0|abs|3|sin|mult -0|abs|3|sin|div -0|abs|3|cos|mult -0|abs|3|cos|div -0|abs|3|1|mult|mult -0|abs|3|1|mult|div -0|abs|3|1|div|mult -0|abs|3|2|add|mult -0|abs|3|2|add|div -0|abs|3|2|sub|mult -0|abs|3|2|sub|div -0|abs|3|div -0|abs|0|div -0|abs|inv -0|abs|sq -0|abs|cb -0|abs|sp -0|abs|sqrt -0|abs|cbrt -0|abs|1|mult -0|abs|1|div -0|abs|2|mult -0|abs|2|div -0|abs|3|mult -0|cbrt|abs -0|abs|3|sp|mult -0|abs|3|sp|div -0|abs|2|abs|mult -0|abs|2|abs|div -0|abs|2|sin|mult -0|abs|2|sin|div -0|abs|2|cos|mult -0|abs|2|cos|div -0|abs|2|1|mult|mult -0|abs|2|1|mult|div -0|abs|2|1|div|mult -0|abs|2|3|div|mult -0|cb|3|2|abd|div -0|cb|3|abs|div -0|cb|3|sin|mult -0|cb|3|sin|div -0|cb|3|cos|mult -0|cb|3|cos|div -0|cb|3|1|mult|mult -0|cb|3|1|mult|div -0|cb|3|1|div|mult -0|cb|3|2|add|mult -0|cb|3|2|add|div -0|cb|3|2|sub|mult -0|cb|3|2|sub|div -0|cb|3|2|abd|mult -0|cb|3|abs|mult -0|cb|3|2|mult|mult -0|cb|3|2|mult|div -0|cb|3|2|div|mult -0|cb|0|abs|div -0|cb|1|sq|div -0|cb|1|sp|div -0|cb|1|sqrt|div -0|cb|1|cbrt|div -0|cb|2|sq|div -0|cb|2|sp|div -0|sp|inv -0|sp|1|mult -0|cb|2|cos|mult -0|cb|1|mult -0|cb|1|div -0|cb|2|mult -0|cb|2|div -0|cb|3|mult -0|cb|3|div -0|cb|3|sp|mult -0|cb|3|sp|div -0|cb|2|abs|mult -0|cb|2|abs|div -0|cb|2|sin|mult -0|cb|2|sin|div -0|sp|1|div -0|cb|2|cos|div -0|cb|2|1|mult|mult -0|cb|2|1|mult|div -0|cb|2|1|div|mult -0|cb|2|3|div|mult -0|cb|3|0|mult|mult -0|cb|3|sq|mult -0|cb|3|sq|div -0|cb|2|cbrt|mult -0|cb|2|cbrt|div -0|cb|3|cbrt|mult -0|cb|3|cbrt|div -0|sp|3|2|mult|div -0|sp|3|sin|div -0|sp|3|cos|mult -0|sp|3|cos|div -0|sp|3|1|mult|mult -0|sp|3|1|mult|div -0|sp|3|1|div|mult -0|sp|3|2|add|mult -0|sp|3|2|add|div -0|sp|3|2|sub|mult -0|sp|3|2|sub|div -0|sp|3|2|abd|mult -0|sp|3|2|abd|div -0|sp|3|2|mult|mult -0|sp|3|sin|mult -0|sp|3|2|div|mult -0|sp|1|cb|mult -0|sp|1|cb|div -0|sp|0|abs|div -0|sp|1|sq|div -0|sp|1|sqrt|div -0|sp|1|cbrt|div -0|sp|2|sq|div -0|sp|2|cb|div -0|cbrt|inv -0|cbrt|sq -0|cbrt|cbrt -0|sp|2|1|div|mult -0|sp|2|mult -0|sp|2|div -0|sp|3|mult -0|sp|3|div -0|sp|2|abs|mult -0|sp|2|abs|div -0|sp|2|sin|mult -0|sp|2|sin|div -0|sp|2|cos|mult -0|sp|2|cos|div -0|sp|2|1|mult|mult -0|sp|2|1|mult|div -1|sp|0|cb|mult -0|sp|2|3|div|mult -0|sp|3|0|mult|mult -0|sp|3|sq|mult -0|sp|3|sq|div -0|sp|3|cb|mult -0|sp|3|cb|div -0|sp|2|cbrt|mult -0|sp|2|cbrt|div -0|sp|3|cbrt|mult -0|sp|3|cbrt|div -0|sp|3|abs|mult -0|sp|3|abs|div -2|sq|0|cbrt|div -2|sq|3|2|mult|sub -2|sq|3|2|mult|abd -2|sq|3|2|mult|mult -2|sq|3|2|div|add -2|sq|3|2|div|sub -2|sq|1|cb|mult -2|sq|1|cb|div -2|sq|0|sq|div -2|sq|0|cb|mult -2|sq|0|cb|div -2|sq|0|sp|mult -2|sq|0|sp|div -2|sq|0|cbrt|mult -2|sq|3|2|mult|add -2|sq|0|abs|mult -2|sq|0|abs|div -2|sq|0|1|div|mult -2|sq|0|3|div|mult -2|sq|1|0|mult|mult -2|sq|1|0|mult|div -2|sq|1|0|div|mult -2|sq|1|sq|div -2|sq|1|sp|mult -2|sq|1|sp|div -2|sq|1|sqrt|mult -2|sq|1|sqrt|div -2|sq|3|1|div|mult -2|sq|3|abs|sub -2|sq|3|abs|mult -2|sq|3|abs|div -2|sq|3|sin|add -2|sq|3|sin|sub -2|sq|3|sin|mult -2|sq|3|sin|div -2|sq|3|cos|add -2|sq|3|cos|sub -2|sq|3|cos|mult -2|sq|3|cos|div -2|sq|3|1|mult|mult -2|sq|3|1|mult|div -2|sq|1|cbrt|mult -2|sq|3|2|add|add -2|sq|3|2|add|sub -2|sq|3|2|add|mult -2|sq|3|2|add|div -2|sq|3|2|sub|add -2|sq|3|2|sub|sub -2|sq|3|2|sub|mult -2|sq|3|2|sub|div -2|sq|3|2|abd|add -2|sq|3|2|abd|sub -2|sq|3|2|abd|mult -2|sq|3|2|abd|div -2|cb|2|cos|add -2|cb|3|sp|abd -2|cb|3|sp|mult -2|cb|3|sp|div -2|cb|2|abs|add -2|cb|2|abs|sub -2|cb|2|abs|abd -2|cb|2|abs|mult -2|cb|2|abs|div -2|cb|2|sin|add -2|cb|2|sin|sub -2|cb|2|sin|abd -2|cb|2|sin|mult -2|cb|2|sin|div -2|cb|3|sp|sub -2|cb|2|cos|sub -2|cb|2|cos|abd -2|cb|2|cos|mult -2|cb|2|cos|div -2|cb|2|1|mult|mult -2|cb|2|1|div|mult -2|cb|2|3|div|add -2|cb|2|3|div|sub -2|cb|2|3|div|abd -2|cb|2|3|div|mult -2|cb|3|0|mult|mult -2|cb|3|0|mult|div -2|cb|sin -2|sq|1|cbrt|div -2|sq|1|3|div|mult -2|sq|2|0|mult|mult -2|sq|2|0|div|mult -2|sq|2|inv|add -2|sq|2|inv|sub -2|cb|0|mult -2|cb|0|div -2|cb|inv -2|cb|sq -2|cb|cb -2|cb|abs -2|sq|3|abs|add -2|cb|cos -2|cb|1|mult -2|cb|1|div -2|cb|2|add -2|cb|2|sub -2|cb|2|abd -2|cb|3|add -2|cb|3|sub -2|cb|3|abd -2|cb|3|mult -2|cb|3|div -2|cb|3|sp|add -2|inv|3|2|sub|abd -2|inv|3|abs|sub -2|inv|3|abs|abd -2|inv|3|sin|add -2|inv|3|sin|sub -2|inv|3|sin|abd -2|inv|3|cos|add -2|inv|3|cos|sub -2|inv|3|cos|abd -2|inv|3|2|add|add -2|inv|3|2|add|sub -2|inv|3|2|add|abd -2|inv|3|2|sub|add -2|inv|3|2|sub|sub -2|inv|3|abs|add -2|inv|3|2|abd|add -2|inv|3|2|abd|sub -2|inv|3|2|abd|abd -2|inv|3|2|mult|add -2|inv|3|2|mult|sub -2|inv|3|2|mult|abd -2|inv|3|2|div|add -2|inv|3|2|div|sub -2|inv|3|2|div|abd -2|sq|0|mult -2|sq|0|div -2|sq|inv -2|inv|3|inv|add -2|inv|2|abs|abd -2|inv|2|sin|add -2|inv|2|sin|sub -2|inv|2|sin|abd -2|inv|2|cos|add -2|inv|2|cos|sub -2|inv|2|cos|abd -2|inv|2|3|div|add -2|inv|2|3|div|sub -2|inv|2|3|div|abd -2|inv|3|exp|add -2|inv|3|exp|sub -2|inv|3|exp|abd -2|sq|sq -2|inv|3|inv|sub -2|inv|3|inv|abd -2|inv|3|sq|add -2|inv|3|sq|sub -2|inv|3|sq|abd -2|inv|3|cb|add -2|inv|3|cb|sub -2|inv|2|cbrt|add -2|inv|2|cbrt|sub -2|inv|2|cbrt|abd -2|inv|3|cbrt|add -2|inv|3|cbrt|sub -2|sq|3|sq|add -2|sq|2|cos|div -2|sq|2|1|mult|mult -2|sq|2|1|div|mult -2|sq|2|3|div|add -2|sq|2|3|div|sub -2|sq|2|3|div|mult -2|sq|3|0|mult|mult -2|sq|3|0|mult|div -2|sq|3|0|div|mult -2|sq|3|exp|add -2|sq|3|exp|sub -2|sq|3|inv|add -2|sq|3|inv|sub -2|sq|2|cos|mult -2|sq|3|sq|sub -2|sq|3|sq|abd -2|sq|3|cb|add -2|sq|3|cb|sub -2|sq|3|cb|mult -2|sq|3|cb|div -2|sq|2|cbrt|add -2|sq|2|cbrt|sub -2|sq|3|cbrt|add -2|sq|3|cbrt|sub -2|sq|3|cbrt|mult -2|sq|3|cbrt|div -2|sq|3|sp|abd -2|sq|sin -2|sq|cos -2|sq|1|mult -2|sq|1|div -2|sq|2|add -2|sq|2|sub -2|sq|3|add -2|sq|3|sub -2|sq|3|mult -2|sq|3|div -2|sq|3|sp|add -2|sq|3|sp|sub -2|cb|3|0|div|mult -2|sq|3|sp|mult -2|sq|3|sp|div -2|sq|2|abs|add -2|sq|2|abs|sub -2|sq|2|abs|mult -2|sq|2|abs|div -2|sq|2|sin|add -2|sq|2|sin|sub -2|sq|2|sin|mult -2|sq|2|sin|div -2|sq|2|cos|add -2|sq|2|cos|sub -2|sp|3|cbrt|mult -2|sp|3|inv|sub -2|sp|3|sq|add -2|sp|3|sq|sub -2|sp|3|sq|mult -2|sp|3|sq|div -2|sp|3|cb|add -2|sp|3|cb|sub -2|sp|3|cb|mult -2|sp|3|cb|div -2|sp|2|cbrt|add -2|sp|2|cbrt|sub -2|sp|3|cbrt|add -2|sp|3|cbrt|sub -2|sp|3|inv|add -2|sp|3|cbrt|div -2|sp|3|abs|add -2|sp|3|abs|sub -2|sp|3|abs|mult -2|sp|3|abs|div -2|sp|3|sin|add -2|sp|3|sin|sub -2|sp|3|sin|mult -2|sp|3|sin|div -2|sp|3|cos|add -2|sp|3|cos|sub -2|sp|3|cos|mult -2|sp|2|cos|sub -2|sp|3|div -2|sp|3|sp|add -2|sp|3|sp|sub -2|sp|3|sp|abd -2|sp|2|abs|add -2|sp|2|abs|sub -2|sp|2|abs|mult -2|sp|2|abs|div -2|sp|2|sin|add -2|sp|2|sin|sub -2|sp|2|sin|mult -2|sp|2|sin|div -2|sp|2|cos|add -2|sp|3|cos|div -2|sp|2|cos|mult -2|sp|2|cos|div -2|sp|2|1|mult|mult -2|sp|2|1|div|mult -2|sp|2|3|div|add -2|sp|2|3|div|sub -2|sp|2|3|div|mult -2|sp|3|0|mult|mult -2|sp|3|0|mult|div -2|sp|3|0|div|mult -2|sp|3|exp|add -2|sp|3|exp|sub -2|sp|1|sqrt|mult -2|sp|0|sp|div -2|sp|0|cbrt|mult -2|sp|0|cbrt|div -2|sp|0|abs|mult -2|sp|0|abs|div -2|sp|0|1|div|mult -2|sp|0|3|div|mult -2|sp|1|0|mult|mult -2|sp|1|0|mult|div -2|sp|1|0|div|mult -2|sp|1|sq|mult -2|sp|1|sq|div -2|sp|1|sp|div -2|sp|0|cb|div -2|sp|1|sqrt|div -2|sp|1|cbrt|mult -2|sp|1|cbrt|div -2|sp|1|3|div|mult -2|sp|2|0|mult|mult -2|sp|2|0|div|mult -2|sp|2|inv|add -2|sp|2|inv|sub -2|sp|2|sq|add -2|sp|2|sq|sub -2|sp|2|cb|add -2|sp|2|cb|sub -2|sp|3|2|abd|sub -2|sp|3|1|mult|mult -2|sp|3|1|mult|div -2|sp|3|1|div|mult -2|sp|3|2|add|add -2|sp|3|2|add|sub -2|sp|3|2|add|mult -2|sp|3|2|add|div -2|sp|3|2|sub|add -2|sp|3|2|sub|sub -2|sp|3|2|sub|mult -2|sp|3|2|sub|div -2|sp|3|2|abd|add -2|sp|3|mult -2|sp|3|2|abd|mult -2|sp|3|2|abd|div -2|sp|3|2|mult|add -2|sp|3|2|mult|sub -2|sp|3|2|mult|mult -2|sp|3|2|div|add -2|sp|3|2|div|sub -2|sp|1|cb|mult -2|sp|1|cb|div -2|sp|0|sq|mult -2|sp|0|sq|div -2|sp|0|cb|mult -2|cb|3|1|div|mult -2|cb|3|abs|div -2|cb|3|sin|add -2|cb|3|sin|sub -2|cb|3|sin|abd -2|cb|3|sin|mult -2|cb|3|sin|div -2|cb|3|cos|add -2|cb|3|cos|sub -2|cb|3|cos|abd -2|cb|3|cos|mult -2|cb|3|cos|div -2|cb|3|1|mult|mult -2|cb|3|1|mult|div -2|cb|3|abs|mult -2|cb|3|2|add|add -2|cb|3|2|add|sub -2|cb|3|2|add|abd -2|cb|3|2|add|mult -2|cb|3|2|add|div -2|cb|3|2|sub|add -2|cb|3|2|sub|sub -2|cb|3|2|sub|abd -2|cb|3|2|sub|mult -2|cb|3|2|sub|div -2|cb|3|2|abd|add -2|cb|3|2|abd|sub -2|cb|3|cb|sub -2|cb|3|exp|add -2|cb|3|exp|sub -2|cb|3|exp|abd -2|cb|3|inv|add -2|cb|3|inv|sub -2|cb|3|inv|abd -2|cb|3|sq|add -2|cb|3|sq|sub -2|cb|3|sq|abd -2|cb|3|sq|mult -2|cb|3|sq|div -2|cb|3|cb|add -2|cb|3|2|abd|abd -2|cb|3|cb|abd -2|cb|2|cbrt|add -2|cb|2|cbrt|sub -2|cb|2|cbrt|abd -2|cb|3|cbrt|add -2|cb|3|cbrt|sub -2|cb|3|cbrt|abd -2|cb|3|cbrt|mult -2|cb|3|cbrt|div -2|cb|3|abs|add -2|cb|3|abs|sub -2|cb|3|abs|abd -2|cb|2|sq|sub -2|cb|1|sp|mult -2|cb|1|sp|div -2|cb|1|sqrt|mult -2|cb|1|sqrt|div -2|cb|1|cbrt|mult -2|cb|1|cbrt|div -2|cb|1|3|div|mult -2|cb|2|0|mult|mult -2|cb|2|0|div|mult -2|cb|2|inv|add -2|cb|2|inv|sub -2|cb|2|inv|abd -2|cb|2|sq|add -2|cb|1|sq|div -2|cb|2|sq|abd -2|sp|0|mult -2|sp|0|div -2|sp|inv -2|sp|sin -2|sp|cos -2|sp|1|mult -2|sp|1|div -2|sp|2|add -2|sp|2|sub -2|sp|3|add -2|sp|3|sub -2|cb|0|cb|div -2|cb|3|2|abd|mult -2|cb|3|2|abd|div -2|cb|3|2|mult|add -2|cb|3|2|mult|sub -2|cb|3|2|mult|abd -2|cb|3|2|mult|mult -2|cb|3|2|div|add -2|cb|3|2|div|sub -2|cb|3|2|div|abd -2|cb|1|cb|div -2|cb|0|sq|mult -2|cb|0|sq|div -2|inv|2|abs|sub -2|cb|0|sp|mult -2|cb|0|sp|div -2|cb|0|cbrt|mult -2|cb|0|cbrt|div -2|cb|0|abs|mult -2|cb|0|abs|div -2|cb|0|1|div|mult -2|cb|0|3|div|mult -2|cb|1|0|mult|mult -2|cb|1|0|mult|div -2|cb|1|0|div|mult -2|cb|1|sq|mult -1|2|div|3|mult -1|cbrt|2|cb|div -1|2|div|0|mult -1|2|div|0|div -1|2|div|sq -1|2|div|cb -1|2|div|sp -1|2|div|cbrt -1|2|div|abs -1|2|div|1|add -1|2|div|1|sub -1|2|div|1|abd -1|2|div|1|mult -1|2|div|2|div -1|cbrt|2|sq|div -1|2|div|3|div -1|2|div|3|sp|mult -1|2|div|2|abs|mult -1|2|div|2|abs|div -1|2|div|2|sin|mult -1|2|div|2|sin|div -1|2|div|2|cos|mult -1|2|div|2|cos|div -1|2|div|2|1|mult|add -1|2|div|2|1|mult|sub -1|2|div|2|1|mult|abd -1|2|div|3|0|mult|mult -1|cbrt|0|sq|div -1|cbrt|3|cos|mult -1|cbrt|3|cos|div -1|cbrt|3|1|mult|mult -1|cbrt|3|2|add|mult -1|cbrt|3|2|add|div -1|cbrt|3|2|sub|mult -1|cbrt|3|2|sub|div -1|cbrt|3|2|abd|mult -1|cbrt|3|2|abd|div -1|cbrt|3|2|mult|mult -1|cbrt|3|2|mult|div -1|cbrt|3|2|div|mult -1|cbrt|0|sq|mult -1|2|div|3|0|mult|div -1|cbrt|0|cb|mult -1|cbrt|0|cb|div -1|cbrt|0|sp|mult -1|cbrt|0|cbrt|mult -1|cbrt|0|cbrt|div -1|cbrt|0|abs|mult -1|cbrt|0|abs|div -1|cbrt|0|2|div|mult -1|cbrt|0|3|div|mult -1|cbrt|1|0|mult|mult -1|cbrt|1|0|div|mult -1|cbrt|2|0|mult|div -1|2|div|2|sq|div -1|2|div|0|cb|mult -1|2|div|0|cb|div -1|2|div|0|sp|mult -1|2|div|0|cbrt|mult -1|2|div|0|cbrt|div -1|2|div|0|abs|mult -1|2|div|0|abs|div -1|2|div|1|0|mult|mult -1|2|div|1|sq|mult -1|2|div|1|sp|mult -1|2|div|1|sqrt|mult -1|2|div|1|cbrt|mult -1|2|div|2|0|mult|div -1|2|div|0|sq|div -1|2|div|2|cb|div -1|3|div|0|mult -1|3|div|0|div -1|3|div|sq -1|3|div|cb -1|3|div|sp -1|3|div|cbrt -1|3|div|abs -1|3|div|1|add -1|3|div|1|sub -1|3|div|1|abd -1|3|div|1|mult -1|2|div|3|cos|div -1|2|div|3|sq|mult -1|2|div|3|sq|div -1|2|div|3|cb|mult -1|2|div|3|cb|div -1|2|div|2|cbrt|div -1|2|div|3|cbrt|mult -1|2|div|3|cbrt|div -1|2|div|3|abs|mult -1|2|div|3|abs|div -1|2|div|3|sin|mult -1|2|div|3|sin|div -1|2|div|3|cos|mult -1|cbrt|3|sin|div -1|2|div|3|1|mult|add -1|2|div|3|1|mult|sub -1|2|div|3|1|mult|mult -1|2|div|3|2|add|mult -1|2|div|3|2|add|div -1|2|div|3|2|sub|mult -1|2|div|3|2|sub|div -1|2|div|3|2|abd|mult -1|2|div|3|2|abd|div -1|2|div|3|2|mult|div -1|2|div|1|cb|mult -1|2|div|0|sq|mult -1|sqrt|2|cbrt|mult -1|sqrt|2|sin|mult -1|sqrt|2|sin|div -1|sqrt|2|cos|mult -1|sqrt|2|cos|div -1|sqrt|2|1|mult|mult -1|sqrt|2|3|div|mult -1|sqrt|3|0|mult|mult -1|sqrt|3|0|mult|div -1|sqrt|3|0|div|mult -1|sqrt|3|sq|mult -1|sqrt|3|sq|div -1|sqrt|3|cb|mult -1|sqrt|3|cb|div -1|sqrt|2|abs|div -1|sqrt|2|cbrt|div -1|sqrt|3|cbrt|mult -1|sqrt|3|cbrt|div -1|sqrt|3|abs|mult -1|sqrt|3|abs|div -1|sqrt|3|sin|mult -1|sqrt|3|sin|div -1|sqrt|3|cos|mult -1|sqrt|3|cos|div -1|sqrt|3|1|mult|mult -1|sqrt|3|2|add|mult -1|sqrt|3|2|add|div -1|sp|2|cb|div -1|sp|0|cb|div -1|sp|0|sp|div -1|sp|0|cbrt|mult -1|sp|0|cbrt|div -1|sp|0|abs|mult -1|sp|0|abs|div -1|sp|0|2|div|mult -1|sp|0|3|div|mult -1|sp|1|0|mult|mult -1|sp|1|0|div|mult -1|sp|2|0|mult|div -1|sp|2|sq|div -1|sqrt|3|2|sub|mult -1|sqrt|0|mult -1|sqrt|0|div -1|sqrt|inv -1|sqrt|cb -1|sqrt|sqrt -1|sqrt|cbrt -1|sqrt|2|mult -1|sqrt|2|div -1|sqrt|3|mult -1|sqrt|3|div -1|sqrt|3|sp|mult -1|sqrt|2|abs|mult -1|cbrt|2|3|div|mult -1|cbrt|cbrt -1|cbrt|2|mult -1|cbrt|2|div -1|cbrt|3|mult -1|cbrt|3|div -1|cbrt|3|sp|mult -1|cbrt|2|abs|mult -1|cbrt|2|abs|div -1|cbrt|2|sin|mult -1|cbrt|2|sin|div -1|cbrt|2|cos|mult -1|cbrt|2|cos|div -1|cbrt|2|1|mult|mult -1|cbrt|sq -1|cbrt|3|0|mult|mult -1|cbrt|3|0|mult|div -1|cbrt|3|0|div|mult -1|cbrt|3|sq|mult -1|cbrt|3|sq|div -1|cbrt|3|cb|mult -1|cbrt|3|cb|div -1|cbrt|2|cbrt|mult -1|cbrt|3|cbrt|mult -1|cbrt|3|abs|mult -1|cbrt|3|abs|div -1|cbrt|3|sin|mult -1|sqrt|0|cbrt|div -1|sqrt|3|2|sub|div -1|sqrt|3|2|abd|mult -1|sqrt|3|2|abd|div -1|sqrt|3|2|mult|mult -1|sqrt|3|2|mult|div -1|sqrt|3|2|div|mult -1|sqrt|0|sq|mult -1|sqrt|0|sq|div -1|sqrt|0|cb|mult -1|sqrt|0|cb|div -1|sqrt|0|sp|mult -1|sqrt|0|cbrt|mult -1|3|div|2|mult -1|sqrt|0|abs|mult -1|sqrt|0|abs|div -1|sqrt|0|2|div|mult -1|sqrt|0|3|div|mult -1|sqrt|1|0|mult|mult -1|sqrt|1|0|div|mult -1|sqrt|2|0|mult|div -1|sqrt|2|sq|div -1|sqrt|2|cb|div -1|cbrt|0|mult -1|cbrt|0|div -1|cbrt|inv -2|0|div|2|abs|mult -2|0|mult|1|3|div|mult -2|0|div|0|div -2|0|div|sq -2|0|div|cb -2|0|div|sp -2|0|div|cbrt -2|0|div|abs -2|0|div|1|mult -2|0|div|1|div -2|0|div|2|mult -2|0|div|3|mult -2|0|div|3|div -2|0|div|3|sp|mult -2|0|mult|1|cbrt|div -2|0|div|2|abs|div -2|0|div|2|sin|mult -2|0|div|2|sin|div -2|0|div|2|cos|mult -2|0|div|2|cos|div -2|0|div|2|1|mult|mult -2|0|div|3|0|mult|div -2|0|div|3|0|div|add -2|0|div|3|0|div|sub -2|0|div|3|0|div|abd -2|0|div|3|sq|mult -2|0|div|3|sq|div -2|0|mult|0|2|div|abd -2|0|mult|1|cb|div -2|0|mult|0|sq|mult -2|0|mult|0|cb|mult -2|0|mult|0|sp|mult -2|0|mult|0|cbrt|mult -2|0|mult|0|abs|add -2|0|mult|0|abs|sub -2|0|mult|0|abs|abd -2|0|mult|0|abs|mult -2|0|mult|0|abs|div -2|0|mult|0|1|div|mult -2|0|mult|0|2|div|add -2|0|mult|0|2|div|sub -2|0|div|3|cb|mult -2|0|mult|0|3|div|add -2|0|mult|0|3|div|sub -2|0|mult|0|3|div|abd -2|0|mult|0|3|div|mult -2|0|mult|1|0|mult|mult -2|0|mult|1|sq|mult -2|0|mult|1|sq|div -2|0|mult|1|sp|mult -2|0|mult|1|sp|div -2|0|mult|1|sqrt|mult -2|0|mult|1|sqrt|div -2|0|mult|1|cbrt|mult -2|inv|nexp -2|0|div|1|0|mult|div -2|0|div|1|sq|mult -2|0|div|1|sq|div -2|0|div|0|inv|add -2|0|div|0|inv|sub -2|0|div|0|inv|abd -2|0|div|1|sp|mult -2|0|div|1|sp|div -2|0|div|1|sqrt|mult -2|0|div|1|sqrt|div -2|0|div|1|cbrt|mult -2|0|div|1|cbrt|div -2|inv|exp -2|0|div|0|abs|div -2|inv|abs -2|inv|sin -2|inv|cos -2|inv|2|add -2|inv|2|sub -2|inv|2|abd -2|inv|3|add -2|inv|3|sub -2|inv|3|sp|add -2|inv|3|sp|sub -2|inv|3|sp|abd -2|inv|2|abs|add -2|0|div|3|2|add|mult -2|0|div|3|cb|div -2|0|div|2|cbrt|mult -2|0|div|3|cbrt|mult -2|0|div|3|cbrt|div -2|0|div|3|abs|mult -2|0|div|3|abs|div -2|0|div|3|sin|mult -2|0|div|3|sin|div -2|0|div|3|cos|mult -2|0|div|3|cos|div -2|0|div|3|1|mult|mult -2|0|div|3|1|mult|div -2|0|mult|1|cb|mult -2|0|div|3|2|add|div -2|0|div|3|2|sub|mult -2|0|div|3|2|sub|div -2|0|div|3|2|abd|mult -2|0|div|3|2|abd|div -2|0|div|3|2|mult|mult -2|0|div|1|cb|mult -2|0|div|1|cb|div -2|0|div|0|sq|div -2|0|div|0|cb|div -2|0|div|0|cbrt|div -2|0|div|0|abs|mult -1|3|div|0|cbrt|mult -1|3|div|3|2|add|mult -1|3|div|3|2|add|div -1|3|div|3|2|sub|mult -1|3|div|3|2|sub|div -1|3|div|3|2|abd|mult -1|3|div|3|2|abd|div -1|3|div|3|2|mult|div -1|3|div|1|cb|mult -1|3|div|0|sq|mult -1|3|div|0|sq|div -1|3|div|0|cb|mult -1|3|div|0|cb|div -1|3|div|0|sp|mult -1|3|div|3|1|mult|sub -1|3|div|0|cbrt|div -1|3|div|0|abs|mult -1|3|div|0|abs|div -1|3|div|1|0|mult|mult -1|3|div|1|sq|mult -1|3|div|1|sp|mult -1|3|div|1|sqrt|mult -1|3|div|1|cbrt|mult -1|3|div|1|2|div|add -1|3|div|1|2|div|sub -1|3|div|1|2|div|abd -1|3|div|2|0|mult|div -1|3|div|3|0|mult|div -1|3|div|2|div -1|3|div|3|div -1|3|div|2|abs|mult -1|3|div|2|abs|div -1|3|div|2|sin|mult -1|3|div|2|sin|div -1|3|div|2|cos|mult -1|3|div|2|cos|div -1|3|div|2|1|mult|add -1|3|div|2|1|mult|sub -1|3|div|2|1|mult|abd -1|3|div|2|1|mult|mult -1|3|div|2|sq|div -1|3|div|3|sq|div -1|3|div|3|cb|div -1|3|div|2|cbrt|mult -1|3|div|2|cbrt|div -1|3|div|3|cbrt|div -1|3|div|3|abs|mult -1|3|div|3|abs|div -1|3|div|3|sin|mult -1|3|div|3|sin|div -1|3|div|3|cos|mult -1|3|div|3|cos|div -1|3|div|3|1|mult|add -2|0|mult|3|sin|div -2|0|mult|3|0|mult|sub -2|0|mult|3|0|mult|abd -2|0|mult|3|0|mult|mult -2|0|mult|3|sq|mult -2|0|mult|3|sq|div -2|0|mult|3|cb|mult -2|0|mult|3|cb|div -2|0|mult|2|cbrt|mult -2|0|mult|3|cbrt|mult -2|0|mult|3|cbrt|div -2|0|mult|3|abs|mult -2|0|mult|3|abs|div -2|0|mult|3|sin|mult -2|0|mult|3|0|mult|add -2|0|mult|3|cos|mult -2|0|mult|3|cos|div -2|0|mult|3|1|mult|mult -2|0|mult|3|1|mult|div -2|0|mult|3|1|div|mult -2|0|mult|3|2|add|mult -2|0|mult|3|2|add|div -2|0|mult|3|2|sub|mult -2|0|mult|3|2|sub|div -2|0|mult|3|2|abd|mult -2|0|mult|3|2|abd|div -2|0|mult|3|2|mult|mult -2|0|mult|3|mult -2|0|mult|0|add -2|0|mult|0|sub -2|0|mult|0|abd -2|0|mult|0|mult -2|0|mult|inv -2|0|mult|sq -2|0|mult|cb -2|0|mult|cbrt -2|0|mult|abs -2|0|mult|1|mult -2|0|mult|1|div -2|0|mult|2|mult -3|2|div|cb -2|0|mult|3|div -2|0|mult|3|sp|mult -2|0|mult|3|sp|div -2|0|mult|2|abs|mult -2|0|mult|2|abs|div -2|0|mult|2|sin|mult -2|0|mult|2|sin|div -2|0|mult|2|cos|mult -2|0|mult|2|cos|div -2|0|mult|2|1|mult|mult -2|0|mult|2|1|div|mult -2|0|mult|2|3|div|mult -3|inv|2|3|div|sub -3|inv|3|sp|add -3|inv|3|sp|sub -3|inv|3|sp|abd -3|inv|2|abs|add -3|inv|2|abs|sub -3|inv|2|abs|abd -3|inv|2|sin|add -3|inv|2|sin|sub -3|inv|2|sin|abd -3|inv|2|cos|add -3|inv|2|cos|sub -3|inv|2|cos|abd -3|inv|2|3|div|add -3|inv|3|sub -3|inv|2|3|div|abd -3|inv|3|exp|add -3|inv|3|exp|sub -3|inv|3|exp|abd -3|sq|0|mult -3|sq|0|div -3|sq|inv -3|sq|sq -3|sq|sin -3|sq|cos -3|sq|1|mult -3|sq|1|div -3|exp|2|cos|abd -3|exp|3|add -3|exp|3|sub -3|exp|3|sp|add -3|exp|3|sp|sub -3|exp|3|sp|abd -3|exp|2|abs|add -3|exp|2|abs|sub -3|exp|2|abs|abd -3|exp|2|sin|add -3|exp|2|sin|sub -3|exp|2|sin|abd -3|exp|2|cos|add -3|exp|2|cos|sub -3|sq|2|add -3|exp|2|3|div|add -3|exp|2|3|div|sub -3|exp|2|3|div|abd -3|inv|exp -3|inv|nexp -3|inv|abs -3|inv|sin -3|inv|cos -3|inv|2|add -3|inv|2|sub -3|inv|2|abd -3|inv|3|add -3|sq|3|2|abd|div -3|sq|2|3|div|sub -3|sq|3|0|mult|mult -3|sq|3|0|div|mult -3|sq|3|exp|add -3|sq|3|exp|sub -3|sq|3|inv|add -3|sq|3|inv|sub -3|sq|2|cbrt|div -3|sq|3|abs|div -3|sq|3|sin|div -3|sq|3|cos|div -3|sq|3|2|add|div -3|sq|3|2|sub|div -3|sq|2|3|div|add -3|sq|1|cb|div -3|sq|0|sq|div -3|sq|0|cb|div -3|sq|0|sp|div -3|sq|0|cbrt|div -3|sq|0|abs|div -3|sq|1|0|mult|div -3|sq|1|sq|div -3|sq|1|sp|div -3|sq|1|sqrt|div -3|sq|1|cbrt|div -3|sq|2|0|mult|div -3|sq|2|abs|mult -3|sq|2|sub -3|sq|2|abd -3|sq|2|mult -3|sq|2|div -3|sq|3|add -3|sq|3|sub -3|sq|3|sp|add -3|sq|3|sp|sub -3|sq|3|sp|abd -3|sq|2|abs|add -3|sq|2|abs|sub -3|sq|2|abs|abd -3|exp|2|abd -3|sq|2|abs|div -3|sq|2|sin|add -3|sq|2|sin|sub -3|sq|2|sin|mult -3|sq|2|sin|div -3|sq|2|cos|add -3|sq|2|cos|sub -3|sq|2|cos|mult -3|sq|2|cos|div -3|sq|2|1|mult|mult -3|sq|2|1|mult|div -3|sq|2|1|div|mult -3|0|mult|2|abs|div -3|0|mult|inv -3|0|mult|sq -3|0|mult|cb -3|0|mult|sp -3|0|mult|cbrt -3|0|mult|abs -3|0|mult|1|mult -3|0|mult|1|div -3|0|mult|2|mult -3|0|mult|2|div -3|0|mult|3|mult -3|0|mult|3|sp|mult -3|0|mult|2|abs|mult -3|0|mult|0|mult -3|0|mult|2|sin|mult -3|0|mult|2|sin|div -3|0|mult|2|cos|mult -3|0|mult|2|cos|div -3|0|mult|2|1|mult|mult -3|0|mult|2|1|mult|div -3|0|mult|2|1|div|mult -3|0|mult|2|cbrt|div -3|0|mult|3|abs|div -3|0|mult|3|sin|div -3|0|mult|3|cos|div -3|0|mult|3|2|add|div -2|3|div|1|cb|div -2|3|div|2|cos|div -2|3|div|2|1|mult|mult -2|3|div|3|0|mult|div -2|3|div|3|sq|div -2|3|div|3|cb|div -2|3|div|3|cbrt|div -2|3|div|3|abs|div -2|3|div|3|sin|div -2|3|div|3|cos|div -2|3|div|3|1|mult|div -2|3|div|3|2|add|div -2|3|div|3|2|sub|div -2|3|div|3|2|abd|div -3|0|mult|3|2|sub|div -2|3|div|0|sq|div -2|3|div|0|cb|div -2|3|div|0|cbrt|div -2|3|div|0|abs|div -2|3|div|1|0|mult|div -2|3|div|1|sq|div -2|3|div|1|sp|div -2|3|div|1|sqrt|div -2|3|div|1|cbrt|div -3|0|mult|0|add -3|0|mult|0|sub -3|0|mult|0|abd -3|0|div|0|cb|div -3|0|div|2|cos|mult -3|0|div|2|cos|div -3|0|div|2|1|mult|mult -3|0|div|2|1|mult|div -3|0|div|2|cbrt|div -3|0|div|3|abs|div -3|0|div|3|sin|div -3|0|div|3|cos|div -3|0|div|3|2|add|div -3|0|div|3|2|sub|div -3|0|div|3|2|abd|div -3|0|div|1|cb|div -3|0|div|0|sq|div -3|0|div|2|sin|div -3|0|div|0|cbrt|div -3|0|div|0|abs|div -3|0|div|1|0|mult|div -3|0|div|1|sq|div -3|0|div|1|sp|div -3|0|div|1|sqrt|div -3|0|div|1|cbrt|div -3|0|div|2|0|mult|div -3|0|div|2|sq|div -3|0|div|2|cb|div -3|exp|2|add -3|exp|2|sub -3|0|div|cb -3|0|mult|3|2|abd|div -3|0|mult|1|cb|div -3|0|mult|0|abs|div -3|0|mult|1|sq|div -3|0|mult|1|sp|div -3|0|mult|1|sqrt|div -3|0|mult|1|cbrt|div -3|0|mult|2|sq|div -3|0|mult|2|cb|div -3|0|mult|2|sp|div -3|0|div|0|div -3|0|div|sq -3|sq|2|sq|div -3|0|div|sp -3|0|div|cbrt -3|0|div|abs -3|0|div|1|mult -3|0|div|1|div -3|0|div|2|mult -3|0|div|2|div -3|0|div|3|mult -3|0|div|3|sp|mult -3|0|div|2|abs|mult -3|0|div|2|abs|div -3|0|div|2|sin|mult -2|cbrt|0|sq|div -2|cbrt|3|sq|div -2|cbrt|3|cb|add -2|cbrt|3|cb|sub -2|cbrt|3|cb|mult -2|cbrt|3|cb|div -2|cbrt|3|abs|div -2|cbrt|3|sin|div -2|cbrt|3|cos|div -2|cbrt|3|1|mult|div -2|cbrt|3|2|add|div -2|cbrt|3|2|sub|div -2|cbrt|3|2|abd|div -2|cbrt|1|cb|div -2|cbrt|3|sq|mult -2|cbrt|0|cb|div -2|cbrt|0|cbrt|div -2|cbrt|0|abs|div -2|cbrt|1|0|mult|div -2|cbrt|1|sq|div -2|cbrt|1|sp|div -2|cbrt|1|sqrt|div -2|cbrt|1|cbrt|div -3|cbrt|0|mult -3|cbrt|0|div -3|cbrt|exp -3|cbrt|nexp -2|cbrt|2|3|div|mult -2|cbrt|2|sin|abd -2|cbrt|2|sin|mult -2|cbrt|2|sin|div -2|cbrt|2|cos|add -2|cbrt|2|cos|sub -2|cbrt|2|cos|abd -2|cbrt|2|cos|mult -2|cbrt|2|cos|div -2|cbrt|2|1|mult|mult -2|cbrt|2|1|div|mult -2|cbrt|2|3|div|add -2|cbrt|2|3|div|sub -2|cbrt|2|3|div|abd -3|cbrt|inv -2|cbrt|3|0|mult|mult -2|cbrt|3|0|mult|div -2|cbrt|3|0|div|mult -2|cbrt|3|exp|add -2|cbrt|3|exp|sub -2|cbrt|3|exp|abd -2|cbrt|3|inv|add -2|cbrt|3|inv|sub -2|cbrt|3|inv|abd -2|cbrt|3|sq|add -2|cbrt|3|sq|sub -2|cbrt|3|sq|abd -3|cbrt|3|0|div|mult -3|cbrt|2|sin|div -3|cbrt|2|cos|add -3|cbrt|2|cos|sub -3|cbrt|2|cos|abd -3|cbrt|2|cos|mult -3|cbrt|2|cos|div -3|cbrt|2|1|mult|mult -3|cbrt|2|1|mult|div -3|cbrt|2|1|div|mult -3|cbrt|2|3|div|add -3|cbrt|2|3|div|sub -3|cbrt|2|3|div|abd -3|cbrt|3|0|mult|mult -3|cbrt|2|sin|mult -3|cbrt|3|exp|add -3|cbrt|3|exp|sub -3|cbrt|3|exp|abd -3|cbrt|3|inv|add -3|cbrt|3|inv|sub -3|cbrt|3|inv|abd -3|cbrt|3|sq|add -3|cbrt|3|sq|sub -3|cbrt|3|sq|abd -3|cbrt|3|cb|add -3|cbrt|3|cb|sub -3|cbrt|2|cbrt|add -3|cbrt|3|add -3|cbrt|sq -3|cbrt|cbrt -3|cbrt|abs -3|cbrt|sin -3|cbrt|cos -3|cbrt|1|mult -3|cbrt|1|div -3|cbrt|2|add -3|cbrt|2|sub -3|cbrt|2|abd -3|cbrt|2|mult -3|cbrt|2|div -2|cbrt|2|sin|sub -3|cbrt|3|sub -3|cbrt|3|sp|add -3|cbrt|3|sp|sub -3|cbrt|3|sp|abd -3|cbrt|2|abs|add -3|cbrt|2|abs|sub -3|cbrt|2|abs|abd -3|cbrt|2|abs|mult -3|cbrt|2|abs|div -3|cbrt|2|sin|add -3|cbrt|2|sin|sub -3|cbrt|2|sin|abd -3|cb|2|1|div|mult -3|cb|2|abs|div -3|cb|2|sin|add -3|cb|2|sin|sub -3|cb|2|sin|abd -3|cb|2|sin|mult -3|cb|2|sin|div -3|cb|2|cos|add -3|cb|2|cos|sub -3|cb|2|cos|abd -3|cb|2|cos|mult -3|cb|2|cos|div -3|cb|2|1|mult|mult -3|cb|2|1|mult|div -3|cb|2|abs|mult -3|cb|2|3|div|add -3|cb|2|3|div|sub -3|cb|2|3|div|abd -3|cb|3|0|mult|mult -3|cb|3|0|div|mult -3|cb|3|exp|add -3|cb|3|exp|sub -3|cb|3|exp|abd -3|cb|3|inv|add -3|cb|3|inv|sub -3|cb|3|inv|abd -3|cb|3|sq|add -3|cb|2|sub -3|sq|2|cb|div -3|cb|0|mult -3|cb|0|div -3|cb|inv -3|cb|sq -3|cb|cb -3|cb|abs -3|cb|sin -3|cb|cos -3|cb|1|mult -3|cb|1|div -3|cb|2|add -3|cb|3|sq|sub -3|cb|2|abd -3|cb|2|mult -3|cb|2|div -3|cb|3|add -3|cb|3|sub -3|cb|3|abd -3|cb|3|sp|add -3|cb|3|sp|sub -3|cb|3|sp|abd -3|cb|2|abs|add -3|cb|2|abs|sub -3|cb|2|abs|abd -2|cbrt|3|sub -2|cbrt|nexp -2|cbrt|inv -2|cbrt|sq -2|cbrt|cbrt -2|cbrt|abs -2|cbrt|sin -2|cbrt|cos -2|cbrt|1|mult -2|cbrt|1|div -2|cbrt|2|add -2|cbrt|2|sub -2|cbrt|2|abd -2|cbrt|3|add -2|cbrt|exp -2|cbrt|3|mult -2|cbrt|3|div -2|cbrt|3|sp|add -2|cbrt|3|sp|sub -2|cbrt|3|sp|abd -2|cbrt|3|sp|mult -2|cbrt|2|abs|add -2|cbrt|2|abs|sub -2|cbrt|2|abs|abd -2|cbrt|2|abs|mult -2|cbrt|2|abs|div -2|cbrt|2|sin|add -3|cb|0|cbrt|div -3|cb|3|sq|abd -3|cb|2|cbrt|div -3|cb|3|abs|div -3|cb|3|sin|div -3|cb|3|cos|div -3|cb|3|2|add|div -3|cb|3|2|sub|div -3|cb|3|2|abd|div -3|cb|1|cb|div -3|cb|0|sq|div -3|cb|0|cb|div -3|cb|0|sp|div -2|3|div|2|cos|mult -3|cb|0|abs|div -3|cb|1|0|mult|div -3|cb|1|sq|div -3|cb|1|sp|div -3|cb|1|sqrt|div -3|cb|1|cbrt|div -3|cb|2|0|mult|div -3|cb|2|sq|div -3|cb|2|cb|div -3|cb|2|sp|div -2|cbrt|0|mult -2|cbrt|0|div -2|abs|1|mult -3|sp|2|cb|div -3|sp|2|sp|div -2|abs|0|mult -2|abs|0|div -2|abs|inv -2|abs|sq -2|abs|cb -2|abs|sp -2|abs|sqrt -2|abs|cbrt -2|abs|log -2|abs|sin -2|abs|cos -3|sp|2|sq|div -2|abs|1|div -2|abs|2|add -2|abs|2|sub -2|abs|2|abd -2|abs|2|mult -2|abs|2|div -2|abs|3|add -2|abs|3|sub -2|abs|3|mult -2|abs|3|div -2|abs|3|sp|add -2|abs|3|sp|sub -3|sp|3|2|abd|div -3|sp|2|div -3|sp|3|add -3|sp|3|sub -3|sp|2|abs|div -3|sp|2|sin|div -3|sp|2|cos|div -3|sp|2|1|mult|div -3|sp|2|cbrt|div -3|sp|3|abs|div -3|sp|3|sin|div -3|sp|3|cos|div -3|sp|3|2|add|div -3|sp|3|2|sub|div -2|abs|3|sp|abd -3|sp|1|cb|div -3|sp|0|sq|div -3|sp|0|cb|div -3|sp|0|sp|div -3|sp|0|cbrt|div -3|sp|0|abs|div -3|sp|1|0|mult|div -3|sp|1|sq|div -3|sp|1|sp|div -3|sp|1|sqrt|div -3|sp|1|cbrt|div -3|sp|2|0|mult|div -2|sin|sp -2|abs|1|sp|div -2|abs|1|sqrt|div -2|abs|1|cbrt|div -2|abs|2|0|mult|div -2|abs|2|sq|div -2|abs|2|cb|div -2|sin|0|mult -2|sin|0|div -2|sin|exp -2|sin|nexp -2|sin|inv -2|sin|sq -2|sin|cb -2|abs|1|sq|div -2|sin|cbrt -2|sin|abs -2|sin|1|mult -2|sin|1|div -2|sin|2|add -2|sin|2|sub -2|sin|2|abd -2|sin|2|mult -2|sin|2|div -2|sin|3|add -2|sin|3|sub -2|sin|3|mult -2|abs|3|cos|div -2|abs|3|sp|mult -2|abs|3|sp|div -2|abs|2|sin|div -2|abs|2|cos|div -2|abs|2|1|mult|div -2|abs|3|0|mult|div -2|abs|3|sq|div -2|abs|3|cb|div -2|abs|2|cbrt|div -2|abs|3|cbrt|div -2|abs|3|abs|div -2|abs|3|sin|div -3|sp|2|mult -2|abs|3|1|mult|div -2|abs|3|2|add|div -2|abs|3|2|sub|div -2|abs|3|2|abd|div -2|abs|3|2|mult|div -2|abs|1|cb|div -2|abs|0|sq|div -2|abs|0|cb|div -2|abs|0|sp|div -2|abs|0|cbrt|div -2|abs|0|abs|div -2|abs|1|0|mult|div -1|0|sq|div -1|2|cos|div -1|3|0|mult|div -1|3|sq|div -1|3|cb|div -1|2|cbrt|div -1|3|cbrt|div -1|3|abs|div -1|3|sin|div -1|3|cos|div -1|3|2|add|div -1|3|2|sub|div -1|3|2|abd|div -1|3|2|mult|div -1|2|sin|div -1|0|cb|div -1|0|cbrt|div -1|0|abs|div -1|2|0|mult|div -1|2|sq|div -1|2|cb|div -2|3|sp|div -2|2|abs|div -2|2|sin|div -2|2|cos|div -2|3|0|mult|div -2|3|sq|div -0|3|2|add|div -0|2|abs|div -0|2|sin|div -0|2|cos|div -0|2|1|mult|div -0|3|sq|div -0|3|cb|div -0|2|cbrt|div -0|3|cbrt|div -0|3|abs|div -0|3|sin|div -0|3|cos|div -0|3|1|mult|div -2|3|cb|div -0|3|2|sub|div -0|3|2|abd|div -0|3|2|mult|div -0|1|cb|div -0|0|abs|div -0|1|sq|div -0|1|sp|div -0|1|sqrt|div -0|1|cbrt|div -0|2|sq|div -0|2|cb|div -1|2|abs|div -3|2|0|mult|div -3|3|2|add|div -3|3|2|sub|div -3|3|2|abd|div -3|1|cb|div -3|0|sq|div -3|0|cb|div -3|0|cbrt|div -3|0|abs|div -3|1|0|mult|div -3|1|sq|div -3|1|sp|div -3|1|sqrt|div -3|1|cbrt|div -3|3|cos|div -3|2|sq|div -3|2|cb|div -3|sp|0|mult -3|sp|0|div -3|sp|inv -3|sp|sq -3|sp|sin -3|sp|cos -3|sp|1|mult -3|sp|1|div -3|sp|2|add -3|sp|2|sub -2|0|cbrt|div -2|3|cbrt|div -2|3|abs|div -2|3|sin|div -2|3|cos|div -2|3|1|mult|div -2|3|2|add|div -2|3|2|sub|div -2|3|2|abd|div -2|1|cb|div -2|0|sq|div -2|0|cb|div -2|0|sp|div -2|sin|3|div -2|0|abs|div -2|1|0|mult|div -2|1|sq|div -2|1|sp|div -2|1|sqrt|div -2|1|cbrt|div -3|2|abs|div -3|2|sin|div -3|2|cos|div -3|2|1|mult|div -3|2|cbrt|div -3|3|sin|div -2|1|div|3|mult -2|1|mult|0|cb|div -2|1|mult|0|sp|div -2|1|mult|0|cbrt|div -2|1|mult|0|abs|div -2|1|div|0|mult -2|1|div|0|div -2|1|div|sq -2|1|div|cb -2|1|div|sp -2|1|div|cbrt -2|1|div|abs -2|1|div|1|div -2|1|div|2|mult -2|1|mult|0|sq|div -2|1|div|3|div -2|1|div|3|sp|mult -2|1|div|2|abs|mult -2|1|div|2|abs|div -2|1|div|2|sin|mult -2|1|div|2|sin|div -2|1|div|2|cos|mult -2|1|div|2|cos|div -2|1|div|3|0|mult|div -2|1|div|3|sq|div -2|1|div|3|cb|div -2|1|div|3|cbrt|div -2|1|mult|2|sin|div -2|1|mult|abs -2|1|mult|1|add -2|1|mult|1|sub -2|1|mult|1|abd -2|1|mult|1|mult -2|1|mult|2|mult -2|1|mult|3|mult -2|1|mult|3|div -2|1|mult|3|sp|mult -2|1|mult|3|sp|div -2|1|mult|2|abs|mult -2|1|mult|2|abs|div -2|1|mult|2|sin|mult -2|1|div|3|abs|div -2|1|mult|2|cos|mult -2|1|mult|2|cos|div -2|1|mult|3|0|mult|div -2|1|mult|3|sq|div -2|1|mult|3|cb|div -2|1|mult|3|cbrt|div -2|1|mult|3|abs|div -2|1|mult|3|sin|div -2|1|mult|3|cos|div -2|1|mult|3|2|add|div -2|1|mult|3|2|sub|div -2|1|mult|3|2|abd|div -2|3|div|2|abs|add -2|3|div|1|mult -2|3|div|1|div -2|3|div|2|add -2|3|div|2|sub -2|3|div|2|abd -2|3|div|2|mult -2|3|div|3|add -2|3|div|3|sub -2|3|div|3|abd -2|3|div|3|div -2|3|div|3|sp|add -2|3|div|3|sp|sub -2|3|div|3|sp|abd -2|3|div|cos -2|3|div|2|abs|sub -2|3|div|2|abs|abd -2|3|div|2|abs|mult -2|3|div|2|abs|div -2|3|div|2|sin|add -2|3|div|2|sin|sub -2|3|div|2|sin|abd -2|3|div|2|sin|mult -2|3|div|2|sin|div -2|3|div|2|cos|add -2|3|div|2|cos|sub -2|3|div|2|cos|abd -2|1|div|1|sq|div -2|1|div|3|sin|div -2|1|div|3|cos|div -2|1|div|3|1|mult|div -2|1|div|3|2|add|div -2|1|div|3|2|sub|div -2|1|div|3|2|abd|div -2|1|div|1|cb|div -2|1|div|0|sq|div -2|1|div|0|cb|div -2|1|div|0|cbrt|div -2|1|div|0|abs|div -2|1|div|1|0|mult|div -2|1|mult|cbrt -2|1|div|1|sp|div -2|1|div|1|sqrt|div -2|1|div|1|cbrt|div -2|3|div|0|mult -2|3|div|0|div -2|3|div|exp -2|3|div|sq -2|3|div|cb -2|3|div|sp -2|3|div|cbrt -2|3|div|abs -2|3|div|sin -2|cos|exp -2|sin|0|cb|div -2|sin|0|cbrt|div -2|sin|0|abs|div -2|sin|1|0|mult|div -2|sin|1|sq|div -2|sin|1|sp|div -2|sin|1|sqrt|div -2|sin|1|cbrt|div -2|sin|2|0|mult|div -2|sin|2|sq|div -2|sin|2|cb|div -2|cos|0|mult -2|cos|0|div -2|sin|0|sq|div -2|cos|nexp -2|cos|inv -2|cos|sq -2|cos|cb -2|cos|sp -2|cos|cbrt -2|cos|abs -2|cos|1|mult -2|cos|1|div -2|cos|2|add -2|cos|2|sub -2|cos|2|abd -2|sin|3|sq|div -2|sin|3|sp|add -2|sin|3|sp|sub -2|sin|3|sp|abd -2|sin|3|sp|mult -2|sin|2|abs|add -2|sin|2|abs|sub -2|sin|2|abs|abd -2|sin|2|abs|mult -2|sin|2|abs|div -2|sin|2|cos|div -2|sin|2|1|mult|div -2|sin|3|0|mult|div -2|cos|2|mult -2|sin|3|cb|div -2|sin|2|cbrt|div -2|sin|3|cbrt|div -2|sin|3|abs|div -2|sin|3|sin|div -2|sin|3|cos|div -2|sin|3|1|mult|div -2|sin|3|2|add|div -2|sin|3|2|sub|div -2|sin|3|2|abd|div -2|sin|3|2|mult|div -2|sin|1|cb|div -2|cos|1|sq|div -2|cos|3|sin|div -2|cos|3|cos|div -2|cos|3|1|mult|div -2|cos|3|2|add|div -2|cos|3|2|sub|div -2|cos|3|2|abd|div -2|cos|3|2|mult|div -2|cos|1|cb|div -2|cos|0|sq|div -2|cos|0|cb|div -2|cos|0|cbrt|div -2|cos|0|abs|div -2|cos|1|0|mult|div -2|cos|3|abs|div -2|cos|1|sp|div -2|cos|1|sqrt|div -2|cos|1|cbrt|div -2|cos|2|0|mult|div -2|cos|2|sq|div -2|cos|2|cb|div -2|1|mult|0|mult -2|1|mult|0|div -2|1|mult|inv -2|1|mult|sq -2|1|mult|cb -2|1|mult|sp -2|cos|2|abs|mult -2|cos|2|div -2|cos|3|add -2|cos|3|sub -2|cos|3|mult -2|cos|3|div -2|cos|3|sp|add -2|cos|3|sp|sub -2|cos|3|sp|abd -2|cos|3|sp|mult -2|cos|2|abs|add -2|cos|2|abs|sub -2|cos|2|abs|abd -3|cbrt|2|cbrt|sub -2|cos|2|abs|div -2|cos|2|sin|add -2|cos|2|sin|sub -2|cos|2|sin|abd -2|cos|2|sin|mult -2|cos|2|sin|div -2|cos|2|1|mult|div -2|cos|3|0|mult|div -2|cos|3|sq|div -2|cos|3|cb|div -2|cos|2|cbrt|div -2|cos|3|cbrt|div -3|2|sub|3|sq|sub -3|2|sub|2|3|div|sub -3|2|sub|2|3|div|abd -3|2|sub|2|3|div|mult -3|2|sub|3|0|mult|mult -3|2|sub|3|0|mult|div -3|2|sub|3|0|div|mult -3|2|sub|3|exp|add -3|2|sub|3|exp|sub -3|2|sub|3|exp|abd -3|2|sub|3|inv|add -3|2|sub|3|inv|sub -3|2|sub|3|inv|abd -3|2|sub|3|sq|add -3|2|sub|2|3|div|add -3|2|sub|3|sq|abd -3|2|sub|3|sq|mult -3|2|sub|3|sq|div -3|2|sub|3|cb|add -3|2|sub|3|cb|sub -3|2|sub|3|cb|mult -3|2|sub|3|cb|div -3|2|sub|2|cbrt|add -3|2|sub|2|cbrt|sub -3|2|sub|2|cbrt|abd -3|2|sub|2|cbrt|mult -3|2|sub|2|cbrt|div -3|2|sub|2|sin|add -3|2|sub|3|add -3|2|sub|3|mult -3|2|sub|3|div -3|2|sub|3|sp|add -3|2|sub|3|sp|sub -3|2|sub|3|sp|abd -3|2|sub|3|sp|mult -3|2|sub|3|sp|div -3|2|sub|2|abs|add -3|2|sub|2|abs|sub -3|2|sub|2|abs|abd -3|2|sub|2|abs|mult -3|2|sub|2|abs|div -3|2|sub|3|cbrt|add -3|2|sub|2|sin|sub -3|2|sub|2|sin|abd -3|2|sub|2|sin|mult -3|2|sub|2|sin|div -3|2|sub|2|cos|add -3|2|sub|2|cos|sub -3|2|sub|2|cos|abd -3|2|sub|2|cos|mult -3|2|sub|2|cos|div -3|2|sub|2|1|mult|mult -3|2|sub|2|1|mult|div -3|2|sub|2|1|div|mult -3|2|sub|2|cb|div -3|2|sub|1|cb|div -3|2|sub|0|sq|div -3|2|sub|0|cb|div -3|2|sub|0|sp|div -3|2|sub|0|cbrt|div -3|2|sub|0|abs|div -3|2|sub|1|0|mult|div -3|2|sub|1|sq|div -3|2|sub|1|sp|div -3|2|sub|1|sqrt|div -3|2|sub|1|cbrt|div -3|2|sub|2|0|mult|div -3|2|sub|2|sq|div -3|2|sub|3|2|mult|div -3|2|abd|0|mult -3|2|abd|0|div -3|2|abd|inv -3|2|abd|sq -3|2|abd|cb -3|2|abd|sp -3|2|abd|sqrt -3|2|abd|cbrt -3|2|abd|log -3|2|abd|sin -3|2|abd|cos -3|2|abd|1|mult -3|2|sub|3|sin|mult -3|2|sub|3|cbrt|sub -3|2|sub|3|cbrt|abd -3|2|sub|3|cbrt|mult -3|2|sub|3|cbrt|div -3|2|sub|3|abs|add -3|2|sub|3|abs|sub -3|2|sub|3|abs|abd -3|2|sub|3|abs|mult -3|2|sub|3|abs|div -3|2|sub|3|sin|add -3|2|sub|3|sin|sub -3|2|sub|3|sin|abd -3|2|sub|2|div -3|2|sub|3|sin|div -3|2|sub|3|cos|add -3|2|sub|3|cos|sub -3|2|sub|3|cos|abd -3|2|sub|3|cos|mult -3|2|sub|3|cos|div -3|2|sub|3|1|mult|mult -3|2|sub|3|1|mult|div -3|2|sub|3|1|div|mult -3|2|sub|3|2|add|mult -3|2|sub|3|2|add|div -3|2|sub|3|2|abd|div -3|2|add|3|sq|abd -3|2|add|2|3|div|abd -3|2|add|2|3|div|mult -3|2|add|3|0|mult|mult -3|2|add|3|0|mult|div -3|2|add|3|0|div|mult -3|2|add|3|exp|add -3|2|add|3|exp|sub -3|2|add|3|exp|abd -3|2|add|3|inv|add -3|2|add|3|inv|sub -3|2|add|3|inv|abd -3|2|add|3|sq|add -3|2|add|3|sq|sub -3|2|add|2|3|div|sub -3|2|add|3|sq|mult -3|2|add|3|sq|div -3|2|add|3|cb|add -3|2|add|3|cb|sub -3|2|add|3|cb|mult -3|2|add|3|cb|div -3|2|add|2|cbrt|add -3|2|add|2|cbrt|sub -3|2|add|2|cbrt|abd -3|2|add|2|cbrt|mult -3|2|add|2|cbrt|div -3|2|add|3|cbrt|add -3|2|add|2|sin|sub -3|2|add|3|mult -3|2|add|3|div -3|2|add|3|sp|add -3|2|add|3|sp|sub -3|2|add|3|sp|abd -3|2|add|3|sp|mult -3|2|add|3|sp|div -3|2|add|2|abs|add -3|2|add|2|abs|sub -3|2|add|2|abs|abd -3|2|add|2|abs|mult -3|2|add|2|abs|div -3|2|add|2|sin|add -3|2|add|3|cbrt|sub -3|2|add|2|sin|abd -3|2|add|2|sin|mult -3|2|add|2|sin|div -3|2|add|2|cos|add -3|2|add|2|cos|sub -3|2|add|2|cos|abd -3|2|add|2|cos|mult -3|2|add|2|cos|div -3|2|add|2|1|mult|mult -3|2|add|2|1|mult|div -3|2|add|2|1|div|mult -3|2|add|2|3|div|add -3|2|sub|inv -3|2|add|0|cb|div -3|2|add|0|cbrt|div -3|2|add|0|abs|div -3|2|add|1|0|mult|div -3|2|add|1|sq|div -3|2|add|1|sp|div -3|2|add|1|sqrt|div -3|2|add|1|cbrt|div -3|2|add|2|0|mult|div -3|2|add|2|sq|div -3|2|add|2|cb|div -3|2|sub|0|mult -3|2|sub|0|div -3|2|add|0|sq|div -3|2|sub|sq -3|2|sub|cb -3|2|sub|sp -3|2|sub|cbrt -3|2|sub|abs -3|2|sub|sin -3|2|sub|cos -3|2|sub|1|mult -3|2|sub|1|div -3|2|sub|2|sub -3|2|sub|2|abd -3|2|sub|2|mult -3|2|add|3|sin|div -3|2|add|3|cbrt|abd -3|2|add|3|cbrt|mult -3|2|add|3|cbrt|div -3|2|add|3|abs|add -3|2|add|3|abs|sub -3|2|add|3|abs|abd -3|2|add|3|abs|mult -3|2|add|3|abs|div -3|2|add|3|sin|add -3|2|add|3|sin|sub -3|2|add|3|sin|abd -3|2|add|3|sin|mult -3|2|abd|1|div -3|2|add|3|cos|add -3|2|add|3|cos|sub -3|2|add|3|cos|abd -3|2|add|3|cos|mult -3|2|add|3|cos|div -3|2|add|3|1|mult|mult -3|2|add|3|1|mult|div -3|2|add|3|1|div|mult -3|2|add|3|2|sub|div -3|2|add|3|2|abd|div -3|2|add|3|2|mult|div -3|2|add|1|cb|div -3|2|mult|3|inv|sub -3|2|mult|2|cos|mult -3|2|mult|2|cos|div -3|2|mult|2|1|mult|mult -3|2|mult|2|1|div|mult -3|2|mult|2|3|div|add -3|2|mult|2|3|div|sub -3|2|mult|2|3|div|abd -3|2|mult|3|0|mult|mult -3|2|mult|3|0|div|mult -3|2|mult|3|exp|add -3|2|mult|3|exp|sub -3|2|mult|3|exp|abd -3|2|mult|3|inv|add -3|2|mult|2|cos|abd -3|2|mult|3|inv|abd -3|2|mult|3|sq|add -3|2|mult|3|sq|sub -3|2|mult|3|sq|abd -3|2|mult|3|sq|mult -3|2|mult|3|cb|add -3|2|mult|3|cb|sub -3|2|mult|3|cb|abd -3|2|mult|3|cb|mult -3|2|mult|2|cbrt|add -3|2|mult|2|cbrt|sub -3|2|mult|2|cbrt|abd -3|2|mult|3|sp|mult -3|2|mult|1|mult -3|2|mult|1|div -3|2|mult|2|add -3|2|mult|2|sub -3|2|mult|2|abd -3|2|mult|2|mult -3|2|mult|3|add -3|2|mult|3|sub -3|2|mult|3|abd -3|2|mult|3|mult -3|2|mult|3|sp|add -3|2|mult|3|sp|sub -3|2|mult|3|sp|abd -3|2|mult|2|cbrt|mult -3|2|mult|2|abs|add -3|2|mult|2|abs|sub -3|2|mult|2|abs|abd -3|2|mult|2|abs|mult -3|2|mult|2|abs|div -3|2|mult|2|sin|add -3|2|mult|2|sin|sub -3|2|mult|2|sin|abd -3|2|mult|2|sin|mult -3|2|mult|2|sin|div -3|2|mult|2|cos|add -3|2|mult|2|cos|sub -3|2|mult|0|sp|div -3|2|mult|3|2|sub|add -3|2|mult|3|2|sub|sub -3|2|mult|3|2|sub|abd -3|2|mult|3|2|sub|mult -3|2|mult|3|2|sub|div -3|2|mult|3|2|abd|add -3|2|mult|3|2|abd|sub -3|2|mult|3|2|abd|abd -3|2|mult|3|2|abd|mult -3|2|mult|3|2|abd|div -3|2|mult|1|cb|div -3|2|mult|0|sq|div -3|2|mult|0|cb|div -3|2|mult|3|2|add|div -3|2|mult|0|cbrt|div -3|2|mult|0|abs|div -3|2|mult|1|0|mult|div -3|2|mult|1|sq|div -3|2|mult|1|sp|div -3|2|mult|1|sqrt|div -3|2|mult|1|cbrt|div -3|2|div|0|mult -3|2|div|0|div -3|2|div|exp -3|2|div|nexp -3|2|div|sq -3|2|mult|3|sin|mult -3|2|mult|3|cbrt|add -3|2|mult|3|cbrt|sub -3|2|mult|3|cbrt|abd -3|2|mult|3|cbrt|mult -3|2|mult|3|abs|add -3|2|mult|3|abs|sub -3|2|mult|3|abs|abd -3|2|mult|3|abs|mult -3|2|mult|3|abs|div -3|2|mult|3|sin|add -3|2|mult|3|sin|sub -3|2|mult|3|sin|abd -3|2|mult|cos -3|2|mult|3|sin|div -3|2|mult|3|cos|add -3|2|mult|3|cos|sub -3|2|mult|3|cos|abd -3|2|mult|3|cos|mult -3|2|mult|3|cos|div -3|2|mult|3|1|mult|mult -3|2|mult|3|1|div|mult -3|2|mult|3|2|add|add -3|2|mult|3|2|add|sub -3|2|mult|3|2|add|abd -3|2|mult|3|2|add|mult -3|2|abd|3|sq|add -3|2|abd|2|1|mult|mult -3|2|abd|2|1|mult|div -3|2|abd|2|1|div|mult -3|2|abd|2|3|div|add -3|2|abd|2|3|div|sub -3|2|abd|2|3|div|mult -3|2|abd|3|0|mult|mult -3|2|abd|3|0|mult|div -3|2|abd|3|0|div|mult -3|2|abd|3|exp|add -3|2|abd|3|exp|sub -3|2|abd|3|inv|add -3|2|abd|3|inv|sub -3|2|abd|2|cos|div -3|2|abd|3|sq|sub -3|2|abd|3|sq|abd -3|2|abd|3|sq|mult -3|2|abd|3|sq|div -3|2|abd|3|cb|add -3|2|abd|3|cb|sub -3|2|abd|3|cb|mult -3|2|abd|3|cb|div -3|2|abd|2|cbrt|add -3|2|abd|2|cbrt|sub -3|2|abd|2|cbrt|mult -3|2|abd|2|cbrt|div -3|2|abd|3|sp|div -3|2|abd|2|add -3|2|abd|2|sub -3|2|abd|2|mult -3|2|abd|2|div -3|2|abd|3|add -3|2|abd|3|sub -3|2|abd|3|mult -3|2|abd|3|div -3|2|abd|3|sp|add -3|2|abd|3|sp|sub -3|2|abd|3|sp|abd -3|2|abd|3|sp|mult -3|2|abd|3|cbrt|add -3|2|abd|2|abs|add -3|2|abd|2|abs|sub -3|2|abd|2|abs|abd -3|2|abd|2|abs|mult -3|2|abd|2|abs|div -3|2|abd|2|sin|add -3|2|abd|2|sin|sub -3|2|abd|2|sin|mult -3|2|abd|2|sin|div -3|2|abd|2|cos|add -3|2|abd|2|cos|sub -3|2|abd|2|cos|mult -3|2|abd|1|cbrt|div -3|2|abd|3|2|sub|mult -3|2|abd|3|2|sub|div -3|2|abd|3|2|mult|div -3|2|abd|1|cb|div -3|2|abd|0|sq|div -3|2|abd|0|cb|div -3|2|abd|0|sp|div -3|2|abd|0|cbrt|div -3|2|abd|0|abs|div -3|2|abd|1|0|mult|div -3|2|abd|1|sq|div -3|2|abd|1|sp|div -3|2|abd|1|sqrt|div -3|2|abd|3|2|sub|abd -3|2|abd|2|0|mult|div -3|2|abd|2|sq|div -3|2|abd|2|cb|div -3|2|mult|0|mult -3|2|mult|0|div -3|2|mult|inv -3|2|mult|sq -3|2|mult|cb -3|2|mult|sp -3|2|mult|cbrt -3|2|mult|abs -3|2|mult|sin -3|2|abd|3|cos|add -3|2|abd|3|cbrt|sub -3|2|abd|3|cbrt|mult -3|2|abd|3|cbrt|div -3|2|abd|3|abs|add -3|2|abd|3|abs|sub -3|2|abd|3|abs|abd -3|2|abd|3|abs|mult -3|2|abd|3|abs|div -3|2|abd|3|sin|add -3|2|abd|3|sin|sub -3|2|abd|3|sin|mult -3|2|abd|3|sin|div -3|2|add|3|add -3|2|abd|3|cos|sub -3|2|abd|3|cos|mult -3|2|abd|3|cos|div -3|2|abd|3|1|mult|mult -3|2|abd|3|1|mult|div -3|2|abd|3|1|div|mult -3|2|abd|3|2|add|add -3|2|abd|3|2|add|sub -3|2|abd|3|2|add|mult -3|2|abd|3|2|add|div -3|2|abd|3|2|sub|add -3|2|abd|3|2|sub|sub -3|sin|2|cos|sub -3|sin|3|sp|abd -3|sin|3|sp|mult -3|sin|2|abs|add -3|sin|2|abs|sub -3|sin|2|abs|abd -3|sin|2|abs|mult -3|sin|2|abs|div -3|sin|2|sin|add -3|sin|2|sin|sub -3|sin|2|sin|abd -3|sin|2|sin|mult -3|sin|2|sin|div -3|sin|2|cos|add -3|sin|3|sp|sub -3|sin|2|cos|abd -3|sin|2|cos|mult -3|sin|2|cos|div -3|sin|2|1|mult|mult -3|sin|2|1|mult|div -3|sin|2|1|div|mult -3|sin|2|3|div|add -3|sin|2|3|div|sub -3|sin|2|3|div|abd -3|sin|2|3|div|mult -3|sin|3|0|mult|mult -3|sin|3|0|mult|div -3|sin|abs -3|abs|1|cbrt|div -3|abs|2|0|mult|div -3|abs|2|sq|div -3|abs|2|cb|div -3|sin|0|mult -3|sin|0|div -3|sin|exp -3|sin|nexp -3|sin|inv -3|sin|sq -3|sin|cb -3|sin|sp -3|sin|cbrt -3|sin|3|0|div|mult -3|sin|1|mult -3|sin|1|div -3|sin|2|add -3|sin|2|sub -3|sin|2|abd -3|sin|2|mult -3|sin|2|div -3|sin|3|add -3|sin|3|sub -3|sin|3|mult -3|sin|3|div -3|sin|3|sp|add -3|sin|0|abs|div -3|sin|3|abs|abd -3|sin|3|abs|mult -3|sin|3|abs|div -3|sin|3|cos|div -3|sin|3|1|mult|div -3|sin|3|2|add|div -3|sin|3|2|sub|div -3|sin|3|2|abd|div -3|sin|3|2|mult|div -3|sin|1|cb|div -3|sin|0|sq|div -3|sin|0|cb|div -3|sin|0|cbrt|div -3|sin|3|abs|sub -3|sin|1|0|mult|div -3|sin|1|sq|div -3|sin|1|sp|div -3|sin|1|sqrt|div -3|sin|1|cbrt|div -3|sin|2|0|mult|div -3|sin|2|sq|div -3|sin|2|cb|div -3|cos|0|mult -3|cos|0|div -3|cos|exp -3|cos|nexp -3|sin|3|cb|sub -3|sin|3|exp|add -3|sin|3|exp|sub -3|sin|3|exp|abd -3|sin|3|inv|add -3|sin|3|inv|sub -3|sin|3|inv|abd -3|sin|3|sq|add -3|sin|3|sq|sub -3|sin|3|sq|abd -3|sin|3|sq|mult -3|sin|3|sq|div -3|sin|3|cb|add -3|abs|1|sqrt|div -3|sin|3|cb|mult -3|sin|3|cb|div -3|sin|2|cbrt|add -3|sin|2|cbrt|sub -3|sin|2|cbrt|abd -3|sin|2|cbrt|mult -3|sin|2|cbrt|div -3|sin|3|cbrt|add -3|sin|3|cbrt|sub -3|sin|3|cbrt|mult -3|sin|3|cbrt|div -3|sin|3|abs|add -3|abs|2|mult -3|abs|sq -3|abs|cb -3|abs|sp -3|abs|sqrt -3|abs|cbrt -3|abs|log -3|abs|sin -3|abs|cos -3|abs|1|mult -3|abs|1|div -3|abs|2|add -3|abs|2|sub -3|abs|2|abd -3|abs|inv -3|abs|2|div -3|abs|3|sub -3|abs|3|mult -3|abs|3|sp|add -3|abs|3|sp|sub -3|abs|3|sp|abd -3|abs|3|sp|mult -3|abs|2|abs|add -3|abs|2|abs|sub -3|abs|2|abs|abd -3|abs|2|abs|mult -3|abs|2|abs|div -3|cbrt|0|cbrt|div -3|cbrt|2|cbrt|abd -3|cbrt|2|cbrt|mult -3|cbrt|2|cbrt|div -3|cbrt|3|abs|div -3|cbrt|3|sin|div -3|cbrt|3|cos|div -3|cbrt|3|2|add|div -3|cbrt|3|2|sub|div -3|cbrt|3|2|abd|div -3|cbrt|1|cb|div -3|cbrt|0|sq|div -3|cbrt|0|cb|div -3|abs|2|sin|add -3|cbrt|0|abs|div -3|cbrt|1|0|mult|div -3|cbrt|1|sq|div -3|cbrt|1|sp|div -3|cbrt|1|sqrt|div -3|cbrt|1|cbrt|div -3|cbrt|2|0|mult|div -3|cbrt|2|sq|div -3|cbrt|2|cb|div -3|abs|0|mult -3|abs|0|div -3|abs|nexp -3|abs|3|1|mult|div -3|abs|3|cb|sub -3|abs|3|cb|mult -3|abs|3|cb|div -3|abs|2|cbrt|add -3|abs|2|cbrt|sub -3|abs|2|cbrt|mult -3|abs|2|cbrt|div -3|abs|3|cbrt|add -3|abs|3|cbrt|sub -3|abs|3|cbrt|mult -3|abs|3|cbrt|div -3|abs|3|sin|div -3|abs|3|cos|div -3|abs|3|cb|add -3|abs|3|2|add|div -3|abs|3|2|sub|div -3|abs|3|2|abd|div -3|abs|3|2|mult|div -3|abs|1|cb|div -3|abs|0|sq|div -3|abs|0|cb|div -3|abs|0|cbrt|div -3|abs|0|abs|div -3|abs|1|0|mult|div -3|abs|1|sq|div -3|abs|1|sp|div -3|abs|2|3|div|mult -3|abs|2|sin|sub -3|abs|2|sin|mult -3|abs|2|sin|div -3|abs|2|cos|add -3|abs|2|cos|sub -3|abs|2|cos|mult -3|abs|2|cos|div -3|abs|2|1|mult|mult -3|abs|2|1|mult|div -3|abs|2|1|div|mult -3|abs|2|3|div|add -3|abs|2|3|div|sub -3|cos|inv -3|abs|3|0|mult|mult -3|abs|3|0|mult|div -3|abs|3|0|div|mult -3|abs|3|exp|add -3|abs|3|exp|sub -3|abs|3|inv|add -3|abs|3|inv|sub -3|abs|3|sq|add -3|abs|3|sq|sub -3|abs|3|sq|abd -3|abs|3|sq|mult -3|abs|3|sq|div -3|1|mult|2|cb|div -3|1|mult|3|sin|div -3|1|mult|3|cos|mult -3|1|mult|3|cos|div -3|1|mult|3|2|add|div -3|1|mult|3|2|sub|div -3|1|mult|3|2|abd|div -3|1|mult|0|sq|div -3|1|mult|0|cb|div -3|1|mult|0|sp|div -3|1|mult|0|cbrt|div -3|1|mult|0|abs|div -3|1|mult|2|0|mult|div -3|1|mult|2|sq|div -3|1|mult|3|sin|mult -3|1|div|0|mult -3|1|div|0|div -3|1|div|sq -3|1|div|cb -3|1|div|sp -3|1|div|cbrt -3|1|div|abs -3|1|div|1|div -3|1|div|2|mult -3|1|div|2|div -3|1|div|3|mult -3|1|div|3|sp|mult -3|1|mult|2|1|mult|add -3|1|mult|1|sub -3|1|mult|1|abd -3|1|mult|1|mult -3|1|mult|2|mult -3|1|mult|2|div -3|1|mult|3|mult -3|1|mult|3|sp|mult -3|1|mult|2|abs|mult -3|1|mult|2|abs|div -3|1|mult|2|sin|mult -3|1|mult|2|sin|div -3|1|mult|2|cos|mult -3|1|mult|2|cos|div -3|1|div|2|abs|mult -3|1|mult|2|1|mult|sub -3|1|mult|2|1|mult|abd -3|1|mult|2|1|mult|mult -3|1|mult|3|0|mult|mult -3|1|mult|3|0|div|mult -3|1|mult|3|sq|mult -3|1|mult|3|cb|mult -3|1|mult|2|cbrt|mult -3|1|mult|2|cbrt|div -3|1|mult|3|cbrt|mult -3|1|mult|3|abs|mult -3|1|mult|3|abs|div -3|2|add|inv -3|1|div|0|cb|div -3|1|div|0|cbrt|div -3|1|div|0|abs|div -3|1|div|1|0|mult|div -3|1|div|1|sq|div -3|1|div|1|sp|div -3|1|div|1|sqrt|div -3|1|div|1|cbrt|div -3|1|div|2|0|mult|div -3|1|div|2|sq|div -3|1|div|2|cb|div -3|2|add|0|mult -3|2|add|0|div -3|1|div|0|sq|div -3|2|add|sq -3|2|add|cb -3|2|add|sp -3|2|add|cbrt -3|2|add|abs -3|2|add|sin -3|2|add|cos -3|2|add|1|mult -3|2|add|1|div -3|2|add|2|add -3|2|add|2|mult -3|2|add|2|div -3|1|div|2|cbrt|mult -3|1|div|2|abs|div -3|1|div|2|sin|mult -3|1|div|2|sin|div -3|1|div|2|cos|mult -3|1|div|2|cos|div -3|1|div|2|1|mult|div -3|1|div|2|1|div|add -3|1|div|2|1|div|sub -3|1|div|2|1|div|abd -3|1|div|3|0|mult|mult -3|1|div|3|sq|mult -3|1|div|3|cb|mult -3|1|mult|1|add -3|1|div|2|cbrt|div -3|1|div|3|cbrt|mult -3|1|div|3|abs|mult -3|1|div|3|abs|div -3|1|div|3|sin|mult -3|1|div|3|sin|div -3|1|div|3|cos|mult -3|1|div|3|cos|div -3|1|div|3|2|add|div -3|1|div|3|2|sub|div -3|1|div|3|2|abd|div -3|1|div|1|cb|div -3|cos|2|3|div|sub -3|cos|2|sin|sub -3|cos|2|sin|abd -3|cos|2|sin|mult -3|cos|2|sin|div -3|cos|2|cos|add -3|cos|2|cos|sub -3|cos|2|cos|abd -3|cos|2|cos|mult -3|cos|2|cos|div -3|cos|2|1|mult|mult -3|cos|2|1|mult|div -3|cos|2|1|div|mult -3|cos|2|3|div|add -3|cos|2|sin|add -3|cos|2|3|div|abd -3|cos|2|3|div|mult -3|cos|3|0|mult|mult -3|cos|3|0|mult|div -3|cos|3|0|div|mult -3|cos|3|exp|add -3|cos|3|exp|sub -3|cos|3|exp|abd -3|cos|3|inv|add -3|cos|3|inv|sub -3|cos|3|inv|abd -3|cos|3|sq|add -3|cos|3|add -3|cos|sq -3|cos|cb -3|cos|sp -3|cos|cbrt -3|cos|abs -3|cos|1|mult -3|cos|1|div -3|cos|2|add -3|cos|2|sub -3|cos|2|abd -3|cos|2|mult -3|cos|2|div -3|cos|3|sq|sub -3|cos|3|sub -3|cos|3|mult -3|cos|3|div -3|cos|3|sp|add -3|cos|3|sp|sub -3|cos|3|sp|abd -3|cos|3|sp|mult -3|cos|2|abs|add -3|cos|2|abs|sub -3|cos|2|abs|abd -3|cos|2|abs|mult -3|cos|2|abs|div -3|cos|1|sqrt|div -3|cos|3|1|mult|div -3|cos|3|2|add|div -3|cos|3|2|sub|div -3|cos|3|2|abd|div -3|cos|3|2|mult|div -3|cos|1|cb|div -3|cos|0|sq|div -3|cos|0|cb|div -3|cos|0|cbrt|div -3|cos|0|abs|div -3|cos|1|0|mult|div -3|cos|1|sq|div -3|cos|1|sp|div -3|cos|3|sin|div -3|cos|1|cbrt|div -3|cos|2|0|mult|div -3|cos|2|sq|div -3|cos|2|cb|div -3|1|mult|0|mult -3|1|mult|0|div -3|1|mult|inv -3|1|mult|sq -3|1|mult|cb -3|1|mult|sp -3|1|mult|cbrt -3|1|mult|abs -3|cos|3|cbrt|add -3|cos|3|sq|abd -3|cos|3|sq|mult -3|cos|3|sq|div -3|cos|3|cb|add -3|cos|3|cb|sub -3|cos|3|cb|mult -3|cos|3|cb|div -3|cos|2|cbrt|add -3|cos|2|cbrt|sub -3|cos|2|cbrt|abd -3|cos|2|cbrt|mult -3|cos|2|cbrt|div -0|3|sp|div -3|cos|3|cbrt|sub -3|cos|3|cbrt|mult -3|cos|3|cbrt|div -3|cos|3|abs|add -3|cos|3|abs|sub -3|cos|3|abs|abd -3|cos|3|abs|mult -3|cos|3|abs|div -3|cos|3|sin|add -3|cos|3|sin|sub -3|cos|3|sin|abd -3|cos|3|sin|mult diff --git a/tests/exec_test/default/sisso.json b/tests/exec_test/default/sisso.json index 32f03e6a802f677052f974bc3401afa1a98252ee..de149bf935a3f909b3a5f589ce096486b41e6149 100644 --- a/tests/exec_test/default/sisso.json +++ b/tests/exec_test/default/sisso.json @@ -1,6 +1,6 @@ { "desc_dim": 2, - "n_sis_select": 1, + "n_sis_select": 2, "max_rung": 2, "n_residual": 1, "data_file": "../data.csv", diff --git a/tests/exec_test/gen_proj/sisso.json b/tests/exec_test/gen_proj/sisso.json index dc65c132bc8d780fa99c16cdf6a25779dc6f0bbe..4ca1df07872f765bb4c28ec586831b0af56708f5 100644 --- a/tests/exec_test/gen_proj/sisso.json +++ b/tests/exec_test/gen_proj/sisso.json @@ -1,16 +1,16 @@ { "desc_dim": 2, - "n_sis_select": 1, + "n_sis_select": 2, "max_rung": 2, "n_residual": 1, "data_file": "../data.csv", "data_file_relatice_to_json": true, "property_key": "Prop", "task_key": "Task", - "leave_out_frac": 0.0, + "leave_out_frac": 0.05, "n_models_store": 1, "n_rung_generate": 1, - "opset": ["add", "sub", "abs_diff", "mult", "div", "inv", "abs", "exp", "log", "sin", "cos", "sq", "cb", "six_pow", "sqrt", "cbrt", "neg_exp"], - "param_opset": [], - "fix_intercept": false + "leave_out_inds": [0, 1, 2, 60, 61], + "fix_intercept": false, + "phi_out_file": "feature_space/phi.txt" } diff --git a/tests/exec_test/reparam_gen_proj/sisso.json b/tests/exec_test/reparam_gen_proj/sisso.json index 90182dad19e3288700eddcb2c4fa45cb076a0e61..6829a1ee034417909ff34a027c24d147a3418408 100644 --- a/tests/exec_test/reparam_gen_proj/sisso.json +++ b/tests/exec_test/reparam_gen_proj/sisso.json @@ -1,6 +1,6 @@ { "desc_dim": 2, - "n_sis_select": 21, + "n_sis_select": 10, "max_rung": 1, "n_residual": 5, "data_file": "data.csv", @@ -10,7 +10,7 @@ "n_models_store": 5, "n_rung_generate": 1, "leave_out_inds": [], - "opset": ["sq"], + "opset": ["sq", "cb"], "param_opset": [ "add", "sub", diff --git a/tests/googletest/feature_creation/feature_generation/test_feat_node.cc b/tests/googletest/feature_creation/feature_generation/test_feat_node.cc index 46106f91c9d4dcd667589254995b920817f80c68..c36dca0d87079a11c3490479c829033bb6575862 100644 --- a/tests/googletest/feature_creation/feature_generation/test_feat_node.cc +++ b/tests/googletest/feature_creation/feature_generation/test_feat_node.cc @@ -22,18 +22,18 @@ namespace protected: void SetUp() override { - node_value_arrs::initialize_values_arr({4}, {1}, 4, 2, false); + node_value_arrs::initialize_values_arr({8}, {1}, 4, 2, false); - _value_1 = {1.0, 2.0, 3.0, 4.0}; + _value_1 = {2, 4, 4, 4, 5, 5, 7, 9}; _test_value_1 = {5.0}; - _value_2 = {10.0, 10.0, 10.0, 1.0}; + _value_2 = {10.0, 10.0, 10.0, 1.0, 10.0, 10.0, 10.0, 1.0}; _test_value_2 = {10.0}; - _value_3 = {1.0, 2.0, 3.0, 1.0}; + _value_3 = {1.0, 2.0, 3.0, 1.0, 1.0, 4.0, 5.0, 1.0}; _test_value_3 = {5.0}; - _value_4 = {1.0, 2.0, 3.0}; + _value_4 = {1.0, 2.0, 3.0,}; _test_value_4 = {}; } @@ -201,4 +201,24 @@ namespace #endif } + + TEST_F(FeatureNodeTest, StandValTests) + { + std::vector<double> test_std = {-1.5, -0.5, -0.5, -0.5, 0, 0, 1, 2}; + + std::shared_ptr<FeatureNode> feat_1 = std::make_shared<FeatureNode>( + 0, + "A", + _value_1, + _test_value_1, + Unit("m") + ); + + double* stand_value_ptr = feat_1->stand_value_ptr(); + std::transform(test_std.begin(), test_std.end(), stand_value_ptr, test_std.begin(), std::minus<double>()); + EXPECT_TRUE(std::all_of(test_std.begin(), test_std.end(), [](double val){return std::abs(val) < 1e-10;})); + + stand_value_ptr = feat_1->stand_test_value_ptr(); + EXPECT_LT(std::abs(*stand_value_ptr), 1e-10); + } } diff --git a/tests/googletest/feature_creation/feature_space/test_feat_space.cc b/tests/googletest/feature_creation/feature_space/test_feat_space.cc index 87d3212e0f075ea297bac43df30fa357197e3898..8b365ab8a667832c275b50c893086b813d29bfc0 100644 --- a/tests/googletest/feature_creation/feature_space/test_feat_space.cc +++ b/tests/googletest/feature_creation/feature_space/test_feat_space.cc @@ -244,4 +244,115 @@ namespace EXPECT_THROW(feat_space.sis(_prop), std::logic_error); } + TEST_F(FeatSpaceTest, RemoveDuplicatesTest) + { + node_value_arrs::finalize_values_arr(); + node_value_arrs::initialize_values_arr({10}, {0}, 8, 0, false); + + InputParser inputs; + inputs.set_task_sizes_train({10}); + inputs.set_allowed_ops({"sq"}); + inputs.set_allowed_param_ops({}); + inputs.set_cross_cor_max(1.0); + inputs.set_l_bound(1e-50); + inputs.set_u_bound(1e50); + inputs.set_n_rung_store(0); + inputs.set_max_rung(0); + inputs.set_n_sis_select(10); + inputs.set_n_rung_generate(0); + inputs.set_max_param_depth(0); + inputs.set_reparam_residual(false); + inputs.set_calc_type("regression"); + + std::vector<double> value_1 = { 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + std::vector<double> value_2 = { 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + std::vector<double> value_3 = { 1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + std::vector<double> value_4 = { 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0}; + std::vector<double> value_6 = { 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, -1.0, 1.0, 0.0, 0.0}; + std::vector<double> value_5 = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}; + std::vector<double> prop = { 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, -1.0, 1.0, 0.0, 0.0}; + inputs.set_prop_train(prop); + + FeatureNode feat_1(0, "A", value_1, std::vector<double>(), Unit()); + FeatureNode feat_2(1, "B", value_2, std::vector<double>(), Unit()); + FeatureNode feat_3(2, "C", value_3, std::vector<double>(), Unit()); + FeatureNode feat_4(3, "D", value_4, std::vector<double>(), Unit()); + FeatureNode feat_5(4, "E", value_5, std::vector<double>(), Unit()); + FeatureNode feat_6(5, "F", value_6, std::vector<double>(), Unit()); + FeatureNode feat_7(6, "G", value_4, std::vector<double>(), Unit()); + FeatureNode feat_8(7, "H", value_1, std::vector<double>(), Unit()); + + std::vector<FeatureNode> phi_0 = { + feat_1, + feat_2, + feat_3, + feat_4, + feat_5, + feat_6, + feat_7, + feat_8 + }; + inputs.set_phi_0(phi_0); + + std::vector<node_ptr> phi(8, nullptr); + std::transform(phi_0.begin(), phi_0.end(), phi.begin(), [](FeatureNode feat){return std::make_shared<FeatureNode>(feat);}); + FeatureSpace feat_space(inputs); + + feat_space.remove_duplicate_features(phi, 2); + EXPECT_EQ(phi.size(), 7); + + feat_space.remove_duplicate_features(phi, 0); + EXPECT_EQ(phi.size(), 6); + } + + + #ifdef PARAMETERIZE + TEST_F(FeatSpaceTest, ReorderByNparamsTest) + { + nlopt_wrapper::MAX_PARAM_DEPTH = 2; + node_value_arrs::initialize_param_storage(); + _inputs.set_max_rung(2); + _inputs.set_max_param_depth(2); + _inputs.set_n_rung_store(0); + _inputs.set_n_rung_generate(0); + _inputs.set_prop_train(_prop); + + FeatureSpace feat_space(_inputs); + std::vector<node_ptr> phi(8); + + phi[0] = feat_space.phi0()[0]; + phi[1] = feat_space.phi0()[1]; + phi[2] = feat_space.phi0()[2]; + phi[0]->set_value(); + phi[1]->set_value(); + phi[2]->set_value(); + + double* val_ptr = feat_space.phi0()[1]->value_ptr(); + + std::vector<double> prop_cb(_prop.size(), 0.0); + std::transform(val_ptr, val_ptr + prop_cb.size(), prop_cb.begin(), [](double val){return std::pow(val + 2.0, 3.0);}); + std::shared_ptr<NLOptimizer> optimizer_cb = nlopt_wrapper::get_optimizer("regression", _inputs.task_sizes_train(), prop_cb, 2); + + std::vector<double> prop_lor(_prop.size(), 0.0); + std::transform(val_ptr, val_ptr + prop_lor.size(), prop_lor.begin(), [](double val){return 1.0 / (2.0 + std::pow(val, 2.0));}); + std::shared_ptr<NLOptimizer> optimizer_lor = nlopt_wrapper::get_optimizer("regression", _inputs.task_sizes_train(), prop_lor, 2); + + phi[3] = std::make_shared<CbNode>(phi[1], 5, 1e-50, 1e50); + phi[4] = std::make_shared<CbParamNode>(phi[1], 6, 1e-50, 1e50, optimizer_cb); + + phi[5] = std::make_shared<SqNode>(phi[1], 7, 1e-50, 1e50); + phi[6] = std::make_shared<InvParamNode>(phi[5], 9, 1e-50, 1e50, optimizer_lor); + phi[7] = std::make_shared<InvNode>(phi[5], 8, 1e-50, 1e50); + + EXPECT_EQ(feat_space.reorder_by_n_params(phi, 5), 7); + EXPECT_EQ(phi[4]->n_params(), 2); + EXPECT_EQ(phi[6]->n_params(), 0); + EXPECT_EQ(phi[7]->n_params(), 4); + + EXPECT_EQ(feat_space.reorder_by_n_params(phi, 0), 6); + EXPECT_EQ(phi[4]->n_params(), 0); + EXPECT_EQ(phi[6]->n_params(), 2); + EXPECT_EQ(phi[7]->n_params(), 4); + } + #endif } diff --git a/tests/googletest/feature_creation/value_storage/test_value_storage.cc b/tests/googletest/feature_creation/value_storage/test_value_storage.cc index 4614922ef947f320642e8cfc0f69b6a75fa9aa7f..e698d90e912f03d18936b494082d82f13b0c19d2 100644 --- a/tests/googletest/feature_creation/value_storage/test_value_storage.cc +++ b/tests/googletest/feature_creation/value_storage/test_value_storage.cc @@ -21,9 +21,9 @@ namespace { //test mean calculations TEST(ValueStorage, ValueStorageTest) { - EXPECT_THROW(node_value_arrs::initialize_values_arr({5}, {2}, 1, -2, true), std::logic_error); + EXPECT_THROW(node_value_arrs::initialize_values_arr({5}, {2}, 2, -2, true), std::logic_error); - node_value_arrs::initialize_values_arr({5}, {2}, 1, 2, true); + node_value_arrs::initialize_values_arr({5}, {2}, 2, 2, true); EXPECT_THROW(node_value_arrs::set_task_sz_train({20}), std::logic_error); EXPECT_THROW(node_value_arrs::set_task_sz_test({6}), std::logic_error); @@ -31,15 +31,19 @@ namespace { EXPECT_EQ(node_value_arrs::N_SAMPLES, 5); EXPECT_EQ(node_value_arrs::N_SAMPLES_TEST, 2); EXPECT_EQ(node_value_arrs::N_RUNGS_STORED, 0); - EXPECT_EQ(node_value_arrs::N_STORE_FEATURES, 1); + EXPECT_EQ(node_value_arrs::N_STORE_FEATURES, 2); EXPECT_EQ(node_value_arrs::N_OP_SLOTS, 6); EXPECT_EQ(node_value_arrs::MAX_RUNG, 2); - EXPECT_EQ(node_value_arrs::VALUES_ARR.size(), 5); - EXPECT_EQ(node_value_arrs::TEST_VALUES_ARR.size(), 2); - EXPECT_EQ(node_value_arrs::TEMP_STORAGE_ARR.size(), node_value_arrs::MAX_N_THREADS * (6 * 1 + 1) * 5); - EXPECT_EQ(node_value_arrs::TEMP_STORAGE_REG.size(), node_value_arrs::MAX_N_THREADS * (6 * 1 + 1)); - EXPECT_EQ(node_value_arrs::TEMP_STORAGE_TEST_ARR.size(), node_value_arrs::MAX_N_THREADS * (6 * 1 + 1) * 2); - EXPECT_EQ(node_value_arrs::TEMP_STORAGE_TEST_REG.size(), node_value_arrs::MAX_N_THREADS * (6 * 1 + 1)); + EXPECT_EQ(node_value_arrs::VALUES_ARR.size(), 10); + EXPECT_EQ(node_value_arrs::TEST_VALUES_ARR.size(), 4); + EXPECT_EQ(node_value_arrs::TEMP_STORAGE_ARR.size(), node_value_arrs::MAX_N_THREADS * (6 * 2 + 1) * 5); + EXPECT_EQ(node_value_arrs::TEMP_STORAGE_REG.size(), node_value_arrs::MAX_N_THREADS * (6 * 2 + 1)); + EXPECT_EQ(node_value_arrs::TEMP_STORAGE_TEST_ARR.size(), node_value_arrs::MAX_N_THREADS * (6 * 2 + 1) * 2); + EXPECT_EQ(node_value_arrs::TEMP_STORAGE_TEST_REG.size(), node_value_arrs::MAX_N_THREADS * (6 * 2 + 1)); + + EXPECT_EQ(node_value_arrs::STANDARDIZED_D_MATRIX.size(), 0); + EXPECT_EQ(node_value_arrs::STANDARDIZED_STORAGE_ARR.size(), node_value_arrs::MAX_N_THREADS * 2 * 3 * 5); + EXPECT_EQ(node_value_arrs::STANDARDIZED_TEST_STORAGE_ARR.size(), node_value_arrs::MAX_N_THREADS * 2 * 3 * 2); EXPECT_THROW(node_value_arrs::resize_values_arr(10, 2), std::logic_error); node_value_arrs::resize_values_arr(1, 2); @@ -53,14 +57,17 @@ namespace { node_value_arrs::initialize_d_matrix_arr(); EXPECT_EQ(node_value_arrs::N_SELECTED, 0); EXPECT_EQ(node_value_arrs::D_MATRIX.size(), 0); + EXPECT_EQ(node_value_arrs::STANDARDIZED_D_MATRIX.size(), 0); node_value_arrs::resize_d_matrix_arr(2); EXPECT_EQ(node_value_arrs::N_SELECTED, 2); EXPECT_EQ(node_value_arrs::D_MATRIX.size(), 10); + EXPECT_EQ(node_value_arrs::STANDARDIZED_D_MATRIX.size(), 10); node_value_arrs::resize_d_matrix_arr(3); EXPECT_EQ(node_value_arrs::N_SELECTED, 5); EXPECT_EQ(node_value_arrs::D_MATRIX.size(), 25); + EXPECT_EQ(node_value_arrs::STANDARDIZED_D_MATRIX.size(), 25); node_value_arrs::get_value_ptr(1, 1, 0)[1] = 1.0; EXPECT_EQ(node_value_arrs::VALUES_ARR[6], 1.0); @@ -71,22 +78,28 @@ namespace { node_value_arrs::get_value_ptr(10, 141, 2, 0)[0] = 1.0; EXPECT_EQ(node_value_arrs::temp_storage_reg(10, 2, 0, false), 141); - EXPECT_EQ(node_value_arrs::access_temp_storage(node_value_arrs::get_op_slot(2, 0, false))[0], 1.0); + EXPECT_EQ(node_value_arrs::access_temp_storage(node_value_arrs::get_op_slot(2, 0, false) * 2)[0], 1.0); node_value_arrs::get_test_value_ptr(10, 141, 2, 0)[0] = 1.0; EXPECT_EQ(node_value_arrs::temp_storage_test_reg(10, 2, 0, false), 141); - EXPECT_EQ(node_value_arrs::access_temp_storage_test(node_value_arrs::get_op_slot(2, 0, false))[0], 1.0); + EXPECT_EQ(node_value_arrs::access_temp_storage_test(node_value_arrs::get_op_slot(2, 0, false) * 2)[0], 1.0); node_value_arrs::get_d_matrix_ptr(1)[0] = 1.0; EXPECT_EQ(node_value_arrs::D_MATRIX[5], 1.0); + node_value_arrs::access_temp_stand_storage(1, false)[0] = 3.0; + EXPECT_EQ(node_value_arrs::STANDARDIZED_STORAGE_ARR[5 + omp_get_thread_num() * 30], 3.0); + + node_value_arrs::access_temp_stand_storage_test(0, true)[0] = 3.0; + EXPECT_EQ(node_value_arrs::STANDARDIZED_TEST_STORAGE_ARR[4 + omp_get_thread_num() * 12], 3.0); + #pragma omp parallel { int sz_reg = (node_value_arrs::N_OP_SLOTS * node_value_arrs::N_PRIMARY_FEATURES + 1); std::fill_n(node_value_arrs::TEMP_STORAGE_REG.data() + sz_reg * omp_get_thread_num(), sz_reg, omp_get_thread_num() + 1); - EXPECT_EQ(node_value_arrs::TEMP_STORAGE_REG[7 * omp_get_thread_num()], omp_get_thread_num() + 1); + EXPECT_EQ(node_value_arrs::TEMP_STORAGE_REG[14 * omp_get_thread_num()], omp_get_thread_num() + 1); node_value_arrs::clear_temp_reg_thread(); - EXPECT_EQ(node_value_arrs::TEMP_STORAGE_REG[7 * omp_get_thread_num()], -1); + EXPECT_EQ(node_value_arrs::TEMP_STORAGE_REG[14 * omp_get_thread_num()], -1); } std::fill_n(node_value_arrs::TEMP_STORAGE_REG.data(), node_value_arrs::TEMP_STORAGE_REG.size(), 2.0); @@ -107,6 +120,9 @@ namespace { EXPECT_EQ(node_value_arrs::PARAM_STORAGE_ARR.size(), 0); EXPECT_EQ(node_value_arrs::PARAM_STORAGE_TEST_ARR.size(), 0); EXPECT_EQ(node_value_arrs::D_MATRIX.size(), 0); + EXPECT_EQ(node_value_arrs::STANDARDIZED_D_MATRIX.size(), 0); + EXPECT_EQ(node_value_arrs::STANDARDIZED_STORAGE_ARR.size(), 0); + EXPECT_EQ(node_value_arrs::STANDARDIZED_TEST_STORAGE_ARR.size(), 0); EXPECT_EQ(node_value_arrs::TASK_SZ_TRAIN.size(), 0); EXPECT_EQ(node_value_arrs::TASK_START_TRAIN.size(), 0); EXPECT_EQ(node_value_arrs::TASK_SZ_TEST.size(), 0); diff --git a/tests/googletest/utils/test_compare_features.cc b/tests/googletest/utils/test_compare_features.cc index cbf0ff1af25616eba94e2e83b06e802dbfd3d790..5d61cf3266fb2399be274e562c319b07396f4b2c 100644 --- a/tests/googletest/utils/test_compare_features.cc +++ b/tests/googletest/utils/test_compare_features.cc @@ -23,52 +23,62 @@ namespace { std::vector<double> val_1 = {1.0, 2.0, 3.0, 4.0}; std::vector<double> val_2 = {2.0, 1.0, 3.0, 4.0}; std::vector<double> val_3 = {2.0, 4.0, 6.0, 8.0}; + + std::vector<double> stand_val_1(4, 0); + util_funcs::standardize(val_1.data(), 4, stand_val_1.data()); + + std::vector<double> stand_val_2(4, 0); + util_funcs::standardize(val_2.data(), 4, stand_val_2.data()); + + std::vector<double> stand_val_3(4, 0); + util_funcs::standardize(val_3.data(), 4, stand_val_3.data()); + std::vector<double> target = {1.0, 3.0, 5.0, 6.0}; std::vector<double> scores = {0.9897782665572893}; std::vector<node_ptr> selected(1); - std::vector<node_sc_pair> mpi_op_sel(1); node_value_arrs::initialize_values_arr({4}, {0}, 1, 0, false); selected[0] = std::make_shared<FeatureNode>(0, "A", val_3, std::vector<double>(), Unit()); - mpi_op_sel[0] = mpi_reduce_op::make_node_sc_pair(selected[0], scores[0]); + std::vector<node_sc_pair> mpi_op_sel(1, node_sc_pair(selected[0], scores[0])); node_value_arrs::initialize_d_matrix_arr(); node_value_arrs::resize_d_matrix_arr(1); std::copy_n(val_3.data(), val_3.size(), node_value_arrs::get_d_matrix_ptr(0)); + std::copy_n(stand_val_3.data(), stand_val_3.size(), node_value_arrs::get_stand_d_matrix_ptr(0)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_pearson_max_corr_1(val_1.data(), 4, 1.0, scores, 0.9897782665572893, 1, 0)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_pearson_max_corr_1_feat_list(val_1.data(), 4, 1.0, selected, scores, 0.9897782665572893)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_pearson_max_corr_1_mpi_op(val_1.data(), 4, 1.0, mpi_op_sel, 0.9897782665572893)); + EXPECT_FALSE(comp_feats::valid_feature_against_selected_pearson_max_corr_1(stand_val_1.data(), 4, 1.0, scores, 0.9897782665572893, 1, 0)); + EXPECT_NE(comp_feats::valid_feature_against_selected_pearson_max_corr_1_feat_list(stand_val_1.data(), 4, 1.0, selected, scores, 0.9897782665572893), 1); + EXPECT_FALSE(comp_feats::valid_feature_against_selected_pearson_max_corr_1_mpi_op(stand_val_1.data(), 4, 1.0, mpi_op_sel, 0.9897782665572893)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_pearson(val_1.data(), 4, 1.0, scores, 0.9897782665572893, 1, 0)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_pearson_feat_list(val_1.data(), 4, 1.0, selected, scores, 0.9897782665572893)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_pearson_mpi_op(val_1.data(), 4, 1.0, mpi_op_sel, 0.9897782665572893)); + EXPECT_FALSE(comp_feats::valid_feature_against_selected_pearson(stand_val_1.data(), 4, 0.99, scores, 0.9897782665572893, 1, 0)); + EXPECT_NE(comp_feats::valid_feature_against_selected_pearson_feat_list(stand_val_1.data(), 4, 0.99, selected, scores, 0.9897782665572893), 1); + EXPECT_FALSE(comp_feats::valid_feature_against_selected_pearson_mpi_op(stand_val_1.data(), 4, 0.99, mpi_op_sel, 0.9897782665572893)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_pearson_max_corr_1(val_2.data(), 4, 1.0, scores, 0.9028289727756884, 1, 0)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_pearson_max_corr_1_feat_list(val_2.data(), 4, 1.0, selected, scores, 0.9028289727756884)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_pearson_max_corr_1_mpi_op(val_2.data(), 4, 1.0, mpi_op_sel, 0.9028289727756884)); + EXPECT_TRUE(comp_feats::valid_feature_against_selected_pearson_max_corr_1(stand_val_2.data(), 4, 1.0, scores, 0.9028289727756884, 1, 0)); + EXPECT_EQ(comp_feats::valid_feature_against_selected_pearson_max_corr_1_feat_list(stand_val_2.data(), 4, 1.0, selected, scores, 0.9028289727756884), 1); + EXPECT_TRUE(comp_feats::valid_feature_against_selected_pearson_max_corr_1_mpi_op(stand_val_2.data(), 4, 1.0, mpi_op_sel, 0.9028289727756884)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_pearson(val_2.data(), 4, 1.0, scores, 0.9028289727756884, 1, 0)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_pearson_feat_list(val_2.data(), 4, 1.0, selected, scores, 0.9028289727756884)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_pearson_mpi_op(val_2.data(), 4, 1.0, mpi_op_sel, 0.9028289727756884)); + EXPECT_TRUE(comp_feats::valid_feature_against_selected_pearson(stand_val_2.data(), 4, 0.99, scores, 0.9028289727756884, 1, 0)); + EXPECT_EQ(comp_feats::valid_feature_against_selected_pearson_feat_list(stand_val_2.data(), 4, 0.99, selected, scores, 0.9028289727756884), 1); + EXPECT_TRUE(comp_feats::valid_feature_against_selected_pearson_mpi_op(stand_val_2.data(), 4, 0.99, mpi_op_sel, 0.9028289727756884)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_spearman_max_corr_1(val_1.data(), 4, 1.0, scores, 0.9897782665572893, 1, 0)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_spearman_max_corr_1_feat_list(val_1.data(), 4, 1.0, selected, scores, 0.9897782665572893)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_spearman_max_corr_1_mpi_op(val_1.data(), 4, 1.0, mpi_op_sel, 0.9897782665572893)); + EXPECT_FALSE(comp_feats::valid_feature_against_selected_spearman_max_corr_1(stand_val_1.data(), 4, 1.0, scores, 0.9897782665572893, 1, 0)); + EXPECT_NE(comp_feats::valid_feature_against_selected_spearman_max_corr_1_feat_list(stand_val_1.data(), 4, 1.0, selected, scores, 0.9897782665572893), 1); + EXPECT_FALSE(comp_feats::valid_feature_against_selected_spearman_max_corr_1_mpi_op(stand_val_1.data(), 4, 1.0, mpi_op_sel, 0.9897782665572893)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_spearman(val_1.data(), 4, 1.0, scores, 0.9897782665572893, 1, 0)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_spearman_feat_list(val_1.data(), 4, 1.0, selected, scores, 0.9897782665572893)); - EXPECT_FALSE(comp_feats::valid_feature_against_selected_spearman_mpi_op(val_1.data(), 4, 1.0, mpi_op_sel, 0.9897782665572893)); + EXPECT_FALSE(comp_feats::valid_feature_against_selected_spearman(stand_val_1.data(), 4, 0.99, scores, 0.9897782665572893, 1, 0)); + EXPECT_NE(comp_feats::valid_feature_against_selected_spearman_feat_list(stand_val_1.data(), 4, 0.99, selected, scores, 0.9897782665572893), 1); + EXPECT_FALSE(comp_feats::valid_feature_against_selected_spearman_mpi_op(stand_val_1.data(), 4, 0.99, mpi_op_sel, 0.9897782665572893)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_spearman_max_corr_1(val_2.data(), 4, 1.0, scores, 0.9028289727756884, 1, 0)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_spearman_max_corr_1_feat_list(val_2.data(), 4, 1.0, selected, scores, 0.9028289727756884)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_spearman_max_corr_1_mpi_op(val_2.data(), 4, 1.0, mpi_op_sel, 0.9028289727756884)); + EXPECT_TRUE(comp_feats::valid_feature_against_selected_spearman_max_corr_1(stand_val_2.data(), 4, 1.0, scores, 0.9028289727756884, 1, 0)); + EXPECT_EQ(comp_feats::valid_feature_against_selected_spearman_max_corr_1_feat_list(stand_val_2.data(), 4, 1.0, selected, scores, 0.9028289727756884), 1); + EXPECT_TRUE(comp_feats::valid_feature_against_selected_spearman_max_corr_1_mpi_op(stand_val_2.data(), 4, 1.0, mpi_op_sel, 0.9028289727756884)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_spearman(val_2.data(), 4, 1.0, scores, 0.9028289727756884, 1, 0)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_spearman_feat_list(val_2.data(), 4, 1.0, selected, scores, 0.9028289727756884)); - EXPECT_TRUE(comp_feats::valid_feature_against_selected_spearman_mpi_op(val_2.data(), 4, 1.0, mpi_op_sel, 0.9028289727756884)); + EXPECT_TRUE(comp_feats::valid_feature_against_selected_spearman(stand_val_2.data(), 4, 0.99, scores, 0.9028289727756884, 1, 0)); + EXPECT_EQ(comp_feats::valid_feature_against_selected_spearman_feat_list(stand_val_2.data(), 4, 0.99, selected, scores, 0.9028289727756884), 1); + EXPECT_TRUE(comp_feats::valid_feature_against_selected_spearman_mpi_op(stand_val_2.data(), 4, 0.99, mpi_op_sel, 0.9028289727756884)); node_value_arrs::finalize_values_arr(); } diff --git a/tests/googletest/utils/test_math_utils.cc b/tests/googletest/utils/test_math_utils.cc index 0e7a91ce475c41dbf472bc0fc2b2f7f9535aba48..1c685039526ff2aa16c07442afeb11e104f4f857 100644 --- a/tests/googletest/utils/test_math_utils.cc +++ b/tests/googletest/utils/test_math_utils.cc @@ -324,6 +324,21 @@ namespace { EXPECT_EQ(util_funcs::max_abs_val<double>(dNeg3.data(), dNeg3.size()), 9.0); } + // test standardize + TEST(MathUtils, StandardizeTest) + { + std::vector<double> test = {2, 4, 4, 4, 5, 5, 7, 9}; + std::vector<double> test_std = {-1.5, -0.5, -0.5, -0.5, 0, 0, 1, 2}; + + util_funcs::standardize(test.data(), test.size(), test.data()); + + EXPECT_LT(std::abs(util_funcs::mean(test)), 1e-10); + EXPECT_LT(std::abs(util_funcs::stand_dev(test) - 1.0), 1e-10); + + std::transform(test.begin(), test.end(), test_std.begin(), test.begin(), std::minus<double>()); + EXPECT_TRUE(std::all_of(test.begin(), test.end(), [](double val){return std::abs(val) < 1e-10;})); + } + // test iterate TEST(MathUtils, IterateTest) { diff --git a/tests/pytest/test_feature_creation/test_feat_generation/test_inv_node.py b/tests/pytest/test_feature_creation/test_feat_generation/test_inv_node.py index 646bb223b576212e5de36a7e3421fedd9dbd912d..88cddd48ebe8f2e715a2bb3c3333fff862c28c43 100644 --- a/tests/pytest/test_feature_creation/test_feat_generation/test_inv_node.py +++ b/tests/pytest/test_feature_creation/test_feat_generation/test_inv_node.py @@ -55,7 +55,7 @@ def test_inv_node(): pass try: - feats.append(InvNode(feat_1, 4, 1e1, 1e50)) + feats.append(InvNode(feat_1, 4, 1e40, 1e50)) raise InvalidFeatureMade("Inversion outside of user specified bounds") except RuntimeError: pass diff --git a/tests/pytest/test_feature_creation/test_feature_space/test_feature_space.py b/tests/pytest/test_feature_creation/test_feature_space/test_feature_space.py index b2dfb0cb0a1177e2195d139f8dff0891d7db224e..bbee1225d57f35892cf5605acf06846eb315900d 100644 --- a/tests/pytest/test_feature_creation/test_feature_space/test_feature_space.py +++ b/tests/pytest/test_feature_creation/test_feature_space/test_feature_space.py @@ -89,11 +89,11 @@ def test_feature_space(): feat_space.sis(inputs.prop_train) assert feat_space.phi_selected[0].postfix_expr == "1|0|add|sq" + assert feat_space.phi_selected[1].d_mat_ind == 1 + assert len(feat_space.phi_selected) == 10 feat_space.sis(list(inputs.prop_train)) - shutil.rmtree("feature_space/") - assert feat_space.phi_selected[0].postfix_expr == "1|0|add|sq" - + assert len(feat_space.phi_selected) == 20 assert ( np.abs( np.corrcoef(inputs.prop_train, inputs.phi_0[0].value)[0, 1] ** 2.0 @@ -107,7 +107,6 @@ def test_feature_space(): assert feat_space.start_rung[0] == 0 assert feat_space.start_rung[1] == 10 assert feat_space.get_feature(0).expr == "feat_0" - assert feat_space.phi_selected[1].d_mat_ind == 1 try: feat_space.remove_feature(feat_space.phi_selected[0].feat_ind)