Changeset 1120
- Timestamp:
- 04/01/21 17:07:37 (4 years ago)
- Location:
- cpp/frams/model/similarity
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/model/similarity/measure-distribution.cpp
r1062 r1120 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-202 0Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2021 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 15 15 { "simil_density", 0, 0, "Density of surface sampling", "f 1 100 10", FIELD(density), "", }, 16 16 { "simil_bin_num", 0, 0, "Number of bins", "d 1 1000 128", FIELD(bin_num), "", }, 17 { "simil_samples_num", 0, 0, "Number of samples", "d 1 1048576 10 48576", FIELD(samples_num), "", },17 { "simil_samples_num", 0, 0, "Number of samples", "d 1 1048576 10000", FIELD(samples_num), "", }, //based on experiments, not much accuracy to gain when this is increased above 1000 18 18 { "evaluateDistance", 0, PARAM_DONTSAVE | PARAM_USERHIDDEN, "Evaluate model dissimilarity", "p f(oGeno,oGeno)", PROCEDURE(p_evaldistance), "Calculates dissimilarity between two models created from Geno objects.", }, 19 19 { 0, }, … … 37 37 funs[i][j] = std::make_pair(0, 0); 38 38 } 39 39 40 40 for (int i = 0; i < 2; i++) 41 41 sst_models[i] = new SolidsShapeTypeModel((*models[i])); 42 43 SimilMeasureDistribution::calculateFuns(); 42 43 SimilMeasureDistribution::calculateFuns(); 44 44 dist = SimilMeasureDistribution::compareFuns(); 45 45 46 46 for (int i = 0; i < 2; i++) 47 47 { … … 60 60 return -1; 61 61 } 62 62 63 63 density = params.at(0); 64 64 bin_num = params.at(1); 65 65 samples_num = params.at(2); 66 66 67 67 return 0; 68 68 } 69 69 70 void SimilMeasureDistribution::calculateFun(std::pair<double, float> *fun, Model &sampled)70 void SimilMeasureDistribution::calculateFun(std::pair<double, float> *fun, const Model &sampled) 71 71 { 72 72 int size = sampled.getPartCount(); … … 75 75 //Check if total number of points pairs is smaller than samples number 76 76 //but first, prevent exceeding int limits 77 if (size < (int) sqrt((double) std::numeric_limits<int>::max())) 78 samples_taken = min(samples_num, size*size); 77 //if (size < (int) sqrt((double) std::numeric_limits<int>::max())) 78 // samples_taken = min(samples_num, size*size); 79 80 rndgen.seed(55); //For determinism. Otherwise the descriptors (that choose samples pseudo-randomly) for the same Model can yield different values and so the dissimilarity between the object and its copy will not be 0. 81 std::uniform_int_distribution<> uniform_distrib(0, sampled.getPartCount() - 1); 79 82 80 83 //Get sampled distribution 81 std::vector<double> dist_vect = (this->*SimilMeasureDistribution::distribution_fun)(samples_taken, &sampled); 84 std::vector<double> dist_vect; 85 dist_vect.reserve(samples_taken); //we will add up to samples_taken elements to this vector 86 (this->*SimilMeasureDistribution::distribution_fun)(samples_taken, uniform_distrib, sampled, dist_vect); 82 87 83 88 auto result = std::minmax_element(dist_vect.begin(), dist_vect.end()); … … 86 91 87 92 //Create histogram 88 vector< float> hist(bin_num);93 vector<int> hist(bin_num); 89 94 int ind = 0; 90 95 91 96 for (unsigned int j = 0; j < dist_vect.size(); j++) 92 97 { 93 ind = (int) std::floor((dist_vect.at(j)-min)*1/(max-min)*bin_num);94 if (ind <= (bin_num -1))95 hist[ind] += 1;98 ind = (int)std::floor((dist_vect.at(j) - min) * 1 / (max - min) * bin_num); 99 if (ind <= (bin_num - 1)) 100 hist[ind]++; 96 101 else if (ind == bin_num) 97 hist[bin_num -1] += 1;102 hist[bin_num - 1]++; 98 103 } 99 104 … … 101 106 for (int j = 0; j < bin_num; j++) 102 107 { 103 fun[j] = std::make_pair(min +(max-min)/bin_num*(j+0.5), hist[j]);108 fun[j] = std::make_pair(min + (max - min) / bin_num * (j + 0.5), hist[j]); 104 109 } 105 110 … … 107 112 float total_mass = 0; 108 113 for (int j = 0; j < bin_num; j++) 109 110 111 114 { 115 total_mass += fun[j].second; 116 } 112 117 113 118 for (int j = 0; j < bin_num; j++) … … 129 134 } 130 135 131 vector<double> SimilMeasureDistribution::D1(int samples_taken, Model *sampled) 132 { 133 vector<double> dist_vect; 134 int size = sampled->getPartCount(); 136 void SimilMeasureDistribution::D1(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect) 137 { 138 int size = sampled.getPartCount(); 135 139 double x = 0; 136 140 double y = 0; 137 141 double z = 0; 138 142 139 143 for (int i = 0; i < size; i++) 140 144 { 141 Pt3D pos = sampled ->getPart(i)->p;145 Pt3D pos = sampled.getPart(i)->p; 142 146 x += pos.x; 143 147 y += pos.y; 144 148 z += pos.z; 145 149 } 146 147 x = x/size; 148 y = y/size; 149 z = z/size; 150 151 Pt3D centroid = {x, y, z}; 152 153 for (int i = 0; i < samples_taken; i++) 154 { 155 int p1 = rndUint(size); 156 double dist = sampled->getPart(p1)->p.distanceTo(centroid); 157 if (dist > 0) 158 dist_vect.push_back(dist); 159 } 160 161 return dist_vect; 162 } 163 164 vector<double> SimilMeasureDistribution::D2(int samples_taken, Model *sampled) 165 { 166 vector<double> dist_vect; 167 int size = sampled->getPartCount(); 168 for (int i = 0; i < samples_taken; i++) 169 { 170 int p1 = rndUint(size); 171 int p2 = rndUint(size); 172 double dist = sampled->getPart(p1)->p.distanceTo(sampled->getPart(p2)->p); 173 if (dist > 0) 174 dist_vect.push_back(dist); 175 } 176 177 return dist_vect; 178 } 179 180 vector<double> SimilMeasureDistribution::D3(int samples_taken, Model *sampled) 181 { 182 vector<double> dist_vect; 183 int size = sampled->getPartCount(); 184 for (int i = 0; i < samples_taken; i++) 185 { 186 int p1 = rndUint(size); 187 int p2 = rndUint(size); 188 int p3 = rndUint(size); 189 190 Pt3D v(sampled->getPart(p2)->p); 191 Pt3D w(sampled->getPart(p3)->p); 192 v -= sampled->getPart(p1)->p; 193 w -= sampled->getPart(p1)->p; 150 151 x = x / size; 152 y = y / size; 153 z = z / size; 154 155 Pt3D centroid = { x, y, z }; 156 157 for (int i = 0; i < samples_taken; i++) 158 { 159 int p1 = distribution(rndgen); 160 double dist = sampled.getPart(p1)->p.distanceTo(centroid); 161 if (dist > 0) 162 dist_vect.push_back(dist); 163 } 164 } 165 166 void SimilMeasureDistribution::D2(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect) 167 { 168 int size = sampled.getPartCount(); 169 for (int i = 0; i < samples_taken; i++) 170 { 171 int p1 = distribution(rndgen); 172 int p2 = distribution(rndgen); 173 double dist = sampled.getPart(p1)->p.distanceTo(sampled.getPart(p2)->p); 174 if (dist > 0) 175 dist_vect.push_back(dist); 176 } 177 } 178 179 void SimilMeasureDistribution::D3(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect) 180 { 181 for (int i = 0; i < samples_taken; i++) 182 { 183 int p1 = distribution(rndgen); 184 int p2 = distribution(rndgen); 185 int p3 = distribution(rndgen); 186 187 Pt3D v(sampled.getPart(p2)->p); 188 Pt3D w(sampled.getPart(p3)->p); 189 v -= sampled.getPart(p1)->p; 190 w -= sampled.getPart(p1)->p; 194 191 Pt3D cross_prod(0); 195 192 cross_prod.vectorProduct(v, w); 196 193 197 194 double dist = 0.5 * cross_prod.length(); 198 195 if (dist > 0) 199 196 dist_vect.push_back(dist); 200 197 } 201 202 return dist_vect; 203 } 204 205 vector<double> SimilMeasureDistribution::D4(int samples_taken, Model *sampled) 206 { 207 vector<double> dist_vect; 208 int size = sampled->getPartCount(); 209 for (int i = 0; i < samples_taken; i++) 210 { 211 int a = rndUint(size); 212 int b = rndUint(size); 213 int c = rndUint(size); 214 int d = rndUint(size); 215 216 Pt3D ad(sampled->getPart(a)->p); 217 Pt3D bd(sampled->getPart(b)->p); 218 Pt3D cd(sampled->getPart(c)->p); 219 220 ad -= sampled->getPart(d)->p; 221 bd -= sampled->getPart(d)->p; 222 cd -= sampled->getPart(d)->p; 223 198 } 199 200 void SimilMeasureDistribution::D4(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect) 201 { 202 for (int i = 0; i < samples_taken; i++) 203 { 204 int a = distribution(rndgen); 205 int b = distribution(rndgen); 206 int c = distribution(rndgen); 207 int d = distribution(rndgen); 208 209 Pt3D ad(sampled.getPart(a)->p); 210 Pt3D bd(sampled.getPart(b)->p); 211 Pt3D cd(sampled.getPart(c)->p); 212 213 ad -= sampled.getPart(d)->p; 214 bd -= sampled.getPart(d)->p; 215 cd -= sampled.getPart(d)->p; 216 224 217 Pt3D cross_prod(0); 225 218 cross_prod.vectorProduct(bd, cd); 226 219 cross_prod.entrywiseProduct(ad); 227 228 double dist = cross_prod.length()/6; 229 if (dist > 0) 230 dist_vect.push_back(dist); 231 } 232 233 return dist_vect; 234 } 235 236 vector<double> SimilMeasureDistribution::A3(int samples_taken, Model *sampled) 237 { 238 vector<double> dist_vect; 239 int size = sampled->getPartCount(); 240 for (int i = 0; i < samples_taken; i++) 241 { 242 int p1 = rndUint(size); 243 int p2 = rndUint(size); 244 int p3 = rndUint(size); 245 double a = sampled->getPart(p1)->p.distanceTo(sampled->getPart(p3)->p); 246 double b = sampled->getPart(p3)->p.distanceTo(sampled->getPart(p2)->p); 247 double c = sampled->getPart(p1)->p.distanceTo(sampled->getPart(p2)->p); 248 double beta = acos((a*a + b*b - c*c)/(2*a*b)); 249 220 221 double dist = cross_prod.length() / 6; 222 if (dist > 0) 223 dist_vect.push_back(dist); 224 } 225 } 226 227 void SimilMeasureDistribution::A3(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect) 228 { 229 int size = sampled.getPartCount(); 230 for (int i = 0; i < samples_taken; i++) 231 { 232 int p1 = distribution(rndgen); 233 int p2 = distribution(rndgen); 234 int p3 = distribution(rndgen); 235 double a = sampled.getPart(p1)->p.distanceTo(sampled.getPart(p3)->p); 236 double b = sampled.getPart(p3)->p.distanceTo(sampled.getPart(p2)->p); 237 double c = sampled.getPart(p1)->p.distanceTo(sampled.getPart(p2)->p); 238 double beta = acos((a * a + b * b - c * c) / (2 * a * b)); 239 250 240 if (!std::isnan(beta)) 251 241 dist_vect.push_back(beta); 252 242 } 253 254 return dist_vect;255 243 } 256 244 257 245 258 246 float dist(feature_t* F1, feature_t* F2) 259 { 260 return abs((*F1) -(*F2));247 { 248 return abs((*F1) - (*F2)); 261 249 } 262 250 … … 266 254 for (int j = 0; j < bin_num; j++) 267 255 { 268 points[j] = { fun[j].first};256 points[j] = { fun[j].first }; 269 257 weights[j] = fun[j].second; 270 258 } … … 275 263 feature_t *points[2]; 276 264 float *weights[2]; 277 265 278 266 for (int i = 0; i < 2; i++) 279 267 { … … 283 271 SimilMeasureDistribution::fillPointsWeights(fun1, points[0], weights[0]); 284 272 SimilMeasureDistribution::fillPointsWeights(fun2, points[1], weights[1]); 285 286 signature_t sig1 = { bin_num, points[0], weights[0]},287 sig2 = {bin_num, points[1], weights[1]};273 274 signature_t sig1 = { bin_num, points[0], weights[0] }, 275 sig2 = { bin_num, points[1], weights[1] }; 288 276 289 277 float e = emd(&sig1, &sig2, dist, 0, 0, bin_num, bin_num); 290 278 291 279 for (int i = 0; i < 2; i++) 292 280 { -
cpp/frams/model/similarity/measure-distribution.h
r1048 r1120 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-202 0Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2021 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 8 8 #include "simil-measure-base.h" 9 9 #include "EMD/emd.h" 10 #include <random> 10 11 11 12 class SimilMeasureDistribution : public SimilMeasureBase … … 13 14 public: 14 15 SimilMeasureDistribution(); 15 ~SimilMeasureDistribution() {};16 ~SimilMeasureDistribution() {}; 16 17 int setParams(std::vector<double> params); 17 18 void calculateFuns(); 18 void calculateFun(std::pair<double, float> *fun, Model &sampled);19 void calculateFun(std::pair<double, float> *fun, const Model &sampled); 19 20 double compareFuns(); 20 21 double EMD(std::pair<double, float> *fun1, std::pair<double, float> *fun2); … … 28 29 std::pair<double, float> *funs[2]; 29 30 SolidsShapeTypeModel *sst_models[2]; 30 std::vector<double> (SimilMeasureDistribution::*distribution_fun)(int samples_taken, Model *sampled);31 void (SimilMeasureDistribution::*distribution_fun)(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect); 31 32 32 33 void fillPointsWeights(std::pair<double, float> *fun, feature_t *points, float *weights); 33 34 double getDistance(); 34 std::vector<double> D2(int samples_taken, Model *sampled); 35 std::vector<double> D1(int samples_taken, Model *sampled); 36 std::vector<double> D3(int samples_taken, Model *sampled); 37 std::vector<double> D4(int samples_taken, Model *sampled); 38 std::vector<double> A3(int samples_taken, Model *sampled); 35 void D2(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect); 36 void D1(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect); 37 void D3(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect); 38 void D4(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect); 39 void A3(int samples_taken, std::uniform_int_distribution<> &distribution, const Model &sampled, std::vector<double> &dist_vect); 40 41 private: 42 std::mt19937 rndgen; 39 43 }; 40 44
Note: See TracChangeset
for help on using the changeset viewer.