00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "problib/conversions.h"
00038
00039 namespace pbl {
00040
00041 void PDFtoMsg(const PDF& pdf, problib::PDF& msg) {
00042 msg.dimensions = pdf.dimensions();
00043 serialize(pdf, msg);
00044
00045 if (pdf.type() == PDF::DISCRETE) {
00046 msg.type = problib::PDF::DISCRETE;
00047 } else {
00048 msg.type = msg.data[0];
00049 }
00050 }
00051
00052 problib::PDF PDFtoMsg(const PDF& pdf) {
00053 problib::PDF msg;
00054 PDFtoMsg(pdf, msg);
00055 return msg;
00056 }
00057
00058 PDF* msgToPDF(const problib::PDF& msg) {
00059 int i_data = 1;
00060 return deserialize(msg, msg.type, i_data);
00061 }
00062
00063 Gaussian* msgToGaussian(const problib::PDF& msg) {
00064 int i_data = 1;
00065 if (msg.type == problib::PDF::GAUSSIAN) {
00066 return deserialize_gaussian(msg, i_data);
00067 }
00068 return 0;
00069 }
00070
00071 Mixture* msgToMixture(const problib::PDF& msg) {
00072 int i_data = 1;
00073 if (msg.type == problib::PDF::MIXTURE) {
00074 return deserialize_mixture(msg, i_data);
00075 }
00076 return 0;
00077 }
00078
00079 PMF* msgToPMF(const problib::PDF& msg) {
00080 if (msg.type == problib::PDF::DISCRETE) {
00081 return deserialize_discrete(msg);
00082 }
00083 return 0;
00084 }
00085
00086 const Mixture* PDFtoMixture(const PDF& pdf) {
00087 if (pdf.type() != PDF::MIXTURE) {
00088 return 0;
00089 }
00090 return static_cast<const Mixture*>(&pdf);
00091 }
00092
00093 const Gaussian* PDFtoGaussian(const PDF& pdf) {
00094 if (pdf.type() != PDF::GAUSSIAN) {
00095 return 0;
00096 }
00097 const Gaussian* G = static_cast<const Gaussian*>(&pdf);
00098 return G;
00099 }
00100
00101 const Uniform* PDFtoUniform(const PDF& pdf) {
00102 if (pdf.type() != PDF::UNIFORM) {
00103 return 0;
00104 }
00105 const Uniform* U = static_cast<const Uniform*>(&pdf);
00106 return U;
00107 }
00108
00109 const PMF* PDFtoPMF(const PDF& pdf) {
00110 if (pdf.type() != PDF::DISCRETE) {
00111 return 0;
00112 }
00113 return static_cast<const PMF*>(&pdf);
00114 }
00115
00116 const Hybrid* PDFtoHybrid(const PDF& pdf) {
00117 if (pdf.type() != PDF::HYBRID) {
00118 return 0;
00119 }
00120 return static_cast<const Hybrid*>(&pdf);
00121 }
00122
00123 std::string typeToName(PDF::PDFType type) {
00124 if (type == PDF::GAUSSIAN) {
00125 return "gaussian";
00126 } else if (type == PDF::MIXTURE) {
00127 return "mixture";
00128 } else if (type == PDF::UNIFORM) {
00129 return "uniform";
00130 } else if (type == PDF::DISCRETE) {
00131 return "discrete";
00132 } else if (type == PDF::HYBRID) {
00133 return "hybrid";
00134 }
00135 return "unknown";
00136 }
00137
00138
00139
00140 void serialize(const PDF& pdf, problib::PDF& msg) {
00141 if (pdf.type() == PDF::GAUSSIAN) {
00142 const Gaussian* gauss = static_cast<const Gaussian*>(&pdf);
00143 serialize_gaussian(*gauss, msg);
00144 } else if (pdf.type() == PDF::MIXTURE) {
00145 const Mixture* mix = static_cast<const Mixture*>(&pdf);
00146 serialize_mixture(*mix, msg);
00147 } else if (pdf.type() == PDF::UNIFORM) {
00148 const Uniform* uniform = static_cast<const Uniform*>(&pdf);
00149 serialize_uniform(*uniform, msg);
00150 } else if (pdf.type() == PDF::DISCRETE) {
00151 const PMF* pmf = static_cast<const PMF*>(&pdf);
00152 serialize_discrete(*pmf, msg);
00153 } else if (pdf.type() == PDF::HYBRID) {
00154 const Hybrid* hybrid = static_cast<const Hybrid*>(&pdf);
00155 serialize_hybrid(*hybrid, msg);
00156 }
00157 }
00158
00159 PDF* deserialize(const problib::PDF& msg, int type, int& i_data) {
00160 if (type == problib::PDF::MIXTURE) {
00161 return deserialize_mixture(msg, i_data);
00162 } else if (type == problib::PDF::GAUSSIAN) {
00163 return deserialize_gaussian(msg, i_data);
00164 } else if (type == problib::PDF::UNIFORM) {
00165 return deserialize_uniform(msg, i_data);
00166 } else if (type == problib::PDF::DISCRETE) {
00167 return deserialize_discrete(msg);
00168 } else if (type == problib::PDF::EXACT) {
00169 return deserialize_exact(msg);
00170 } else if (type == problib::PDF::HYBRID) {
00171 return deserialize_hybrid(msg, i_data);
00172 }
00173 return 0;
00174 }
00175
00176 void serialize_gaussian(const Gaussian& gauss, problib::PDF& msg) {
00177 int dimensions = gauss.dimensions();
00178 int new_data_size = dimensions + ((dimensions + 1) * dimensions / 2) + 1;
00179
00180 msg.data.reserve(msg.data.size() + new_data_size);
00181
00182 msg.type = problib::PDF::GAUSSIAN;
00183 msg.data.push_back(msg.type);
00184
00185 const arma::vec& mu = gauss.getMean();
00186 for(int i = 0; i < dimensions; ++i) {
00187 msg.data.push_back(mu(i));
00188 }
00189
00190 const arma::mat& cov = gauss.getCovariance();
00191 for(int i = 0; i < dimensions; ++i) {
00192 for(int j = i; j < dimensions; ++j) {
00193 msg.data.push_back(cov(i, j));
00194 }
00195 }
00196 }
00197
00198 Gaussian* deserialize_gaussian(const problib::PDF& msg, int& i_data) {
00199 arma::vec mu(msg.dimensions);
00200 for(unsigned int i = 0; i < msg.dimensions; ++i) {
00201 mu(i) = msg.data[i_data++];
00202 }
00203
00204 arma::mat cov(msg.dimensions, msg.dimensions);
00205 for(unsigned int i = 0; i < msg.dimensions; ++i) {
00206 for(unsigned int j = i; j < msg.dimensions; ++j) {
00207 cov(i, j) = msg.data[i_data];
00208 cov(j, i) = msg.data[i_data];
00209 ++i_data;
00210 }
00211 }
00212
00213 return new Gaussian(mu, cov);
00214 }
00215
00216 void serialize_mixture(const Mixture& mix, problib::PDF& msg) {
00217
00218 msg.data.push_back(problib::PDF::MIXTURE);
00219
00220
00221 msg.data.push_back(mix.components());
00222
00223
00224 for(int i = 0; i < mix.components(); ++i) {
00225 msg.data.push_back(mix.getWeight(i));
00226 const PDF& pdf = mix.getComponent(i);
00227 serialize(pdf, msg);
00228 }
00229 }
00230
00231 Mixture* deserialize_mixture(const problib::PDF& msg, int& i_data) {
00232 Mixture* mix = new Mixture();
00233
00234 int num_components = (int)msg.data[i_data++];
00235
00236 for(int c = 0; c < num_components; ++c) {
00237 double w = msg.data[i_data++];
00238 int type = (int)msg.data[i_data++];
00239
00240 PDF* component = deserialize(msg, type, i_data);
00241 mix->addComponent(*component, w);
00242 delete component;
00243 }
00244
00245 mix->normalizeWeights();
00246
00247 return mix;
00248 }
00249
00250 void serialize_uniform(const Uniform& uniform, problib::PDF& msg) {
00251 msg.data.push_back(problib::PDF::UNIFORM);
00252 msg.data.push_back(uniform.getMaxDensity());
00253 }
00254
00255 Uniform* deserialize_uniform(const problib::PDF& msg, int& i_data) {
00256 Uniform* uniform = new Uniform(msg.dimensions);
00257 uniform->setDensity(msg.data[i_data++]);
00258 return uniform;
00259 }
00260
00261 void serialize_discrete(const PMF& pmf, problib::PDF& msg) {
00262 pmf.getValues(msg.values);
00263 pmf.getProbabilities(msg.probabilities);
00264 msg.domain_size = pmf.getDomainSize();
00265 }
00266
00267 PMF* deserialize_discrete(const problib::PDF& msg) {
00268 PMF* pmf = new PMF(msg.domain_size);
00269 std::vector<double>::const_iterator it_p = msg.probabilities.begin();
00270 for(std::vector<std::string>::const_iterator it_v = msg.values.begin(); it_v != msg.values.end(); ++it_v) {
00271 pmf->setProbability(*it_v, *it_p);
00272 ++it_p;
00273 }
00274 pmf->setDomainSize(msg.domain_size);
00275 return pmf;
00276 }
00277
00278 void serialize_hybrid(const Hybrid& hybrid, problib::PDF& msg) {
00279
00280 msg.data.push_back(problib::PDF::HYBRID);
00281
00282
00283 msg.data.push_back(hybrid.getPDFS().size());
00284
00285
00286 const std::vector<PDF*> pdfs = hybrid.getPDFS();
00287 for(std::vector<PDF*>::const_iterator it = pdfs.begin(); it != pdfs.end(); ++it) {
00288 const PDF& pdf = **it;
00289
00290 if (pdf.type() == PDF::DISCRETE) {
00291 bool already_contains_pmf = msg.domain_size != 0 || !msg.values.empty();
00292 assert_msg(!already_contains_pmf, "Can currently only decode at most one discrete pdf in hybrid pdf message.");
00293 msg.data.push_back(problib::PDF::DISCRETE);
00294 }
00295
00296 serialize(pdf, msg);
00297 }
00298 }
00299
00300 Hybrid* deserialize_hybrid(const problib::PDF& msg, int& i_data) {
00301 Hybrid* hybrid = new Hybrid();
00302
00303 int num_components = (int)msg.data[i_data++];
00304
00305 for(int c = 0; c < num_components; ++c) {
00306 int type = (int)msg.data[i_data++];
00307
00308 PDF* pdf = deserialize(msg, type, i_data);
00309 hybrid->addPDF(*pdf, -1);
00310 delete pdf;
00311 }
00312
00313 return hybrid;
00314 }
00315
00316 PDF* deserialize_exact(const problib::PDF& msg) {
00317 if (!msg.exact_value_vec.empty()) {
00318
00319 unsigned int dim = msg.exact_value_vec.size();
00320 arma::vec mu(dim);
00321 for(unsigned int i = 0; i < dim; ++i) {
00322 mu(i) = msg.exact_value_vec[i];
00323 }
00324 arma::mat cov = arma::zeros(dim, dim);
00325 return new Gaussian(mu, cov);
00326 } else if (msg.exact_value_str != "") {
00327
00328 PMF* pmf = new PMF();
00329 pmf->setProbability(msg.exact_value_str, 1.0);
00330 return pmf;
00331 }
00332
00333 return 0;
00334 }
00335
00336 }