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