Changeset 450adf for src/Fragmentation
- 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)
- Location:
- src/Fragmentation/Exporters
- Files:
-
- 4 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 { -
src/Fragmentation/Exporters/SphericalPointDistribution.hpp
r2199c2 r450adf 21 21 22 22 #include "LinearAlgebra/Vector.hpp" 23 24 class SphericalPointDistributionTest; 23 25 24 26 /** contains getters for the VSEPR model for specific number of electrons. … … 72 74 static Polygon_t matchSphericalPointDistributions( 73 75 const WeightedPolygon_t &_polygon, 74 constPolygon_t &_newpolygon76 Polygon_t &_newpolygon 75 77 ); 76 78 … … 80 82 static const double SQRT_3; 81 83 84 //!> typedef for a full rotation specification consisting of axis and angle. 82 85 typedef std::pair<Vector, double> Rotation_t; 83 86 87 //!> typedef for a list of indices (of points in a polygon) 84 88 typedef std::list<unsigned int> IndexList_t; 89 //!> typedef enumerating possibly multiple points accumulated as one point 90 typedef std::list< IndexList_t > IndexTupleList_t; 91 //!> typedef for a vector of indices 85 92 typedef std::vector<unsigned int> IndexArray_t; 93 //!> typedef for a Vector of positions 86 94 typedef std::vector<Vector> VectorArray_t; 95 //!> typedef for a Vector of positions with weights 96 typedef std::vector< std::pair<Vector, int> > WeightedVectorArray_t; 87 97 88 98 //!> amplitude up to which deviations in checks of rotations are tolerated … … 90 100 91 101 private: 102 //!> grant unit tests access to private parts 103 friend class SphericalPointDistributionTest; 104 92 105 static std::pair<double, double> calculateErrorOfMatching( 93 106 const std::vector<Vector> &_old, … … 116 129 static IndexList_t findBestMatching( 117 130 const WeightedPolygon_t &_polygon, 118 const Polygon_t &_newpolygon 131 Polygon_t &_newpolygon 132 ); 133 134 static IndexList_t joinPoints( 135 Polygon_t &_newpolygon, 136 const VectorArray_t &_newpoints, 137 const IndexTupleList_t &_bestmatching 119 138 ); 120 139 -
src/Fragmentation/Exporters/unittests/SphericalPointDistributionUnitTest.cpp
r2199c2 r450adf 245 245 } 246 246 247 /** UnitTest for joinPoints() 248 */ 249 void SphericalPointDistributionTest::joinPointsTest() 250 { 251 // test with simple configuration of three points 252 { 253 SphericalPointDistribution::Polygon_t newpolygon; 254 newpolygon += Vector(1.,0.,0.); 255 newpolygon += Vector(0.,1.,0.); 256 newpolygon += Vector(0.,0.,1.); 257 SphericalPointDistribution::Polygon_t expectedpolygon = newpolygon; 258 SphericalPointDistribution::IndexTupleList_t matching; 259 matching += SphericalPointDistribution::IndexList_t(1,0); 260 matching += SphericalPointDistribution::IndexList_t(1,1); 261 matching += SphericalPointDistribution::IndexList_t(1,2); 262 SphericalPointDistribution::IndexList_t IndexList = 263 SphericalPointDistribution::joinPoints( 264 newpolygon, 265 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()), 266 matching); 267 SphericalPointDistribution::IndexList_t expected; 268 expected += 0,1,2; 269 CPPUNIT_ASSERT_EQUAL( expected, IndexList ); 270 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon ); 271 } 272 273 // test with simple configuration of three points, only two are picked 274 { 275 SphericalPointDistribution::Polygon_t newpolygon; 276 newpolygon += Vector(1.,0.,0.); 277 newpolygon += Vector(0.,1.,0.); 278 newpolygon += Vector(0.,0.,1.); 279 SphericalPointDistribution::Polygon_t expectedpolygon = newpolygon; 280 SphericalPointDistribution::IndexTupleList_t matching; 281 matching += SphericalPointDistribution::IndexList_t(1,1); 282 matching += SphericalPointDistribution::IndexList_t(1,2); 283 SphericalPointDistribution::IndexList_t IndexList = 284 SphericalPointDistribution::joinPoints( 285 newpolygon, 286 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()), 287 matching); 288 SphericalPointDistribution::IndexList_t expected; 289 expected += 1,2; 290 CPPUNIT_ASSERT_EQUAL( expected, IndexList ); 291 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon ); 292 } 293 294 // test with simple configuration of three points, two are joined 295 { 296 SphericalPointDistribution::Polygon_t newpolygon; 297 newpolygon += Vector(1.,0.,0.); 298 newpolygon += Vector(0.,1.,0.); 299 newpolygon += Vector(0.,0.,1.); 300 SphericalPointDistribution::Polygon_t expectedpolygon; 301 expectedpolygon += Vector(1.,0.,0.); 302 expectedpolygon += Vector(0.,M_SQRT1_2,M_SQRT1_2); 303 SphericalPointDistribution::IndexTupleList_t matching; 304 SphericalPointDistribution::IndexList_t joined; 305 joined += 1,2; 306 matching += SphericalPointDistribution::IndexList_t(1,0); 307 matching += joined; 308 SphericalPointDistribution::IndexList_t IndexList = 309 SphericalPointDistribution::joinPoints( 310 newpolygon, 311 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()), 312 matching); 313 SphericalPointDistribution::IndexList_t expected; 314 expected += 0,1; 315 CPPUNIT_ASSERT_EQUAL( expected, IndexList ); 316 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon ); 317 } 318 319 // test with simple configuration of six points, two are joined, jumbled indices 320 { 321 SphericalPointDistribution::Polygon_t newpolygon; 322 newpolygon += Vector(1.,0.,1.); 323 newpolygon += Vector(1.,0.,0.); 324 newpolygon += Vector(1.,1.,0.); 325 newpolygon += Vector(0.,1.,0.); 326 newpolygon += Vector(0.,0.,1.); 327 newpolygon += Vector(1.,0.,1.); 328 SphericalPointDistribution::Polygon_t expectedpolygon; 329 expectedpolygon += Vector(1.,0.,1.); 330 expectedpolygon += Vector(1.,0.,0.); 331 expectedpolygon += Vector(1.,1.,0.); 332 expectedpolygon += Vector(1.,0.,1.); 333 expectedpolygon += Vector(0.,M_SQRT1_2,M_SQRT1_2); // new centers go last 334 SphericalPointDistribution::IndexTupleList_t matching; 335 SphericalPointDistribution::IndexList_t joined; 336 joined += 3,4; 337 matching += SphericalPointDistribution::IndexList_t(1,1); 338 matching += joined; 339 SphericalPointDistribution::IndexList_t IndexList = 340 SphericalPointDistribution::joinPoints( 341 newpolygon, 342 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()), 343 matching); 344 SphericalPointDistribution::IndexList_t expected; 345 expected += 1,4; 346 CPPUNIT_ASSERT_EQUAL( expected, IndexList ); 347 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon ); 348 } 349 } 247 350 248 351 /** UnitTest for matchSphericalPointDistributions() with three points -
src/Fragmentation/Exporters/unittests/SphericalPointDistributionUnitTest.hpp
r2199c2 r450adf 23 23 CPPUNIT_TEST_SUITE( SphericalPointDistributionTest) ; 24 24 CPPUNIT_TEST ( areEqualToWithinBoundsTest ); 25 CPPUNIT_TEST ( joinPointsTest ); 25 26 CPPUNIT_TEST ( matchSphericalPointDistributionsTest_2 ); 26 27 CPPUNIT_TEST ( matchSphericalPointDistributionsTest_3 ); … … 36 37 void tearDown(); 37 38 void areEqualToWithinBoundsTest(); 39 void joinPointsTest(); 38 40 void matchSphericalPointDistributionsTest_2(); 39 41 void matchSphericalPointDistributionsTest_3();
Note:
See TracChangeset
for help on using the changeset viewer.