1 #ifndef TMPJBALGORITHM_H_ 2 #define TMPJBALGORITHM_H_ 3 4 // Copyright (c) 2015 Mario Albert 5 6 // This file is part of the source of CoCoALib, the CoCoA Library. 7 8 // CoCoALib is free software: you can redistribute it and/or modify 9 // it under the terms of the GNU General Public License as published by 10 // the Free Software Foundation, either version 3 of the License, or 11 // (at your option) any later version. 12 13 // CoCoALib is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // You should have received a copy of the GNU General Public License 19 // along with CoCoALib. If not, see <http://www.gnu.org/licenses/>. 20 21 #include "TmpJBSets.H" 22 23 namespace CoCoA { 24 namespace Involutive { 25 26 /****************************************************************************************************************************/ 27 /*!\brief This class compares the LPP of the polynomials in Janet Triples 28 */ 29 /*****************************************************************************************************************************/ 30 struct IsLowerLPP { 31 /** 32 * The "compare" method 33 * @param t1 JanetTriple 34 * @param t2 JanetTriple 35 * The output is: LPP(t1.myPolynomial)<LPP(t2.myPolynomial) 36 **/ operatorIsLowerLPP37 bool operator()(const JanetTriple& t1, const JanetTriple& t2) { 38 return ((LPP(t1.myPolynomial) < LPP(t2.myPolynomial)) 39 || ((LPP(t1.myPolynomial) == LPP(t2.myPolynomial)) && (t1.myAncestor < t2.myAncestor))); 40 } 41 }; 42 43 /** 44 * @brief Virtual algorithm class 45 * @details Every algorithm for computing Janet basis should be a subclass of 46 * JBAlgorithm. It provides interfaces for computing and returning Janet basis. 47 */ 48 class JBAlgorithm { 49 public: 50 /* 51 virtual constructor because of inheritance 52 */ ~JBAlgorithm()53 virtual ~JBAlgorithm() { 54 } 55 56 /** 57 * Purely virtual method to compute a Janet basis. Must be specified in subclasses. 58 * @param beginInput a const iterator to a vector of RingElems. Should be the beginning of the vector. 59 * @param endInput a const iterator to a vector of RingElems. Should be the end of the vector. 60 */ 61 virtual void myComputer(std::vector<RingElem>::const_iterator beginInput, 62 std::vector<RingElem>::const_iterator endInput) = 0; 63 64 /** 65 * This purley virtual method returns the result. Must be specified in subclasses. 66 * @return It returns a JanetContainer containing the computed basis. 67 */ 68 virtual JanetContainer myOutputResult() = 0; 69 70 protected: 71 /** 72 * Proteced Constructor. The user should not use this class directly. 73 * The constructor initialize the class members myPolyRing and myPPMValue. 74 * @param polyRing 75 */ JBAlgorithm(SparsePolyRing polyRing)76 JBAlgorithm(SparsePolyRing polyRing) 77 : myPolyRing(polyRing), 78 myPPMValue(PPM(myPolyRing)) { 79 } 80 81 const SparsePolyRing myPolyRing; 82 83 const PPMonoid myPPMValue; 84 }; 85 86 class TQAlgorithm : public JBAlgorithm { 87 public: ~TQAlgorithm()88 virtual ~TQAlgorithm() { 89 } 90 91 /** 92 * See at base class 93 */ 94 virtual void myComputer(std::vector<RingElem>::const_iterator beginInput, 95 std::vector<RingElem>::const_iterator endInput) = 0; 96 97 /** 98 * Returns the result. 99 * It extracts the computed Janet Basis out of a TQSet as a list and inserts 100 * the result in a JanetContainer. 101 * @return JanetConatiner 102 */ 103 JanetContainer myOutputResult(); 104 105 protected: 106 /** 107 * Constructor: It calls the constructor of the base class and initializes 108 * a myJTree. 109 * @param polyRing 110 */ TQAlgorithm(SparsePolyRing polyRing)111 TQAlgorithm(SparsePolyRing polyRing) 112 : JBAlgorithm(polyRing), 113 myJTree(myPolyRing, 0, 0) { 114 } 115 116 /** 117 * A purely virtual method. Must be defined in a subclass. 118 * It access TQSets (or a subclass of it) which is defined in subclasses 119 * @return A reference to TQSets 120 */ 121 virtual TQSets& myGetSets() = 0; 122 123 /** 124 * The method initializes a TQSet which was accessed by myGetSets(). It inserts 125 * the elements of a vector<RingElem> between beginInput and endInput 126 * @param beginInput 127 * @param endInput 128 */ 129 void myInitialization(std::vector<RingElem>::const_iterator beginInput, 130 std::vector<RingElem>::const_iterator endInput); 131 132 /** 133 * It modifies the instance such that it represents the trival ideal: 134 * The set T in TQSets contains only the JanetTriple of the RingElem 1. 135 */ 136 void myTrivialIdeal(); 137 138 JanetTree myJTree; 139 }; 140 141 /** 142 * The class is a specialization of the TQAlgorithm. It uses the Degree TQ Algorithm 143 * to compute a Janet Basis. This algorithm is described in 144 * "Gerdt - Construction of Janet Bases II. Polynomial Bases" 145 */ 146 class DegreeTQ : public TQAlgorithm { 147 public: 148 /** 149 * Constructor: It calls the constructor of the base class (TQAlgorithm) and initializes 150 * mySets with the option crit and the ring polyRing 151 * 152 * @param polyRing 153 * @param crit a bitflag with three elements. If a bit is true mySets uses the corresponding involutive 154 * criteria 155 */ 156 DegreeTQ(SparsePolyRing polyRing, std::bitset<3> crit = std::bitset<3>(0)) TQAlgorithm(polyRing)157 : TQAlgorithm(polyRing), 158 mySets(myPolyRing, crit) { 159 } 160 161 /** 162 * accessor for the base class to mySets 163 * @return TQSets 164 */ myGetSets()165 TQSets& myGetSets() { 166 return mySets; 167 } 168 169 /** 170 * Implementation of the algorithm to compute the Janet Basis via the DegreeTQ strategy 171 * @param beginInput 172 * @param endInput 173 */ 174 void myComputer(std::vector<RingElem>::const_iterator beginInput, std::vector<RingElem>::const_iterator endInput); 175 176 private: 177 TQSets mySets; 178 }; 179 180 /** 181 * The class is a specialization of the TQAlgorithm. It uses the Degree TQ Algorithm 182 * to compute a Janet Basis. This algorithm is described in 183 * "Gerdt - "On Computing Janet Bases for Degree Compatible Orderings" 184 */ 185 class BlockTQ : public TQAlgorithm { 186 public: 187 188 /** 189 * Constructor: It calls the constructor of the base class (TQAlgorithm) and initializes 190 * mySets with the options crit, strategy and the ring polyRing 191 * 192 * @param polyRing 193 * @param crit a bitflag with three elements. If a bit is true mySets uses the corresponding involutive 194 * criteria 195 * @param strategy specified the concrete strategy. One could choose between TQPSets::Low (default) or TQPSets::High 196 */ 197 BlockTQ(SparsePolyRing polyRing, std::bitset<3> crit = std::bitset<3>(0), TQPSets::Strategy strategy = 198 TQPSets::Low) TQAlgorithm(polyRing)199 : TQAlgorithm(polyRing), 200 mySets(myPolyRing, crit, strategy) { 201 } 202 203 /** 204 * accessor for the base class to mySets 205 * @return TQSets 206 */ myGetSets()207 TQSets& myGetSets() { 208 return mySets; 209 } 210 211 /** 212 * Implementation of the algorithm to compute the Janet Basis via the DegreeTQ strategy 213 * @param beginInput 214 * @param endInput 215 */ 216 void myComputer(std::vector<RingElem>::const_iterator beginInput, std::vector<RingElem>::const_iterator endInput); 217 218 private: 219 TQPSets mySets; 220 }; 221 222 /** 223 * The class is a specialization of JBAlgorithm. It uses a polynomial completion to compute a Janet basis. 224 * It first uses the method ComputeGBasis of CoCoALib to compute a Groebner basis for the input. 225 * Afterwards it complete it to a Janet basis. 226 */ 227 class CompletionGB : public JBAlgorithm { 228 public: 229 /** 230 * Constructor: It calls the constructor of the base class (JBAlgorithm) and initializes myJTree 231 * 232 * @param polyRing 233 */ CompletionGB(SparsePolyRing polyRing)234 CompletionGB(SparsePolyRing polyRing) 235 : JBAlgorithm(polyRing), 236 myJTree(myPolyRing, 0, 0) { 237 } 238 239 /** 240 * Implementation of the algorithm to compute the Janet Basis via the completion algorithm. 241 * @param beginInput 242 * @param endInput 243 */ 244 void myComputer(std::vector<RingElem>::const_iterator beginInput, std::vector<RingElem>::const_iterator endInput); 245 246 /** 247 * Returns the result. 248 * It initializes a JanetContainer with myPolyRing and myJBasis 249 * @return JanetConatiner 250 */ 251 JanetContainer myOutputResult(); 252 253 private: 254 typedef std::pair<RingElem, PPMonoidElem> elemPair; 255 typedef std::list<elemPair> elemPairList; 256 typedef std::list<elemPair>::iterator elemPairIter; 257 258 /** 259 * This class is used to compare two pairs p1, p2 of <RingElem, PPMonoidElem> 260 * p1 < p2 if LPP(p1.RingElem) < LPP(p2.RingElem) 261 */ 262 struct LPPCompare { operatorLPPCompare263 bool operator()(const elemPair& r1, const elemPair& r2) { 264 return LPP(r1.first) < LPP(r2.first); 265 } 266 } myLPPComparison; 267 268 /** 269 * This class is used to compare two JanetTriples p1, p2 270 * p1 < p2 if LPP(p1.pol) < LPP(p2.pol) 271 */ 272 struct TripleLPPCompare { operatorTripleLPPCompare273 bool operator()(const JanetTriple& r1, const JanetTriple& r2) { 274 return LPP(r1.myGetPol()) < LPP(r2.myGetPol()); 275 } 276 } myLPPTripleComparison; 277 278 /** 279 * This method first computes the reduced Groebner Basis out out the Input beginInput .. endInput. 280 * Then it inserts the result in the Janet Tree. Due to the fact, that the reduced Groebner Basis 281 * is contained in the Janet basis we do not get any collisions. 282 * 283 * @param beginInput 284 * @param endInput 285 */ 286 void myBuildInitialTree(std::vector<RingElem>::const_iterator beginInput, 287 std::vector<RingElem>::const_iterator endInput); 288 289 /** 290 * This method checks if the PPMonoidElem m is multiplicative for index 291 * To decide this it moves through the JanetTree 292 * 293 * @param m [description] 294 * @param index [description] 295 * 296 * @return true is m is nonmultiplicative for index 297 */ 298 bool myElemIsNonMultForIndex(const PPMonoidElem& m, long index); 299 300 /** 301 * It insert the pair (elem, anc) to list (at the end) 302 * 303 * @param list it is a reference to a list 304 * @param elem 305 * @param anc 306 */ 307 void myPushToProlongList(elemPairList& list, const RingElem& elem, const PPMonoidElem& anc); 308 309 /** 310 * It insert the pair (elem, anc) to list (s.t. the list remains sorted after LPP(elem)) 311 * 312 * @param list it is a reference to a list 313 * @param elem 314 * @param anc 315 */ 316 void myInsertToProlongList(elemPairList& list, const RingElem& elem, const PPMonoidElem& anc); 317 318 /** 319 * This method takes the Janet basis which is represented by myJBasis and myJTree which is possibly 320 * not minimal and sorts it by degree and minimizes it. 321 */ 322 void mySortAndMinimizeJanetBasis(); 323 324 std::list<JanetTriple> myJBasis; 325 326 JanetTree myJTree; 327 328 }; 329 } 330 } /* namespace CoCoA */ 331 332 #endif /* TMPJBALGORITHM_H_ */ 333