DMP_BBO library
MetaParametersRBFN.cpp
Go to the documentation of this file.
1 
24 #include <boost/serialization/export.hpp>
25 #include <boost/archive/text_iarchive.hpp>
26 #include <boost/archive/text_oarchive.hpp>
27 #include <boost/archive/xml_iarchive.hpp>
28 #include <boost/archive/xml_oarchive.hpp>
30 
33 
34 
37 
38 #include <iostream>
39 #include <unordered_map>
40 
41 #include <boost/serialization/base_object.hpp>
42 #include <boost/serialization/nvp.hpp>
43 #include <boost/serialization/vector.hpp>
44 
45 
46 
47 using namespace Eigen;
48 using namespace std;
49 
50 namespace DmpBbo {
51 
52 MetaParametersRBFN::MetaParametersRBFN(int expected_input_dim, const std::vector<Eigen::VectorXd>& centers_per_dim, double intersection_height, double regularization)
53 :
54  MetaParameters(expected_input_dim),
55  n_bfs_per_dim_(VectorXi::Zero(0)),
56  centers_per_dim_(centers_per_dim),
57  intersection_height_(intersection_height),
58  regularization_(regularization)
59 {
60  assert(expected_input_dim==(int)centers_per_dim_.size());
61  for (unsigned int dd=0; dd<centers_per_dim_.size(); dd++)
62  assert(centers_per_dim_[dd].size()>0);
63  assert(intersection_height_>0 && intersection_height_<1);
64  assert(regularization>=0.0);
65 }
66 
67 MetaParametersRBFN::MetaParametersRBFN(int expected_input_dim, const Eigen::VectorXi& n_bfs_per_dim, double intersection_height, double regularization)
68 :
69  MetaParameters(expected_input_dim),
70  n_bfs_per_dim_(n_bfs_per_dim),
71  centers_per_dim_(std::vector<Eigen::VectorXd>(0)),
72  intersection_height_(intersection_height),
73  regularization_(regularization)
74 {
75  assert(expected_input_dim==n_bfs_per_dim_.size());
76  for (int dd=0; dd<n_bfs_per_dim_.size(); dd++)
77  assert(n_bfs_per_dim_[dd]>0);
78  assert(intersection_height_>0 && intersection_height_<1);
79  assert(regularization>=0.0);
80 };
81 
82 MetaParametersRBFN::MetaParametersRBFN(int expected_input_dim, int n_bfs, double intersection_height, double regularization)
83 :
84  MetaParameters(expected_input_dim),
85  n_bfs_per_dim_(VectorXi::Constant(1,n_bfs)),
86  centers_per_dim_(std::vector<Eigen::VectorXd>(0)),
87  intersection_height_(intersection_height),
88  regularization_(regularization)
89 {
90  assert(expected_input_dim==n_bfs_per_dim_.size());
91  for (int dd=0; dd<n_bfs_per_dim_.size(); dd++)
92  assert(n_bfs_per_dim_[dd]>0);
93  assert(intersection_height_>0 && intersection_height_<1);
94  assert(regularization>=0.0);
95 };
96 
98 {
99  MetaParametersRBFN* cloned;
100  if (centers_per_dim_.size()>0)
101  cloned = new MetaParametersRBFN(getExpectedInputDim(),centers_per_dim_,intersection_height_,regularization_);
102  else
103  cloned = new MetaParametersRBFN(getExpectedInputDim(),n_bfs_per_dim_,intersection_height_,regularization_);
104 
105  return cloned;
106 }
107 
109 void MetaParametersRBFN::getCentersAndWidths(const VectorXd& min, const VectorXd& max, Eigen::MatrixXd& centers, Eigen::MatrixXd& widths) const
110 {
111  int n_dims = getExpectedInputDim();
112  assert(min.size()==n_dims);
113  assert(max.size()==n_dims);
114 
115  vector<VectorXd> centers_per_dim_local(n_dims);
116  if (!centers_per_dim_.empty())
117  {
118  centers_per_dim_local = centers_per_dim_;
119  }
120  else
121  {
122  // Centers are not know yet, compute them based on min and max
123  for (int i_dim=0; i_dim<n_dims; i_dim++)
124  centers_per_dim_local[i_dim] = VectorXd::LinSpaced(n_bfs_per_dim_[i_dim],min[i_dim],max[i_dim]);
125  }
126 
127  // Determine the widths from the centers (separately for each dimension)
128  vector<VectorXd> widths_per_dim_local(n_dims);
129  for (int i_dim=0; i_dim<n_dims; i_dim++)
130  {
131  VectorXd cur_centers = centers_per_dim_local[i_dim]; // Abbreviation for convenience
132  int n_centers = cur_centers.size();
133  VectorXd cur_widths(n_centers);
134 
135  if (n_centers==1)
136  {
137  cur_widths[0] = 1.0;
138  }
139  else
140  {
141  // Consider two neighbouring basis functions, exp(-0.5(x-c0)^2/w^2) and exp(-0.5(x-c1)^2/w^2)
142  // Assuming the widths are the same for both, they are certain to intersect at x = 0.5(c0+c1)
143  // And we want the activation at x to be 'intersection'. So
144  // y = exp(-0.5(x-c0)^2/w^2)
145  // intersection = exp(-0.5((0.5(c0+c1))-c0)^2/w^2)
146  // intersection = exp(-0.5((0.5*c1-0.5*c0)^2/w^2))
147  // intersection = exp(-0.5((0.5*(c1-c0))^2/w^2))
148  // intersection = exp(-0.5(0.25*(c1-c0)^2/w^2))
149  // intersection = exp(-0.125((c1-c0)^2/w^2))
150  // w = sqrt((c1-c0)^2/-8*ln(intersection))
151  for (int cc=0; cc<n_centers-1; cc++)
152  {
153  double w = sqrt(pow(cur_centers[cc+1]-cur_centers[cc],2)/(-8*log(intersection_height_)));
154  cur_widths[cc] = w;
155  }
156  cur_widths[n_centers-1] = cur_widths[n_centers-2];
157  }
158  widths_per_dim_local[i_dim] = cur_widths;
159  }
160 
161  VectorXd digit_max(n_dims);
162  int n_centers = 1;
163  for (int i_dim=0; i_dim<n_dims; i_dim++)
164  {
165  n_centers = n_centers*centers_per_dim_local[i_dim].size();
166  digit_max[i_dim] = centers_per_dim_local[i_dim].size();
167  }
168  VectorXi digit = VectorXi::Zero(n_dims);
169 
170  centers.resize(n_centers,n_dims);
171  widths.resize(n_centers,n_dims);
172  int i_center=0;
173 
174  while (digit[0]<digit_max(0))
175  {
176  for (int i_dim=0; i_dim<n_dims; i_dim++)
177  {
178  centers(i_center,i_dim) = centers_per_dim_local[i_dim][digit[i_dim]];
179  widths(i_center,i_dim) = widths_per_dim_local[i_dim][digit[i_dim]];
180  }
181  i_center++;
182 
183  // Increment last digit by one
184  digit[n_dims-1]++;
185  for (int i_dim=n_dims-1; i_dim>0; i_dim--)
186  {
187  if (digit[i_dim]>=digit_max[i_dim])
188  {
189  digit[i_dim] = 0;
190  digit[i_dim-1]++;
191  }
192  }
193  }
194 
195 }
196 
197 template<class Archive>
198 void MetaParametersRBFN::serialize(Archive & ar, const unsigned int version)
199 {
200  // serialize base class information
201  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(MetaParameters);
202 
203  ar & BOOST_SERIALIZATION_NVP(n_bfs_per_dim_);
204  ar & BOOST_SERIALIZATION_NVP(centers_per_dim_);
205  ar & BOOST_SERIALIZATION_NVP(intersection_height_);
206  ar & BOOST_SERIALIZATION_NVP(regularization_);
207 }
208 
210 {
211  RETURN_STRING_FROM_BOOST_SERIALIZATION_XML("MetaParametersRBFN");
212 }
213 
214 }
BOOST_CLASS_EXPORT_IMPLEMENT(DmpBbo::MetaParametersRBFN)
For boost::serialization.
MetaParametersRBFN * clone(void) const
Return a pointer to a deep copy of the MetaParameters object.
Meta-parameters for the Radial Basis Function Network (RBFN) function approximator.
int getExpectedInputDim(void) const
The expected dimensionality of the input data.
double regularization(void) const
Accessor function for regularization.
#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.
Base class for all meta-parameters of function approximators.
void getCentersAndWidths(const Eigen::VectorXd &min, const Eigen::VectorXd &max, Eigen::MatrixXd &centers, Eigen::MatrixXd &widths) const
Get the centers and widths of the basis functions.
Header file to generate strings from boost serialized files.
MetaParametersRBFN class header file.
Header file for serialization of Eigen matrices.