Commit 96143d3f authored by Thomas Purcell's avatar Thomas Purcell
Browse files

Bug Fix

Correct bugs when attempting to allow additional features when max_cor < 1
parent 8aa67ecc
......@@ -1019,12 +1019,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;
......@@ -1090,7 +1092,7 @@ 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)))
{
double cur_score = scores[inds[ii]];
bool valid_feat = _is_valid(
int valid_feat = _is_valid(
generated_phi[inds[ii]]->stand_value_ptr(),
_n_samp_train,
_cross_cor_max,
......@@ -1099,24 +1101,26 @@ 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]]->stand_value_ptr(),
_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);
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());
phi_sel_private.push_back(generated_phi[inds[ii]]);
scores_sel_private.push_back(cur_score);
......@@ -1130,38 +1134,86 @@ 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]->stand_value_ptr(), _n_samp_train, _cross_cor_max, phi_sel, scores_sel, scores_sel_private[sc])
)
if(scores_sel_private[sc] > scores_sel[worst_score_ind])
{
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))
{
if(phi_sel.size() == _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() + _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))
{
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)
......@@ -1270,7 +1322,6 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss)
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;
......@@ -1395,6 +1446,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];
......@@ -1413,7 +1465,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)
......
......@@ -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
......
......@@ -72,7 +72,7 @@ std::vector<node_sc_pair> mpi_reduce_op::select_top_feats(std::vector<node_sc_pa
int out_ind = 0;
while((out_ind < N_SIS_SELECT) && (ff < in_vec_2.size()))
{
if(in_vec_2[ff]._feat && IS_VALID(in_vec_2[ff]._feat->value_ptr(), in_vec_2[ff]._feat->n_samp(), CROSS_COR_MAX, out_vec, in_vec_2[ff]._score))
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;
......
......@@ -30,7 +30,7 @@ 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)
......@@ -90,11 +90,16 @@ bool comp_feats::valid_feature_against_selected_pearson_max_corr_1(
continue;
}
double comp_value = 1.0 / static_cast<double>(n_samp) * std::inner_product(
val_ptr,
val_ptr + n_samp,
node_value_arrs::get_stand_d_matrix_ptr(dd),
-1.0 * base_val
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)
......@@ -105,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,
......@@ -123,19 +128,24 @@ bool comp_feats::valid_feature_against_selected_pearson_max_corr_1_feat_list(
continue;
}
double comp_value = 1.0 / static_cast<double>(n_samp) * std::inner_product(
val_ptr,
val_ptr + n_samp,
selected[ff]->stand_value_ptr(true),
-1.0 * base_val
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(
......@@ -155,11 +165,16 @@ bool comp_feats::valid_feature_against_selected_pearson_max_corr_1_mpi_op(
continue;
}
double comp_value = 1.0 / static_cast<double>(n_samp) * std::inner_product(
val_ptr,
val_ptr + n_samp,
feat_sc._feat->stand_value_ptr(true),
-1.0 * base_val
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)
......@@ -187,8 +202,6 @@ bool comp_feats::valid_feature_against_selected_pearson(
}
DGEMV_OUT.resize(end_sel - start_sel);
double base_val = std::inner_product(val_ptr, val_ptr + n_samp, val_ptr, 0.0) / static_cast<double>(n_samp);
dgemv_(
'N',
DGEMV_OUT.size(),
......@@ -203,13 +216,10 @@ bool comp_feats::valid_feature_against_selected_pearson(
1
);
double comp_value = (
base_val - std::abs(DGEMV_OUT[idamax_(DGEMV_OUT.size(), DGEMV_OUT.data(), 1) - 1])
);
return std::abs(comp_value) >= (1.0 - cross_cor_max + 5.0e-9);
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,
......@@ -218,20 +228,21 @@ bool comp_feats::valid_feature_against_selected_pearson_feat_list(
const double cur_score
)
{
double base_val = std::inner_product(val_ptr, val_ptr + n_samp, val_ptr, 0.0);
int is_valid = 1;
double comp_value = 1.0;
for(int ff = 0; ff < selected.size(); ++ff)
{
double 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), -base_val)
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(
......@@ -242,15 +253,13 @@ bool comp_feats::valid_feature_against_selected_pearson_mpi_op(
const double cur_score
)
{
double base_val = std::inner_product(val_ptr, val_ptr + n_samp, val_ptr, 0.0);
for(auto& feat_sc : out_vec)
{
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), -base_val)
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;
}
......@@ -300,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,
......@@ -334,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(
......@@ -390,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,
......@@ -431,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(
......@@ -465,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(
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;
}
......
......@@ -139,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
);
/**
......@@ -180,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,
......@@ -243,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,
......@@ -306,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,
......@@ -369,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,
......
{
"desc_dim": 2,
"n_sis_select": 1,
"n_sis_select": 2,
"max_rung": 2,
"n_residual": 1,
"data_file": "../data.csv",
......