|
GiNaC
1.6.2
|
00001 00005 /* 00006 * GiNaC Copyright (C) 1999-2011 Johannes Gutenberg University Mainz, Germany 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #ifndef GINAC_SYMMETRY_H 00024 #define GINAC_SYMMETRY_H 00025 00026 #include "ex.h" 00027 #include "archive.h" 00028 00029 #include <set> 00030 00031 namespace GiNaC { 00032 00033 class sy_is_less; 00034 class sy_swap; 00035 00038 class symmetry : public basic 00039 { 00040 friend class sy_is_less; 00041 friend class sy_swap; 00042 friend int canonicalize(exvector::iterator v, const symmetry &symm); 00043 00044 GINAC_DECLARE_REGISTERED_CLASS(symmetry, basic) 00045 00046 // types 00047 public: 00049 typedef enum { 00050 none, 00051 symmetric, 00052 antisymmetric, 00053 cyclic 00054 } symmetry_type; 00055 00056 // other constructors 00057 public: 00059 symmetry(unsigned i); 00060 00062 symmetry(symmetry_type t, const symmetry &c1, const symmetry &c2); 00063 00064 // non-virtual functions in this class 00065 public: 00067 symmetry_type get_type() const {return type;} 00068 00070 void set_type(symmetry_type t) {type = t;} 00071 00073 symmetry &add(const symmetry &c); 00074 00079 void validate(unsigned n); 00080 00082 bool has_symmetry() const {return type != none || !children.empty(); } 00084 bool has_nonsymmetric() const; 00086 bool has_cyclic() const; 00087 00089 void archive(archive_node& n) const; 00091 void read_archive(const archive_node& n, lst& syms); 00092 protected: 00093 void do_print(const print_context & c, unsigned level) const; 00094 void do_print_tree(const print_tree & c, unsigned level) const; 00095 unsigned calchash() const; 00096 00097 // member variables 00098 private: 00100 symmetry_type type; 00101 00103 std::set<unsigned> indices; 00104 00106 exvector children; 00107 }; 00108 GINAC_DECLARE_UNARCHIVER(symmetry); 00109 00110 00111 // global functions 00112 00113 inline symmetry sy_none() { return symmetry(); } 00114 inline symmetry sy_none(const symmetry &c1, const symmetry &c2) { return symmetry(symmetry::none, c1, c2); } 00115 inline symmetry sy_none(const symmetry &c1, const symmetry &c2, const symmetry &c3) { return symmetry(symmetry::none, c1, c2).add(c3); } 00116 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); } 00117 00118 inline symmetry sy_symm() { symmetry s; s.set_type(symmetry::symmetric); return s; } 00119 inline symmetry sy_symm(const symmetry &c1, const symmetry &c2) { return symmetry(symmetry::symmetric, c1, c2); } 00120 inline symmetry sy_symm(const symmetry &c1, const symmetry &c2, const symmetry &c3) { return symmetry(symmetry::symmetric, c1, c2).add(c3); } 00121 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); } 00122 00123 inline symmetry sy_anti() { symmetry s; s.set_type(symmetry::antisymmetric); return s; } 00124 inline symmetry sy_anti(const symmetry &c1, const symmetry &c2) { return symmetry(symmetry::antisymmetric, c1, c2); } 00125 inline symmetry sy_anti(const symmetry &c1, const symmetry &c2, const symmetry &c3) { return symmetry(symmetry::antisymmetric, c1, c2).add(c3); } 00126 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); } 00127 00128 inline symmetry sy_cycl() { symmetry s; s.set_type(symmetry::cyclic); return s; } 00129 inline symmetry sy_cycl(const symmetry &c1, const symmetry &c2) { return symmetry(symmetry::cyclic, c1, c2); } 00130 inline symmetry sy_cycl(const symmetry &c1, const symmetry &c2, const symmetry &c3) { return symmetry(symmetry::cyclic, c1, c2).add(c3); } 00131 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); } 00132 00133 // These return references to preallocated common symmetries (similar to 00134 // the numeric flyweights). 00135 const symmetry & not_symmetric(); 00136 const symmetry & symmetric2(); 00137 const symmetry & symmetric3(); 00138 const symmetry & symmetric4(); 00139 const symmetry & antisymmetric2(); 00140 const symmetry & antisymmetric3(); 00141 const symmetry & antisymmetric4(); 00142 00150 extern int canonicalize(exvector::iterator v, const symmetry &symm); 00151 00153 ex symmetrize(const ex & e, exvector::const_iterator first, exvector::const_iterator last); 00154 00156 inline ex symmetrize(const ex & e, const exvector & v) 00157 { 00158 return symmetrize(e, v.begin(), v.end()); 00159 } 00160 00162 ex antisymmetrize(const ex & e, exvector::const_iterator first, exvector::const_iterator last); 00163 00165 inline ex antisymmetrize(const ex & e, const exvector & v) 00166 { 00167 return antisymmetrize(e, v.begin(), v.end()); 00168 } 00169 00172 ex symmetrize_cyclic(const ex & e, exvector::const_iterator first, exvector::const_iterator last); 00173 00176 inline ex symmetrize_cyclic(const ex & e, const exvector & v) 00177 { 00178 return symmetrize(e, v.begin(), v.end()); 00179 } 00180 00181 } // namespace GiNaC 00182 00183 #endif // ndef GINAC_SYMMETRY_H