Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/schemes/hyperelliptic_curves/hypellfrob/recurrences_zn_poly.h
4156 views
1
/* ============================================================================
2
3
recurrences_zn_poly.h: header for recurrences_zn_poly.cpp
4
5
This file is part of hypellfrob (version 2.1.1).
6
7
Copyright (C) 2007, 2008, David Harvey
8
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13
14
This program 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 along
20
with this program; if not, write to the Free Software Foundation, Inc.,
21
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23
============================================================================ */
24
25
26
#include <vector>
27
#include <NTL/ZZ.h>
28
#include <zn_poly/zn_poly.h>
29
30
31
32
namespace hypellfrob {
33
34
35
/*
36
This struct stores precomputed information that can then be used to shift
37
evaluation values of a polynomial F(x) of degree d.
38
39
Specifically, given the values
40
F(0), F(b), F(2*b), ..., F(d*b),
41
the shift() method computes
42
F(a), F(a + b), F(a + 2*b), ..., F(a + d*b).
43
44
PRECONDITIONS:
45
d >= 0
46
1, 2, ..., d + 1 are invertible
47
a + i*b are invertible for -d <= i <= d
48
49
*/
50
struct Shifter
51
{
52
ulong d;
53
54
// input_twist is a vector of length d + 1.
55
// The i-th entry is \prod_{0 <= j <= d, j != i} (i-j)^(-1).
56
// todo: this is symmetric, so can make it d/2 + 1, but need to
57
// deal with even/odd cases separately?
58
ulong* input_twist;
59
60
// output_twist is a vector of length d + 1.
61
// The i-th entry is b^(-d) \prod_{0 <= j <= d} (a + (i-j)*b).
62
ulong* output_twist;
63
64
// precomputed info for performing middle product against a "kernel"
65
// polynomial of degree 2d. The coefficients of "kernel" are
66
// (a + k*b)^(-1) for -d <= k <= d.
67
zn_array_mulmid_precomp1_t kernel_precomp;
68
69
// Scratch space for shift(), length d + 1
70
ulong* scratch;
71
72
// zn_poly modulus object
73
const zn_mod_struct* mod;
74
75
~Shifter();
76
77
// Constructor (performs various precomputations)
78
Shifter(ulong d, ulong a, ulong b, const zn_mod_t mod);
79
80
// Shifts evaluation values as described above.
81
// Assumes both output and input have length d + 1.
82
void shift(ulong* output, const ulong* input);
83
};
84
85
86
/*
87
Grrr..... I would rather use vector<ulong>, but then strictly speaking
88
I can't be guaranteed that the data is stored in a simple array format,
89
so here I go rolling my own....
90
*/
91
struct ulong_array
92
{
93
ulong* data;
94
95
ulong_array()
96
{
97
data = NULL;
98
}
99
100
ulong_array(ulong amount)
101
{
102
data = (ulong*) malloc(sizeof(ulong) * amount);
103
}
104
105
~ulong_array()
106
{
107
if (data)
108
free(data);
109
}
110
111
void resize(ulong amount)
112
{
113
if (data)
114
data = (ulong*) realloc(data, sizeof(ulong) * amount);
115
else
116
data = (ulong*) malloc(sizeof(ulong) * amount);
117
}
118
};
119
120
121
122
int check_params(ulong k, ulong u, const zn_mod_t mod);
123
124
125
126
struct LargeEvaluator
127
{
128
int r;
129
ulong k, u, k2, odd;
130
const std::vector<std::vector<ulong> >& M0;
131
const std::vector<std::vector<ulong> >& M1;
132
const zn_mod_t& mod;
133
Shifter* shifter;
134
std::vector<ulong_array> scratch;
135
136
LargeEvaluator(int r, ulong k, ulong u,
137
const std::vector<std::vector<ulong> >& M0,
138
const std::vector<std::vector<ulong> >& M1,
139
const zn_mod_t& mod);
140
141
~LargeEvaluator();
142
143
void evaluate(int half, std::vector<ulong_array>& output, ulong offset);
144
void evaluate_all(std::vector<ulong_array>& output);
145
};
146
147
148
149
int zn_poly_interval_products(
150
std::vector<std::vector<std::vector<ulong> > >& output,
151
const std::vector<std::vector<ulong> >& M0,
152
const std::vector<std::vector<ulong> >& M1,
153
const std::vector<NTL::ZZ>& target, const zn_mod_t& mod);
154
155
156
};
157
158
// ----------------------- end of file
159
160