24 #include <boost/serialization/export.hpp> 25 #include <boost/serialization/vector.hpp> 26 #include <boost/archive/text_iarchive.hpp> 27 #include <boost/archive/text_oarchive.hpp> 28 #include <boost/archive/xml_iarchive.hpp> 29 #include <boost/archive/xml_oarchive.hpp> 45 #include <eigen3/Eigen/Core> 46 #include <eigen3/Eigen/SVD> 47 #include <eigen3/Eigen/LU> 51 using namespace Eigen;
55 UnifiedModel::UnifiedModel(
const Eigen::MatrixXd& centers,
const Eigen::MatrixXd& widths,
const Eigen::VectorXd& weights,
bool normalized_basis_functions,
bool lines_pivot_at_max_activation)
57 int n_basis_functions = centers.rows();
58 int n_dims = centers.cols();
60 assert(n_basis_functions==widths.rows());
61 assert(n_dims ==widths.cols());
62 assert(n_basis_functions==weights.size());
64 centers_.resize(n_basis_functions);
65 covars_.resize(n_basis_functions);
66 slopes_.resize(n_basis_functions);
67 offsets_.resize(n_basis_functions);
68 priors_.resize(n_basis_functions);
70 for (
int i=0; i<n_basis_functions; i++)
72 centers_[i] = centers.row(i);
73 covars_[i] = widths.row(i).asDiagonal();
74 covars_[i] = covars_[i].array().square();
75 offsets_[i] = weights[i];
77 slopes_[i] = VectorXd::Zero(n_dims);
81 normalized_basis_functions_ = normalized_basis_functions;
82 lines_pivot_at_max_activation_ = lines_pivot_at_max_activation;
83 slopes_as_angles_ =
false;
85 cosine_basis_functions_ =
false;
87 initializeAllValuesVectorSize();
90 UnifiedModel::UnifiedModel(
const Eigen::MatrixXd& centers,
const Eigen::MatrixXd& widths,
const Eigen::MatrixXd& slopes,
const Eigen::VectorXd& offsets,
bool normalized_basis_functions,
bool lines_pivot_at_max_activation)
92 int n_basis_functions = centers.rows();
93 #ifndef NDEBUG // Variables below are only required for asserts; check for NDEBUG to avoid warnings. 94 int n_dims = centers.cols();
97 assert(n_basis_functions==widths.rows());
98 assert(n_dims ==widths.cols());
99 assert(n_basis_functions==slopes.rows());
100 assert(n_dims ==slopes.cols());
101 assert(n_basis_functions==offsets.size());
103 centers_.resize(n_basis_functions);
104 covars_.resize(n_basis_functions);
105 slopes_.resize(n_basis_functions);
106 offsets_.resize(n_basis_functions);
107 priors_.resize(n_basis_functions);
109 for (
int i=0; i<n_basis_functions; i++)
111 centers_[i] = centers.row(i);
112 covars_[i] = widths.row(i).asDiagonal();
113 covars_[i] = covars_[i].array().square();
114 slopes_[i] = slopes.row(i);
115 offsets_[i] = offsets[i];
120 normalized_basis_functions_ = normalized_basis_functions;
121 lines_pivot_at_max_activation_ = lines_pivot_at_max_activation;
122 slopes_as_angles_ =
false;
124 cosine_basis_functions_ =
false;
126 initializeAllValuesVectorSize();
130 UnifiedModel::UnifiedModel(
const Eigen::MatrixXd& angular_frequencies,
const Eigen::VectorXd& phases,
const Eigen::VectorXd& weights)
132 int n_basis_functions = angular_frequencies.rows();
133 int n_dims = angular_frequencies.cols();
135 assert(n_basis_functions==phases.size());
136 assert(n_basis_functions==weights.size());
138 centers_.resize(n_basis_functions);
139 covars_.resize(n_basis_functions);
140 slopes_.resize(n_basis_functions);
141 offsets_.resize(n_basis_functions);
142 priors_.resize(n_basis_functions);
144 for (
int i=0; i<n_basis_functions; i++)
146 centers_[i] = VectorXd(1);
147 centers_[i][0] = phases[i];
149 covars_[i] = MatrixXd(1,n_dims);
150 covars_[i] = angular_frequencies.row(i);
152 offsets_[i] = weights[i];
154 slopes_[i] = VectorXd::Zero(n_dims);
159 normalized_basis_functions_ =
false;
160 lines_pivot_at_max_activation_ =
false;
161 slopes_as_angles_ =
false;
163 cosine_basis_functions_ =
true;
165 initializeAllValuesVectorSize();
168 UnifiedModel::UnifiedModel(
169 const std::vector<Eigen::VectorXd>& centers,
170 const std::vector<Eigen::MatrixXd>& covars,
171 const std::vector<Eigen::VectorXd>& slopes,
172 const std::vector<double>& offsets,
173 const std::vector<double>& priors,
174 bool normalized_basis_functions,
175 bool lines_pivot_at_max_activation)
182 normalized_basis_functions_(normalized_basis_functions),
183 lines_pivot_at_max_activation_(lines_pivot_at_max_activation),
184 slopes_as_angles_(false)
186 cosine_basis_functions_ =
false;
188 initializeAllValuesVectorSize();
191 void UnifiedModel::initializeAllValuesVectorSize(
void)
194 all_values_vector_size_ = 0;
195 int n_basis_functions = centers_.size();
196 if (n_basis_functions>0)
198 all_values_vector_size_ += centers_.size()*centers_[0].size();
199 all_values_vector_size_ += covars_.size() *covars_[0].cols();
200 all_values_vector_size_ += offsets_.size();
201 all_values_vector_size_ += slopes_.size() *slopes_[0].size();
202 all_values_vector_size_ += priors_.size();
209 return new UnifiedModel(centers_,covars_,slopes_,offsets_,priors_,normalized_basis_functions_,lines_pivot_at_max_activation_);
216 if (lines_pivot_at_max_activation_ == lines_pivot_at_max_activation)
230 int n_lines = centers_.size();
231 VectorXd ac(n_lines);
232 for (
int i_line=0; i_line<n_lines; i_line++)
234 ac[i_line] = slopes_[i_line].dot(centers_[i_line]);
236 if (lines_pivot_at_max_activation)
240 offsets_[i_line] = offsets_[i_line] + ac[i_line];
246 offsets_[i_line] = offsets_[i_line] - ac[i_line];
253 lines_pivot_at_max_activation_ = lines_pivot_at_max_activation;
258 slopes_as_angles_ = slopes_as_angles;
259 cerr << __FILE__ <<
":" << __LINE__ <<
":";
260 cerr <<
"Not implemented yet!!!" << endl;
261 slopes_as_angles_ =
false;
269 int n_time_steps = inputs.rows();
278 int n_lines = centers_.size();
279 lines.resize(n_time_steps,n_lines);
280 for (
int i_line=0; i_line<n_lines; i_line++)
282 lines.col(i_line) = inputs*slopes_[i_line];
283 lines.col(i_line).array() += offsets_[i_line];
285 if (lines_pivot_at_max_activation_)
289 double ac = slopes_[i_line].dot(centers_[i_line]);
290 lines.col(i_line).array() -= ac;
303 MatrixXd activations;
306 output = (lines.array()*activations.array()).rowwise().sum();
354 if ( inputs.rows()==inputs_cached_.rows() && inputs.cols()==inputs_cached_.cols() )
357 if ( (inputs.array()==inputs_cached_.array()).all() )
360 kernel_activations = kernel_activations_cached_;
367 if (cosine_basis_functions_)
374 BasisFunction::Cosine::activations(covars_,centers_,inputs,kernel_activations);
378 BasisFunction::Gaussian::activations(centers_,covars_,priors_,inputs,kernel_activations,normalized_basis_functions_);
384 inputs_cached_ = inputs;
385 kernel_activations_cached_ = kernel_activations;
390 template<
class Archive>
391 void UnifiedModel::serialize(Archive & ar,
const unsigned int version)
396 ar & BOOST_SERIALIZATION_NVP(centers_);
397 ar & BOOST_SERIALIZATION_NVP(covars_);
398 ar & BOOST_SERIALIZATION_NVP(slopes_);
399 ar & BOOST_SERIALIZATION_NVP(offsets_);
400 ar & BOOST_SERIALIZATION_NVP(priors_);
401 ar & BOOST_SERIALIZATION_NVP(normalized_basis_functions_);
402 ar & BOOST_SERIALIZATION_NVP(lines_pivot_at_max_activation_);
403 ar & BOOST_SERIALIZATION_NVP(slopes_as_angles_);
404 ar & BOOST_SERIALIZATION_NVP(all_values_vector_size_);
405 ar & BOOST_SERIALIZATION_NVP(caching_);
415 selected_values_labels = set<string>();
416 selected_values_labels.insert(
"centers");
417 selected_values_labels.insert(
"widths");
418 selected_values_labels.insert(
"offsets");
419 selected_values_labels.insert(
"slopes");
420 selected_values_labels.insert(
"priors");
428 selected_mask.fill(0);
434 size = centers_.size()*centers_[0].size();
435 if (selected_values_labels.find(
"centers")!=selected_values_labels.end())
436 selected_mask.segment(offset,size).fill(1);
440 size = covars_.size()*covars_[0].cols();
441 if (selected_values_labels.find(
"widths")!=selected_values_labels.end())
442 selected_mask.segment(offset,size).fill(2);
446 size = offsets_.size();
447 if (selected_values_labels.find(
"offsets")!=selected_values_labels.end())
448 selected_mask.segment(offset,size).fill(3);
452 size = slopes_.size()*slopes_[0].size();
453 if (selected_values_labels.find(
"slopes")!=selected_values_labels.end())
454 selected_mask.segment(offset,size).fill(4);
464 int n_basis_functions = centers_.size();
467 for (
int i_bfs=0; i_bfs<n_basis_functions; i_bfs++)
469 values.segment(offset,n_dims) = centers_[i_bfs]; offset += n_dims;
470 values.segment(offset,n_dims) = covars_[i_bfs].diagonal(); offset += n_dims;
471 values.segment(offset,n_dims) = slopes_[i_bfs]; offset += n_dims;
472 values[offset] = offsets_[i_bfs]; offset += 1;
473 values[offset] = priors_[i_bfs]; offset += 1;
500 if (all_values_vector_size_ != values.size())
502 cerr << __FILE__ <<
":" << __LINE__ <<
": values is of wrong size." << endl;
507 int n_basis_functions = centers_.size();
510 for (
int i_bfs=0; i_bfs<n_basis_functions; i_bfs++)
512 VectorXd cur_center = values.segment(offset,n_dims);
515 if ( !(centers_[i_bfs].array() == cur_center.array()).all() )
518 centers_[i_bfs] = values.segment(offset,n_dims) ; offset += n_dims;
520 VectorXd cur_width = values.segment(offset,n_dims);
523 if ( !(covars_[i_bfs].diagonal().array() == cur_width.array()).all() )
526 covars_[i_bfs].diagonal() = values.segment(offset,n_dims) ; offset += n_dims;
530 slopes_[i_bfs] = values.segment(offset,n_dims) ; offset += n_dims;
531 offsets_[i_bfs] = values[offset] ; offset += 1;
532 priors_[i_bfs] = values[offset] ; offset += 1;
575 bool UnifiedModel::saveGridData(
const VectorXd& min,
const VectorXd& max,
const VectorXi& n_samples_per_dim,
string save_directory,
bool overwrite)
const 577 if (save_directory.empty())
580 #ifndef NDEBUG // Variables below are only required for asserts; check for NDEBUG to avoid warnings. 581 int n_dims = min.size();
582 assert(n_dims==max.size());
583 assert(n_dims==n_samples_per_dim.size());
592 MatrixXd activations;
593 if (cosine_basis_functions_)
595 BasisFunction::Cosine::activations(covars_,centers_,inputs,activations);
599 BasisFunction::Gaussian::activations(centers_,covars_,priors_,inputs,activations,normalized_basis_functions_);
600 if (normalized_basis_functions_)
602 MatrixXd unnormalized_activations;
603 BasisFunction::Gaussian::activations(centers_,covars_,priors_,inputs,unnormalized_activations,
false);
604 saveMatrix(save_directory,
"activations_unnormalized_grid.txt",unnormalized_activations,overwrite);
608 MatrixXd predictions;
611 saveMatrix(save_directory,
"n_samples_per_dim.txt",n_samples_per_dim,overwrite);
612 saveMatrix(save_directory,
"inputs_grid.txt",inputs,overwrite);
613 saveMatrix(save_directory,
"lines_grid.txt",lines,overwrite);
614 saveMatrix(save_directory,
"activations_grid.txt",activations,overwrite);
615 saveMatrix(save_directory,
"predictions_grid.txt",predictions,overwrite);
623 if (modifier.compare(
"lines_pivot_at_max_activation")==0)
626 if (modifier.compare(
"slopes_as_angles")==0)
UnifiedModel class header file.
Header file for input/output of Eigen matrices to ASCII files.
void getParameterVectorMask(const std::set< std::string > selected_values_labels, Eigen::VectorXi &selected_mask) const
Get a mask for selecting parameters.
FunctionApproximator class header file.
void setParameterVectorModifierPrivate(std::string modifier, bool new_value)
Turn certain modifiers on or off, see Parameterizable::setParameterVectorModifier().
std::string toString(void) const
Returns a string representation of the object.
bool saveGridData(const Eigen::VectorXd &min, const Eigen::VectorXd &max, const Eigen::VectorXi &n_samples_per_dim, std::string directory, bool overwrite=false) const
Generate a grid of inputs, and output the response of the basis functions and line segments for these...
void getLines(const Eigen::Ref< const Eigen::MatrixXd > &inputs, Eigen::MatrixXd &lines) const
Get the output of each linear model (unweighted) for the given inputs.
static void generateInputsGrid(const Eigen::VectorXd &min, const Eigen::VectorXd &max, const Eigen::VectorXi &n_samples_per_dim, Eigen::MatrixXd &inputs_grid)
Generate a input samples that lie on a grid (much like Matlab's meshgrid) For instance, if min = [2 6], and max = [3 8], and n_samples_per_dim = [3 5] then this function first makes linearly spaces samples along each dimension, e.g.
void set_slopes_as_angles(bool slopes_as_angles)
Whether to return slopes as angles or slopes in UnifiedModel::getParameterVectorAll() ...
void set_lines_pivot_at_max_activation(bool lines_pivot_at_max_activation)
Set whether the offsets should be adapted so that the line segments pivot around the mode of the basi...
Class for providing access to a model's parameters as a vector.
bool saveMatrix(std::string filename, Eigen::Matrix< Scalar, RowsAtCompileTime, ColsAtCompileTime > matrix, bool overwrite=false)
Save an Eigen matrix to an ASCII file.
BasisFunction header file.
void kernelActivations(const Eigen::Ref< const Eigen::MatrixXd > &inputs, Eigen::MatrixXd &kernel_activations) const
Get the kernel activations for given inputs.
#define RETURN_STRING_FROM_BOOST_SERIALIZATION_XML(name)
Macro to convert the boost XML serialization of an object into a string.
void getParameterVectorAll(Eigen::VectorXd &all_values) const
Return a vector that returns all available parameter values.
The unified model, which can be used to represent the model of all other function approximators...
BOOST_CLASS_EXPORT_IMPLEMENT(DmpBbo::UnifiedModel)
For boost::serialization.
void getSelectableParameters(std::set< std::string > &selected_values_labels) const
Return all the names of the parameter types that can be selected.
int getParameterVectorAllSize(void) const
Get the size of the parameter values vector when it contains all available parameter values...
UnifiedModel * clone(void) const
Return a pointer to a deep copy of the object.
void evaluate(const Eigen::Ref< const Eigen::MatrixXd > &inputs, Eigen::MatrixXd &output) const
Compute the sum of the locally weighted lines.
Header file to generate strings from boost serialized files.
void setParameterVectorAll(const Eigen::VectorXd &values)
Set all available parameter values with one vector.
int getExpectedInputDim(void) const
The expected dimensionality of the input data.
Header file for serialization of Eigen matrices.