9 std::vector<size_t> sortedGroups;
10 for (
auto const& cl : groups) {
11 sortedGroups.push_back(cl.first);
14 std::sort(sortedGroups.begin(), sortedGroups.end(), [&](
const size_t left,
const size_t right) {
15 return groups.at(left).size() < groups.at(right).size() ||
16 (groups.at(left).size() == groups.at(right).size() && groups.at(left).front().front() < groups.at(right).front().front());
20 while (!sortedGroups.empty()) {
22 size_t currentRoot = sortedGroups.back();
23 sortedGroups.pop_back();
24 sortHierarchical(currentRoot, sortedGroups);
25 sortedSymmetries.push_back(currentRoot);
34 return sortedSymmetries.begin();
38 return sortedSymmetries.end();
43 return groups.at(index);
46bool DftSymmetries::existsInFirstSymmetry(
size_t index,
size_t value)
const {
48 if (symmetry.front() == value) {
55bool DftSymmetries::existsInSymmetry(
size_t index,
size_t value)
const {
57 for (
size_t index : symmetry) {
66int DftSymmetries::applySymmetry(std::vector<std::vector<size_t>>
const& symmetry,
size_t value,
size_t index)
const {
67 for (std::vector<size_t> element : symmetry) {
68 if (element[0] == value) {
69 return element[index];
75std::vector<std::vector<size_t>> DftSymmetries::createSymmetry(std::vector<std::vector<size_t>> parentSymmetry, std::vector<std::vector<size_t>> childSymmetry,
77 std::vector<std::vector<size_t>> result;
78 for (std::vector<size_t> childSym : childSymmetry) {
79 std::vector<size_t> symmetry;
80 for (
size_t child : childSym) {
81 int bijectionValue = applySymmetry(parentSymmetry, child, index);
82 if (bijectionValue >= 0) {
83 symmetry.push_back(bijectionValue);
89 result.push_back(symmetry);
94void DftSymmetries::sortHierarchical(
size_t parent, std::vector<size_t>& candidates) {
96 std::vector<size_t> children;
97 for (
int i = candidates.size() - 1;
i >= 0; --
i) {
98 size_t currentRoot = candidates[
i];
99 if (existsInSymmetry(parent, currentRoot)) {
102 children.insert(children.begin(), currentRoot);
103 candidates.erase(candidates.begin() + i);
108 for (
size_t i = 0;
i < children.size(); ++
i) {
110 for (
size_t index = 1; index < groups.at(parent).front().size(); ++index) {
111 std::vector<std::vector<size_t>> possibleSymmetry = createSymmetry(groups.at(parent), groups.at(children[i]), index);
112 if (possibleSymmetry.empty()) {
116 for (
size_t j = 0; j < children.size(); ) {
122 if (possibleSymmetry == groups.at(children[j])) {
123 STORM_LOG_TRACE(
"Child " << children[j] <<
" ignored as created by symmetries " << parent <<
" and " << children[i]);
124 groups.erase(children[j]);
125 children.erase(children.begin() + j);
139 while (!children.empty()) {
141 size_t largestChild = children.back();
143 sortHierarchical(largestChild, children);
144 sortedSymmetries.push_back(largestChild);
149 for (
size_t index : symmetries.sortedSymmetries) {
150 os <<
"Symmetry group for " << index <<
'\n';
151 for (
auto const& eqClass : symmetries.groups.at(index)) {
152 for (
auto const& i : eqClass) {
std::vector< std::vector< size_t > > const & getSymmetryGroup(size_t index) const
Get symmetry group corresponding to give top level index.
std::vector< size_t >::const_iterator begin() const
Retrieves an constant iterator that points to the beginning of the ordered symmetry groups.
std::vector< size_t >::const_iterator end() const
Retrieves an constant iterator that points past the last ordered symmetry group.
size_t nrSymmetries() const
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ASSERT(cond, message)
std::ostream & operator<<(std::ostream &os, DFTElementState st)