70symmetry::symmetry(
unsigned i) : type(none)
89 inherited::read_archive(
n, sym_lst);
91 if (!(
n.find_unsigned(
"type", t)))
92 throw (std::runtime_error(
"unknown symmetry type in archive"));
98 if (
n.find_ex(
"child", e, sym_lst, i))
99 add(ex_to<symmetry>(e));
108 if (
n.find_unsigned(
"index", u, i))
121 inherited::archive(
n);
123 n.add_unsigned(
"type",
type);
127 n.add_unsigned(
"index", i);
131 n.add_ex(
"child", i);
145 const symmetry &othersymm = ex_to<symmetry>(other);
154 size_t this_size =
indices.size();
155 size_t that_size = othersymm.
indices.size();
156 if (this_size > that_size)
158 if (this_size < that_size)
161 for (
auto i=
indices.begin(),j=othersymm.
indices.begin(); i!=end; ++i,++j) {
173 for (
size_t i=0; i<
children.size(); ++i) {
174 int cmpval = ex_to<symmetry>(
children[i])
175 .compare_same_type(ex_to<symmetry>(othersymm.
children[i]));
215 case none:
c.s <<
'!';
break;
218 case cyclic:
c.s <<
'@';
break;
219 default:
c.s <<
'?';
break;
223 for (
size_t i=0; i<num; i++) {
234 c.s << std::string(level,
' ') << class_name() <<
" @" <<
this
235 << std::hex <<
", hash=0x" <<
hashvalue <<
", flags=0x" <<
flags << std::dec
239 case none:
c.s <<
"none";
break;
242 case cyclic:
c.s <<
"cycl";
break;
243 default:
c.s <<
"<unknown>";
break;
246 c.s <<
", indices=(";
257 i.print(
c, level +
c.delta_indent);
295 throw (std::logic_error(
"symmetry:add(): children must have same number of indices"));
299 std::set<unsigned> un;
300 set_union(
indices.begin(),
indices.end(),
c.indices.begin(),
c.indices.end(), inserter(un, un.begin()));
301 if (un.size() !=
indices.size() +
c.indices.size())
302 throw (std::logic_error(
"symmetry::add(): the same index appears in more than one child"));
315 throw (std::range_error(
"symmetry::verify(): index values are out of range"));
317 for (
unsigned i=0; i<
n; i++)
328 static ex s = dynallocate<symmetry>(0);
329 return ex_to<symmetry>(s);
334 static ex s = dynallocate<symmetry>(1);
335 return ex_to<symmetry>(s);
340 static ex s = dynallocate<symmetry>(2);
341 return ex_to<symmetry>(s);
346 static ex s = dynallocate<symmetry>(3);
347 return ex_to<symmetry>(s);
352 static ex s = dynallocate<symmetry>();
353 return ex_to<symmetry>(s);
359 return ex_to<symmetry>(s);
365 return ex_to<symmetry>(s);
371 return ex_to<symmetry>(s);
377 return ex_to<symmetry>(s);
383 return ex_to<symmetry>(s);
389 return ex_to<symmetry>(s);
393 exvector::iterator
v;
402 GINAC_ASSERT(ex_to<symmetry>(lh).indices.size() == ex_to<symmetry>(rh).indices.size());
403 auto ait = ex_to<symmetry>(lh).indices.begin(), aitend = ex_to<symmetry>(lh).indices.end(), bit = ex_to<symmetry>(rh).indices.begin();
404 while (ait != aitend) {
405 int cmpval =
v[*ait].compare(
v[*bit]);
417 exvector::iterator
v;
428 GINAC_ASSERT(ex_to<symmetry>(lh).indices.size() == ex_to<symmetry>(rh).indices.size());
429 auto ait = ex_to<symmetry>(lh).indices.begin(), aitend = ex_to<symmetry>(lh).indices.end(), bit = ex_to<symmetry>(rh).indices.begin();
430 while (ait != aitend) {
431 v[*ait].swap(
v[*bit]);
441 if (
symm.indices.size() < 2)
442 return std::numeric_limits<int>::max();
445 bool something_changed =
false;
448 while (first !=
last) {
450 int child_sign =
canonicalize(v, ex_to<symmetry>(*first));
453 if (child_sign != std::numeric_limits<int>::max()) {
454 something_changed =
true;
480 return something_changed ? sign : std::numeric_limits<int>::max();
485static ex symm(
const ex & e, exvector::const_iterator first, exvector::const_iterator
last,
bool asymmetric)
488 unsigned num =
last - first;
496 unsigned *iv =
new unsigned[num], *iv2;
497 for (
unsigned i=0; i<num; i++)
499 iv2 = (asymmetric ?
new unsigned[num] :
nullptr);
505 while (std::next_permutation(iv, iv + num)) {
507 for (
unsigned i=0; i<num; i++)
511 memcpy(iv2, iv, num *
sizeof(
unsigned));
514 sum_v.push_back(term);
516 ex sum = dynallocate<add>(sum_v);
537 unsigned num =
last - first;
543 lst new_lst = orig_lst;
548 for (
unsigned i=0; i<num-1; i++) {
549 ex perm = new_lst.
op(0);
560 return symm(*
this, v.begin(), v.end(),
false);
567 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
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(add, expairseq, print_func< print_context >(&add::do_print). print_func< print_latex >(&add::do_print_latex). print_func< print_csrc >(&add::do_print_csrc). print_func< print_tree >(&add::do_print_tree). print_func< print_python_repr >(&add::do_print_python_repr)) add
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.
Interface to GiNaC's symmetry definitions.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...