Macaulay2 Engine
Loading...
Searching...
No Matches
polynom.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_POLYNOM_HPP
11#define BIBASIS_POLYNOM_HPP
12
43
44#include <iostream>
45#include "allocator.hpp"
46
47namespace BIBasis
48{
49 template <typename MonomType>
50 class Polynom
51 {
52 private:
53 MonomType* MonomListHead;
55 static MonomType UniteMonom;
56
57 public:
58 Polynom();
59 Polynom(const Polynom& anotherPolynom);
60 ~Polynom();
61
62 void SetOne();
63 void SetZero();
64 bool IsZero() const;
65 unsigned long Length() const;
66 typename MonomType::Integer Degree() const;
67 const MonomType& Lm() const;
68 void RidOfLm();
69
70 void* operator new(std::size_t);
71 void operator delete(void *ptr);
72
73 const Polynom& operator=(const Polynom& anotherPolynom);
74 const Polynom& operator+=(const MonomType& newMonom);
75 const Polynom& operator+=(const Polynom& anotherPolynom);
76 const Polynom& operator*=(typename MonomType::Integer var);
77 const Polynom& operator*=(const MonomType& anotherMonom);
78 const Polynom& operator*=(const Polynom& anotherPolynom);
79
80 bool operator==(const Polynom &anotherPolynom) const;
81 bool operator!=(const Polynom &anotherPolynom) const;
82 bool operator<(const Polynom& anotherPolynom) const;
83 bool operator>(const Polynom& anotherPolynom) const;
84 static int Compare(const Polynom& polynomA, const Polynom& polynomB);
85
86 void Reduction(const Polynom& anotherPolynom);
87 void HeadReduction(const Polynom& anotherPolynom);
88 void MergeWith(Polynom& anotherPolynom);
89
90 private:
91 const MonomType * const * Find(const MonomType& monom) const;
92 };
93
94 template <typename MonomType>
96
97 template <typename MonomType>
99
100 template <typename MonomType>
105
106 template <typename MonomType>
108 : MonomListHead(0)
109 {
110 if (!anotherPolynom.MonomListHead)
111 {
112 return;
113 }
114 else
115 {
116 MonomType **iterator = &MonomListHead,
117 *iteratorAnother = anotherPolynom.MonomListHead;
118 while (iteratorAnother)
119 {
120 *iterator = new MonomType(*iteratorAnother);
121
122 iterator = &((*iterator)->Next);
123 iteratorAnother = iteratorAnother->Next;
124 }
125 }
126 }
127
128 template <typename MonomType>
133
134 template <typename MonomType>
136 {
137 SetZero();
138 MonomListHead = new MonomType();
139 }
140
141 template <typename MonomType>
143 {
144 if (MonomListHead)
145 {
146 MonomType* tmpMonom = 0;
147 while (MonomListHead)
148 {
149 tmpMonom = MonomListHead;
151 delete tmpMonom;
152 }
153 }
154 }
155
156 template <typename MonomType>
158 {
159 return !MonomListHead;
160 }
161
162 template <typename MonomType>
163 unsigned long Polynom<MonomType>::Length() const
164 {
165 unsigned long length = 0;
166 MonomType* iterator = MonomListHead;
167 while (iterator)
168 {
169 iterator = iterator->Next;
170 ++length;
171 }
172 return length;
173 }
174
175 template <typename MonomType>
176 typename MonomType::Integer Polynom<MonomType>::Degree() const
177 {
178 if (!MonomListHead)
179 {
180 return 0;
181 }
182 else
183 {
184 return MonomListHead->Degree();
185 }
186 }
187
188 template <typename MonomType>
189 const MonomType& Polynom<MonomType>::Lm() const
190 {
191 if (MonomListHead)
192 {
193 return *MonomListHead;
194 }
195 else
196 {
197 return UniteMonom;
198 }
199 }
200
201 template <typename MonomType>
203 {
204 if (MonomListHead)
205 {
206 MonomType* tmpMonom(MonomListHead);
208 delete tmpMonom;
209 }
210 }
211
212 template <typename MonomType>
213 void* Polynom<MonomType>::operator new(std::size_t)
214 {
215 return Allocator.Allocate();
216 }
217
218 template <typename MonomType>
219 void Polynom<MonomType>::operator delete(void *ptr)
220 {
221 Allocator.Free(ptr);
222 }
223
224 template <typename MonomType>
226 {
227 if (!anotherPolynom.MonomListHead)
228 {
229 SetZero();
230 }
231 else
232 {
233 MonomType *iteratorAnother = anotherPolynom.MonomListHead,
234 **iterator = &MonomListHead;
235 while (*iterator && iteratorAnother)
236 {
237 **iterator = *iteratorAnother;
238 iterator = &((*iterator)->Next);
239 iteratorAnother = iteratorAnother->Next;
240 }
241
242 if (*iterator)
243 {
244 MonomType* monomToDelete = (*iterator)->Next;
245 *iterator = 0;
246 while (monomToDelete)
247 {
248 iteratorAnother = monomToDelete;
249 monomToDelete = monomToDelete->Next;
250 delete iteratorAnother;
251 }
252 }
253 else while (iteratorAnother)
254 {
255 *iterator = new MonomType(*iteratorAnother);
256 iterator = &((*iterator)->Next);
257 iteratorAnother = iteratorAnother->Next;
258 }
259 }
260 return *this;
261 }
262
263 template <typename MonomType>
264 const Polynom<MonomType>& Polynom<MonomType>::operator+=(const MonomType& newMonom)
265 {
266 MonomType** position = const_cast<MonomType**>(Find(newMonom));
267 MonomType* tmpMonom = 0;
268
269 if (!position)
270 {
271 tmpMonom = new MonomType(newMonom);
272 tmpMonom->Next = MonomListHead;
273 MonomListHead = tmpMonom;
274 }
275 else
276 {
277 if (*position && **position == newMonom)
278 {
279 tmpMonom = *position;
280 *position = (*position)->Next;
281 delete tmpMonom;
282 }
283 else
284 {
285 tmpMonom = new MonomType(newMonom);
286 tmpMonom->Next = (*position)->Next;
287 (*position)->Next = tmpMonom;
288 }
289 }
290
291 return *this;
292 }
293
294 template <typename MonomType>
296 {
297 if (anotherPolynom.MonomListHead)
298 {
299 MonomType **iterator = &MonomListHead,
300 *iteratorAnother = anotherPolynom.MonomListHead,
301 *tmpMonom = 0;
302
303 while (*iterator && iteratorAnother)
304 {
305 switch ((**iterator).Compare(*iteratorAnother))
306 {
307 case -1:
308 tmpMonom = new MonomType(*iteratorAnother);
309 tmpMonom->Next = *iterator;
310 *iterator = tmpMonom;
311 iterator = &(tmpMonom->Next);
312 iteratorAnother = iteratorAnother->Next;
313 break;
314 case 0:
315 tmpMonom = *iterator;
316 *iterator = (*iterator)->Next;
317 delete tmpMonom;
318 iteratorAnother = iteratorAnother->Next;
319 break;
320 case 1:
321 iterator = &((*iterator)->Next);
322 break;
323 }
324 }
325
326 while (iteratorAnother)
327 {
328 *iterator = new MonomType(*iteratorAnother);
329 iterator = &((*iterator)->Next);
330 iteratorAnother = iteratorAnother->Next;
331 }
332 }
333
334 return *this;
335 }
336
337 template <typename MonomType>
338 const Polynom<MonomType>& Polynom<MonomType>::operator*=(typename MonomType::Integer var)
339 {
340 if (MonomListHead)
341 {
342 Polynom<MonomType> polynomWithVar;
343 MonomType **iterator = &MonomListHead,
344 **iteratorWithVar = &polynomWithVar.MonomListHead;
345
346 while (*iterator)
347 {
348 if ((**iterator)[var])
349 {
350 *iteratorWithVar = *iterator;
351 *iterator = (*iterator)->Next;
352 (*iteratorWithVar)->Next = 0;
353 iteratorWithVar = &((*iteratorWithVar)->Next);
354 }
355 else
356 {
357 iterator = &((*iterator)->Next);
358 }
359 }
360
361 iterator = &MonomListHead;
362 while (*iterator)
363 {
364 **iterator *= var;
365 iterator = &((*iterator)->Next);
366 }
367
368 MergeWith(polynomWithVar);
369 }
370
371 return *this;
372 }
373
374 template <typename MonomType>
375 const Polynom<MonomType>& Polynom<MonomType>::operator*=(const MonomType& anotherMonom)
376 {
377 if (MonomListHead)
378 {
379 for (typename MonomType::Integer i = 0; i < anotherMonom.GetDimIndepend(); ++i)
380 {
381 if (anotherMonom[i])
382 {
383 *this *= i;
384 }
385 }
386 }
387 return *this;
388 }
389
390 template <typename MonomType>
392 {
393 if (MonomListHead)
394 {
395 Polynom<MonomType> *tmpPolynom = 0,
396 *tmpResult = new Polynom<MonomType>();
397 MonomType* iteratorAnother = anotherPolynom.MonomListHead;
398
399 while (iteratorAnother)
400 {
401 tmpPolynom = new Polynom<MonomType>(*this);
402 *tmpPolynom *= *iteratorAnother;
403 tmpResult->MergeWith(*tmpPolynom);
404 delete tmpPolynom;
405 iteratorAnother = iteratorAnother->Next;
406 }
407 SetZero();
408 MonomListHead = tmpResult->MonomListHead;
409 tmpResult->MonomListHead = 0;
410 delete tmpResult;
411 }
412 return *this;
413 }
414
415 template <typename MonomType>
416 bool Polynom<MonomType>::operator==(const Polynom<MonomType>& anotherPolynom) const
417 {
418 MonomType *iterator = MonomListHead,
419 *anotherIterator = anotherPolynom.MonomListHead;
420
421 while (iterator && anotherIterator)
422 {
423 if (*iterator != *anotherIterator)
424 {
425 break;
426 }
427 iterator = iterator->Next;
428 anotherIterator = anotherIterator->Next;
429 }
430 return !iterator && !anotherIterator;
431 }
432
433 template <typename MonomType>
434 bool Polynom<MonomType>::operator!=(const Polynom<MonomType>& anotherPolynom) const
435 {
436 MonomType *iterator = MonomListHead,
437 *anotherIterator = anotherPolynom.MonomListHead;
438
439 while (iterator && anotherIterator)
440 {
441 if (*iterator != *anotherIterator)
442 {
443 break;
444 }
445 iterator = iterator->Next;
446 anotherIterator = anotherIterator->Next;
447 }
448 return iterator || anotherIterator;
449 }
450
451 template <typename MonomType>
452 bool Polynom<MonomType>::operator<(const Polynom<MonomType>& anotherPolynom) const
453 {
454 MonomType *iterator = MonomListHead,
455 *anotherIterator = anotherPolynom.MonomListHead;
456
457 while (iterator && anotherIterator)
458 {
459 switch ((*iterator).Compare(*anotherIterator))
460 {
461 case -1:
462 return true;
463 break;
464 case 1:
465 return false;
466 break;
467 case 0:
468 iterator = iterator->Next;
469 anotherIterator = anotherIterator->Next;
470 break;
471 }
472 }
473 return !iterator && !anotherIterator;
474 }
475
476 template <typename MonomType>
477 bool Polynom<MonomType>::operator>(const Polynom<MonomType>& anotherPolynom) const
478 {
479 MonomType *iterator = MonomListHead,
480 *anotherIterator = anotherPolynom.MonomListHead;
481
482 while (iterator && anotherIterator)
483 {
484 switch ((*iterator).Compare(*anotherIterator))
485 {
486 case -1:
487 return false;
488 break;
489 case 1:
490 return true;
491 break;
492 case 0:
493 iterator = iterator->Next;
494 anotherIterator = anotherIterator->Next;
495 break;
496 }
497 }
498 return iterator && !anotherIterator;
499 }
500
501 template <typename MonomType>
503 {
504 MonomType *iteratorA = polynomA.MonomListHead,
505 *iteratorB = polynomB.MonomListHead;
506
507 while (iteratorA && iteratorB)
508 {
509 switch ((*iteratorA).Compare(*iteratorB))
510 {
511 case -1:
512 return -1;
513 break;
514 case 1:
515 return 1;
516 break;
517 case 0:
518 iteratorA = iteratorA->Next;
519 iteratorB = iteratorB->Next;
520 break;
521 }
522 }
523
524 if (iteratorA)
525 {
526 return 1;
527 }
528 else if (iteratorB)
529 {
530 return -1;
531 }
532 else
533 {
534 return 0;
535 }
536 }
537
538 template <typename MonomType>
540 {
541 if (MonomListHead && anotherPolynom.MonomListHead)
542 {
543 MonomType* tmpMonom = new MonomType();
544 Polynom<MonomType>* tmpPolynom = 0;
545 MonomType* iterator = MonomListHead;
546 const MonomType& anotherLm = anotherPolynom.Lm();
547
548 while (iterator)
549 {
550 if (iterator->IsDivisibleBy(anotherLm))
551 {
552 tmpMonom->SetQuotientOf(*iterator, anotherLm);
553 tmpPolynom = new Polynom<MonomType>(anotherPolynom);
554 *tmpPolynom *= *tmpMonom;
555 MergeWith(*tmpPolynom);
556 delete tmpPolynom;
557 iterator = MonomListHead;
558 }
559 else
560 {
561 break;
562 }
563 }
564
565 if (MonomListHead)
566 {
567 MonomType* iterator2 = iterator;
568 iterator = iterator->Next;
569 while (iterator)
570 {
571 if (iterator->IsDivisibleBy(anotherLm))
572 {
573 tmpMonom->SetQuotientOf(*iterator, anotherLm);
574 tmpPolynom = new Polynom<MonomType>(anotherPolynom);
575 *tmpPolynom *= *tmpMonom;
576 MergeWith(*tmpPolynom);
577 delete tmpPolynom;
578 iterator = iterator2->Next;
579 }
580 else
581 {
582 iterator2 = iterator2->Next;
583 iterator = iterator2->Next;
584 }
585 }
586 }
587 delete tmpMonom;
588 }
589 }
590
591 template <typename MonomType>
593 {
594 if (MonomListHead && anotherPolynom.MonomListHead)
595 {
596 MonomType* tmpMonom = new MonomType();
597 Polynom<MonomType>* tmpPolynom = 0;
598 MonomType* iterator = MonomListHead;
599 const MonomType& anotherLm = anotherPolynom.Lm();
600
601 while (iterator)
602 {
603 if (iterator->IsDivisibleBy(anotherLm))
604 {
605 tmpMonom->SetQuotientOf(*iterator, anotherLm);
606 tmpPolynom = new Polynom<MonomType>(anotherPolynom);
607 *tmpPolynom *= *tmpMonom;
608 MergeWith(*tmpPolynom);
609 delete tmpPolynom;
610 iterator = MonomListHead;
611 }
612 else
613 {
614 break;
615 }
616 }
617 delete tmpMonom;
618 }
619 }
620
621 template <typename MonomType>
623 {
624 MonomType **iterator = &MonomListHead,
625 *iteratorAnother = anotherPolynom.MonomListHead,
626 *tmpPointer = 0;
627
628 while (*iterator && iteratorAnother)
629 {
630 switch ((**iterator).Compare(*iteratorAnother))
631 {
632 case -1:
633 tmpPointer = iteratorAnother;
634 iteratorAnother = iteratorAnother->Next;
635 tmpPointer->Next = *iterator;
636 *iterator = tmpPointer;
637 iterator = &(tmpPointer->Next);
638 break;
639 case 0:
640 tmpPointer = *iterator;
641 *iterator = (*iterator)->Next;
642 delete tmpPointer;
643 tmpPointer = iteratorAnother;
644 iteratorAnother = iteratorAnother->Next;
645 delete tmpPointer;
646 break;
647 case 1:
648 iterator = &((*iterator)->Next);
649 break;
650 }
651 }
652
653 if (iteratorAnother)
654 {
655 *iterator = iteratorAnother;
656 }
657
658 anotherPolynom.MonomListHead = 0;
659 }
660
661 template <typename MonomType>
662 const MonomType * const * Polynom<MonomType>::Find(const MonomType& monom) const
663 {
664 if (!MonomListHead || *MonomListHead < monom)
665 {
666 return 0;
667 }
668
669 MonomType * const *previousPointer = &MonomListHead,
670 * const *currentPointer = 0;
671 unsigned long range(Length()), middle;
672
673 while ((middle = range >> 1) > 0)
674 {
675 currentPointer = previousPointer;
676 for (unsigned long i = 0; i < middle; ++i)
677 {
678 currentPointer = &((*currentPointer)->Next);
679 }
680
681 switch ((**currentPointer).Compare(monom))
682 {
683 case 1:
684 previousPointer = currentPointer;
685 range -= middle;
686 break;
687 case -1:
688 range = middle;
689 break;
690 case 0:
691 return currentPointer;
692 }
693 }
694
695 return previousPointer;
696 }
697}
698
699#endif // BIBASIS_POLYNOM_HPP
BIBasis::FastAllocator — per-size-class slab allocator for BIBasis's small objects.
Slab allocator handing out fixed-size blocks for one BIBasis type per instance.
Definition allocator.hpp:57
bool operator!=(const Polynom &anotherPolynom) const
Definition polynom.hpp:434
static FastAllocator Allocator
Definition polynom.hpp:54
const Polynom & operator=(const Polynom &anotherPolynom)
Definition polynom.hpp:225
static int Compare(const Polynom &polynomA, const Polynom &polynomB)
Definition polynom.hpp:502
MonomType::Integer Degree() const
Definition polynom.hpp:176
void Reduction(const Polynom &anotherPolynom)
Definition polynom.hpp:539
MonomType * MonomListHead
Definition polynom.hpp:53
bool operator==(const Polynom &anotherPolynom) const
Definition polynom.hpp:416
const Polynom & operator+=(const MonomType &newMonom)
Definition polynom.hpp:264
bool IsZero() const
Definition polynom.hpp:157
void MergeWith(Polynom &anotherPolynom)
Definition polynom.hpp:622
const MonomType & Lm() const
Definition polynom.hpp:189
bool operator<(const Polynom &anotherPolynom) const
Definition polynom.hpp:452
unsigned long Length() const
Definition polynom.hpp:163
static MonomType UniteMonom
Definition polynom.hpp:55
bool operator>(const Polynom &anotherPolynom) const
Definition polynom.hpp:477
const MonomType *const * Find(const MonomType &monom) const
Definition polynom.hpp:662
const Polynom & operator*=(typename MonomType::Integer var)
Definition polynom.hpp:338
void HeadReduction(const Polynom &anotherPolynom)
Definition polynom.hpp:592