Changeset 1120 for cpp/frams/model/similarity/measuredistribution.cpp
 Timestamp:
 04/01/21 17:07:37 (9 days ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

cpp/frams/model/similarity/measuredistribution.cpp
r1062 r1120 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999202 0Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 19992021 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 pseudorandomly) 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/(maxmin)*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 +(maxmin)/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 {
Note: See TracChangeset
for help on using the changeset viewer.