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