1 /* Frobby: Software for monomial ideal computations.
2 Copyright (C) 2007 Bjarke Hammersholt Roune (www.broune.com)
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see http://www.gnu.org/licenses/.
16 */
17 #include "stdinc.h"
18 #include "BigPolynomial.h"
19
20 #include "Term.h"
21 #include "TermTranslator.h"
22 #include "VarSorter.h"
23
24 #include <algorithm>
25 #include <sstream>
26
BigPolynomial()27 BigPolynomial::BigPolynomial() {
28 }
29
BigPolynomial(const VarNames & names)30 BigPolynomial::BigPolynomial(const VarNames& names):
31 _names(names) {
32 }
33
getTermCount() const34 size_t BigPolynomial::getTermCount() const {
35 return _coefTerms.size();
36 }
37
getVarCount() const38 size_t BigPolynomial::getVarCount() const {
39 return _names.getVarCount();
40 }
41
getNames() const42 const VarNames& BigPolynomial::getNames() const {
43 return _names;
44 }
45
sortTermsReverseLex()46 void BigPolynomial::sortTermsReverseLex() {
47 sort(_coefTerms.begin(), _coefTerms.end(), compareCoefTermsReverseLex);
48 }
49
sortVariables()50 void BigPolynomial::sortVariables() {
51 VarSorter sorter(_names);
52 sorter.getOrderedNames(_names);
53 for (size_t i = 0; i < _coefTerms.size(); ++i)
54 sorter.permute(_coefTerms[i].term);
55 }
56
clear()57 void BigPolynomial::clear() {
58 _coefTerms.clear();
59 }
60
clearAndSetNames(const VarNames & names)61 void BigPolynomial::clearAndSetNames(const VarNames& names) {
62 clear();
63 _names = names;
64 }
65
getCoef(size_t index) const66 const mpz_class& BigPolynomial::getCoef(size_t index) const {
67 ASSERT(index < getTermCount());
68
69 return _coefTerms[index].coef;
70 }
71
getTerm(size_t index) const72 const vector<mpz_class>& BigPolynomial::getTerm(size_t index) const {
73 ASSERT(index < getTermCount());
74
75 return _coefTerms[index].term;
76 }
77
newLastTerm()78 void BigPolynomial::newLastTerm() {
79 _coefTerms.resize(_coefTerms.size() + 1);
80 _coefTerms.back().term.resize(getVarCount());
81 }
82
getLastTerm()83 vector<mpz_class>& BigPolynomial::getLastTerm() {
84 ASSERT(getTermCount() > 0);
85
86 return _coefTerms.back().term;
87 }
88
getLastCoef()89 mpz_class& BigPolynomial::getLastCoef() {
90 ASSERT(getTermCount() > 0);
91
92 return _coefTerms.back().coef;
93 }
94
renameVars(const VarNames & names)95 void BigPolynomial::renameVars(const VarNames& names) {
96 ASSERT(names.getVarCount() == _names.getVarCount());
97 _names = names;
98 }
99
add(const mpz_class & coef,const vector<mpz_class> term)100 void BigPolynomial::add(const mpz_class& coef,
101 const vector<mpz_class> term) {
102 ASSERT(term.size() == getVarCount());
103
104 _coefTerms.resize(_coefTerms.size() + 1);
105 _coefTerms.back().coef = coef;
106 _coefTerms.back().term = term;
107 }
108
add(const mpz_class & coef,const Term & term,const TermTranslator & translator)109 void BigPolynomial::add(const mpz_class& coef,
110 const Term& term,
111 const TermTranslator& translator) {
112 ASSERT(term.getVarCount() == getVarCount());
113 ASSERT(translator.getVarCount() == getVarCount());
114
115 _coefTerms.resize(_coefTerms.size() + 1);
116 _coefTerms.back().coef = coef;
117
118 vector<mpz_class>& bigTerm = _coefTerms.back().term;
119 bigTerm.reserve(term.getVarCount());
120 for (size_t var = 0; var < term.getVarCount(); ++var)
121 bigTerm.push_back(translator.getExponent(var, term));
122 }
123
operator ==(const BigPolynomial & poly) const124 bool BigPolynomial::operator==(const BigPolynomial& poly) const {
125 return _names == poly._names && _coefTerms == poly._coefTerms;
126 }
127
operator ==(const BigCoefTerm & coefTerm) const128 bool BigPolynomial::BigCoefTerm::operator==(const BigCoefTerm& coefTerm) const {
129 return coef == coefTerm.coef && term == coefTerm.term;
130 }
131
print(FILE * file) const132 void BigPolynomial::print(FILE* file) const {
133 ostringstream out;
134 out << *this;
135 fputs(out.str().c_str(), file);
136 }
137
print(ostream & out) const138 void BigPolynomial::print(ostream& out) const {
139 out << "/---- BigPolynomial of " << _coefTerms.size() << " terms:\n";
140 for (vector<BigCoefTerm>::const_iterator it = _coefTerms.begin();
141 it != _coefTerms.end(); ++it) {
142 out << ' ' << it->coef << " ";
143 for (vector<mpz_class>::const_iterator entry = it->term.begin();
144 entry != it->term.end(); ++entry)
145 out << ' ' << *entry;
146 out << '\n';
147 }
148 out << "----/ End of list.\n";
149 }
150
compareCoefTermsReverseLex(const BigCoefTerm & a,const BigCoefTerm & b)151 bool BigPolynomial::compareCoefTermsReverseLex(const BigCoefTerm& a,
152 const BigCoefTerm& b) {
153 for (size_t var = 0; var < a.term.size(); ++var)
154 if (a.term[var] != b.term[var])
155 return a.term[var] > b.term[var];
156 return a.coef < b.coef;
157 }
158
operator <<(ostream & out,const BigPolynomial & poly)159 ostream& operator<<(ostream& out, const BigPolynomial& poly) {
160 poly.print(out);
161 return out;
162 }
163