Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241782 views
1
/*********************************************************************
2
3
(c) Copyright 2006-2010 Salman Baig and Chris Hall
4
5
This file is part of ELLFF
6
7
ELLFF is free software: you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation, either version 3 of the License, or
10
(at your option) any later version.
11
12
ELLFF is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
16
17
You should have received a copy of the GNU General Public License
18
along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
*********************************************************************/
21
22
//
23
// rational function field F_q(t)
24
//
25
26
#include <assert.h>
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <math.h>
30
#include <NTL/ZZX.h>
31
#include <NTL/lzz_p.h>
32
#include <NTL/lzz_pE.h>
33
#include <NTL/lzz_pX.h>
34
#include <NTL/lzz_pEX.h>
35
#include <NTL/lzz_pXFactoring.h>
36
#include <NTL/lzz_pX.h>
37
38
#include "lzz_pEratX.h"
39
40
NTL_CLIENT
41
42
///////////////////////////////////////////////////////////////////////////
43
// basic rational elements of F_q(t)
44
45
zz_pEratX::zz_pEratX(const zz_pEX& num, const zz_pEX& den)
46
{
47
init(num, den);
48
}
49
50
zz_pEratX::zz_pEratX(const zz_pEX& num)
51
{
52
zz_pEX den;
53
den = 1;
54
init(num, den);
55
}
56
57
zz_pEratX::zz_pEratX()
58
{
59
init();
60
}
61
62
void zz_pEratX::init()
63
{
64
num = 0;
65
den = 1;
66
}
67
68
void zz_pEratX::init(const zz_pEX& num)
69
{
70
zz_pEX one;
71
one = 1;
72
init(num, one);
73
}
74
75
void zz_pEratX::init(const zz_pEX& num, const zz_pEX& den)
76
{
77
assert(!IsZero(den));
78
this->num = num;
79
this->den = den;
80
zz_pEX d = GCD(num, den);
81
this->num /= d;
82
this->den /= d;
83
zz_pE c = LeadCoeff(this->den);
84
this->num /= c;
85
this->den /= c;
86
}
87
88
// g(t) = t^deg(f)*f(1/t)
89
90
void zz_pEratX::flip(zz_pEX& g, const zz_pEX& f)
91
{
92
g = 0;
93
for (int i = 0; i <= deg(f); i++)
94
g = (g<<1) + coeff(f, i);
95
}
96
97
// perform involution t-->1/t
98
99
void zz_pEratX::inv_t()
100
{
101
zz_pEX new_num, new_den;
102
int deg_num = deg(num), deg_den = deg(den);
103
flip(new_num, num);
104
flip(new_den, den);
105
if (deg_num < deg_den)
106
new_num <<= deg_den - deg_num;
107
else if (deg_num > deg_den)
108
new_den <<= deg_num - deg_den;
109
num = new_num;
110
den = new_den;
111
}
112
113
int IsZero(const zz_pEratX& f)
114
{
115
return (IsZero(f.num));
116
}
117
118
int IsConstant(const zz_pEratX& f)
119
{
120
if (IsZero(f.num))
121
return 1;
122
if (deg(f.num) != 0)
123
return 0;
124
if (deg(f.den) != 0)
125
return 0;
126
return 1;
127
}
128
129
int deg(const zz_pEratX& f)
130
{
131
return IsZero(f.num) ? -1 : deg(f.num) - deg(f.den);
132
}
133
134
long operator==(const zz_pEratX& a, const zz_pEratX& b)
135
{
136
return IsZero(a.num*b.den - b.num*a.den);
137
}
138
139
// l*x
140
141
zz_pEratX operator*(const long l, const zz_pEratX& x)
142
{
143
zz_pEratX result(x.num, x.den);
144
result.num *= l;
145
return result;
146
}
147
148
// a*b
149
150
zz_pEratX operator*(const zz_pEratX& a, const zz_pEratX& b)
151
{
152
zz_pEratX result(a.num*b.num, a.den*b.den);
153
return result;
154
}
155
156
// a/b
157
158
zz_pEratX operator/(const zz_pEratX& a, const zz_pEX& b)
159
{
160
static zz_pEratX result;
161
assert(!IsZero(b));
162
result.init(a.num, a.den*b);
163
return result;
164
}
165
166
// a/b
167
168
zz_pEratX operator/(const zz_pEratX& a, const zz_pEratX& b)
169
{
170
static zz_pEratX result;
171
assert(!IsZero(b));
172
result.init(a.num*b.den, a.den*b.num);
173
return result;
174
}
175
176
// a+b
177
178
zz_pEratX operator+(const zz_pEratX& a, const zz_pE& b)
179
{
180
static zz_pEratX result;
181
result.init(a.num + b*a.den, a.den);
182
return result;
183
}
184
185
// a+b
186
187
zz_pEratX operator+(const zz_pEratX& a, const zz_pEratX& b)
188
{
189
static zz_pEratX result;
190
result.init(a.num*b.den + b.num*a.den, a.den*b.den);
191
return result;
192
}
193
194
// a+b
195
196
zz_pEratX operator-(const zz_pEratX& a, const zz_pEratX& b)
197
{
198
static zz_pEratX result;
199
result.init(a.num*b.den - b.num*a.den, a.den*b.den);
200
return result;
201
}
202
203
// compute x^e
204
205
zz_pEratX operator^(const zz_pEratX& x, const int e)
206
{
207
zz_pEX one;
208
one = 1;
209
210
zz_pEratX result(one), l;
211
long i;
212
213
assert(e >= 0);
214
215
if (e == 0) return result;
216
217
// I = 2^i
218
for (i = 0, l = x; (1<<i) <= e; i++) {
219
if (e & (1<<i))
220
result = result * l;
221
l = l * l;
222
}
223
224
return result;
225
}
226
227
// compose rational functions (f,g)-->f(g)
228
229
zz_pEratX eval(const zz_pEratX& f, const zz_pEratX& g)
230
{
231
static zz_pEratX r;
232
233
r.init();
234
if (IsZero(f.num))
235
return r;
236
237
return eval(f.num, g) / eval(f.den, g);
238
}
239
240
// compose polynomial with rational function (f,g)-->f(g)
241
242
zz_pEratX eval(const zz_pEX& f, const zz_pEratX& g)
243
{
244
static zz_pEratX r, z;
245
static zz_pEX t;
246
static zz_pE c;
247
long i;
248
249
c = coeff(f, deg(f));
250
t = c;
251
r.init(t);
252
for (i = deg(f)-1; i >= 0; i--) {
253
//r = r*g + coeff(f,i);
254
c = coeff(f, i);
255
z = r*g;
256
r = z+c;
257
}
258
259
return r;
260
}
261
262
263