Skip to content

Commit 4adf7b0

Browse files
committed
flint: perf: use mpoly for sparse univariate computations
This improves performance for things like "gcd_(1-x^20,1-x^1000000)" since FLINT poly has a dense representation whereas mpoly is sparse. "Real life" benchmarks such as forcer or minceex are unchanged, they have dense polynomials.
1 parent 7ed2880 commit 4adf7b0

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

sources/flintinterface.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ static_assert(sizeof(slong) == sizeof(int64_t), "flint interface expects slong i
3737
#] Types
3838
*/
3939

40+
/*
41+
* FLINT's univariate poly has a dense representation. For sufficiently sparse polynomials it is
42+
* faster to use mpoly instead, which is sparse. For a density <= this threshold we switch, where
43+
* the density defined as is "number of terms" / "maximum degree".
44+
*/
45+
#define UNIVARIATE_DENSITY_THR 0.01
46+
4047
/*
4148
#[ flint::cleanup :
4249
*/
@@ -1061,6 +1068,7 @@ flint::var_map_t flint::get_variables(const vector <WORD *> &es, const bool with
10611068
const bool sort_vars) {
10621069

10631070
int32_t num_vars = 0;
1071+
uint32_t num_terms = 0;
10641072
// To be used if we sort by highest degree, as the polu code does.
10651073
vector<int32_t> degrees;
10661074
var_map_t var_map;
@@ -1069,6 +1077,9 @@ flint::var_map_t flint::get_variables(const vector <WORD *> &es, const bool with
10691077
for ( size_t ei = 0; ei < es.size(); ei++ ) {
10701078
WORD *e = es[ei];
10711079

1080+
// We count the total number of terms to determine "density".
1081+
num_terms++;
1082+
10721083
// fast notation
10731084
if ( *e == -SNUMBER ) {
10741085
}
@@ -1152,6 +1163,17 @@ flint::var_map_t flint::get_variables(const vector <WORD *> &es, const bool with
11521163
}
11531164
}
11541165

1166+
if ( var_map.size() == 1 ) {
1167+
// In the univariate case, if the polynomials are sufficiently sparse force the use of the
1168+
// multivariate routines, which use a sparse representation, by adding a dummy map entry.
1169+
const float density = (float)num_terms / (float)degrees[0];
1170+
if ( density <= UNIVARIATE_DENSITY_THR ) {
1171+
// -1 will never be a symbol code. Built-in symbols from 0 to 19, and 20 is the first
1172+
// user symbol.
1173+
var_map[-1] = num_vars;
1174+
}
1175+
}
1176+
11551177
return var_map;
11561178
}
11571179
/*

0 commit comments

Comments
 (0)