CoxIter  1.2
CoxIter - Computing invariants of hyperbolic Coxeter groups
polynomials.h
Go to the documentation of this file.
1 /*
2 Copyright (C) 2013, 2014, 2015
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 <string>
34 #include <vector>
35 #include <iostream>
36 #include <cmath>
37 #include <iterator>
38 #include <map>
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
49 {
54  template <typename Type>
55  void polynomialDisplay( const vector< Type >& iPolynomial )
56  {
57  bool bFirst( true );
58  unsigned int iSize( iPolynomial.size( ) );
59 
60  for( unsigned int i( 0 ); i < iSize; i++ )
61  {
62  if( iPolynomial[i] != 0 )
63  {
64  if( bFirst )
65  {
66  cout << iPolynomial[i] << ( i ? " * x" + string( i > 1 ? "^" + to_string( i ) : "" ) : "" );
67  bFirst = false;
68  }
69  else
70  {
71  if( ( iPolynomial[i] != 1 && iPolynomial[i] != -1 ) || !i )
72  cout << ( iPolynomial[i] > 0 ? " + " : " - " ) << abs( iPolynomial[i] ) << ( i ? " * x" + string( i > 1 ? "^" + to_string( i ) : "" ) : "" );
73  else
74  cout << ( iPolynomial[i] > 0 ? " + " : " - " ) << "x" + string( i > 1 ? "^" + to_string( i ) : "" );
75  }
76  }
77  }
78  }
79 
84  template <typename Type>
85  void symbolDisplay( const vector< Type >& iSymbol )
86  {
87  bool bFirst( true );
88  unsigned int iSize( iSymbol.size( ) );
89 
90  cout << "[";
91  for( unsigned int i( 0 ); i < iSize; i++ )
92  {
93  if( iSymbol[i] )
94  {
95  for( unsigned int j(0); j < iSymbol[i]; j++ )
96  {
97  cout << ( bFirst ? "" : "," ) << i;
98  bFirst = false;
99  }
100  }
101  }
102  cout << "]";
103  }
104 
110  template <typename Type>
111  void polynomialDotSymbol( vector< Type >& iPolynomial, const unsigned int& iSymbol )
112  {
113  vector< Type > iPolynomialBackup( iPolynomial );
114  unsigned int iPolynomialDegree( iPolynomial.size( ) - 1 );
115 
116  for( unsigned int i( 1 ); i < iSymbol - 1; i++ )
117  iPolynomial.push_back( 0 );
118  iPolynomial.push_back( iPolynomial[ iPolynomialDegree ] );
119 
120  if( iPolynomialDegree < iSymbol )
121  {
122  for( unsigned int i( 1 ); i <= iPolynomialDegree; i++ )
123  iPolynomial[i] = iPolynomial[ i - 1 ] + iPolynomialBackup[i];
124 
125  fill( iPolynomial.begin( ) + iPolynomialDegree + 1, iPolynomial.end( ) - iPolynomialDegree, iPolynomial[ iPolynomialDegree ] );
126 
127  for( unsigned int i( 1 ); i <= iPolynomialDegree ; i++ ) // TODO: gérer degré plus petit que symbole
128  iPolynomial[ iPolynomialDegree + iSymbol - i - 1 ] = iPolynomial[ iPolynomialDegree + iSymbol - i ] + iPolynomialBackup[ iPolynomialDegree - i ];
129  }
130  else
131  {
132  for( unsigned int i( 1 ); i < iSymbol; i++ )
133  iPolynomial[i] = iPolynomial[ i - 1 ] + iPolynomialBackup[i];
134 
135  for( unsigned int i( iSymbol ); i < iPolynomialDegree; i++ )
136  iPolynomial[i] = iPolynomial[i-1] - iPolynomialBackup[i-iSymbol] + iPolynomialBackup[i];
137 
138  for( unsigned int i( 1 ); i < iSymbol && i <= iPolynomialDegree ; i++ )
139  iPolynomial[ iPolynomialDegree + iSymbol - i - 1 ] = iPolynomial[ iPolynomialDegree + iSymbol - i ] + iPolynomialBackup[ iPolynomialDegree - i ];
140  }
141  }
142 
143  template <typename Type>
144  bool dividePolynomialBySymbol( vector< Type >& iPolynomial, const unsigned int& iSymbol )
145  {
146  unsigned int iPolynomialDegree( iPolynomial.size( ) - 1 );
147 
148  // Removing eventual 0
149  while( iPolynomial[ iPolynomialDegree ] == 0 )
150  iPolynomialDegree--;
151 
152  vector< Type > iWorking( iPolynomial.begin( ), iPolynomial.begin( ) + iPolynomialDegree + 1 );
153  vector< Type > iQuotient;
154 
155  unsigned int i;
156  Type iTemp;
157 
158  if( iPolynomialDegree < iSymbol - 1 )
159  return false;
160 
161  while( iPolynomialDegree >= iSymbol )
162  {
163  iTemp = iWorking[ iPolynomialDegree ];
164  iQuotient.insert( iQuotient.begin( ), iTemp );
165 
166  for( i = 0; i < iSymbol; i++ )
167  iWorking[ iPolynomialDegree - i ] -= iTemp;
168 
169  iPolynomialDegree--;
170 
171  while( iWorking[ iPolynomialDegree ] == 0 && iPolynomialDegree >= 1 )
172  {
173  iQuotient.insert( iQuotient.begin( ), 0 );
174  iPolynomialDegree--;
175  }
176  }
177 
178  if( iPolynomialDegree < iSymbol - 1 )
179  {
180  for( i = 0; i <= iPolynomialDegree; i++ )
181  {
182  if( iWorking[i] != 0 )
183  return false;
184  }
185  }
186 
187  iTemp = iWorking[ iPolynomialDegree ];
188  iQuotient.insert( iQuotient.begin( ), iTemp );
189 
190  for( i = 0; i < iPolynomialDegree; i++ )
191  {
192  if( iWorking[i] != iTemp )
193  return false;
194  }
195 
196  iPolynomial = iQuotient;
197 
198  return true;
199  }
200 
208  template <typename Type>
209  bool dividePolynomialByPolynomial( vector< Type >& iNumerator, const vector< Type >& iDenominator )
210  {
211  unsigned int dN( iNumerator.size( ) - 1 ), dD( iDenominator.size( ) - 1 );
212 
213  if( dN < dD || ( dD == 0 && iDenominator[0] != 0 ) )
214  return false;
215 
216  vector< Type > iWorking( iNumerator ), iQuotient;
217 
218  unsigned int i;
219  Type iTemp;
220 
221  while( dN >= dD )
222  {
223  if( iWorking[ dN ] % iDenominator[ dD ] != 0 )
224  return false;
225 
226  iTemp = iWorking[ dN ] / iDenominator[ dD ];
227  iQuotient.insert( iQuotient.begin( ), iTemp );
228 
229  for( i = 0; i <= dD; i++ )
230  iWorking[dN - i] -= iTemp * iDenominator[dD - i];
231 
232  dN--;
233 
234  while( iWorking[ dN ] == 0 && dN >= 1 && dN >= dD )
235  {
236  iQuotient.insert( iQuotient.begin( ), 0 );
237  dN--;
238  }
239  }
240 
241  for( i = 0; i <= dN; i++ )
242  {
243  if( iWorking[i] != 0 )
244  return false;
245  }
246 
247  iNumerator = iQuotient;
248 
249  return true;
250  }
251 
252  extern vector< vector< mpz_class > > iCyclotomicPolynomials;
253 }
254 
255 #endif
bool dividePolynomialBySymbol(vector< Type > &iPolynomial, const unsigned int &iSymbol)
Definition: polynomials.h:144
T abs(const T &r)
Definition: rational.h:98
void polynomialDisplay(const vector< Type > &iPolynomial)
Definition: polynomials.h:55
void symbolDisplay(const vector< Type > &iSymbol)
Definition: polynomials.h:85
bool dividePolynomialByPolynomial(vector< Type > &iNumerator, const vector< Type > &iDenominator)
Definition: polynomials.h:209
vector< vector< mpz_class > > iCyclotomicPolynomials
List of some cyclotomic polynomials (we want to be able to multiply/divide with the growth series so ...
Definition: polynomials.cpp:27
void polynomialDotSymbol(vector< Type > &iPolynomial, const unsigned int &iSymbol)
Definition: polynomials.h:111
Definition: polynomials.cpp:25