Commit a6092afc authored by Thomas Purcell's avatar Thomas Purcell
Browse files

Created an interface to interact with non-linear parameterization

Works in the input file interface need to test with python interface
parent a4744c4c
......@@ -289,7 +289,7 @@ void Model::to_file(std::string filename, bool train, std::vector<int> test_inds
out_file_stream << "# Feature Rung, Units, and Expressions" << std::endl;
for(int ff = 0; ff < _feats.size(); ++ff)
out_file_stream << std::setw(6) << std::left << "# " + std::to_string(ff) + ", " << std::to_string(_feats[ff]->rung()) + ", " << std::setw(50) << _feats[ff]->unit().toString() + ", " << _feats[ff]->postfix_expr() + "," << _feats[ff]->expr() << std::endl;
out_file_stream << std::setw(6) << std::left << "# " + std::to_string(ff) + ", " << std::to_string(_feats[ff]->rung()) + ", " << std::setw(50) << _feats[ff]->unit().toString() + ", " << _feats[ff]->postfix_expr() + ", " << _feats[ff]->expr() << std::endl;
out_file_stream << "# Number of Samples Per Task" << std::endl;
if(train)
......
......@@ -23,6 +23,7 @@ FeatureSpace::FeatureSpace(
std::shared_ptr<MPI_Interface> mpi_comm,
std::vector<node_ptr> phi_0,
std::vector<std::string> allowed_ops,
std::map<std::string, std::vector<std::string>> allowed_param_ops,
std::vector<double> prop,
std::vector<int> task_sizes,
int max_phi,
......@@ -34,7 +35,9 @@ FeatureSpace::FeatureSpace(
):
_phi(phi_0),
_phi_0(phi_0),
_allowed_param_ops(allowed_param_ops),
_allowed_ops(allowed_ops),
_prop(prop),
_scores(phi_0.size(), 0.0),
_task_sizes(task_sizes),
_start_gen(1, 0),
......@@ -50,10 +53,10 @@ FeatureSpace::FeatureSpace(
_n_rung_generate(n_rung_generate)
{
initialize_fs(prop);
initialize_fs();
}
void FeatureSpace::initialize_fs(std::vector<double> prop)
void FeatureSpace::initialize_fs()
{
if(_n_rung_store == -1)
_n_rung_store = _max_phi - 1;
......@@ -80,13 +83,22 @@ void FeatureSpace::initialize_fs(std::vector<double> prop)
else
_un_operators.push_back(allowed_op_maps::unary_operator_map[op]);
}
for(auto& op : _allowed_param_ops)
{
if((op.first.compare("add") == 0) || (op.first.compare("sub") == 0) || (op.first.compare("mult") == 0) || (op.first.compare("abs_diff") == 0))
_com_bin_param_operators.push_back(std::make_pair(allowed_op_maps::binary_param_operator_map[op.first], op.second));
else if((op.first.compare("div") == 0))
_bin_param_operators.push_back(std::make_pair(allowed_op_maps::binary_param_operator_map[op.first], op.second));
else
_un_param_operators.push_back(std::make_pair(allowed_op_maps::unary_param_operator_map[op.first], op.second));
}
generate_feature_space(prop);
generate_feature_space();
_scores.reserve(_phi.size());
_scores.resize(_phi.size());
}
void FeatureSpace::generate_new_feats(std::vector<node_ptr>::iterator& feat, std::vector<node_ptr>& feat_set, int& feat_ind, double l_bound, double u_bound)
void FeatureSpace::generate_new_feats(std::vector<node_ptr>::iterator& feat, std::vector<node_ptr>& feat_set,int& feat_ind, double l_bound, double u_bound)
{
int phi_ind = feat - _phi.begin();
feat_set.reserve(feat_set.size() + _un_operators.size() + phi_ind * (_com_bin_operators.size() + 2 * _bin_operators.size()));
......@@ -104,6 +116,19 @@ void FeatureSpace::generate_new_feats(std::vector<node_ptr>::iterator& feat, std
}
}
for(auto& op : _un_param_operators)
{
try
{
feat_set.push_back(op.first(*feat, feat_ind, l_bound, u_bound, op.second, _prop));
++feat_ind;
}
catch(const InvalidFeatureException& e)
{
// Do Nothing
}
}
for(auto& op : _com_bin_operators)
{
for(auto feat_2 = _phi.begin(); feat_2 != feat; ++feat_2)
......@@ -120,6 +145,22 @@ void FeatureSpace::generate_new_feats(std::vector<node_ptr>::iterator& feat, std
}
}
for(auto& op : _com_bin_param_operators)
{
for(auto feat_2 = _phi.begin(); feat_2 != feat; ++feat_2)
{
try
{
feat_set.push_back(op.first(*feat, *feat_2, feat_ind, l_bound, u_bound, op.second, _prop));
++feat_ind;
}
catch(const InvalidFeatureException& e)
{
// Do Nothing
}
}
}
for(auto& op : _bin_operators)
{
for(auto feat_2 = _phi.begin(); feat_2 != feat; ++feat_2)
......@@ -144,9 +185,34 @@ void FeatureSpace::generate_new_feats(std::vector<node_ptr>::iterator& feat, std
}
}
}
for(auto& op : _bin_param_operators)
{
for(auto feat_2 = _phi.begin(); feat_2 != feat; ++feat_2)
{
try
{
feat_set.push_back(op.first(*feat, *feat_2, feat_ind, l_bound, u_bound, op.second, _prop));
++feat_ind;
}
catch(const InvalidFeatureException& e)
{
// Do Nothing
}
try
{
feat_set.push_back(op.first(*feat_2, *feat, feat_ind, l_bound, u_bound, op.second, _prop));
++feat_ind;
}
catch(const InvalidFeatureException& e)
{
// Do Nothing
}
}
}
}
void FeatureSpace::generate_feature_space(std::vector<double>& prop)
void FeatureSpace::generate_feature_space()
{
double u_bound = 1e50;
double l_bound = 1e-50;
......@@ -214,7 +280,7 @@ void FeatureSpace::generate_feature_space(std::vector<double>& prop)
_scores.resize(_phi.size());
_mpi_comm->barrier();
_project(prop.data(), _scores.data(), _phi, _task_sizes, 1);
_project(_prop.data(), _scores.data(), _phi, _task_sizes, 1);
_scores.erase(_scores.begin(), _scores.begin() + _start_gen[_start_gen.size() - 1]);
inds = util_funcs::argsort(_scores);
......
......@@ -22,6 +22,7 @@
#include <iostream>
#include <iomanip>
#include <utility>
#ifdef PY_BINDINGS
namespace np = boost::python::numpy;
......@@ -40,11 +41,17 @@ class FeatureSpace
std::vector<node_ptr> _phi; //!< all features
std::vector<node_ptr> _phi_0; //!< initial feature space
std::vector<std::pair<un_param_op_node_gen, std::vector<std::string>>> _un_param_operators; //!< list of all parameterized unary operators with free parameters
std::vector<std::pair<bin_param_op_node_gen, std::vector<std::string>>> _com_bin_param_operators; //!< list of all parameterized commutable binary operators with free parameters
std::vector<std::pair<bin_param_op_node_gen, std::vector<std::string>>> _bin_param_operators; //!< list of all parameterized binary operators with free parameters
std::map<std::string, std::vector<std::string>> _allowed_param_ops; //!< Map of parameterization operator set (set of operators and non-linear parameters used for a non-linear least squares fit to property)
std::vector<std::string> _allowed_ops; //!< list of all allowed operators strings
std::vector<un_op_node_gen> _un_operators; //!< list of all unary operators
std::vector<bin_op_node_gen> _com_bin_operators; //!< list of all commutable binary operators
std::vector<bin_op_node_gen> _bin_operators; //!< list of all binary operators
std::vector<double> _prop; //!< The property to fit
std::vector<double> _scores; //!< projection scores for each feature
std::vector<int> _task_sizes; //!< The number of elements in each task (training data)
......@@ -72,6 +79,7 @@ public:
* @param mpi_comm MPI communicator for the calculations
* @param phi_0 The initial set of features to combine
* @param allowed_ops list of allowed operators
* @param allowed_param_ops dictionary of the parameterizable operators and their associated free parameters
* @param prop The property to be learned (training data)
* @param max_phi highest rung value for the calculation
* @param n_sis_select number of features to select during each SIS step
......@@ -84,6 +92,7 @@ public:
std::shared_ptr<MPI_Interface> mpi_comm,
std::vector<node_ptr> phi_0,
std::vector<std::string> allowed_ops,
std::map<std::string, std::vector<std::string>> allowed_param_ops,
std::vector<double> prop,
std::vector<int> task_sizes,
int max_phi=1,
......@@ -99,13 +108,13 @@ public:
*
* @param prop The property trying to be learned
*/
void initialize_fs(std::vector<double> prop);
void initialize_fs();
/**
* @brief Generate the full feature set from the allowed operators and initial feature set
* @details populates phi with all features from an initial set and the allowed operators
*/
void generate_feature_space(std::vector<double>& prop);
void generate_feature_space();
/**
* @brief The selected feature space
......@@ -267,6 +276,7 @@ public:
* @param mpi_comm MPI communicator for the calculations
* @param phi_0 The initial set of features to combine
* @param allowed_ops list of allowed operators
* @param allowed_param_ops dictionary of the parameterizable operators and their associated free parameters
* @param prop The property to be learned (training data)
* @param max_phi highest rung value for the calculation
* @param n_sis_select number of features to select during each SIS step
......@@ -278,6 +288,7 @@ public:
FeatureSpace(
py::list phi_0,
py::list allowed_ops,
py::dict allowed_param_ops,
py::list prop,
py::list task_sizes,
int max_phi=1,
......@@ -295,6 +306,7 @@ public:
* @param mpi_comm MPI communicator for the calculations
* @param phi_0 The initial set of features to combine
* @param allowed_ops list of allowed operators
* @param allowed_param_ops dictionary of the parameterizable operators and their associated free parameters
* @param prop The property to be learned (training data)
* @param max_phi highest rung value for the calculation
* @param n_sis_select number of features to select during each SIS step
......@@ -306,6 +318,7 @@ public:
FeatureSpace(
py::list phi_0,
py::list allowed_ops,
py::dict allowed_param_ops,
np::ndarray prop,
py::list task_sizes,
int max_phi=1,
......
......@@ -264,6 +264,11 @@ public:
* @brief The parameters used for introducing more non linearity in the operators
*/
inline std::array<double, 2> parameters(){return {1.0, 0.0};}
/**
* @brief Set the non-linear parameters
*/
void set_parameters(std::array<double, 2>){};
};
#endif
......@@ -33,8 +33,8 @@ class ModelNode: public FeatureNode
}
protected:
int _rung;
std::string _expr_postfix;
int _rung;
public:
/**
* @brief Base Constructor
......@@ -176,6 +176,7 @@ public:
* @param add_sub_leaves [description]
*/
void update_div_mult_leaves(std::map<std::string, double>& div_mult_leaves, double fact, double& expected_abs_tot);
};
#endif
......@@ -322,6 +322,11 @@ public:
*/
virtual std::array<double, 2> parameters() = 0;
/**
* @brief Set the non-linear parameters
*/
virtual void set_parameters(std::array<double, 2>) = 0;
#ifdef PY_BINDINGS
// DocString: node_value_py
......
......@@ -23,6 +23,8 @@
#include "ceres/ceres.h"
#include "glog/logging.h"
#include<iomanip>
using ceres::AutoDiffCostFunction;
using ceres::CostFunction;
using ceres::Problem;
......@@ -260,7 +262,18 @@ public:
*/
inline void update_postfix(std::string& cur_expr)
{
cur_expr = get_postfix_term() + "|" + cur_expr;
std::stringstream postfix;
postfix << get_postfix_term() << ":";
if((_params[0] == 1.0) && (_params[1] == 0.0))
{
postfix << "1.0,0.0";
}
else
{
postfix << std::setprecision(13) << std::scientific << _params[0] << ",";
postfix << std::setprecision(13) << std::scientific << _params[1];
}
cur_expr = postfix.str() + "|" + cur_expr;
for(int nn = N - 1; nn >= 0; --nn)
_feats[nn]->update_postfix(cur_expr);
};
......@@ -293,6 +306,11 @@ public:
*/
inline std::array<double, 2> parameters(){return _params;}
/**
* @brief Set the non-linear parameters
*/
inline void set_parameters(std::array<double, 2> params){_params = params;}
/**
* @brief Solve the non-linear optimization to set the parameters
* @details Fits the data points from _feats->value_ptr and prop to get the parameters for the feature
......
......@@ -96,7 +96,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "|" + _feats[0]->expr() + "|";}
inline std::string expr(){return "|" + std::to_string(_params[0]) + "*" + _feats[0]->expr() + " + " + std::to_string(_params[1]) + "|";}
// DocString: abs_node_set_value
/**
......
......@@ -98,7 +98,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "|" + _feats[0]->expr() + " - (" + _feats[1]->expr() + ")|";}
inline std::string expr(){return "|" + _feats[0]->expr() + " - (" + std::to_string(_params[0]) + "*" + _feats[1]->expr() + " + " + std::to_string(_params[1]) + ")|";}
// DocString: abs_diff_node_set_value
/**
......
......@@ -97,7 +97,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "(" + _feats[0]->expr() + " + " + _feats[1]->expr() + ")";}
inline std::string expr(){return "(" + _feats[0]->expr() + " + " + std::to_string(_params[0]) + "*" + _feats[1]->expr() + " + " + std::to_string(_params[1]) + ")";}
// DocString: add_node_set_value
/**
......
......@@ -96,7 +96,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "(" + _feats[0]->expr() + ")^3";}
inline std::string expr(){return "(" + std::to_string(_params[0]) + "*" + _feats[0]->expr() + " + " + std::to_string(_params[1]) + ")^3";}
// DocString: cb_node_set_value
/**
......
......@@ -96,7 +96,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "cbrt(" + _feats[0]->expr() + ")";}
inline std::string expr(){return "cbrt(" + std::to_string(_params[0]) + "*" + _feats[0]->expr() + " + " + std::to_string(_params[1]) + ")";}
// DocString: cbrt_node_set_value
/**
......
......@@ -96,7 +96,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "cos(" + _feats[0]->expr() + ")";}
inline std::string expr(){return "cos(" + std::to_string(_params[0]) + "*" + _feats[0]->expr() + " + " + std::to_string(_params[1]) + ")";}
// DocString: cos_node_set_value
/**
......
......@@ -97,7 +97,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "[(" + _feats[0]->expr() + ") / (" + _feats[1]->expr() + ")]";}
inline std::string expr(){return "[(" + _feats[0]->expr() + ") / (" + std::to_string(_params[0]) + "*" + _feats[1]->expr() + " + " + std::to_string(_params[1]) + ")]";}
// DocString: div_node_set_value
/**
......
......@@ -96,7 +96,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "exp(" + _feats[0]->expr() + ")";}
inline std::string expr(){return "exp(" + std::to_string(_params[0]) + "*" + _feats[0]->expr() + " + " + std::to_string(_params[1]) + ")";}
// DocString: exp_node_set_value
/**
......
......@@ -84,7 +84,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "1.0 / (" + _feats[0]->expr() + ")";}
inline std::string expr(){return "1.0 / (" + std::to_string(_params[0]) + "*" + _feats[0]->expr() + " + " + std::to_string(_params[1]) + ")";}
// DocString: inv_node_set_value
/**
......
......@@ -96,7 +96,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "log(" + _feats[0]->expr() + ")";}
inline std::string expr(){return "log(" + std::to_string(_params[0]) + "*" + _feats[0]->expr() + " + " + std::to_string(_params[1]) + ")";}
// DocString: log_node_set_value
/**
......
......@@ -97,7 +97,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "[(" + _feats[0]->expr() + ") * (" + _feats[1]->expr() + ")]";}
inline std::string expr(){return "[(" + std::to_string(_params[0]) + "*" + _feats[0]->expr() + ") * (" + _feats[1]->expr() + ")]";}
// DocString: mult_node_set_value
/**
......
......@@ -97,7 +97,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "exp[-1.0*(" + _feats[0]->expr() + ")]";}
inline std::string expr(){return "exp[-1.0*(" + std::to_string(_params[0]) + "*" + _feats[0]->expr() + " + " + std::to_string(_params[1]) + ")]";}
// DocString: neg_exp_node_set_value
/**
......
......@@ -97,7 +97,7 @@ public:
/**
* @brief Get the expression for the overall feature (From root node down)
*/
inline std::string expr(){return "sin(" + _feats[0]->expr() + ")";}
inline std::string expr(){return "sin(" + std::to_string(_params[0]) + "*" + _feats[0]->expr() + " + " + std::to_string(_params[1]) + ")";}
// DocString: sin_node_set_value
/**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment