/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2012 University of Bonn. All rights reserved. * Copyright (C) 2013 Frederik Heber. All rights reserved. * * * This file is part of MoleCuilder. * * MoleCuilder is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * MoleCuilder is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MoleCuilder. If not, see . */ /* * IndexSetContainer.cpp * * Created on: Aug 2, 2012 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "IndexSetContainer.hpp" #include #include "CodePatterns/Log.hpp" #include "Fragmentation/Summation/IndexSet.hpp" #include "Fragmentation/KeySetsContainer.hpp" IndexSet::ptr IndexSetContainer::createSuperSet(const KeySetsContainer &_keysets) const { // create superset IndexSet::ptr _AllIndices(new IndexSet); for (KeySetsContainer::ArrayOfIntVectors::const_iterator iter = _keysets.KeySets.begin(); iter != _keysets.KeySets.end(); ++iter) for(KeySetsContainer::IntVector::const_iterator keyiter = (*iter).begin(); keyiter != (*iter).end(); ++keyiter) { if (*keyiter != -1) _AllIndices->insert((Index_t)*keyiter); } LOG(2, "DEBUG: AllIndices is " << *_AllIndices << "."); return _AllIndices; } IndexSet::ptr IndexSetContainer::createSuperSet(const std::vector &_container) const { // create superset IndexSet::ptr _AllIndices(new IndexSet); for (std::vector::const_iterator iter = _container.begin(); iter != _container.end(); ++iter) for(IndexSet::const_iterator keyiter = (*iter).begin(); keyiter != (*iter).end(); ++keyiter) { if (*keyiter != -1) _AllIndices->insert((Index_t)*keyiter); } LOG(2, "DEBUG: AllIndices is " << *_AllIndices << "."); return _AllIndices; } IndexSet::ptr IndexSetContainer::createSuperSet(const std::vector &_container) const { // create superset IndexSet::ptr _AllIndices(new IndexSet); for (std::vector::const_iterator iter = _container.begin(); iter != _container.end(); ++iter) for(IndexSet::const_iterator keyiter = (*iter)->begin(); keyiter != (*iter)->end(); ++keyiter) { if (*keyiter != -1) _AllIndices->insert((Index_t)*keyiter); } LOG(2, "DEBUG: AllIndices is " << *_AllIndices << "."); return _AllIndices; } IndexSetContainer::IndexSetContainer(const KeySetsContainer &_keysets) : AllIndices(createSuperSet(_keysets)) { const size_t SupersetSize = AllIndices->size(); // create container with all keysets for (KeySetsContainer::ArrayOfIntVectors::const_iterator iter = _keysets.KeySets.begin(); iter != _keysets.KeySets.end(); ++iter) { // create the IndexSets ... IndexSet tempset; for(KeySetsContainer::IntVector::const_iterator keyiter = (*iter).begin(); keyiter != (*iter).end(); ++keyiter) if (*keyiter != -1) tempset.insert((Index_t)*keyiter); // ... and insert, making sure that super set is AllIndices when present if (tempset.size() < SupersetSize) insert(tempset); else insert(AllIndices); } } size_t IndexSetContainer::countSetsTillLevel(const size_t level) const { // check if any sets are present if (getContainer().empty()) return 0; // define ends of interval SortedVector::Container_t::const_iterator start = getContainer().begin(); SortedVector::Container_t::const_iterator end = --getContainer().end(); // check whether all are smaller if ((*end)->size() <= level) return getContainer().size(); // check whether all are larger if ((*start)->size() > level) return 0; // continue as long as interval has more than one element while (std::distance(start, end) > 1) { // create iterator in between SortedVector::Container_t::const_iterator midpoint = start; std::advance( midpoint, std::distance(start, end)/2 ); // check iter and half the interval if ((*midpoint)->size() <= level) start = midpoint; else end = midpoint; } return std::distance(getContainer().begin(), end); }