1 //   Copyright (c)  2015 Mario Albert
2 
3 //   This file is part of the source of CoCoALib, the CoCoA Library.
4 
5 //   CoCoALib is free software: you can redistribute it and/or modify
6 //   it under the terms of the GNU General Public License as published by
7 //   the Free Software Foundation, either version 3 of the License, or
8 //   (at your option) any later version.
9 
10 //   CoCoALib is distributed in the hope that it will be useful,
11 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //   GNU General Public License for more details.
14 
15 //   You should have received a copy of the GNU General Public License
16 //   along with CoCoALib.  If not, see <http://www.gnu.org/licenses/>.
17 
18 #include "CoCoA/TmpUniversalInvolutiveBasisContainer.H"
19 
20 namespace CoCoA
21 {
22   namespace Involutive
23   {
24     using std::map;
25     using std::pair;
26     using std::string;
27     using std::unique_ptr;
28     using std::vector;
29 
30 
myInitializeJBMill()31     void UniversalInvolutiveBasisContainer::myInitializeJBMill() const
32     {
33       if (jbMillPtr == nullptr)
34       {
35         JBMill::Builder builder;
36         builder.setInput(generators);
37         builder.setStrategy(strategy);
38         jbMillPtr = unique_ptr<JBMill>(new JBMill(builder));
39       }
40     }
41 
myInitializeAndValidatePBMill(string fcnName)42     void UniversalInvolutiveBasisContainer::myInitializeAndValidatePBMill(string fcnName) const
43     {
44       if (pbMillPtr == nullptr)
45       {
46         myInitializeJBMill();
47         if (!IamDeltaRegular())
48         {
49           CoCoA_THROW_ERROR("This ideal is not delta regular", fcnName);
50         }
51         // The ideal must be delta regular and the pb is not already generated
52         CoCoA_ASSERT(IamDeltaRegular());
53         PBMill::Converter converter;
54         converter.setJBMill(*jbMillPtr);
55         pbMillPtr = unique_ptr<PBMill>(new PBMill(converter));
56       }
57     }
58 
myValidateHomogeneous(string fcnName)59     void UniversalInvolutiveBasisContainer::myValidateHomogeneous(string fcnName) const
60     {
61       if (!IamHomogeneous())
62       {
63         CoCoA_THROW_ERROR("This ideal is not homogeneous", fcnName);
64       }
65     }
66 
myValidateDegRevLexOrdering(string fcnName)67     void UniversalInvolutiveBasisContainer::myValidateDegRevLexOrdering(string fcnName) const
68     {
69       if(!(IsStdDegRevLex(ordering(PPM(owner(generators.front()))))))
70       {
71         CoCoA_THROW_ERROR(ERR::PPOrder, fcnName);
72       }
73     }
74 
myValidateMonomialIdeal(string fcnName)75     void UniversalInvolutiveBasisContainer::myValidateMonomialIdeal(string fcnName) const
76     {
77       if (!IamMonomial())
78       {
79         CoCoA_THROW_ERROR("This ideal is not monomial", fcnName);
80       }
81     }
82 
myValidateCohenMacaulay(string fcnName)83     void UniversalInvolutiveBasisContainer::myValidateCohenMacaulay(string fcnName) const
84     {
85       if(!IamCohenMacaulay())
86       {
87         CoCoA_THROW_ERROR("This ideal is not Cohen Macualay", fcnName);
88       }
89     }
90 
IamDeltaRegular()91     bool UniversalInvolutiveBasisContainer::IamDeltaRegular() const
92     {
93       if (IsUncertain3(isDeltaRegular))
94       {
95         myInitializeJBMill();
96         isDeltaRegular = jbMillPtr->IamPommaretBasis();
97       }
98       return IsTrue3(isDeltaRegular);
99     }
100 
IamMonomial()101     bool UniversalInvolutiveBasisContainer::IamMonomial() const
102     {
103       if (IsUncertain3(isMonomial))
104       {
105         myInitializeJBMill();
106         isMonomial = jbMillPtr->IamMonomialIdeal();
107       }
108       return IsTrue3(isMonomial);
109     }
110 
IamHomogeneous()111     bool UniversalInvolutiveBasisContainer::IamHomogeneous() const
112     {
113       if (IsUncertain3(isHomogeneous))
114       {
115         myInitializeJBMill();
116         isHomogeneous = jbMillPtr->IamHomogenous();
117       }
118       return IsTrue3(isHomogeneous);
119     }
120 
myMultVars()121     map<PPMonoidElem, vector<bool> > UniversalInvolutiveBasisContainer::myMultVars() const
122     {
123       if (multVars.empty())
124       {
125         myInitializeJBMill();
126         myMultAndNonMultVars();
127       }
128       return multVars;
129     }
130 
myNonMultVars()131     map<PPMonoidElem, vector<bool> > UniversalInvolutiveBasisContainer::myNonMultVars() const
132     {
133       if (multVars.empty())
134       {
135         myInitializeJBMill();
136         myMultAndNonMultVars();
137       }
138       return nonMultVars;
139     }
140 
myHilbertPol(RingElem s)141     RingElem UniversalInvolutiveBasisContainer::myHilbertPol(RingElem s) const
142     {
143       if (owner(hilbertPol) != owner(s))
144       {
145         myInitializeJBMill();
146         hilbertPol = jbMillPtr->myHilbertPol(s);
147       }
148       return hilbertPol;
149     }
150 
myHilbertSeries(RingElem s)151     RingElem UniversalInvolutiveBasisContainer::myHilbertSeries(RingElem s) const
152     {
153       if (owner(hilbertSeries) != owner(s))
154       {
155         myInitializeJBMill();
156         hilbertSeries = jbMillPtr->myHilbertSeries(s);
157       }
158       return hilbertSeries;
159     }
160 
myHilbertFunc(BigInt s)161     BigInt UniversalInvolutiveBasisContainer::myHilbertFunc(BigInt s) const
162     {
163       myInitializeJBMill();
164       return jbMillPtr->myHilbertFunc(s);
165     }
166 
167 
myMultAndNonMultVars()168     void UniversalInvolutiveBasisContainer::myMultAndNonMultVars() const
169     {
170       multVars      = jbMillPtr->myMultVars();
171       nonMultVars   = multVars;
172       for (map<PPMonoidElem, vector<bool> >::iterator i = nonMultVars.begin(); i != nonMultVars.end(); ++i)
173       {
174         (i->second).flip();
175       }
176     }
177 
myFirstSyzygy()178     FGModule UniversalInvolutiveBasisContainer::myFirstSyzygy() const
179     {
180       if (firstSyzygyPtr == nullptr)
181       {
182         myInitializeJBMill();
183         firstSyzygyPtr = unique_ptr<FGModule>(new FGModule(jbMillPtr->mySyzygy()));
184       }
185       return *firstSyzygyPtr;
186     }
187 
myDimension()188     long UniversalInvolutiveBasisContainer::myDimension() const
189     {
190       if (dimension < 0)
191       {
192         myInitializeJBMill();
193         dimension = jbMillPtr->myDim();
194       }
195       return dimension;
196     }
197 
myDegree()198     long UniversalInvolutiveBasisContainer::myDegree() const
199     {
200       if (degree < 0)
201       {
202         myInitializeJBMill();
203         degree = jbMillPtr->myDeg();
204       }
205       return degree;
206     }
207 
myComplementaryDecomposition()208     UniversalInvolutiveBasisContainer::ComplementaryDecomposition UniversalInvolutiveBasisContainer::myComplementaryDecomposition() const
209     {
210       if (complementaryDecompositionPtr == nullptr)
211       {
212         myInitializeJBMill();
213         complementaryDecompositionPtr = unique_ptr<ComplementaryDecomposition>(new ComplementaryDecomposition(jbMillPtr->myComplementaryDecompositionPolynomial()));
214       }
215       return *complementaryDecompositionPtr;
216     }
217 
myDepth()218     long UniversalInvolutiveBasisContainer::myDepth() const
219     {
220       if (depth < 0)
221       {
222         myInitializeAndValidatePBMill(__FUNCTION__);
223         myValidateHomogeneous(__FUNCTION__);
224         depth = pbMillPtr->myDepth();
225       }
226       return depth;
227     }
228 
myProjDim()229     long UniversalInvolutiveBasisContainer::myProjDim() const
230     {
231       if (projDim < 0)
232       {
233         myInitializeAndValidatePBMill(__FUNCTION__);
234         myValidateHomogeneous(__FUNCTION__);
235         projDim = pbMillPtr->myProjDim();
236       }
237       return projDim;
238     }
239 
mySocle()240     vector<RingElem> UniversalInvolutiveBasisContainer::mySocle() const
241     {
242       if (soclePtr == nullptr)
243       {
244         myInitializeAndValidatePBMill(__FUNCTION__);
245         myValidateHomogeneous(__FUNCTION__);
246         myValidateDegRevLexOrdering(__FUNCTION__);
247         myValidateCohenMacaulay(__FUNCTION__);
248         soclePtr = unique_ptr<vector<RingElem> >(new vector<RingElem>(pbMillPtr->mySocle()));
249       }
250       return *soclePtr;
251     }
252 
myExtremalBettiNumbers()253     map<pair<long, long>, long> UniversalInvolutiveBasisContainer::myExtremalBettiNumbers() const
254     {
255       if (extremalBettiNumbers.empty())
256       {
257         myInitializeAndValidatePBMill(__FUNCTION__);
258         myValidateHomogeneous(__FUNCTION__);
259         myValidateDegRevLexOrdering(__FUNCTION__);
260         extremalBettiNumbers = pbMillPtr->myExtremalBettiNumbers();
261       }
262       return extremalBettiNumbers;
263     }
264 
myRegularSequence()265     vector<RingElem> UniversalInvolutiveBasisContainer::myRegularSequence() const
266     {
267       if (regularSequence.empty())
268       {
269         myInitializeAndValidatePBMill(__FUNCTION__);
270         regularSequence = pbMillPtr->myRegSeq();
271       }
272       return regularSequence;
273     }
274 
myMaximalStronglyIndependentSet()275     vector<RingElem> UniversalInvolutiveBasisContainer::myMaximalStronglyIndependentSet() const
276     {
277       if (maximalStronglyIndependentSet.empty())
278       {
279         myInitializeAndValidatePBMill(__FUNCTION__);
280         maximalStronglyIndependentSet = pbMillPtr->myMaxStronglyIndependentSet();
281       }
282       return maximalStronglyIndependentSet;
283     }
284 
myRegularity()285     long UniversalInvolutiveBasisContainer::myRegularity() const
286     {
287       if (regularity < 0)
288       {
289         myInitializeAndValidatePBMill(__FUNCTION__);
290         myValidateHomogeneous(__FUNCTION__);
291         myValidateDegRevLexOrdering(__FUNCTION__);
292         regularity = pbMillPtr->myRegularity();
293       }
294       return regularity;
295     }
296 
mySatiety()297     long UniversalInvolutiveBasisContainer::mySatiety() const
298     {
299       if (satiety < 0)
300       {
301         myInitializeAndValidatePBMill(__FUNCTION__);
302         myValidateHomogeneous(__FUNCTION__);
303         myValidateDegRevLexOrdering(__FUNCTION__);
304         satiety = pbMillPtr->mySatiety();
305       }
306       return satiety;
307     }
308 
mySaturation()309     vector<RingElem> UniversalInvolutiveBasisContainer::mySaturation() const
310     {
311       if (saturation.empty())
312       {
313         myInitializeAndValidatePBMill(__FUNCTION__);
314         myValidateHomogeneous(__FUNCTION__);
315         myValidateDegRevLexOrdering(__FUNCTION__);
316         saturation = pbMillPtr->mySaturation();
317       }
318       return saturation;
319     }
320 
IamCohenMacaulay()321     bool UniversalInvolutiveBasisContainer::IamCohenMacaulay() const
322     {
323       if (IsUncertain3(isCohenMacaulayRing))
324       {
325         myInitializeAndValidatePBMill(__FUNCTION__);
326         isCohenMacaulayRing = (myDepth() == myDimension());
327       }
328       return IsTrue3(isCohenMacaulayRing);
329     }
330 
myJanetBasis()331     const std::vector<RingElem>& UniversalInvolutiveBasisContainer::myJanetBasis() const
332     {
333       if (janetBasis.empty())
334       {
335         myInitializeJBMill();
336         janetBasis = jbMillPtr->myReturnJB();
337       }
338       return janetBasis;
339     }
340 
341   } // end namespace Involutive
342 } // end namespace CoCoA
343