Cadabra
Computer algebra system for field theory problems
Adjform.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 #include <map>
5 #include <iosfwd>
6 #include <cstdint>
7 #include <string>
8 #include "Compare.hh"
9 #include "Kernel.hh"
10 #include "Storage.hh"
11 
12 namespace cadabra {
13 
14  class IndexMap;
15 
28 
29  class Adjform
30  {
31  public:
34  using value_type = short;
37  using array_type = std::vector<value_type>;
38  using const_reference = array_type::const_reference;
39  using const_iterator = array_type::const_iterator;
40 
41  Adjform();
42  template <typename IndexIterator>
43  Adjform(IndexIterator beg, IndexIterator end, IndexMap& index_map, const Kernel& kernel);
44  template <typename ValueIterator>
45  Adjform(ValueIterator beg, ValueIterator end, bool push_as_coordinates);
46 
47  const_iterator begin() const;
48  const_iterator end() const;
49 
50  // Return the position of the given index starting from the given
51  // offset (but returning the position from the actual start). Returns
52  // this->size() if not found.
53  size_type index_of(value_type index, size_type offset = 0) const;
54 
55  bool operator < (const Adjform& other) const;
56  bool operator == (const Adjform& other) const;
57  bool operator != (const Adjform& other) const;
58 
60 
61  size_type size() const;
62  size_type max_size() const;
63  bool empty() const;
64 
65  // Return true if the value at 'pos' is < 0
66  bool is_free_index(size_type pos) const;
67  // Return true if the value at pos is >= 0
68  bool is_dummy_index(size_type pos) const;
69 
70  size_type n_free_indices() const;
71  size_type n_dummy_indices() const;
72 
73  // Contract pairs of this type of index, e.g. with value=-1 '-1 -2 -3 -1' -> '3 -2 -3 0'.
74  // Returns true if the index was found and replaced.
75  bool resolve_dummy(value_type value);
76 
77  // Push value(s) to the end and contract it if a eqivalent is found, e.g. with
78  // value=-1 '-1 -2 -3' -> '3 -2 -3 0'
79  void push_index(value_type value);
80  void push_indices(const Adjform& other);
81 
82  // PUsh value to the end, but do not attempt to contract it, e.g. with
83  // value=-1 '-1 -2 -3' -> '-1 -2 -3 -1'
84  void push_coordinate(value_type value);
85  void push_coordinates(const Adjform& other);
86 
87  // Push an iterator by calling IndexMap::is_coordinate to see if push_index or
88  // push_coordinate should be used
89  void push(Ex::iterator iterator, IndexMap& index_map, const Kernel& kernel);
90 
91  // Swap the values at positions a and b
92  void swap(size_type a, size_type b);
93 
94  // Cycle the values by moving the last element to the front n times,
95  // e.g. with n=1 '3 -2 -3 0' -> '1 0 -2 -3'
96  void rotate(size_type n);
97 
98  // Sort indices so that all free indices are at the beginning and all contracted
99  // pairs at the end and next to each other, e.g. '3 -2 -3 0' -> '-3 -2 3 2'
100  void sort();
101 
102  // Produce a unique integer to represent the current permutation
103  uint64_t to_lehmer_code() const;
104  // The total number of possible permutations of values
105  uint64_t max_lehmer_code() const;
106  // String representation where indices are named 'a-z' in the order they appear
107  std::string to_string() const;
108 
109  private:
110  // Storage of an index configuration; has a maximal size
111  // equal to size_type (not size_t).
113  };
114 
119 
120  class IndexMap
121  {
122  public:
123  IndexMap(const Kernel& kernel);
124  ~IndexMap();
125  // Return a negative integer for each unique index
126  Adjform::value_type get_free_index(Ex::iterator index);
127  // Return true if index has the Coordinate or Symbol property, or is an integer
128  static bool is_coordinate(const Kernel& kernel, Ex::iterator index);
129  private:
130  std::unique_ptr<Ex_comparator> comp;
131  std::unique_ptr<Ex> data;
132  };
133 
138 
140  {
141  public:
142  using integer_type = int32_t;
143  using map_t = std::map<Adjform, integer_type>;
144  using iterator = map_t::iterator;
145  using const_iterator = map_t::const_iterator;
146 
148  ProjectedAdjform(const Adjform& adjform, const integer_type& value = 1);
149 
150  // Add all contributions from 'other' into 'this'
151  void combine(const ProjectedAdjform& other);
152  void combine(const ProjectedAdjform& other, integer_type factor);
155 
156  // Multiply all terms by a scalar factor
157  void multiply(const integer_type& k);
160 
161  iterator begin();
162  const_iterator begin() const;
163  iterator end();
164  const_iterator end() const;
165 
166  void clear(); // Remove all entries
167  size_t size() const; // Number of entries
168  size_t max_size() const; // Returns the number of terms there would be if fully symmetrized
169  size_t n_indices() const; // Returns the number of indices each adjform has
170  bool empty() const; // True if there are no entries
171 
172  // Get the value of the term, or zero if it doesn't exist
173  const integer_type& get(const Adjform& adjform) const;
174  // Sets the given term to value, creating/removing the term if required
175  void set(const Adjform& adjform, const integer_type& value = 1);
176  // Adds value to the given term, creating/removing the term if required
177  void add(const Adjform& adjform, const integer_type& value = 1);
178 
179  // Symmetrise or anti-symmetrise in the given indices
180  // e.g. if the only term is abcd then
181  // apply_young_symmetry({0, 1, 2}, false) -> abcd + acbd + bacd + bcad + cabd + cbad
182  // apply_young_symmetry({2, 3, 4}, true) -> abcd - abdc - acbd + acdb - adcb + adbc
183  void apply_young_symmetry(const std::vector<size_t>& indices, bool antisymmetric);
184 
185  // Symmetrize in indices starting at the indices in 'positions' with each group
186  // 'n_indices' long.
187  // e.g. if the only term is abcdefg then apply_ident_symmetry({0, 2, 4}, 2) ->
188  // abcdefg + abefcdg + cdabefg + cdefabg + efabcdg + efcdabg
189  void apply_ident_symmetry(const std::vector<size_t>& positions, size_t n_indices);
190  void apply_ident_symmetry(const std::vector<size_t>& positions, size_t n_indices, const std::vector<std::vector<int>>& commutation_matrix);
191 
192  // Symmetrize cyclically so abc -> abc + bca + cab
193  void apply_cyclic_symmetry();
194 
195  private:
196  // Unsafe (but faster) versions of the public functions
197  void set_(const Adjform& adjform, const integer_type& value = 1);
198  void add_(const Adjform& adjform, const integer_type& value = 1);
199 
202  };
203 
204  template <typename IndexIterator>
205  Adjform::Adjform(IndexIterator beg, IndexIterator end, IndexMap& index_map, const Kernel& kernel)
206  {
207  while (beg != end) {
208  push(beg, index_map, kernel);
209  ++beg;
210  }
211  }
212 
213  template <typename ValueIterator>
214  Adjform::Adjform(ValueIterator beg, ValueIterator end, bool push_as_coordinates)
215  {
216  while (beg != end) {
217  auto val = *beg;
218  if (push_as_coordinates)
219  push_coordinate(val);
220  else
221  push_index(val);
222  ++beg;
223  }
224  }
225  }
226 
227 
228 std::ostream& operator << (std::ostream& os, const cadabra::Adjform& adjform);
229 std::ostream& operator << (std::ostream& os, const cadabra::ProjectedAdjform& adjex);
std::ostream & operator<<(std::ostream &os, const cadabra::Adjform &adjform)
Definition: Adjform.cc:644
Representation of the index structure of a tensor monomial, using a storage format which resembles an...
Definition: Adjform.hh:30
void rotate(size_type n)
Definition: Adjform.cc:265
bool empty() const
Definition: Adjform.cc:160
size_type n_dummy_indices() const
Definition: Adjform.cc:181
uint64_t to_lehmer_code() const
Definition: Adjform.cc:288
bool operator!=(const Adjform &other) const
Definition: Adjform.cc:140
size_type size() const
Definition: Adjform.cc:150
value_type size_type
Definition: Adjform.hh:35
const_iterator end() const
Definition: Adjform.cc:119
std::vector< value_type > array_type
Definition: Adjform.hh:37
size_type index_of(value_type index, size_type offset=0) const
Definition: Adjform.cc:124
void push(Ex::iterator iterator, IndexMap &index_map, const Kernel &kernel)
Definition: Adjform.cc:241
uint64_t max_lehmer_code() const
Definition: Adjform.cc:352
array_type::const_iterator const_iterator
Definition: Adjform.hh:39
void push_coordinates(const Adjform &other)
Definition: Adjform.cc:230
bool operator==(const Adjform &other) const
Definition: Adjform.cc:135
void swap(size_type a, size_type b)
Definition: Adjform.cc:250
const_reference operator[](size_type idx) const
Definition: Adjform.cc:145
Adjform()
Definition: Adjform.cc:109
bool is_dummy_index(size_type pos) const
Definition: Adjform.cc:171
array_type data
Definition: Adjform.hh:112
const_iterator begin() const
Definition: Adjform.cc:114
array_type::const_reference const_reference
Definition: Adjform.hh:38
bool operator<(const Adjform &other) const
Definition: Adjform.cc:130
void push_index(value_type value)
Definition: Adjform.cc:202
void sort()
Definition: Adjform.cc:278
bool resolve_dummy(value_type value)
Definition: Adjform.cc:186
void push_indices(const Adjform &other)
Definition: Adjform.cc:214
short value_type
The maximal number of index slots is set by value_type: for a short, the maximal number of slots is 1...
Definition: Adjform.hh:34
size_type max_size() const
Definition: Adjform.cc:155
std::string to_string() const
Definition: Adjform.cc:360
value_type difference_type
Definition: Adjform.hh:36
size_type n_free_indices() const
Definition: Adjform.cc:176
void push_coordinate(value_type value)
Definition: Adjform.cc:225
bool is_free_index(size_type pos) const
Definition: Adjform.cc:166
To ensure consistency when creating adjforms out of two different Ex objects an IndexMap object is re...
Definition: Adjform.hh:121
static bool is_coordinate(const Kernel &kernel, Ex::iterator index)
Definition: Adjform.cc:407
std::unique_ptr< Ex > data
Definition: Adjform.hh:131
std::unique_ptr< Ex_comparator > comp
Definition: Adjform.hh:130
IndexMap(const Kernel &kernel)
Definition: Adjform.cc:380
~IndexMap()
Definition: Adjform.cc:387
Adjform::value_type get_free_index(Ex::iterator index)
Definition: Adjform.cc:392
Definition: Kernel.hh:15
Representation of a sum of tensor monomials, each having the same tensor names, but with different in...
Definition: Adjform.hh:140
void set_(const Adjform &adjform, const integer_type &value=1)
Definition: Adjform.cc:534
friend ProjectedAdjform operator*(ProjectedAdjform lhs, const integer_type &rhs)
Definition: Adjform.cc:467
map_t::iterator iterator
Definition: Adjform.hh:144
size_t size() const
Definition: Adjform.cc:498
void apply_cyclic_symmetry()
Definition: Adjform.cc:624
map_t data
Definition: Adjform.hh:200
iterator begin()
Definition: Adjform.cc:473
ProjectedAdjform & operator*=(const integer_type &k)
Definition: Adjform.cc:461
static integer_type zero
Definition: Adjform.hh:201
size_t max_size() const
Definition: Adjform.cc:503
bool empty() const
Definition: Adjform.cc:517
ProjectedAdjform & operator+=(const ProjectedAdjform &other)
Definition: Adjform.cc:444
void set(const Adjform &adjform, const integer_type &value=1)
Definition: Adjform.cc:528
std::map< Adjform, integer_type > map_t
Definition: Adjform.hh:143
map_t::const_iterator const_iterator
Definition: Adjform.hh:145
int32_t integer_type
Definition: Adjform.hh:142
void multiply(const integer_type &k)
Definition: Adjform.cc:455
void combine(const ProjectedAdjform &other)
Definition: Adjform.cc:432
void add_(const Adjform &adjform, const integer_type &value=1)
Definition: Adjform.cc:548
void clear()
Definition: Adjform.cc:493
void add(const Adjform &adjform, const integer_type &value=1)
Definition: Adjform.cc:542
void apply_ident_symmetry(const std::vector< size_t > &positions, size_t n_indices)
Definition: Adjform.cc:601
void apply_young_symmetry(const std::vector< size_t > &indices, bool antisymmetric)
Definition: Adjform.cc:561
size_t n_indices() const
Definition: Adjform.cc:510
const integer_type & get(const Adjform &adjform) const
Definition: Adjform.cc:522
friend ProjectedAdjform operator+(ProjectedAdjform lhs, const ProjectedAdjform &rhs)
Definition: Adjform.cc:450
ProjectedAdjform()
Definition: Adjform.cc:422
iterator end()
Definition: Adjform.cc:483
Functions to handle the exchange properties of two or more symbols in a product.
Definition: Adjform.cc:83
Ex rhs(Ex_ptr ex)
Definition: py_ex.cc:375
Ex lhs(Ex_ptr ex)
Definition: py_ex.cc:363
end
Definition: nevaluate.py:22
int k
Definition: passing.cc:4