- Timestamp:
- Sep 12, 2016, 11:48:36 PM (8 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_StructOpt_integration_tests, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, GeometryObjects, Gui_displays_atomic_force_velocity, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, Ubuntu_1604_changes, stable
- Children:
- 653cea
- Parents:
- 2199c2
- git-author:
- Frederik Heber <heber@…> (06/29/14 21:20:49)
- git-committer:
- Frederik Heber <heber@…> (09/12/16 23:48:36)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Fragmentation/Exporters/SphericalPointDistribution.cpp
r2199c2 r450adf 63 63 typedef std::vector<double> DistanceArray_t; 64 64 65 // class generator: taken from www.cplusplus.com example std::generate 66 struct c_unique { 67 int current; 68 c_unique() {current=0;} 69 int operator()() {return current++;} 70 } UniqueNumber; 71 65 72 inline 66 73 DistanceArray_t calculatePairwiseDistances( … … 83 90 } 84 91 85 // class generator: taken from www.cplusplus.com example std::generate 86 struct c_unique { 87 int current; 88 c_unique() {current=0;} 89 int operator()() {return current++;} 90 } UniqueNumber; 91 92 /** Calculate the center of a given set of points in \a _positions but only 93 * for those indicated by \a _indices. 94 * 95 */ 96 inline 97 Vector calculateCenter( 98 const SphericalPointDistribution::VectorArray_t &_positions, 99 const SphericalPointDistribution::IndexList_t &_indices) 100 { 101 Vector Center; 102 Center.Zero(); 103 for (SphericalPointDistribution::IndexList_t::const_iterator iter = _indices.begin(); 104 iter != _indices.end(); ++iter) 105 Center += _positions[*iter]; 106 if (!_indices.empty()) 107 Center *= 1./(double)_indices.size(); 108 109 return Center; 110 } 111 112 /** Decides by an orthonormal third vector whether the sign of the rotation 113 * angle should be negative or positive. 114 * 115 * \return -1 or 1 116 */ 117 inline 118 double determineSignOfRotation( 119 const Vector &_oldPosition, 120 const Vector &_newPosition, 121 const Vector &_RotationAxis 122 ) 123 { 124 Vector dreiBein(_oldPosition); 125 dreiBein.VectorProduct(_RotationAxis); 126 dreiBein.Normalize(); 127 const double sign = 128 (dreiBein.ScalarProduct(_newPosition) < 0.) ? -1. : +1.; 129 LOG(6, "DEBUG: oldCenter on plane is " << _oldPosition 130 << ", newCenter in plane is " << _newPosition 131 << ", and dreiBein is " << dreiBein); 132 return sign; 133 } 134 135 /** Convenience function to recalculate old and new center for determining plane 136 * rotation. 137 */ 138 inline 139 void calculateOldAndNewCenters( 140 Vector &_oldCenter, 141 Vector &_newCenter, 142 const SphericalPointDistribution::VectorArray_t &_referencepositions, 143 const SphericalPointDistribution::VectorArray_t &_currentpositions, 144 const SphericalPointDistribution::IndexList_t &_bestmatching) 145 { 146 const size_t NumberIds = std::min(_bestmatching.size(), (size_t)3); 147 SphericalPointDistribution::IndexList_t continuousIds(NumberIds, -1); 148 std::generate(continuousIds.begin(), continuousIds.end(), UniqueNumber); 149 _oldCenter = calculateCenter(_referencepositions, continuousIds); 150 // C++11 defines a copy_n function ... 151 SphericalPointDistribution::IndexList_t::const_iterator enditer = _bestmatching.begin(); 152 std::advance(enditer, NumberIds); 153 SphericalPointDistribution::IndexList_t firstbestmatchingIds(NumberIds, -1); 154 std::copy(_bestmatching.begin(), enditer, firstbestmatchingIds.begin()); 155 _newCenter = calculateCenter( _currentpositions, firstbestmatchingIds); 156 } 92 157 /** Returns squared L2 error of the given \a _Matching. 93 158 * … … 219 284 } 220 285 221 /** Decides by an orthonormal third vector whether the sign of the rotation222 * angle should be negative or positive.223 *224 * \return -1 or 1225 */226 inline227 double determineSignOfRotation(228 const Vector &_oldPosition,229 const Vector &_newPosition,230 const Vector &_RotationAxis231 )232 {233 Vector dreiBein(_oldPosition);234 dreiBein.VectorProduct(_RotationAxis);235 dreiBein.Normalize();236 const double sign =237 (dreiBein.ScalarProduct(_newPosition) < 0.) ? -1. : +1.;238 LOG(6, "DEBUG: oldCenter on plane is " << _oldPosition239 << ", newCenter in plane is " << _newPosition240 << ", and dreiBein is " << dreiBein);241 return sign;242 }243 244 286 /** Finds combinatorially the best matching between points in \a _polygon 245 287 * and \a _newpolygon. … … 247 289 * We find the matching with the smallest L2 error, where we break when we stumble 248 290 * upon a matching with zero error. 291 * 292 * As points in \a _polygon may be have a weight greater 1 we have to match it to 293 * multiple points in \a _newpolygon. Eventually, these multiple points are combined 294 * for their center of weight, which is the only thing follow-up function see of 295 * these multiple points. Hence, we actually modify \a _newpolygon in the process 296 * such that the returned IndexList_t indicates a bijective mapping in the end. 249 297 * 250 298 * \sa recurseMatchings() for going through all matchings … … 255 303 */ 256 304 SphericalPointDistribution::IndexList_t SphericalPointDistribution::findBestMatching( 257 const SphericalPointDistribution::WeightedPolygon_t &_polygon,258 const SphericalPointDistribution::Polygon_t &_newpolygon305 const WeightedPolygon_t &_polygon, 306 Polygon_t &_newpolygon 259 307 ) 260 308 { … … 280 328 recurseMatchings(MCS, matching, indices, matchingsize); 281 329 } 282 return MCS.bestmatching; 283 } 284 285 inline 286 Vector calculateCenter( 287 const SphericalPointDistribution::VectorArray_t &_positions, 288 const SphericalPointDistribution::IndexList_t &_indices) 289 { 290 Vector Center; 291 Center.Zero(); 292 for (SphericalPointDistribution::IndexList_t::const_iterator iter = _indices.begin(); 293 iter != _indices.end(); ++iter) 294 Center += _positions[*iter]; 295 if (!_indices.empty()) 296 Center *= 1./(double)_indices.size(); 297 298 return Center; 299 } 300 301 inline 302 void calculateOldAndNewCenters( 303 Vector &_oldCenter, 304 Vector &_newCenter, 305 const SphericalPointDistribution::VectorArray_t &_referencepositions, 306 const SphericalPointDistribution::VectorArray_t &_currentpositions, 307 const SphericalPointDistribution::IndexList_t &_bestmatching) 308 { 309 const size_t NumberIds = std::min(_bestmatching.size(), (size_t)3); 310 SphericalPointDistribution::IndexList_t continuousIds(NumberIds, -1); 311 std::generate(continuousIds.begin(), continuousIds.end(), UniqueNumber); 312 _oldCenter = calculateCenter(_referencepositions, continuousIds); 313 // C++11 defines a copy_n function ... 314 SphericalPointDistribution::IndexList_t::const_iterator enditer = _bestmatching.begin(); 315 std::advance(enditer, NumberIds); 316 SphericalPointDistribution::IndexList_t firstbestmatchingIds(NumberIds, -1); 317 std::copy(_bestmatching.begin(), enditer, firstbestmatchingIds.begin()); 318 _newCenter = calculateCenter( _currentpositions, firstbestmatchingIds); 330 331 // combine multiple points and create simple IndexList from IndexTupleList 332 IndexTupleList_t bestmatching; 333 for (IndexList_t::const_iterator iter = MCS.bestmatching.begin(); 334 iter != MCS.bestmatching.end(); ++iter) 335 bestmatching.push_back(IndexList_t(1, *iter)); 336 const SphericalPointDistribution::IndexList_t IndexList = 337 joinPoints(_newpolygon, MCS.newpoints, bestmatching); 338 339 return IndexList; 340 } 341 342 SphericalPointDistribution::IndexList_t SphericalPointDistribution::joinPoints( 343 Polygon_t &_newpolygon, 344 const VectorArray_t &_newpoints, 345 const IndexTupleList_t &_bestmatching 346 ) 347 { 348 // combine all multiple points 349 IndexList_t IndexList; 350 IndexArray_t removalpoints; 351 unsigned int UniqueIndex = _newpolygon.size(); // all indices up to size are used right now 352 VectorArray_t newCenters; 353 newCenters.reserve(_bestmatching.size()); 354 for (IndexTupleList_t::const_iterator tupleiter = _bestmatching.begin(); 355 tupleiter != _bestmatching.end(); ++tupleiter) { 356 ASSERT (tupleiter->size() > 0, 357 "findBestMatching() - encountered tuple in bestmatching with size 0."); 358 if (tupleiter->size() == 1) { 359 // add point and index 360 IndexList.push_back(*tupleiter->begin()); 361 } else { 362 // combine into weighted and normalized center 363 Vector Center = calculateCenter(_newpoints, *tupleiter); 364 Center.Normalize(); 365 _newpolygon.push_back(Center); 366 LOG(5, "DEBUG: Combining " << tupleiter->size() << "points to weighted center " 367 << Center << " with new index " << UniqueIndex); 368 // mark for removal 369 removalpoints.insert(removalpoints.end(), tupleiter->begin(), tupleiter->end()); 370 // add new index 371 IndexList.push_back(UniqueIndex++); 372 } 373 } 374 // IndexList is now our new bestmatching (that is bijective) 375 LOG(4, "DEBUG: Our new bijective IndexList reads as " << IndexList); 376 377 // modifying _newpolygon: remove all points in removalpoints, add those in newCenters 378 Polygon_t allnewpoints = _newpolygon; 379 { 380 _newpolygon.clear(); 381 std::sort(removalpoints.begin(), removalpoints.end()); 382 size_t i = 0; 383 IndexArray_t::const_iterator removeiter = removalpoints.begin(); 384 for (Polygon_t::iterator iter = allnewpoints.begin(); 385 iter != allnewpoints.end(); ++iter, ++i) { 386 if ((removeiter != removalpoints.end()) && (i == *removeiter)) { 387 // don't add, go to next remove index 388 ++removeiter; 389 } else { 390 // otherwise add points 391 _newpolygon.push_back(*iter); 392 } 393 } 394 } 395 LOG(4, "DEBUG: The polygon with recentered points removed is " << _newpolygon); 396 397 // map IndexList to new shrinked _newpolygon 398 typedef std::set<unsigned int> IndexSet_t; 399 IndexSet_t SortedIndexList(IndexList.begin(), IndexList.end()); 400 IndexList.clear(); 401 { 402 size_t offset = 0; 403 IndexSet_t::const_iterator listiter = SortedIndexList.begin(); 404 IndexArray_t::const_iterator removeiter = removalpoints.begin(); 405 for (size_t i = 0; i < allnewpoints.size(); ++i) { 406 if ((removeiter != removalpoints.end()) && (i == *removeiter)) { 407 ++offset; 408 ++removeiter; 409 } else if ((listiter != SortedIndexList.end()) && (i == *listiter)) { 410 IndexList.push_back(*listiter - offset); 411 ++listiter; 412 } 413 } 414 } 415 LOG(4, "DEBUG: Our new bijective IndexList corrected for removed points reads as " 416 << IndexList); 417 418 return IndexList; 319 419 } 320 420 … … 497 597 SphericalPointDistribution::matchSphericalPointDistributions( 498 598 const SphericalPointDistribution::WeightedPolygon_t &_polygon, 499 constSphericalPointDistribution::Polygon_t &_newpolygon599 SphericalPointDistribution::Polygon_t &_newpolygon 500 600 ) 501 601 {
Note:
See TracChangeset
for help on using the changeset viewer.