source: src/Fragmentation/Summation/SubsetMap.cpp@ 830b3e

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing 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_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 830b3e was 19c50e, checked in by Frederik Heber <heber@…>, 12 years ago

IndexSetContainer now treats super set specially.

  • The super set must not gather its subsets via the gatherSubsets() as by construction all other sets are its subsets! As the super set is very large the power set way is no good idea.
  • added default cstor for SortedVector
  • removed SubsetMap::getMaximumSubsetLevel() as is replaced by ::getMaximumSetLevel() which is the level to sum up to.
  • changed all uses of getMaximumSubsetLevel() to getMaximumSetLevel().
  • TESTFIX: Changed unit test function on getMaximumSubsetLevel() to check on getMaximumSetLevel()
  • removed OrthogonalFullSummator as is fully replacable by OrthogonalSummator.
  • changed IndexSetContainer::createSuperSet a bit.
  • IndexSetContainer::AllIndices is now no more static convenience entity but truely contains the super set (non-statically). ::createSuperSet() is for convenience to be called in cstor for AllIndices.
  • Property mode set to 100644
File size: 7.5 KB
RevLine 
[2df580]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * SubsetMap.cpp
25 *
26 * Created on: Jul 3, 2012
27 * Author: heber
28 */
29
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "CodePatterns/MemDebug.hpp"
37
38#include "SubsetMap.hpp"
39
40#include <boost/bind.hpp>
41#include <boost/foreach.hpp>
[19c50e]42#include <boost/lambda/lambda.hpp>
[2df580]43#include <algorithm>
44#include <bitset>
45#include <set>
46
[19c50e]47#include "CodePatterns/Assert.hpp"
[2df580]48#include "CodePatterns/Log.hpp"
49
50SubsetMap::SubsetMap(IndexSetContainer &_container) :
51 tempset(new IndexSet())
52{
53 /// go through all IndexSets
[19c50e]54 const IndexSetContainer::Container_t &container = _container.getContainer();
55 for (IndexSetContainer::Container_t::const_iterator iter = container.begin();
56 iter != container.end(); ++iter) {
57 // check whether its the super set
58 if (*iter == _container.getSuperSet()) {
59 // place all other sets as its subsets
60 std::vector<IndexSet> returnsets;
61 returnsets.reserve(container.size());
62 for (IndexSetContainer::Container_t::const_iterator insertiter = container.begin();
63 insertiter != container.end(); ++insertiter)
64 if (iter != insertiter) {
65 LOG(2, "INFO: Current subset is " << **insertiter << " for super set.");
66 ASSERT( _container.getSuperSet()->contains(**insertiter),
67 "SubsetMap::SubsetMap() - "+toString(**insertiter)+" is not contained in super set "
68 +toString(*_container.getSuperSet())+".");
69 returnsets.push_back(**insertiter);
70 }
71 Lookup.insert( std::make_pair(*iter, IndexSetContainer::ptr(new IndexSetContainer(returnsets))) );
72 } else {
73 gatherSubsets(*iter);
74 }
75 }
[2df580]76}
77
78void SubsetMap::gatherSubsets(const IndexSet_ptr &ptr) {
79 // get the sets size and the size of the power sets
80 const size_t SetSize = ptr->size();
81 LOG(1, "INFO: Current set to gather all subsets for is " << *ptr << " with size " << SetSize << ".");
82 const size_t NoPowerSubsets = getNoPowerSets(SetSize);
83 LOG(1, "INFO: There are " << NoPowerSubsets << " sets to check for containment.");
84 std::vector<IndexSet> returnsets;
85 // sets is the number of possible subsets to check: NotContained means still
86 // needs check or is not contained; Contained means is contained, or has
87 // already been treated via a super(sub)set.
88 typedef std::vector<enum ContainedState> StateOfSubsets;
89 StateOfSubsets sets( NoPowerSubsets, NotContained);
90 // we have to traverse backwards, i.e. from greatest subsets to smallest to
91 // make the best possible use of the subset knowledge we already have for these
92 // subsets of the subset.
93 // WARNING: last set is the set itself which must not be in IndexSetContainer due to
94 // cyclic structure which shared_ptr cannot resolve.
95 StateOfSubsets::reverse_iterator iter = sets.rbegin()+1;
96 for (;iter != sets.rend(); iter = std::find(iter+1, sets.rend(), NotContained)) {
97 // get IndexSet (get index via distance)
98 // NOTE: reverse iterator naturally give reverse distance, hence flip both arguments
99 // also, reverse iterator is off by one, see ASSERT
100 const size_t index = std::distance(iter, sets.rend())-1;
101 ASSERT( sets.at(index) == *iter,
102 "SubsetMap::gatherSubsets() - distance from begin to iterator is not correct.");
103 *tempset = getSubset(*ptr, index );
104 LOG(2, "INFO: Current subset is " << *tempset << " at " << index << ".");
105 // check whether IndexSet is contained and known
106 if (ptr->contains(*tempset)) {
107 // mark as contained
108 *iter = Contained;
109 LOG(3, "DEBUG: Marking subset as Contained.");
110 if (Lookup.count(tempset)) {
111 LOG(2, "DEBUG: Subset is present in Lookup, adding.");
112 returnsets.push_back(*tempset);
113 // if so, also add its contained sets and mark them out
114 const IndexSetContainer::Container_t &container = getSubsets(tempset)->getContainer();
115 if (container.size()) {
116 LOG(2, "DEBUG: Subset is also present in Lookup, adding all its subsets");
117 for(IndexSetContainer::Container_t::const_iterator containeriter = container.begin();
118 containeriter != container.end();
119 ++containeriter) {
120 const size_t subindex = getPowerSetIndex(ptr, **containeriter);
121 LOG(4, "INFO: Current subset of subset is " << **containeriter << " at " << subindex << ".");
122 if (sets[subindex] != Contained) {
123 LOG(5, "DEBUG: Setting power subset to Contained.");
124 sets[subindex] = Contained;
125 returnsets.push_back(**containeriter);
126 }
127 }
128 }
129 }
130 }
131 }
132 LOG(1, "INFO: Adding " << returnsets.size() << " sets to Lookup for set " << *ptr << ".");
133 Lookup.insert( std::make_pair(ptr, IndexSetContainer::ptr(new IndexSetContainer(returnsets))) );
134}
135
136const size_t SubsetMap::getPowerSetIndex(const IndexSet_ptr &ptr, const IndexSet &subset) {
137 ASSERT( (ptr->size() < MAX_SETSIZE) && (subset.size() < MAX_SETSIZE),
138 "SubsetMap::getPowerSetIndex() - power sets of subsets must not be bigger than "
139 +toString((int)MAX_SETSIZE)+".");
140 ASSERT( ptr->contains(subset),
141 "SubsetMap::getPowerSetIndex() - "+(toString(*ptr))+" does not contain "
142 +toString(subset)+".");
143 std::bitset<MAX_SETSIZE> bits(0);
144 // go through each and search for indices present in both
145 IndexSet::iterator indexiter = ptr->begin();
146 IndexSet::iterator subindexiter = subset.begin();
147 for (; subindexiter != subset.end();) {
148 if (*indexiter == *subindexiter) {
149 // if matching, set bit and advance both iterators
150 bits.set( (size_t)std::distance(ptr->begin(), indexiter) );
151 ++indexiter;
152 ++subindexiter;
153 // if not, advance the iterator lacking behind
154 } else if ( *indexiter < *subindexiter) {
155 ++indexiter;
156 } else {
157 ++subindexiter;
158 }
159 }
160 return bits.to_ulong();
161}
162
163IndexSet SubsetMap::getSubset(const IndexSet &_set, size_t PowerSetNo) {
164 ASSERT( _set.size() < MAX_SETSIZE,
165 "SubsetMap::getSubset() - power sets of subsets must not be bigger than "
166 +toString((int)MAX_SETSIZE)+".");
167 ASSERT((PowerSetNo >= 0) && (PowerSetNo < getNoPowerSets(_set.size())),
168 "SubsetMap::getSubset() - Power set index "+toString(PowerSetNo)+" is out of range.");
169 std::bitset<MAX_SETSIZE> bits(PowerSetNo);
170 // place index into container with random access
171 std::vector<IndexSet::value_type> indices(_set.begin(), _set.end());
172 IndexSet indexset;
173 // go through each bit and insert if 1, not if 0
174 for (size_t index=0; index < indices.size(); ++index)
175 if (bits[index])
176 indexset.insert(indices[index]);
177 return indexset;
178}
[db11d4]179
[d199cc]180size_t SubsetMap::getMaximumSetLevel() const
181{
182 // last one is super set
183 Lookup_t::const_iterator iter = --Lookup.end();
184 return iter->first->size();
185}
Note: See TracBrowser for help on using the repository browser.