/usr/include/ginac/symmetry.h is in libginac-dev 1.6.2-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | /** @file symmetry.h
*
* Interface to GiNaC's symmetry definitions. */
/*
* GiNaC Copyright (C) 1999-2011 Johannes Gutenberg University Mainz, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef GINAC_SYMMETRY_H
#define GINAC_SYMMETRY_H
#include "ex.h"
#include "archive.h"
#include <set>
namespace GiNaC {
class sy_is_less;
class sy_swap;
/** This class describes the symmetry of a group of indices. These objects
* can be grouped into a tree to form complex mixed symmetries. */
class symmetry : public basic
{
friend class sy_is_less;
friend class sy_swap;
friend int canonicalize(exvector::iterator v, const symmetry &symm);
GINAC_DECLARE_REGISTERED_CLASS(symmetry, basic)
// types
public:
/** Type of symmetry */
typedef enum {
none, /**< no symmetry properties */
symmetric, /**< totally symmetric */
antisymmetric, /**< totally antisymmetric */
cyclic /**< cyclic symmetry */
} symmetry_type;
// other constructors
public:
/** Create leaf node that represents one index. */
symmetry(unsigned i);
/** Create node with two children. */
symmetry(symmetry_type t, const symmetry &c1, const symmetry &c2);
// non-virtual functions in this class
public:
/** Get symmetry type. */
symmetry_type get_type() const {return type;}
/** Set symmetry type. */
void set_type(symmetry_type t) {type = t;}
/** Add child node, check index sets for consistency. */
symmetry &add(const symmetry &c);
/** Verify that all indices of this node are in the range [0..n-1].
* This function throws an exception if the verification fails.
* If the top node has a type != none and no children, add all indices
* in the range [0..n-1] as children. */
void validate(unsigned n);
/** Check whether this node actually represents any kind of symmetry. */
bool has_symmetry() const {return type != none || !children.empty(); }
/** Check whether this node involves anything non symmetric. */
bool has_nonsymmetric() const;
/** Check whether this node involves a cyclic symmetry. */
bool has_cyclic() const;
/** Save (a.k.a. serialize) object into archive. */
void archive(archive_node& n) const;
/** Read (a.k.a. deserialize) object from archive. */
void read_archive(const archive_node& n, lst& syms);
protected:
void do_print(const print_context & c, unsigned level) const;
void do_print_tree(const print_tree & c, unsigned level) const;
unsigned calchash() const;
// member variables
private:
/** Type of symmetry described by this node. */
symmetry_type type;
/** Sorted union set of all indices handled by this node. */
std::set<unsigned> indices;
/** Vector of child nodes. */
exvector children;
};
GINAC_DECLARE_UNARCHIVER(symmetry);
// global functions
inline symmetry sy_none() { return symmetry(); }
inline symmetry sy_none(const symmetry &c1, const symmetry &c2) { return symmetry(symmetry::none, c1, c2); }
inline symmetry sy_none(const symmetry &c1, const symmetry &c2, const symmetry &c3) { return symmetry(symmetry::none, c1, c2).add(c3); }
inline symmetry sy_none(const symmetry &c1, const symmetry &c2, const symmetry &c3, const symmetry &c4) { return symmetry(symmetry::none, c1, c2).add(c3).add(c4); }
inline symmetry sy_symm() { symmetry s; s.set_type(symmetry::symmetric); return s; }
inline symmetry sy_symm(const symmetry &c1, const symmetry &c2) { return symmetry(symmetry::symmetric, c1, c2); }
inline symmetry sy_symm(const symmetry &c1, const symmetry &c2, const symmetry &c3) { return symmetry(symmetry::symmetric, c1, c2).add(c3); }
inline symmetry sy_symm(const symmetry &c1, const symmetry &c2, const symmetry &c3, const symmetry &c4) { return symmetry(symmetry::symmetric, c1, c2).add(c3).add(c4); }
inline symmetry sy_anti() { symmetry s; s.set_type(symmetry::antisymmetric); return s; }
inline symmetry sy_anti(const symmetry &c1, const symmetry &c2) { return symmetry(symmetry::antisymmetric, c1, c2); }
inline symmetry sy_anti(const symmetry &c1, const symmetry &c2, const symmetry &c3) { return symmetry(symmetry::antisymmetric, c1, c2).add(c3); }
inline symmetry sy_anti(const symmetry &c1, const symmetry &c2, const symmetry &c3, const symmetry &c4) { return symmetry(symmetry::antisymmetric, c1, c2).add(c3).add(c4); }
inline symmetry sy_cycl() { symmetry s; s.set_type(symmetry::cyclic); return s; }
inline symmetry sy_cycl(const symmetry &c1, const symmetry &c2) { return symmetry(symmetry::cyclic, c1, c2); }
inline symmetry sy_cycl(const symmetry &c1, const symmetry &c2, const symmetry &c3) { return symmetry(symmetry::cyclic, c1, c2).add(c3); }
inline symmetry sy_cycl(const symmetry &c1, const symmetry &c2, const symmetry &c3, const symmetry &c4) { return symmetry(symmetry::cyclic, c1, c2).add(c3).add(c4); }
// These return references to preallocated common symmetries (similar to
// the numeric flyweights).
const symmetry & not_symmetric();
const symmetry & symmetric2();
const symmetry & symmetric3();
const symmetry & symmetric4();
const symmetry & antisymmetric2();
const symmetry & antisymmetric3();
const symmetry & antisymmetric4();
/** Canonicalize the order of elements of an expression vector, according to
* the symmetry properties defined in a symmetry tree.
*
* @param v Start of expression vector
* @param symm Root node of symmetry tree
* @return the overall sign introduced by the reordering (+1, -1 or 0)
* or numeric_limits<int>::max() if nothing changed */
extern int canonicalize(exvector::iterator v, const symmetry &symm);
/** Symmetrize expression over a set of objects (symbols, indices). */
ex symmetrize(const ex & e, exvector::const_iterator first, exvector::const_iterator last);
/** Symmetrize expression over a set of objects (symbols, indices). */
inline ex symmetrize(const ex & e, const exvector & v)
{
return symmetrize(e, v.begin(), v.end());
}
/** Antisymmetrize expression over a set of objects (symbols, indices). */
ex antisymmetrize(const ex & e, exvector::const_iterator first, exvector::const_iterator last);
/** Antisymmetrize expression over a set of objects (symbols, indices). */
inline ex antisymmetrize(const ex & e, const exvector & v)
{
return antisymmetrize(e, v.begin(), v.end());
}
/** Symmetrize expression by cyclic permuation over a set of objects
* (symbols, indices). */
ex symmetrize_cyclic(const ex & e, exvector::const_iterator first, exvector::const_iterator last);
/** Symmetrize expression by cyclic permutation over a set of objects
* (symbols, indices). */
inline ex symmetrize_cyclic(const ex & e, const exvector & v)
{
return symmetrize(e, v.begin(), v.end());
}
} // namespace GiNaC
#endif // ndef GINAC_SYMMETRY_H
|