CoxIter  1.3
CoxIter - Computing invariants of hyperbolic Coxeter groups
polynomials.h
Go to the documentation of this file.
1 /*
2 Copyright (C) 2013-2017
3 Rafael Guglielmetti, rafael.guglielmetti@unifr.ch
4 */
5 
6 /*
7 This file is part of CoxIter and AlVin.
8 
9 CoxIter is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as
11 published by the Free Software Foundation, either version 3 of the
12 License, or (at your option) any later version.
13 
14 CoxIter is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with CoxIter. If not, see <http://www.gnu.org/licenses/>.
21 */
22 
30 #ifndef __POLYNOMIALS_H__
31 #define __POLYNOMIALS_H__
32 
33 #include <cmath>
34 #include <iostream>
35 #include <iterator>
36 #include <map>
37 #include <string>
38 #include <vector>
39 
40 #ifdef _USE_LOCAL_GMP_
41 #include "gmpxx.h"
42 #else
43 #include <gmpxx.h>
44 #endif
45 
46 using namespace std;
47 
48 namespace Polynomials {
53 template <typename Type>
54 void polynomialDisplay(const vector<Type> &polynomial) {
55  bool isFirst(true);
56  unsigned int iSize(polynomial.size());
57 
58  for (unsigned int i(0); i < iSize; i++) {
59  if (polynomial[i] != 0) {
60  if (isFirst) {
61  cout << polynomial[i]
62  << (i ? " * x" + string(i > 1 ? "^" + to_string(i) : "") : "");
63  isFirst = false;
64  } else {
65  if ((polynomial[i] != 1 && polynomial[i] != -1) || !i)
66  cout << (polynomial[i] > 0 ? " + " : " - ") << abs(polynomial[i])
67  << (i ? " * x" + string(i > 1 ? "^" + to_string(i) : "") : "");
68  else
69  cout << (polynomial[i] > 0 ? " + " : " - ")
70  << "x" + string(i > 1 ? "^" + to_string(i) : "");
71  }
72  }
73  }
74 }
75 
80 template <typename Type> void symbolDisplay(const vector<Type> &symbol) {
81  bool isFirst(true);
82  unsigned int iSize(symbol.size());
83 
84  cout << "[";
85  for (unsigned int i(0); i < iSize; i++) {
86  if (symbol[i]) {
87  for (unsigned int j(0); j < symbol[i]; j++) {
88  cout << (isFirst ? "" : ",") << i;
89  isFirst = false;
90  }
91  }
92  }
93  cout << "]";
94 }
95 
101 template <typename Type>
102 void polynomialDotSymbol(vector<Type> &polynomial, const unsigned int &symbol) {
103  vector<Type> polynomialBackup(polynomial);
104  unsigned int polynomialDegree(polynomial.size() - 1);
105 
106  for (unsigned int i(1); i < symbol - 1; i++)
107  polynomial.push_back(0);
108 
109  polynomial.push_back(polynomial[polynomialDegree]);
110 
111  if (polynomialDegree < symbol) {
112  for (unsigned int i(1); i <= polynomialDegree; i++)
113  polynomial[i] = polynomial[i - 1] + polynomialBackup[i];
114 
115  fill(polynomial.begin() + polynomialDegree + 1,
116  polynomial.end() - polynomialDegree, polynomial[polynomialDegree]);
117 
118  for (unsigned int i(1); i <= polynomialDegree;
119  i++) // TODO: gérer degré plus petit que symbole
120  polynomial[polynomialDegree + symbol - i - 1] =
121  polynomial[polynomialDegree + symbol - i] +
122  polynomialBackup[polynomialDegree - i];
123  } else {
124  for (unsigned int i(1); i < symbol; i++)
125  polynomial[i] = polynomial[i - 1] + polynomialBackup[i];
126 
127  for (unsigned int i(symbol); i < polynomialDegree; i++)
128  polynomial[i] = polynomial[i - 1] - polynomialBackup[i - symbol] +
129  polynomialBackup[i];
130 
131  for (unsigned int i(1); i < symbol && i <= polynomialDegree; i++)
132  polynomial[polynomialDegree + symbol - i - 1] =
133  polynomial[polynomialDegree + symbol - i] +
134  polynomialBackup[polynomialDegree - i];
135  }
136 }
137 
138 template <typename Type>
139 bool dividePolynomialBySymbol(vector<Type> &polynomial,
140  const unsigned int &symbol) {
141  unsigned int polynomialDegree(polynomial.size() - 1);
142 
143  // Removing eventual 0
144  while (polynomial[polynomialDegree] == 0)
145  polynomialDegree--;
146 
147  vector<Type> iWorking(polynomial.begin(),
148  polynomial.begin() + polynomialDegree + 1);
149  vector<Type> quotient;
150 
151  unsigned int i;
152  Type temp;
153 
154  if (polynomialDegree < symbol - 1)
155  return false;
156 
157  while (polynomialDegree >= symbol) {
158  temp = iWorking[polynomialDegree];
159  quotient.insert(quotient.begin(), temp);
160 
161  for (i = 0; i < symbol; i++)
162  iWorking[polynomialDegree - i] -= temp;
163 
164  polynomialDegree--;
165 
166  while (iWorking[polynomialDegree] == 0 && polynomialDegree >= 1) {
167  quotient.insert(quotient.begin(), 0);
168  polynomialDegree--;
169  }
170  }
171 
172  if (polynomialDegree < symbol - 1) {
173  for (i = 0; i <= polynomialDegree; i++) {
174  if (iWorking[i] != 0)
175  return false;
176  }
177  }
178 
179  temp = iWorking[polynomialDegree];
180  quotient.insert(quotient.begin(), temp);
181 
182  for (i = 0; i < polynomialDegree; i++) {
183  if (iWorking[i] != temp)
184  return false;
185  }
186 
187  polynomial = quotient;
188 
189  return true;
190 }
191 
200 template <typename Type>
201 bool dividePolynomialByPolynomial(vector<Type> &numerator,
202  const vector<Type> &denominator) {
203  unsigned int numDeg(numerator.size() - 1), denomDeg(denominator.size() - 1);
204 
205  if (numDeg < denomDeg || (denomDeg == 0 && denominator[0] != 0))
206  return false;
207 
208  vector<Type> working(numerator), quotient;
209 
210  unsigned int i;
211  Type temp;
212 
213  while (numDeg >= denomDeg) {
214  if (working[numDeg] % denominator[denomDeg] != 0)
215  return false;
216 
217  temp = working[numDeg] / denominator[denomDeg];
218  quotient.insert(quotient.begin(), temp);
219 
220  for (i = 0; i <= denomDeg; i++)
221  working[numDeg - i] -= temp * denominator[denomDeg - i];
222 
223  numDeg--;
224 
225  while (working[numDeg] == 0 && numDeg >= 1 && numDeg >= denomDeg) {
226  quotient.insert(quotient.begin(), 0);
227  numDeg--;
228  }
229  }
230 
231  for (i = 0; i <= numDeg; i++) {
232  if (working[i] != 0)
233  return false;
234  }
235 
236  numerator = quotient;
237 
238  return true;
239 }
240 
241 extern vector<vector<mpz_class>>
246 } // namespace Polynomials
247 
248 #endif
Definition: polynomials.cpp:25
void polynomialDotSymbol(vector< Type > &polynomial, const unsigned int &symbol)
Definition: polynomials.h:102
bool dividePolynomialBySymbol(vector< Type > &polynomial, const unsigned int &symbol)
Definition: polynomials.h:139
vector< vector< mpz_class > > cyclotomicPolynomials
Definition: polynomials.cpp:26
bool dividePolynomialByPolynomial(vector< Type > &numerator, const vector< Type > &denominator)
Definition: polynomials.h:201
void polynomialDisplay(const vector< Type > &polynomial)
Definition: polynomials.h:54
void symbolDisplay(const vector< Type > &symbol)
Definition: polynomials.h:80
T abs(const T &r)
Definition: rational.h:95