@@ -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 .02f
46+
4047/*
4148 #[ flint::cleanup :
4249*/
@@ -1061,7 +1068,9 @@ 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 ;
1064- // To be used if we sort by highest degree, as the polu code does.
1071+ // We count the total number of terms to determine "density".
1072+ uint32_t num_terms = 0 ;
1073+ // To be used if we sort by highest degree, as the poly code does.
10651074 vector<int32_t > degrees;
10661075 var_map_t var_map;
10671076
@@ -1071,8 +1080,10 @@ flint::var_map_t flint::get_variables(const vector <WORD *> &es, const bool with
10711080
10721081 // fast notation
10731082 if ( *e == -SNUMBER ) {
1083+ num_terms++;
10741084 }
10751085 else if ( *e == -SYMBOL ) {
1086+ num_terms++;
10761087 if ( !var_map.count (e[1 ]) ) {
10771088 var_map[e[1 ]] = num_vars++;
10781089 degrees.push_back (1 );
@@ -1087,6 +1098,7 @@ flint::var_map_t flint::get_variables(const vector <WORD *> &es, const bool with
10871098 }
10881099 else {
10891100 for ( WORD i = with_arghead ? ARGHEAD:0 ; with_arghead ? i < e[0 ]:e[i] != 0 ; i += e[i] ) {
1101+ num_terms++;
10901102 if ( i+1 < i+e[i]-ABS (e[i+e[i]-1 ]) && e[i+1 ] != SYMBOL ) {
10911103 MLOCK (ErrorMessageLock);
10921104 MesPrint (" ERROR: polynomials and polyratfuns must contain symbols only" );
@@ -1152,6 +1164,16 @@ flint::var_map_t flint::get_variables(const vector <WORD *> &es, const bool with
11521164 }
11531165 }
11541166
1167+ if ( var_map.size () == 1 ) {
1168+ // In the univariate case, if the polynomials are sufficiently sparse force the use of the
1169+ // multivariate routines, which use a sparse representation, by adding a dummy map entry.
1170+ if ( (float )num_terms <= UNIVARIATE_DENSITY_THR * (float )degrees[0 ] ) {
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