69symmetry::symmetry(
unsigned i) : type(none)
88 inherited::read_archive(
n, sym_lst);
90 if (!(
n.find_unsigned(
"type", t)))
91 throw (std::runtime_error(
"unknown symmetry type in archive"));
97 if (
n.find_ex(
"child", e, sym_lst, i))
98 add(ex_to<symmetry>(e));
107 if (
n.find_unsigned(
"index", u, i))
120 inherited::archive(
n);
122 n.add_unsigned(
"type",
type);
126 n.add_unsigned(
"index", i);
130 n.add_ex(
"child", i);
144 const symmetry &othersymm = ex_to<symmetry>(other);
153 size_t this_size =
indices.size();
154 size_t that_size = othersymm.
indices.size();
155 if (this_size > that_size)
157 if (this_size < that_size)
160 for (
auto i=
indices.begin(),j=othersymm.
indices.begin(); i!=end; ++i,++j) {
172 for (
size_t i=0; i<
children.size(); ++i) {
173 int cmpval = ex_to<symmetry>(
children[i])
174 .compare_same_type(ex_to<symmetry>(othersymm.
children[i]));
214 case none:
c.s <<
'!';
break;
217 case cyclic:
c.s <<
'@';
break;
218 default:
c.s <<
'?';
break;
222 for (
size_t i=0; i<num; i++) {
233 c.s << std::string(level,
' ') << class_name() <<
" @" <<
this
234 << std::hex <<
", hash=0x" <<
hashvalue <<
", flags=0x" <<
flags << std::dec
238 case none:
c.s <<
"none";
break;
241 case cyclic:
c.s <<
"cycl";
break;
242 default:
c.s <<
"<unknown>";
break;
245 c.s <<
", indices=(";
256 i.print(
c, level +
c.delta_indent);
270 if (ex_to<symmetry>(i).has_nonsymmetric())
282 if (ex_to<symmetry>(i).has_cyclic())
294 throw (std::logic_error(
"symmetry:add(): children must have same number of indices"));
298 std::set<unsigned> un;
299 set_union(
indices.begin(),
indices.end(),
c.indices.begin(),
c.indices.end(), inserter(un, un.begin()));
300 if (un.size() !=
indices.size() +
c.indices.size())
301 throw (std::logic_error(
"symmetry::add(): the same index appears in more than one child"));
314 throw (std::range_error(
"symmetry::verify(): index values are out of range"));
316 for (
unsigned i=0; i<
n; i++)
327 static ex s = dynallocate<symmetry>(0);
328 return ex_to<symmetry>(s);
333 static ex s = dynallocate<symmetry>(1);
334 return ex_to<symmetry>(s);
339 static ex s = dynallocate<symmetry>(2);
340 return ex_to<symmetry>(s);
345 static ex s = dynallocate<symmetry>(3);
346 return ex_to<symmetry>(s);
351 static ex s = dynallocate<symmetry>();
352 return ex_to<symmetry>(s);
358 return ex_to<symmetry>(s);
364 return ex_to<symmetry>(s);
370 return ex_to<symmetry>(s);
376 return ex_to<symmetry>(s);
382 return ex_to<symmetry>(s);
388 return ex_to<symmetry>(s);
392 exvector::iterator
v;
401 GINAC_ASSERT(ex_to<symmetry>(lh).indices.size() == ex_to<symmetry>(rh).indices.size());
402 auto ait = ex_to<symmetry>(lh).indices.begin(), aitend = ex_to<symmetry>(lh).indices.end(), bit = ex_to<symmetry>(rh).indices.begin();
403 while (ait != aitend) {
404 int cmpval =
v[*ait].compare(
v[*bit]);
416 exvector::iterator
v;
427 GINAC_ASSERT(ex_to<symmetry>(lh).indices.size() == ex_to<symmetry>(rh).indices.size());
428 auto ait = ex_to<symmetry>(lh).indices.begin(), aitend = ex_to<symmetry>(lh).indices.end(), bit = ex_to<symmetry>(rh).indices.begin();
429 while (ait != aitend) {
430 v[*ait].swap(
v[*bit]);
440 if (
symm.indices.size() < 2)
441 return std::numeric_limits<int>::max();
444 bool something_changed =
false;
447 while (first !=
last) {
449 int child_sign =
canonicalize(v, ex_to<symmetry>(*first));
452 if (child_sign != std::numeric_limits<int>::max()) {
453 something_changed =
true;
479 return something_changed ? sign : std::numeric_limits<int>::max();
484static ex symm(
const ex & e, exvector::const_iterator first, exvector::const_iterator
last,
bool asymmetric)
487 unsigned num =
last - first;
495 unsigned *iv =
new unsigned[num], *iv2;
496 for (
unsigned i=0; i<num; i++)
498 iv2 = (asymmetric ?
new unsigned[num] :
nullptr);
504 while (std::next_permutation(iv, iv + num)) {
506 for (
unsigned i=0; i<num; i++)
510 memcpy(iv2, iv, num *
sizeof(
unsigned));
513 sum_v.push_back(term);
515 ex sum = dynallocate<add>(sum_v);
536 unsigned num =
last - first;
542 lst new_lst = orig_lst;
547 for (
unsigned i=0; i<num-1; i++) {
548 ex perm = new_lst.
op(0);
559 return symm(*
this, v.begin(), v.end(),
false);
566 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...