Macaulay2 Engine
Loading...
Searching...
No Matches
involutive.hpp
Go to the documentation of this file.
1/*****************************************************************************
2 * Copyright (C) 2006-2011 by Mikhail V. Zinin *
3 * mzinin@gmail.com *
4 * *
5 * You may redistribute this file under the terms of the GNU General *
6 * Public License as published by the Free Software Foundation, either *
7 * version 2 of the License, or any later version. *
8 *****************************************************************************/
9
10#ifndef BIBASIS_INVOLUTIVE_HPP
11#define BIBASIS_INVOLUTIVE_HPP
12
46
47#include <list>
48#include <algorithm>
49#include "pcomparator.hpp"
50#include "qset.hpp"
51#include "tset.hpp"
52#include "matrix.hpp"
53#include "matrix-con.hpp"
54
55namespace BIBasis
56{
57 template <typename MonomType>
59 {
60 private:
61 std::list<Polynom<MonomType>*> GBasis;
64 const PolynomialRing* const PRing;
65
66 public:
67 BooleanInvolutiveBasis(const Matrix* matrix, bool toGroebner);
69
70 const Polynom<MonomType>& operator[](int number) const;
71 unsigned Length() const;
72
73 const Matrix* ToMatrix() const;
74
75 private:
76 void FillInitialSet(const Matrix* matrix, std::list<Polynom<MonomType>*>& initialSet) const;
77
80 , const std::list<Polynom<MonomType>*>& set
81 , bool toGroebner) const;
83 , const std::list<Polynom<MonomType>*>& set
84 , bool toGroebner) const;
85 void ReduceSet(bool toGroebner);
86 void Reset();
87 void Construct(const std::list<Polynom<MonomType>*>& set, bool toGroebner);
89 };
90
91 template <typename MonomType>
93 : GBasis()
96 , PRing(matrix->get_ring()->cast_to_PolynomialRing())
97 {
98 try
99 {
100 std::list<Polynom<MonomType>*> initialSet;
101 FillInitialSet(matrix, initialSet);
102
103 Construct(initialSet, toGroebner);
104
105 initialSet.clear();
106 }
107 catch(std::string& errorString)
108 {
109 ERROR(errorString.c_str());
110 Reset();
111 }
112 catch(...)
113 {
114 ERROR("BIBasis::BooleanInvolutiveBasis::BooleanInvolutiveBasis(): unknown error.");
115 Reset();
116 }
117 }
118
119 template <typename MonomType>
124
125 template <typename MonomType>
127 {
128 typename std::list<Polynom<MonomType>*>::const_iterator it(GBasis.begin());
129 for (unsigned i = Length()-1-num; i > 0; i--)
130 {
131 ++it;
132 }
133 return **it;
134 }
135
136 template <typename MonomType>
138 {
139 return GBasis.size();
140 }
141
142 template <typename MonomType>
144 {
145 MatrixConstructor matrixConstructor(PRing->make_FreeModule(1), 0);
146 const Monoid* monoid = PRing->getMonoid();
147 const ring_elem coefficientUnit = PRing->getCoefficients()->one();
148 monomial tmpRingMonomial = monoid->make_one();
149
150 for (typename std::list<Polynom<MonomType>*>::const_iterator currentPolynom = GBasis.begin();
151 currentPolynom != GBasis.end();
152 ++currentPolynom)
153 {
154 if (!*currentPolynom)
155 {
156 continue;
157 }
158
159 ring_elem currentRingPolynomial;
160
161 for (const MonomType* currentMonom = &(**currentPolynom).Lm();
162 currentMonom;
163 currentMonom = currentMonom->Next)
164 {
165 exponents_t currentExponent = newarray_atomic_clear(int, MonomType::GetDimIndepend());
166 typename std::set<typename MonomType::Integer> variablesSet = currentMonom->GetVariablesSet();
167
168 for (typename std::set<typename MonomType::Integer>::const_iterator currentVariable = variablesSet.begin();
169 currentVariable != variablesSet.end();
170 ++currentVariable)
171 {
172 currentExponent[*currentVariable] = 1;
173 }
174
175 monoid->from_expvector(currentExponent, tmpRingMonomial);
176 freemem(currentExponent);
177
178 ring_elem tmpRingPolynomial = PRing->make_flat_term(coefficientUnit, tmpRingMonomial);
179 PRing->add_to(currentRingPolynomial, tmpRingPolynomial);
180 }
181
182 matrixConstructor.append(PRing->make_vec(0, currentRingPolynomial));
183 }
184
185 return matrixConstructor.to_matrix();
186 }
187
188 template <typename MonomType>
189 void BooleanInvolutiveBasis<MonomType>::FillInitialSet(const Matrix* matrix, std::list<Polynom<MonomType>*>& initialSet) const
190 {
191 const Monoid* monoid = PRing->getMonoid();
192 typename MonomType::Integer independ = MonomType::GetDimIndepend();
193
194 //construct Polynom for every column in matrix
195 for (int column = 0; column < matrix->n_cols(); ++column)
196 {
197 vec polynomVector = matrix->elem(column);
198 if (!polynomVector)
199 {
200 continue;
201 }
202
203 Polynom<MonomType>* currentPolynom = new Polynom<MonomType>();
204
205 for (Nterm& currentTerm : polynomVector->coeff)
206 {
207 exponents_t monomVector = newarray_atomic(int, independ);
208 monoid->to_expvector(currentTerm.monom, monomVector);
209
210 //construct Monom for every term
211 MonomType* currentMonom = new MonomType();
212 if (!currentMonom)
213 {
214 freemem(monomVector);
215 throw std::string("BIBasis::BooleanInvolutiveBasis::FillInitialSet(): got NULL instead of new monom.");
216 }
217
218 for (typename MonomType::Integer currentVariable = 0; currentVariable < independ; ++currentVariable)
219 {
220 if (monomVector[currentVariable])
221 {
222 *currentMonom *= currentVariable;
223 }
224 }
225
226 *currentPolynom += *currentMonom;
227 freemem(monomVector);
228 delete currentMonom;
229 }
230
231 initialSet.push_back(currentPolynom);
232 }
233 }
234
235 template <typename MonomType>
237 {
238 /* As far as currentTriple can't be 0 (checked in QSET and TSET),
239 * no need to check for NULL pointer.
240 */
241
242 const Triple<MonomType>* involutiveDivisor = 0;
243 Polynom<MonomType>* originalForm = 0;
244 Polynom<MonomType>* normalForm = new Polynom<MonomType>();
245
246 if (triple->GetVariable() == -1)
247 {
248 originalForm = new Polynom<MonomType>(*triple->GetPolynom());
249 }
250 else
251 {
252 originalForm = new Polynom<MonomType>(*triple->GetWeakAncestor()->GetPolynom());
253 (*originalForm) *= triple->GetVariable();
254 }
255
256 while (!originalForm->IsZero())
257 {
258 involutiveDivisor = IntermediateBasis.Find(originalForm->Lm());
259 while (involutiveDivisor)
260 {
261 originalForm->HeadReduction(*involutiveDivisor->GetPolynom());
262 if (!originalForm->IsZero())
263 {
264 involutiveDivisor = IntermediateBasis.Find(originalForm->Lm());
265 }
266 else
267 {
268 involutiveDivisor = 0;
269 }
270 }
271
272 if (!originalForm->IsZero())
273 {
274 (*normalForm) += originalForm->Lm();
275 originalForm->RidOfLm();
276 }
277 }
278
279 delete originalForm;
280 return normalForm;
281 }
282
283 template <typename MonomType>
285 , const std::list<Polynom<MonomType>*>& set
286 , bool toGroebner) const
287 {
288 if (!polynom || polynom->IsZero())
289 {
290 return 0;
291 }
292
293 typename std::list<Polynom<MonomType>*>::const_iterator it(set.begin()), setEnd(set.end());
294 const MonomType& plm = polynom->Lm();
295
296 while (it != setEnd)
297 {
298 if (toGroebner && plm.IsDivisibleBy((**it).Lm()))
299 {
300 return *it;
301 }
302 else if (!toGroebner && plm.IsPommaretDivisibleBy((**it).Lm()))
303 {
304 return *it;
305 }
306 ++it;
307 }
308
309 return 0;
310 }
311
312 template <typename MonomType>
314 , const std::list<Polynom<MonomType>*>& set
315 , bool toGroebner) const
316 {
317 if (!polynom)
318 {
319 return 0;
320 }
321
323 const Polynom<MonomType>* currentReducer = 0;
324
325 while (!polynom->IsZero())
326 {
327 currentReducer = FindDivisor(polynom, set, toGroebner);
328 while (currentReducer)
329 {
330 polynom->Reduction(*currentReducer);
331 currentReducer = FindDivisor(polynom, set, toGroebner);
332 }
333 if (!polynom->IsZero())
334 {
335 (*result) += polynom->Lm();
336 polynom->RidOfLm();
337 }
338 }
339
340 polynom = result;
341 return result;
342 }
343
344 template <typename MonomType>
346 {
347 std::list<Polynom<MonomType>*> tmpPolySet;
349
350 while (!GBasis.empty())
351 {
352 Polynom<MonomType>* currentPolynom = GBasis.front();
353 GBasis.pop_front();
354 currentPolynom = Reduce(currentPolynom, tmpPolySet, toGroebner);
355
356 if (currentPolynom && !currentPolynom->IsZero())
357 {
358 const MonomType& hLm = currentPolynom->Lm();
359 typename std::list<Polynom<MonomType>*>::iterator iteratorTmpPolySet = tmpPolySet.begin();
360 while (iteratorTmpPolySet != tmpPolySet.end())
361 {
362 if ((**iteratorTmpPolySet).Lm().IsDivisibleBy(hLm))
363 {
364 GBasis.push_back(*iteratorTmpPolySet);
365 iteratorTmpPolySet = tmpPolySet.erase(iteratorTmpPolySet);
366 }
367 else
368 {
369 ++iteratorTmpPolySet;
370 }
371 }
372 tmpPolySet.push_back(currentPolynom);
373 }
374 }
375
376 unsigned tmpPolySetSize = static_cast<unsigned int>(tmpPolySet.size());
377 for (unsigned i = 0; i < tmpPolySetSize; ++i)
378 {
379 Polynom<MonomType>* currentPolynom = tmpPolySet.front();
380 tmpPolySet.pop_front();
381 currentPolynom = Reduce(currentPolynom, tmpPolySet, toGroebner);
382 if (!currentPolynom || currentPolynom->IsZero())
383 {
384 tmpPolySetSize--;
385 }
386 else
387 {
388 tmpPolySet.push_back(currentPolynom);
389 }
390 }
391
392 GBasis = tmpPolySet;
393 }
394
395 template <typename MonomType>
397 {
398 IntermediateBasis.Clear();
399 ProlongationsSet.Clear();
400 GBasis.clear();
401 }
402
403 template <typename MonomType>
404 void BooleanInvolutiveBasis<MonomType>::Construct(const std::list<Polynom<MonomType>*>& set, bool toGroebner)
405 {
406 Reset();
407 GBasis = set;
408 ReduceSet(true);
409
410 ProlongationsSet.Insert(GBasis);
411 GBasis.clear();
412
414 ProlongationsSet.Clear();
415
417 while (i2 != IntermediateBasis.End())
418 {
419 GBasis.push_back(const_cast<Polynom<MonomType>*>((**i2).GetPolynom()));
420 ++i2;
421 }
422 ReduceSet(toGroebner);
423 }
424
425 template <typename MonomType>
427 {
428 typename TSet<MonomType>::Iterator tit(IntermediateBasis.Begin());
429 Polynom<MonomType>* newNormalForm = 0;
430 Triple<MonomType>* currentTriple = 0;
431
432 while (!ProlongationsSet.Empty())
433 {
434 currentTriple = ProlongationsSet.Get();
435 newNormalForm = NormalForm(currentTriple);
436 /* As far as currentTriple can't be 0 (checked in QSET and TSET),
437 * NormalForm can't return 0.
438 */
439
440 std::set<typename MonomType::Integer> currentNmpSet;
441 const Triple<MonomType>* currentAncestor = 0;
442 if (!newNormalForm->IsZero() && newNormalForm->Lm() == currentTriple->GetPolynomLm())
443 {
444 currentNmpSet = currentTriple->GetNmp();
445 currentAncestor = currentTriple->GetAncestor();
446 if (currentAncestor == currentTriple)
447 {
448 currentAncestor = 0;
449 }
450 }
451 delete currentTriple;
452
453 if (!newNormalForm->IsZero())
454 {
455 std::list<Triple<MonomType>*> newProlongations;
456 tit = IntermediateBasis.Begin();
457
458 while (tit != IntermediateBasis.End())
459 {
460 if ((**tit).GetPolynomLm().IsTrueDivisibleBy(newNormalForm->Lm()))
461 {
462 ProlongationsSet.DeleteDescendants(*tit);
463 newProlongations.push_back(*tit);
464 tit = IntermediateBasis.Erase(tit);
465 }
466 else
467 {
468 ++tit;
469 }
470 }
471
472 IntermediateBasis.PushBack(new Triple<MonomType>(newNormalForm, currentAncestor, currentNmpSet, 0, -1));
473 if (!newNormalForm->Degree())
474 {
475 return;
476 }
477
478 IntermediateBasis.CollectNonMultiProlongations(--IntermediateBasis.End(), newProlongations);
479 ProlongationsSet.Insert(newProlongations);
480 }
481 else
482 {
483 delete newNormalForm;
484 }
485 }
486 }
487
488}
489
490#endif // BIBASIS_INVOLUTIVE_HPP
exponents::Exponents exponents_t
BooleanInvolutiveBasis(const Matrix *matrix, bool toGroebner)
std::list< Polynom< MonomType > * > GBasis
TSet< MonomType > IntermediateBasis
const Matrix * ToMatrix() const
const PolynomialRing *const PRing
Polynom< MonomType > * Reduce(Polynom< MonomType > *polynom, const std::list< Polynom< MonomType > * > &set, bool toGroebner) const
Polynom< MonomType > * NormalForm(const Triple< MonomType > *triple) const
QSet< MonomType > ProlongationsSet
const Polynom< MonomType > * FindDivisor(const Polynom< MonomType > *polynom, const std::list< Polynom< MonomType > * > &set, bool toGroebner) const
void Construct(const std::list< Polynom< MonomType > * > &set, bool toGroebner)
void FillInitialSet(const Matrix *matrix, std::list< Polynom< MonomType > * > &initialSet) const
const Polynom< MonomType > & operator[](int number) const
void ReduceSet(bool toGroebner)
MonomType::Integer Degree() const
Definition polynom.hpp:176
void Reduction(const Polynom &anotherPolynom)
Definition polynom.hpp:539
bool IsZero() const
Definition polynom.hpp:157
const MonomType & Lm() const
Definition polynom.hpp:189
void HeadReduction(const Polynom &anotherPolynom)
Definition polynom.hpp:592
std::list< Triple< MonomType > * >::const_iterator ConstIterator
Definition tset.hpp:56
std::list< Triple< MonomType > * >::iterator Iterator
Definition tset.hpp:55
const Triple * GetWeakAncestor() const
Definition triple.hpp:173
const Polynom< MonomType > * GetPolynom() const
Definition triple.hpp:155
const std::set< typename MonomType::Integer > & GetNmp() const
Definition triple.hpp:185
MonomType::Integer GetVariable() const
Definition triple.hpp:179
const Triple * GetAncestor() const
Definition triple.hpp:167
const MonomType & GetPolynomLm() const
Definition triple.hpp:161
ring_elem elem(int i, int j) const
Definition matrix.cpp:307
int n_cols() const
Definition matrix.hpp:147
Matrix * to_matrix()
void append(vec v)
Mutable builder used to assemble an immutable Matrix one column (or one term) at a time.
void to_expvector(const_monomial m, exponents_t result_exp) const
Definition monoid.cpp:747
monomial make_one() const
Definition monoid.cpp:455
void from_expvector(const_exponents exp, monomial result) const
Definition monoid.cpp:742
Engine-side commutative monomial monoid: variable names, ordering, multidegree machinery,...
Definition monoid.hpp:89
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
#define Matrix
Definition factory.cpp:14
#define monomial
Definition gb-toric.cpp:11
void freemem(void *s)
Definition m2-mem.cpp:103
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
MatrixConstructor — the mutable builder that produces an immutable Matrix.
Matrix — the engine's immutable homomorphism F -> G between free modules.
#define newarray_atomic_clear(T, len)
Definition newdelete.hpp:93
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
BIBasis::PointerLessComparator / PointerMoreComparator — pointer-deref comparators for STL containers...
BIBasis::QSet<MonomType> — prolongation work-queue sorted by leading monomial.
int monom[1]
Definition ringelem.hpp:160
Singly linked-list node carrying one term of a polynomial-ring element.
Definition ringelem.hpp:156
BIBasis::TSet<MonomType> — the running intermediate involutive basis (T-set).