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> 43 #include <eigen3/Eigen/LU> 45 using namespace Eigen;
50 ModelParametersGMR::ModelParametersGMR(std::vector<double> priors,
51 std::vector<Eigen::VectorXd> means,
52 std::vector<Eigen::MatrixXd> covars,
int n_dims_out)
54 size_t n_gaussians = priors.size();
55 assert(n_gaussians>0);
56 int n_dims_gmm = means[0].size();
57 int n_dims_in = n_dims_gmm - n_dims_out;
59 #ifndef NDEBUG // Check for NDEBUG to avoid 'unused variable' warnings 62 assert(means.size() == n_gaussians);
63 assert(covars.size() == n_gaussians);
64 for (
size_t i = 0; i < n_gaussians; i++)
66 assert(means[i].size() == n_dims_gmm);
67 assert(covars[i].cols() == n_dims_gmm);
68 assert(covars[i].rows() == n_dims_gmm);
74 means_x_.resize(n_gaussians);
75 means_y_.resize(n_gaussians);
76 covars_x_.resize(n_gaussians);
77 covars_y_.resize(n_gaussians);
78 covars_y_x_.resize(n_gaussians);
80 for (
size_t i = 0; i < n_gaussians; i++)
82 means_x_[i] = means[i].segment(0,n_dims_in);
83 means_y_[i] = means[i].segment(n_dims_in,n_dims_out);
85 covars_x_[i] = covars[i].block(0,0,n_dims_in,n_dims_in);
86 covars_y_[i] = covars[i].block(n_dims_in,n_dims_in,n_dims_out,n_dims_out);
87 covars_y_x_[i] = covars[i].block(n_dims_in, 0, n_dims_out, n_dims_in);
91 updateCachedMembers();
93 all_values_vector_size_ = 0;
98 ModelParametersGMR::ModelParametersGMR(
int n_observations, std::vector<double> priors,
99 std::vector<Eigen::VectorXd> means,
100 std::vector<Eigen::MatrixXd> covars,
104 assert(n_observations >= 0);
106 n_observations_ = n_observations;
109 ModelParametersGMR::ModelParametersGMR(std::vector<double> priors,
110 std::vector<Eigen::VectorXd> means_x, std::vector<Eigen::VectorXd> means_y,
111 std::vector<Eigen::MatrixXd> covars_x, std::vector<Eigen::MatrixXd> covars_y,
112 std::vector<Eigen::MatrixXd> covars_y_x)
119 covars_y_x_(covars_y_x)
122 size_t n_gaussians = priors.size();
124 #ifndef NDEBUG // Check for NDEBUG to avoid 'unused variable' warnings for n_dims_in and n_dims_out. 125 assert(n_gaussians>0);
126 assert(means_x_.size() == n_gaussians);
127 assert(means_y_.size() == n_gaussians);
128 assert(covars_x_.size() == n_gaussians);
129 assert(covars_y_.size() == n_gaussians);
130 assert(covars_y_x_.size() == n_gaussians);
133 for (
size_t i = 0; i < n_gaussians; i++)
135 assert(means_x_[i].size() == n_dims_in);
136 assert(covars_x_[i].rows() == n_dims_in);
137 assert(covars_x_[i].cols() == n_dims_in);
138 assert(covars_y_x_[i].cols() == n_dims_in);
142 for (
size_t i = 0; i < n_gaussians; i++)
144 assert(covars_y_[i].rows() == n_dims_out);
145 assert(covars_y_[i].cols() == n_dims_out);
146 assert(covars_y_x_[i].rows() == n_dims_out);
150 updateCachedMembers();
152 all_values_vector_size_ = 0;
167 ModelParametersGMR::ModelParametersGMR(
int n_observations, std::vector<double> priors,
168 std::vector<Eigen::VectorXd> means_x, std::vector<Eigen::VectorXd> means_y,
169 std::vector<Eigen::MatrixXd> covars_x, std::vector<Eigen::MatrixXd> covars_y,
170 std::vector<Eigen::MatrixXd> covars_y_x)
173 assert(n_observations >= 0);
175 n_observations_ = n_observations;
179 void ModelParametersGMR::updateCachedMembers(
void)
184 covars_x_inv_.resize(n_gaussians);
185 mvgd_scale_.resize(n_gaussians);
186 for (
int i=0; i<n_gaussians; i++)
188 covars_x_inv_[i] = covars_x_[i].inverse();
191 double in_sqrt = pow(2*M_PI,n_dims_in)*covars_x_[i].determinant();
192 mvgd_scale_[i] = pow(in_sqrt,-0.5);
198 std::vector<double> priors;
199 std::vector<VectorXd> means_x;
200 std::vector<VectorXd> means_y;
201 std::vector<MatrixXd> covars_x;
202 std::vector<MatrixXd> covars_y;
203 std::vector<MatrixXd> covars_y_x;
204 int n_observations = n_observations_;
206 for (
size_t i = 0; i < priors_.size(); i++)
208 priors.push_back(priors_[i]);
209 means_x.push_back(VectorXd(means_x_[i]));
210 means_y.push_back(VectorXd(means_y_[i]));
211 covars_x.push_back(MatrixXd(covars_x_[i]));
212 covars_y.push_back(MatrixXd(covars_y_[i]));
213 covars_y_x.push_back(MatrixXd(covars_y_x_[i]));
216 return new ModelParametersGMR(n_observations, priors, means_x, means_y, covars_x, covars_y, covars_y_x);
219 template<
class Archive>
220 void ModelParametersGMR::serialize(Archive & ar,
const unsigned int version)
225 ar & BOOST_SERIALIZATION_NVP(priors_);
226 ar & BOOST_SERIALIZATION_NVP(means_x_);
227 ar & BOOST_SERIALIZATION_NVP(means_y_);
228 ar & BOOST_SERIALIZATION_NVP(covars_x_);
229 ar & BOOST_SERIALIZATION_NVP(covars_y_);
230 ar & BOOST_SERIALIZATION_NVP(covars_y_x_);
231 ar & BOOST_SERIALIZATION_NVP(covars_x_inv_);
232 ar & BOOST_SERIALIZATION_NVP(mvgd_scale_);
241 bool ModelParametersGMR::saveGMM(std::string directory,
const std::vector<Eigen::VectorXd>& centers,
const std::vector<Eigen::MatrixXd>& covars,
bool overwrite,
int iter)
243 for (
size_t i_gau = 0; i_gau < centers.size(); i_gau++)
248 stream <<
"_iter" << setw(2) << setfill(
'0') << iter;
249 stream <<
"_mu" << setw(3) << setfill(
'0') << i_gau <<
".txt";
250 string filename = stream.str();
251 if (!
saveMatrix(directory, filename, centers[i_gau], overwrite))
255 stringstream stream2;
258 stream2 <<
"_iter" << setw(2) << setfill(
'0') << iter;
259 stream2 <<
"_covar" << setw(3) << setfill(
'0') << i_gau <<
".txt";
260 filename = stream2.str();
262 if (!
saveMatrix(directory, filename, covars[i_gau], overwrite))
270 if (save_directory.empty())
277 int n_gaussians = means_x_.size();
278 int n_dims_in = means_x_[0].size();
279 int n_dims_out = means_y_[0].size();
280 int n_dims_gmm = n_dims_in + n_dims_out;
283 std::vector<VectorXd> means(n_gaussians);
284 std::vector<MatrixXd> covars(n_gaussians);
285 for (
int i_gau = 0; i_gau < n_gaussians; i_gau++)
287 means[i_gau] = VectorXd(n_dims_gmm);
288 means[i_gau].segment(0, n_dims_in) = means_x_[i_gau];
289 means[i_gau].segment(n_dims_in, n_dims_out) = means_y_[i_gau];
291 covars[i_gau] = MatrixXd(n_dims_gmm,n_dims_gmm);
292 covars[i_gau].fill(0);
293 covars[i_gau].block(0, 0, n_dims_in, n_dims_in) = covars_x_[i_gau];
294 covars[i_gau].block(n_dims_in, n_dims_in, n_dims_out, n_dims_out) = covars_y_[i_gau];
295 covars[i_gau].block(n_dims_in, 0, n_dims_out, n_dims_in) = covars_y_x_[i_gau];
296 covars[i_gau].block(0, n_dims_in, n_dims_in, n_dims_out) = covars_y_x_[i_gau].transpose();
299 saveGMM(save_directory,means,covars,overwrite);
307 int n_gaussians = means_x_.size();
308 assert(n_gaussians>0);
309 int n_dims_in = means_x_[0].size();
310 int n_dims_out = means_y_[0].size();
311 int n_dims_gmm = n_dims_in + n_dims_out;
314 for (
int i_gau = 0; i_gau < n_gaussians; i_gau++)
318 n_rows += n_dims_gmm;
321 gmm_as_matrix = MatrixXd::Zero(n_rows,n_dims_gmm);
323 gmm_as_matrix(0,0) = n_gaussians;
324 gmm_as_matrix(0,1) = n_dims_out;
325 gmm_as_matrix(1,0) = n_observations_;
327 VectorXd mean = VectorXd(n_dims_gmm);
328 MatrixXd covar = MatrixXd(n_dims_gmm,n_dims_gmm);
330 for (
int i_gau = 0; i_gau < n_gaussians; i_gau++)
332 mean.segment(0, n_dims_in) = means_x_[i_gau];
333 mean.segment(n_dims_in, n_dims_out) = means_y_[i_gau];
335 covar.block(0, 0, n_dims_in, n_dims_in) = covars_x_[i_gau];
336 covar.block(n_dims_in, n_dims_in, n_dims_out, n_dims_out) = covars_y_[i_gau];
337 covar.block(n_dims_in, 0, n_dims_out, n_dims_in) = covars_y_x_[i_gau];
338 covar.block(0, n_dims_in, n_dims_in, n_dims_out) = covars_y_x_[i_gau].transpose();
340 gmm_as_matrix(cur_row,0) = priors_[i_gau];
341 gmm_as_matrix.row(cur_row+1) = mean;
342 gmm_as_matrix.block(cur_row+2,0,n_dims_gmm,n_dims_gmm) = covar;
344 cur_row += 1 + 1 + n_dims_gmm;
350 int n_dims_gmm = gmm_matrix.cols();
351 int n_rows = gmm_matrix.rows();
352 assert(n_dims_gmm>1);
355 int n_gaussians = gmm_matrix(0,0);
356 int n_dims_out = gmm_matrix(0,1);
357 int n_observations = gmm_matrix(1,0);
359 assert(n_rows == (2+ (n_gaussians*(1+1+n_dims_gmm))));
361 vector<double> priors(n_gaussians);
362 vector<VectorXd> means(n_gaussians);
363 vector<MatrixXd> covars(n_gaussians);
366 for (
int i_gau = 0; i_gau < n_gaussians; i_gau++)
368 priors[i_gau] = gmm_matrix(cur_row,0);
370 means[i_gau] = gmm_matrix.row(cur_row+1);
372 covars[i_gau] = gmm_matrix.block(cur_row+2,0,n_dims_gmm,n_dims_gmm);
374 cur_row += 1 + 1 + n_dims_gmm;
382 if (filename.empty())
385 MatrixXd gmm_as_matrix;
388 if (!
saveMatrix(filename, gmm_as_matrix, overwrite))
405 selected_values_labels = set<string>();
550 int n_gaussians = means_x_.size();
554 vector<VectorXd> centers = means_x_;
555 vector<MatrixXd> covars = covars_x_;
557 vector<VectorXd> slopes(n_gaussians);
558 vector<double> offsets(n_gaussians);
560 for (
int i_gau=0; i_gau<n_gaussians; i_gau++)
562 slopes[i_gau] = (covars_y_x_[i_gau] * covars_x_inv_[i_gau]).transpose();
564 assert(means_y_[i_gau].size()==1);
565 offsets[i_gau] = means_y_[i_gau][0] - slopes[i_gau].dot(means_x_[i_gau]);
569 bool normalized_basis_functions =
true;
570 bool lines_pivot_at_max_activation =
false;
572 return new UnifiedModel(centers, covars, slopes, offsets, priors_, normalized_basis_functions,lines_pivot_at_max_activation);
UnifiedModel class header file.
void getParameterVectorAll(Eigen::VectorXd &all_values) const
Return a vector that returns all available parameter values.
Header file for input/output of Eigen matrices to ASCII files.
FunctionApproximator class header file.
bool saveGMMToMatrix(std::string filename, bool overwrite=false) const
Save the GMM as a matrix in an ASCII file.
static bool saveGMM(std::string directory, const std::vector< Eigen::VectorXd > ¢ers, const std::vector< Eigen::MatrixXd > &covars, bool overwrite=false, int iter=-1)
Save a Gaussian mixture model to a directory; useful for debugging.
static ModelParametersGMR * fromMatrix(const Eigen::MatrixXd &gmm_matrix)
Initialize a GMM from a matrix.
bool saveMatrix(std::string filename, Eigen::Matrix< Scalar, RowsAtCompileTime, ColsAtCompileTime > matrix, bool overwrite=false)
Save an Eigen matrix to an ASCII file.
BOOST_CLASS_EXPORT_IMPLEMENT(DmpBbo::ModelParametersGMR)
For boost::serialization.
virtual int getExpectedOutputDim(void) const
The expected dimensionality of the output data.
static ModelParametersGMR * loadGMMFromMatrix(std::string filename)
Load the GMM from a matrix in an ASCII file.
void toMatrix(Eigen::MatrixXd &gmm_as_matrix) const
This function represents the Gaussian Mixture Model as one big matrix.
#define RETURN_STRING_FROM_BOOST_SERIALIZATION_XML(name)
Macro to convert the boost XML serialization of an object into a string.
std::string toString(void) const
Returns a string representation of the object.
UnifiedModel * toUnifiedModel(void) const
Convert these model parameters to unified model parameters.
ModelParameters * clone(void) const
Return a pointer to a deep copy of the ModelParameters object.
void getParameterVectorMask(const std::set< std::string > selected_values_labels, Eigen::VectorXi &selected_mask) const
Get a mask for selecting parameters.
The unified model, which can be used to represent the model of all other function approximators...
void setParameterVectorAll(const Eigen::VectorXd &values)
Set all available parameter values with one vector.
Model parameters for the GMR function approximator.
ModelParametersGMR class header file.
void getSelectableParameters(std::set< std::string > &selected_values_labels) const
Return all the names of the parameter types that can be selected.
Base class for all model parameters of function approximators.
virtual int getExpectedInputDim(void) const
The expected dimensionality of the input data.
Header file to generate strings from boost serialized files.
unsigned int getNumberOfGaussians(void) const
Get the number of Gaussians in the GMM.
bool loadMatrix(std::string filename, Eigen::Matrix< Scalar, RowsAtCompileTime, ColsAtCompileTime > &m)
Load an Eigen matrix from an ASCII file.
Header file for serialization of Eigen matrices.