This file is indexed.

/usr/include/pynac/symmetry.h is in libpynac-dev 0.3.2+dfsg-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
/** @file symmetry.h
 *
 *  Interface to GiNaC's symmetry definitions. */

/*
 *  GiNaC Copyright (C) 1999-2008 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 <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;

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;
};


// 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__