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>
42 
49 template <typename Group, typename Representative>
51  public:
52  using group_type = Group;
53  using element_type = typename Group::element_type;
54  using representative_type = Representative;
55 
56  // Compiler generated functions
57  Representation() = delete;
58  Representation(const Representation&) = default;
62 
65  Representation(std::map<element_type, representative_type> generator_reps)
66  : generator_representatives_(std::move(generator_reps)) {
67  // N.B. this may mutate generator_reps, e.g. if it has an identity
68  init(generator_representatives_, element_representatives_);
69  }
70 
72  size_t order() const { return element_representatives_.size(); }
73 
76  std::shared_ptr<group_type> group() const {
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  // make sure identity is not among the generators
100  TA_ASSERT(generator_reps.end() ==
101  generator_reps.find(group_type::identity()));
102 
103  // make element->operator map
104  // start with generator->operator map
105  element_reps = generator_reps;
106 
107  // then add the identity element
108  element_reps[group_type::identity()] = identity<representative_type>();
109 
110  // Generate the remaining elements in the group by multiplying by generators
111  // to keep track of elements already added make an extra vector
112  std::vector<element_type> elements;
113  for (const auto& eop : element_reps) elements.push_back(eop.first);
114 
115  for (size_t i = 0; i < elements.size(); ++i) {
116  auto e = std::cref(elements[i]);
117  auto e_op = std::cref(element_reps[e]);
118  for (const auto& g_op_pair : generator_reps) {
119  const auto& g = g_op_pair.first;
120  const auto& g_op = g_op_pair.second;
121  auto h = e * g;
122  if (element_reps.find(h) == element_reps.end()) {
123  auto h_op = e_op.get() * g_op;
124  element_reps[h] = h_op;
125  const auto orig_elements_capacity = elements.capacity();
126  elements.emplace_back(std::move(h));
127  // update e and e_op if capacity changed
128  if (orig_elements_capacity != elements.capacity()) {
129  e = std::cref(elements[i]);
130  e_op = std::cref(element_reps[e]);
131  }
132  }
133  }
134  }
135  } // init()
136 
137 }; // class Representation
138 
139 } // namespace symmetry
140 } // namespace TiledArray
141 
142 #endif /* TILEDARRAY_SYMM_REPRESENTATION_H__INCLUDED */
Representation & operator=(const Representation &)=default
const std::map< element_type, representative_type > & representatives() const
typename Group::element_type element_type
#define TA_ASSERT(EXPR,...)
Definition: error.h:39
Representation(Representation &&)=default
std::shared_ptr< group_type > group() const
Representation(const Representation &)=default
Representation(std::map< element_type, representative_type > generator_reps)
size_t order() const
the order of the representation = the order of the group
Representation & operator=(Representation &&)=default
T identity()
identity for group of objects of type T