TiledArray  0.7.0
representation.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2015 Virginia Tech
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Edward F Valeev
19  * Department of Chemistry, Virginia Tech
20  *
21  * representation.h
22  * May 13, 2015
23  *
24  */
25 
26 #ifndef TILEDARRAY_SYMM_REPRESENTATION_H__INCLUDED
27 #define TILEDARRAY_SYMM_REPRESENTATION_H__INCLUDED
28 
29 #include <functional>
30 #include <map>
31 #include <memory>
32 #include <vector>
33 
34 #include <TiledArray/error.h>
35 
36 namespace TiledArray {
37  namespace symmetry {
38 
40  template <typename T> T identity();
41 
46  template <typename Group, typename Representative>
48  public:
49  using group_type = Group;
50  using element_type = typename Group::element_type;
51  using representative_type = Representative;
52 
53  // Compiler generated functions
54  Representation() = delete;
55  Representation(const Representation&) = default;
56  Representation(Representation&&) = default;
57  Representation& operator=(const Representation&) = default;
59 
61  Representation(std::map<element_type,representative_type> generator_reps) :
62  generator_representatives_(std::move(generator_reps))
63  {
64  // N.B. this may mutate generator_reps, e.g. if it has an identity
65  init(generator_representatives_, element_representatives_);
66  }
67 
69  size_t order() const {
70  return element_representatives_.size();
71  }
72 
75  std::shared_ptr<group_type> group() const {
76 
77  // extract generators and elements
78  std::vector<element_type> generators;
79  generators.reserve(generator_representatives_.size());
80  for(const auto& g_op_pair: generator_representatives_) {
81  generators.emplace_back(g_op_pair.first);
82  }
83 
84  return std::make_shared<group_type>(std::move(generators));
85  }
86 
87  const std::map<element_type,representative_type>& representatives() const {
88  return element_representatives_;
89  }
90 
91  private:
92  std::shared_ptr<group_type> g_;
93  std::map<element_type,representative_type> generator_representatives_;
94  std::map<element_type,representative_type> element_representatives_;
95 
97  static void init(std::map<element_type,representative_type>& generator_reps,
98  std::map<element_type,representative_type>& element_reps) {
99 
100  // make sure identity is not among the generators
101  TA_ASSERT(generator_reps.end() ==
102  generator_reps.find(group_type::identity()));
103 
104  // make element->operator map
105  // start with generator->operator map
106  element_reps = generator_reps;
107 
108  // then add the identity element
109  element_reps[group_type::identity()] = identity<representative_type>();
110 
111  // Generate the remaining elements in the group by multiplying by generators
112  // to keep track of elements already added make an extra vector
113  std::vector<element_type> elements;
114  for(const auto& eop: element_reps)
115  elements.push_back(eop.first);
116 
117  for(size_t i = 0; i < elements.size(); ++i) {
118  auto e = std::cref(elements[i]);
119  auto e_op = std::cref(element_reps[e]);
120  for(const auto& g_op_pair: generator_reps) {
121  const auto& g = g_op_pair.first;
122  const auto& g_op = g_op_pair.second;
123  auto h = e * g;
124  if(element_reps.find(h) == element_reps.end()) {
125  auto h_op = e_op.get() * g_op;
126  element_reps[h] = h_op;
127  const auto orig_elements_capacity = elements.capacity();
128  elements.emplace_back(std::move(h));
129  // update e and e_op if capacity changed
130  if (orig_elements_capacity != elements.capacity()) {
131  e = std::cref(elements[i]);
132  e_op = std::cref(element_reps[e]);
133  }
134  }
135  }
136  }
137  } // init()
138 
139  }; // class Representation
140 
141  } // namespace symmetry
142 } // namespace TiledArray
143 
144 #endif /* TILEDARRAY_SYMM_REPRESENTATION_H__INCLUDED */
Representation(std::map< element_type, representative_type > generator_reps)
Construct Representation from a set of {generator,operator} pairs construct operator representation o...
const std::map< element_type, representative_type > & representatives() const
STL namespace.
Representation & operator=(const Representation &)=default
std::shared_ptr< group_type > group() const
#define TA_ASSERT(a)
Definition: error.h:107
T identity()
identity for group of objects of type T
size_t order() const
the order of the representation = the order of the group
typename Group::element_type element_type