Frobby 0.9.5
UniHashPolynomial.cpp
Go to the documentation of this file.
1/* Frobby: Software for monomial ideal computations.
2 Copyright (C) 2009 University of Aarhus
3 Contact Bjarke Hammersholt Roune for license information (www.broune.com)
4
5 This program 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 2 of the License, or
8 (at your option) any later version.
9
10 This program 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 this program. If not, see http://www.gnu.org/licenses/.
17*/
18#include "stdinc.h"
19#include "UniHashPolynomial.h"
20
21#include "CoefBigTermConsumer.h"
22#include "VarNames.h"
23#include <algorithm>
24
25void UniHashPolynomial::add(bool plus, const mpz_class& exponent) {
26 mpz_class& ref = _terms[exponent];
27 if (plus)
28 ++ref;
29 else
30 --ref;
31 if (ref == 0)
32 _terms.erase(exponent);
33}
34
35void UniHashPolynomial::add(int coef, size_t exponent) {
36 if (coef == 0)
37 return;
38 mpz_class& ref = _terms[exponent];
39 ref += coef;
40 if (ref == 0)
41 _terms.erase(exponent);
42}
43
44void UniHashPolynomial::add(const mpz_class& coef, const mpz_class& exponent) {
45 if (coef == 0)
46 return;
47 mpz_class& ref = _terms[exponent];
48 ref += coef;
49 if (ref == 0)
50 _terms.erase(exponent);
51}
52
53namespace {
55 class RefCompare {
56 public:
57 typedef HashMap<mpz_class, mpz_class> TermMap;
58 bool operator()(TermMap::const_iterator a, TermMap::const_iterator b) {
59 return a->first > b->first;
60 }
61 };
62}
63
64void UniHashPolynomial::feedTo(CoefBigTermConsumer& consumer, bool inCanonicalOrder) const {
65 VarNames names;
66 names.addVar("t");
67 consumer.consumeRing(names);
68 vector<mpz_class> term(1);
69
70 consumer.beginConsuming();
71
72 if (!inCanonicalOrder) {
73 // Output the terms in whatever order _terms is storing them.
74 TermMap::const_iterator termsEnd = _terms.end();
75 TermMap::const_iterator it = _terms.begin();
76 for (; it != termsEnd; ++it) {
77 ASSERT(it->second != 0);
78 term[0] = it->first;
79 consumer.consume(it->second, term);
80 }
81 } else {
82
83 // Fill refs with references in order to sort them. We can't sort
84 // _terms since HashMap doesn't support that, so we have to sort
85 // references into _terms instead.
86 vector<TermMap::const_iterator> refs;
87 refs.reserve(_terms.size());
88
89 TermMap::const_iterator termsEnd = _terms.end();
90 for (TermMap::const_iterator it = _terms.begin();
91 it != termsEnd; ++it)
92 refs.push_back(it);
93
94 sort(refs.begin(), refs.end(), RefCompare());
95
96 // Output the terms in the sorted order specified by refs.
97 vector<TermMap::const_iterator>::const_iterator refsEnd = refs.end();
98 vector<TermMap::const_iterator>::const_iterator refIt = refs.begin();
99 for (; refIt != refsEnd; ++refIt) {
100 TermMap::const_iterator it = *refIt;
101 ASSERT(it->second != 0);
102 term[0] = it->first;
103 consumer.consume(it->second, term);
104 }
105 }
106
107 consumer.doneConsuming();
108}
109
111 return _terms.size();
112}
virtual void beginConsuming()=0
virtual void consume(const mpz_class &coef, const Term &term)
virtual void doneConsuming()=0
virtual void consumeRing(const VarNames &names)=0
size_t getTermCount() const
void feedTo(CoefBigTermConsumer &consumer, bool inCanonicalOrder=false) const
void add(bool plus, const mpz_class &exponent)
Add +t^exponent or -t^exponent to the polynomial depending on whether plus is true or false,...
Defines the variables of a polynomial ring and facilities IO involving them.
Definition: VarNames.h:40
bool addVar(const string &name)
Adds the variable and returns true if name is not already a variable.
Definition: VarNames.cpp:44
#define ASSERT(X)
Definition: stdinc.h:86