3 #include "optimal_vars_finder.h"
14 // XXX: copy-pasted from normal.cpp.
16 * Statistical information about symbols in polynomials
19 /** This structure holds information about the highest and lowest degrees
20 * in which a symbol appears in two multivariate polynomials "a" and "b".
21 * A vector of these structures with information about all symbols in
22 * two polynomials can be created with the function get_symbol_stats().
24 * @see get_symbol_stats */
27 /** Reference to symbol */
30 /** Highest degree of symbol in polynomial "a" */
33 /** Highest degree of symbol in polynomial "b" */
36 /** Lowest degree of symbol in polynomial "a" */
39 /** Lowest degree of symbol in polynomial "b" */
42 /** Maximum of deg_a and deg_b (Used for sorting) */
45 /** Maximum number of terms of leading coefficient of symbol in both polynomials */
46 std::size_t max_lcnops;
48 /** Commparison operator for sorting */
49 bool operator<(const sym_desc &x) const
51 if (max_deg == x.max_deg)
52 return max_lcnops < x.max_lcnops;
54 return max_deg < x.max_deg;
58 // Vector of sym_desc structures
59 typedef std::vector<sym_desc> sym_desc_vec;
61 // Add symbol the sym_desc_vec (used internally by get_symbol_stats())
62 static void add_symbol(const ex &s, sym_desc_vec &v)
64 sym_desc_vec::const_iterator it = v.begin(), itend = v.end();
66 if (it->sym.is_equal(s)) // If it's already in there, don't add it a second time
75 // Collect all symbols of an expression (used internally by get_symbol_stats())
76 static void collect_symbols(const ex &e, sym_desc_vec &v)
78 if (is_a<symbol>(e)) {
80 } else if (is_exactly_a<add>(e) || is_exactly_a<mul>(e)) {
81 for (size_t i=0; i<e.nops(); i++)
82 collect_symbols(e.op(i), v);
83 } else if (is_exactly_a<power>(e)) {
84 collect_symbols(e.op(0), v);
89 * @brief Find the order of variables which is optimal for GCD computation.
91 * Collects statistical information about the highest and lowest degrees
92 * of all variables that appear in two polynomials. Sorts the variables
93 * by minimum degree (lowest to highest). The information gathered by
94 * this function is used by GCD routines to find out the main variable
95 * for GCD computation.
97 * @param a first multivariate polynomial
98 * @param b second multivariate polynomial
99 * @param v vector of sym_desc structs (filled in) */
100 static void get_symbol_stats(const ex &a, const ex &b, sym_desc_vec &v)
102 collect_symbols(a, v);
103 collect_symbols(b, v);
104 sym_desc_vec::iterator it = v.begin(), itend = v.end();
105 while (it != itend) {
106 int deg_a = a.degree(it->sym);
107 int deg_b = b.degree(it->sym);
110 it->max_deg = std::max(deg_a, deg_b);
111 it->max_lcnops = std::max(a.lcoeff(it->sym).nops(), b.lcoeff(it->sym).nops());
112 it->ldeg_a = a.ldegree(it->sym);
113 it->ldeg_b = b.ldegree(it->sym);
116 std::sort(v.begin(), v.end());
118 // XXX: end copy-paste from normal.cpp
120 } // anonymous namespace of helper functions
122 exvector gcd_optimal_variables_order(const ex& a, const ex& b)
125 get_symbol_stats(a, b, v);
127 vars.reserve(v.size());
128 for (std::size_t i = v.size(); i-- != 0; )
129 vars.push_back(v[i].sym);