68symmetry::symmetry(
unsigned i) : type(none)
87 inherited::read_archive(
n, sym_lst);
89 if (!(
n.find_unsigned(
"type", t)))
90 throw (std::runtime_error(
"unknown symmetry type in archive"));
96 if (
n.find_ex(
"child", e, sym_lst, i))
97 add(ex_to<symmetry>(e));
106 if (
n.find_unsigned(
"index", u, i))
119 inherited::archive(
n);
121 n.add_unsigned(
"type",
type);
125 n.add_unsigned(
"index", i);
129 n.add_ex(
"child", i);
143 const symmetry &othersymm = ex_to<symmetry>(other);
152 size_t this_size =
indices.size();
153 size_t that_size = othersymm.
indices.size();
154 if (this_size > that_size)
156 if (this_size < that_size)
159 for (
auto i=
indices.begin(),j=othersymm.
indices.begin(); i!=end; ++i,++j) {
171 for (
size_t i=0; i<
children.size(); ++i) {
172 int cmpval = ex_to<symmetry>(
children[i])
173 .compare_same_type(ex_to<symmetry>(othersymm.
children[i]));
213 case none:
c.s <<
'!';
break;
216 case cyclic:
c.s <<
'@';
break;
217 default:
c.s <<
'?';
break;
221 for (
size_t i=0; i<num; i++) {
232 c.s << std::string(level,
' ') << class_name() <<
" @" <<
this
233 << std::hex <<
", hash=0x" <<
hashvalue <<
", flags=0x" <<
flags << std::dec
237 case none:
c.s <<
"none";
break;
240 case cyclic:
c.s <<
"cycl";
break;
241 default:
c.s <<
"<unknown>";
break;
244 c.s <<
", indices=(";
255 i.print(
c, level +
c.delta_indent);
269 if (ex_to<symmetry>(i).has_nonsymmetric())
281 if (ex_to<symmetry>(i).has_cyclic())
293 throw (std::logic_error(
"symmetry:add(): children must have same number of indices"));
297 std::set<unsigned> un;
298 set_union(
indices.begin(),
indices.end(),
c.indices.begin(),
c.indices.end(), inserter(un, un.begin()));
299 if (un.size() !=
indices.size() +
c.indices.size())
300 throw (std::logic_error(
"symmetry::add(): the same index appears in more than one child"));
313 throw (std::range_error(
"symmetry::verify(): index values are out of range"));
315 for (
unsigned i=0; i<
n; i++)
326 static ex s = dynallocate<symmetry>(0);
327 return ex_to<symmetry>(s);
332 static ex s = dynallocate<symmetry>(1);
333 return ex_to<symmetry>(s);
338 static ex s = dynallocate<symmetry>(2);
339 return ex_to<symmetry>(s);
344 static ex s = dynallocate<symmetry>(3);
345 return ex_to<symmetry>(s);
350 static ex s = dynallocate<symmetry>();
351 return ex_to<symmetry>(s);
357 return ex_to<symmetry>(s);
363 return ex_to<symmetry>(s);
369 return ex_to<symmetry>(s);
375 return ex_to<symmetry>(s);
381 return ex_to<symmetry>(s);
387 return ex_to<symmetry>(s);
391 exvector::iterator
v;
400 GINAC_ASSERT(ex_to<symmetry>(lh).indices.size() == ex_to<symmetry>(rh).indices.size());
401 auto ait = ex_to<symmetry>(lh).indices.begin(), aitend = ex_to<symmetry>(lh).indices.end(), bit = ex_to<symmetry>(rh).indices.begin();
402 while (ait != aitend) {
403 int cmpval =
v[*ait].compare(
v[*bit]);
415 exvector::iterator
v;
426 GINAC_ASSERT(ex_to<symmetry>(lh).indices.size() == ex_to<symmetry>(rh).indices.size());
427 auto ait = ex_to<symmetry>(lh).indices.begin(), aitend = ex_to<symmetry>(lh).indices.end(), bit = ex_to<symmetry>(rh).indices.begin();
428 while (ait != aitend) {
429 v[*ait].swap(
v[*bit]);
439 if (
symm.indices.size() < 2)
440 return std::numeric_limits<int>::max();
443 bool something_changed =
false;
446 while (first !=
last) {
448 int child_sign =
canonicalize(v, ex_to<symmetry>(*first));
451 if (child_sign != std::numeric_limits<int>::max()) {
452 something_changed =
true;
478 return something_changed ? sign : std::numeric_limits<int>::max();
483static ex symm(
const ex & e, exvector::const_iterator first, exvector::const_iterator
last,
bool asymmetric)
486 unsigned num =
last - first;
494 unsigned *iv =
new unsigned[num], *iv2;
495 for (
unsigned i=0; i<num; i++)
497 iv2 = (asymmetric ?
new unsigned[num] :
nullptr);
503 while (std::next_permutation(iv, iv + num)) {
505 for (
unsigned i=0; i<num; i++)
509 memcpy(iv2, iv, num *
sizeof(
unsigned));
512 sum_v.push_back(term);
514 ex sum = dynallocate<add>(sum_v);
535 unsigned num =
last - first;
541 lst new_lst = orig_lst;
546 for (
unsigned i=0; i<num-1; i++) {
547 ex perm = new_lst.
op(0);
558 return symm(*
this, v.begin(), v.end(),
false);
565 return symm(*
this, v.begin(), v.end(),
true);
Interface to GiNaC's sums of expressions.
Archiving of GiNaC expressions.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
const basic & setflag(unsigned f) const
Set some status_flags.
unsigned hashvalue
hash value
unsigned flags
of type status_flags
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Wrapper template for making GiNaC classes out of STL containers.
const_iterator end() const
const_iterator begin() const
ex op(size_t i) const override
Return operand/member at position i.
container & remove_first()
Remove first element.
container & append(const ex &b)
Add element at back.
Lightweight wrapper for GiNaC's symbolic objects.
const_iterator begin() const noexcept
ex symmetrize_cyclic() const
Symmetrize expression by cyclic permutation over its free indices.
const_iterator end() const noexcept
ex subs(const exmap &m, unsigned options=0) const
ex symmetrize() const
Symmetrize expression over its free indices.
ex antisymmetrize() const
Antisymmetrize expression over its free indices.
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
Base class for print_contexts.
Context for tree-like output for debugging.
@ expanded
.expand(0) has already done its job (other expand() options ignore this flag)
@ evaluated
.eval() has already done its job
@ hash_calculated
.calchash() has already done its job
@ no_pattern
disable pattern matching
sy_is_less(exvector::iterator v_)
bool operator()(const ex &lh, const ex &rh) const
sy_swap(exvector::iterator v_, bool &s)
void operator()(const ex &lh, const ex &rh)
This class describes the symmetry of a group of indices.
void read_archive(const archive_node &n, lst &syms) override
Read (a.k.a.
void validate(unsigned n)
Verify that all indices of this node are in the range [0..n-1].
symmetry_type
Type of symmetry.
@ symmetric
totally symmetric
@ antisymmetric
totally antisymmetric
@ none
no symmetry properties
bool has_nonsymmetric() const
Check whether this node involves anything non symmetric.
symmetry & add(const symmetry &c)
Add child node, check index sets for consistency.
symmetry_type type
Type of symmetry described by this node.
void do_print(const print_context &c, unsigned level) const
exvector children
Vector of child nodes.
bool has_cyclic() const
Check whether this node involves a cyclic symmetry.
std::set< unsigned > indices
Sorted union set of all indices handled by this node.
symmetry(unsigned i)
Create leaf node that represents one index.
unsigned calchash() const override
Compute the hash value of an object and if it makes sense to store it in the objects status_flags,...
void do_print_tree(const print_tree &c, unsigned level) const
void archive(archive_node &n) const override
Save (a.k.a.
Definition of GiNaC's lst.
const symmetry & antisymmetric4()
const symmetry & symmetric3()
const symmetry & not_symmetric()
ex symmetrize(const ex &thisex)
const symmetry & antisymmetric3()
const symmetry & antisymmetric2()
static const symmetry & index1()
const symmetry & symmetric2()
const numeric factorial(const numeric &n)
Factorial combinatorial function.
static const symmetry & index2()
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
static const symmetry & index3()
static unsigned make_hash_seed(const std::type_info &tinfo)
We need a hash function which gives different values for objects of different types.
unsigned rotate_left(unsigned n)
Rotate bits of unsigned value by one bit to the left.
ex antisymmetrize(const ex &thisex)
static const symmetry & index0()
const symmetry & symmetric4()
void shaker_sort(It first, It last, Cmp comp, Swap swapit)
void cyclic_permutation(It first, It last, It new_first, Swap swapit)
static ex symm(const ex &e, exvector::const_iterator first, exvector::const_iterator last, bool asymmetric)
int canonicalize(exvector::iterator v, const symmetry &symm)
Canonicalize the order of elements of an expression vector, according to the symmetry properties defi...
ex symmetrize_cyclic(const ex &thisex)
int permutation_sign(It first, It last)
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT_T(lst, basic, print_func< print_context >(&lst::do_print). print_func< print_tree >(&lst::do_print_tree)) template<> bool lst GINAC_BIND_UNARCHIVER(lst)
Specialization of container::info() for lst.
std::vector< ex > exvector
Makes the interface to the underlying bignum package available.
Interface to GiNaC's overloaded operators.
#define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(classname, supername, options)
Macro for inclusion in the implementation of each registered class.
Interface to GiNaC's symmetry definitions.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...