Cadabra Computer algebra system for field theory problems
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
13
14  class IndexMap;
15
28
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
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
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);
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);
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
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
149
150  // Add all contributions from 'other' into 'this'
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
174  // Sets the given term to value, creating/removing the term if required
176  // Adds value to the given term, creating/removing the term if required
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
199
202  };
203
204  template <typename IndexIterator>
206  {
207  while (beg != end) {
208  push(beg, index_map, kernel);
209  ++beg;
210  }
211  }
212
213  template <typename ValueIterator>
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
Representation of the index structure of a tensor monomial, using a storage format which resembles an...
void rotate(size_type n)
bool empty() const
size_type n_dummy_indices() const
uint64_t to_lehmer_code() const
size_type size() const
value_type size_type
const_iterator end() const
std::vector< value_type > array_type
size_type index_of(value_type index, size_type offset=0) const
void push(Ex::iterator iterator, IndexMap &index_map, const Kernel &kernel)
uint64_t max_lehmer_code() const
array_type::const_iterator const_iterator
void swap(size_type a, size_type b)
const_reference operator[](size_type idx) const
bool is_dummy_index(size_type pos) const
array_type data
const_iterator begin() const
array_type::const_reference const_reference
void push_index(value_type value)
void sort()
bool resolve_dummy(value_type value)
short value_type
The maximal number of index slots is set by value_type: for a short, the maximal number of slots is 1...
size_type max_size() const
std::string to_string() const
value_type difference_type
size_type n_free_indices() const
void push_coordinate(value_type value)
bool is_free_index(size_type pos) const
To ensure consistency when creating adjforms out of two different Ex objects an IndexMap object is re...
static bool is_coordinate(const Kernel &kernel, Ex::iterator index)
std::unique_ptr< Ex > data
std::unique_ptr< Ex_comparator > comp
IndexMap(const Kernel &kernel)
~IndexMap()
Definition: Kernel.hh:15
Representation of a sum of tensor monomials, each having the same tensor names, but with different in...
map_t::iterator iterator
size_t size() const
void apply_cyclic_symmetry()
map_t data
iterator begin()
static integer_type zero
size_t max_size() const
bool empty() const
map_t::const_iterator const_iterator
int32_t integer_type
void multiply(const integer_type &k)
void clear()
void apply_ident_symmetry(const std::vector< size_t > &positions, size_t n_indices)
void apply_young_symmetry(const std::vector< size_t > &indices, bool antisymmetric)
size_t n_indices() const