]> www.ginac.de Git - ginac.git/blob - ginac/normal.cpp
Use C++11 range-based foor loops and auto, where possible.
[ginac.git] / ginac / normal.cpp
1 /** @file normal.cpp
2  *
3  *  This file implements several functions that work on univariate and
4  *  multivariate polynomials and rational functions.
5  *  These functions include polynomial quotient and remainder, GCD and LCM
6  *  computation, square-free factorization and rational function normalization. */
7
8 /*
9  *  GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24  */
25
26 #include "normal.h"
27 #include "basic.h"
28 #include "ex.h"
29 #include "add.h"
30 #include "constant.h"
31 #include "expairseq.h"
32 #include "fail.h"
33 #include "inifcns.h"
34 #include "lst.h"
35 #include "mul.h"
36 #include "numeric.h"
37 #include "power.h"
38 #include "relational.h"
39 #include "operators.h"
40 #include "matrix.h"
41 #include "pseries.h"
42 #include "symbol.h"
43 #include "utils.h"
44 #include "polynomial/chinrem_gcd.h"
45
46 #include <algorithm>
47 #include <map>
48
49 namespace GiNaC {
50
51 // If comparing expressions (ex::compare()) is fast, you can set this to 1.
52 // Some routines like quo(), rem() and gcd() will then return a quick answer
53 // when they are called with two identical arguments.
54 #define FAST_COMPARE 1
55
56 // Set this if you want divide_in_z() to use remembering
57 #define USE_REMEMBER 0
58
59 // Set this if you want divide_in_z() to use trial division followed by
60 // polynomial interpolation (always slower except for completely dense
61 // polynomials)
62 #define USE_TRIAL_DIVISION 0
63
64 // Set this to enable some statistical output for the GCD routines
65 #define STATISTICS 0
66
67
68 #if STATISTICS
69 // Statistics variables
70 static int gcd_called = 0;
71 static int sr_gcd_called = 0;
72 static int heur_gcd_called = 0;
73 static int heur_gcd_failed = 0;
74
75 // Print statistics at end of program
76 static struct _stat_print {
77         _stat_print() {}
78         ~_stat_print() {
79                 std::cout << "gcd() called " << gcd_called << " times\n";
80                 std::cout << "sr_gcd() called " << sr_gcd_called << " times\n";
81                 std::cout << "heur_gcd() called " << heur_gcd_called << " times\n";
82                 std::cout << "heur_gcd() failed " << heur_gcd_failed << " times\n";
83         }
84 } stat_print;
85 #endif
86
87
88 /** Return pointer to first symbol found in expression.  Due to GiNaC's
89  *  internal ordering of terms, it may not be obvious which symbol this
90  *  function returns for a given expression.
91  *
92  *  @param e  expression to search
93  *  @param x  first symbol found (returned)
94  *  @return "false" if no symbol was found, "true" otherwise */
95 static bool get_first_symbol(const ex &e, ex &x)
96 {
97         if (is_a<symbol>(e)) {
98                 x = e;
99                 return true;
100         } else if (is_exactly_a<add>(e) || is_exactly_a<mul>(e)) {
101                 for (size_t i=0; i<e.nops(); i++)
102                         if (get_first_symbol(e.op(i), x))
103                                 return true;
104         } else if (is_exactly_a<power>(e)) {
105                 if (get_first_symbol(e.op(0), x))
106                         return true;
107         }
108         return false;
109 }
110
111
112 /*
113  *  Statistical information about symbols in polynomials
114  */
115
116 /** This structure holds information about the highest and lowest degrees
117  *  in which a symbol appears in two multivariate polynomials "a" and "b".
118  *  A vector of these structures with information about all symbols in
119  *  two polynomials can be created with the function get_symbol_stats().
120  *
121  *  @see get_symbol_stats */
122 struct sym_desc {
123         /** Reference to symbol */
124         ex sym;
125
126         /** Highest degree of symbol in polynomial "a" */
127         int deg_a;
128
129         /** Highest degree of symbol in polynomial "b" */
130         int deg_b;
131
132         /** Lowest degree of symbol in polynomial "a" */
133         int ldeg_a;
134
135         /** Lowest degree of symbol in polynomial "b" */
136         int ldeg_b;
137
138         /** Maximum of deg_a and deg_b (Used for sorting) */
139         int max_deg;
140
141         /** Maximum number of terms of leading coefficient of symbol in both polynomials */
142         size_t max_lcnops;
143
144         /** Commparison operator for sorting */
145         bool operator<(const sym_desc &x) const
146         {
147                 if (max_deg == x.max_deg)
148                         return max_lcnops < x.max_lcnops;
149                 else
150                         return max_deg < x.max_deg;
151         }
152 };
153
154 // Vector of sym_desc structures
155 typedef std::vector<sym_desc> sym_desc_vec;
156
157 // Add symbol the sym_desc_vec (used internally by get_symbol_stats())
158 static void add_symbol(const ex &s, sym_desc_vec &v)
159 {
160         for (auto & it : v)
161                 if (it.sym.is_equal(s))  // If it's already in there, don't add it a second time
162                         return;
163
164         sym_desc d;
165         d.sym = s;
166         v.push_back(d);
167 }
168
169 // Collect all symbols of an expression (used internally by get_symbol_stats())
170 static void collect_symbols(const ex &e, sym_desc_vec &v)
171 {
172         if (is_a<symbol>(e)) {
173                 add_symbol(e, v);
174         } else if (is_exactly_a<add>(e) || is_exactly_a<mul>(e)) {
175                 for (size_t i=0; i<e.nops(); i++)
176                         collect_symbols(e.op(i), v);
177         } else if (is_exactly_a<power>(e)) {
178                 collect_symbols(e.op(0), v);
179         }
180 }
181
182 /** Collect statistical information about symbols in polynomials.
183  *  This function fills in a vector of "sym_desc" structs which contain
184  *  information about the highest and lowest degrees of all symbols that
185  *  appear in two polynomials. The vector is then sorted by minimum
186  *  degree (lowest to highest). The information gathered by this
187  *  function is used by the GCD routines to identify trivial factors
188  *  and to determine which variable to choose as the main variable
189  *  for GCD computation.
190  *
191  *  @param a  first multivariate polynomial
192  *  @param b  second multivariate polynomial
193  *  @param v  vector of sym_desc structs (filled in) */
194 static void get_symbol_stats(const ex &a, const ex &b, sym_desc_vec &v)
195 {
196         collect_symbols(a.eval(), v);   // eval() to expand assigned symbols
197         collect_symbols(b.eval(), v);
198         for (auto & it : v) {
199                 int deg_a = a.degree(it.sym);
200                 int deg_b = b.degree(it.sym);
201                 it.deg_a = deg_a;
202                 it.deg_b = deg_b;
203                 it.max_deg = std::max(deg_a, deg_b);
204                 it.max_lcnops = std::max(a.lcoeff(it.sym).nops(), b.lcoeff(it.sym).nops());
205                 it.ldeg_a = a.ldegree(it.sym);
206                 it.ldeg_b = b.ldegree(it.sym);
207         }
208         std::sort(v.begin(), v.end());
209
210 #if 0
211         std::clog << "Symbols:\n";
212         it = v.begin(); itend = v.end();
213         while (it != itend) {
214                 std::clog << " " << it->sym << ": deg_a=" << it->deg_a << ", deg_b=" << it->deg_b << ", ldeg_a=" << it->ldeg_a << ", ldeg_b=" << it->ldeg_b << ", max_deg=" << it->max_deg << ", max_lcnops=" << it->max_lcnops << endl;
215                 std::clog << "  lcoeff_a=" << a.lcoeff(it->sym) << ", lcoeff_b=" << b.lcoeff(it->sym) << endl;
216                 ++it;
217         }
218 #endif
219 }
220
221
222 /*
223  *  Computation of LCM of denominators of coefficients of a polynomial
224  */
225
226 // Compute LCM of denominators of coefficients by going through the
227 // expression recursively (used internally by lcm_of_coefficients_denominators())
228 static numeric lcmcoeff(const ex &e, const numeric &l)
229 {
230         if (e.info(info_flags::rational))
231                 return lcm(ex_to<numeric>(e).denom(), l);
232         else if (is_exactly_a<add>(e)) {
233                 numeric c = *_num1_p;
234                 for (size_t i=0; i<e.nops(); i++)
235                         c = lcmcoeff(e.op(i), c);
236                 return lcm(c, l);
237         } else if (is_exactly_a<mul>(e)) {
238                 numeric c = *_num1_p;
239                 for (size_t i=0; i<e.nops(); i++)
240                         c *= lcmcoeff(e.op(i), *_num1_p);
241                 return lcm(c, l);
242         } else if (is_exactly_a<power>(e)) {
243                 if (is_a<symbol>(e.op(0)))
244                         return l;
245                 else
246                         return pow(lcmcoeff(e.op(0), l), ex_to<numeric>(e.op(1)));
247         }
248         return l;
249 }
250
251 /** Compute LCM of denominators of coefficients of a polynomial.
252  *  Given a polynomial with rational coefficients, this function computes
253  *  the LCM of the denominators of all coefficients. This can be used
254  *  to bring a polynomial from Q[X] to Z[X].
255  *
256  *  @param e  multivariate polynomial (need not be expanded)
257  *  @return LCM of denominators of coefficients */
258 static numeric lcm_of_coefficients_denominators(const ex &e)
259 {
260         return lcmcoeff(e, *_num1_p);
261 }
262
263 /** Bring polynomial from Q[X] to Z[X] by multiplying in the previously
264  *  determined LCM of the coefficient's denominators.
265  *
266  *  @param e  multivariate polynomial (need not be expanded)
267  *  @param lcm  LCM to multiply in */
268 static ex multiply_lcm(const ex &e, const numeric &lcm)
269 {
270         if (is_exactly_a<mul>(e)) {
271                 size_t num = e.nops();
272                 exvector v; v.reserve(num + 1);
273                 numeric lcm_accum = *_num1_p;
274                 for (size_t i=0; i<num; i++) {
275                         numeric op_lcm = lcmcoeff(e.op(i), *_num1_p);
276                         v.push_back(multiply_lcm(e.op(i), op_lcm));
277                         lcm_accum *= op_lcm;
278                 }
279                 v.push_back(lcm / lcm_accum);
280                 return (new mul(v))->setflag(status_flags::dynallocated);
281         } else if (is_exactly_a<add>(e)) {
282                 size_t num = e.nops();
283                 exvector v; v.reserve(num);
284                 for (size_t i=0; i<num; i++)
285                         v.push_back(multiply_lcm(e.op(i), lcm));
286                 return (new add(v))->setflag(status_flags::dynallocated);
287         } else if (is_exactly_a<power>(e)) {
288                 if (is_a<symbol>(e.op(0)))
289                         return e * lcm;
290                 else
291                         return pow(multiply_lcm(e.op(0), lcm.power(ex_to<numeric>(e.op(1)).inverse())), e.op(1));
292         } else
293                 return e * lcm;
294 }
295
296
297 /** Compute the integer content (= GCD of all numeric coefficients) of an
298  *  expanded polynomial. For a polynomial with rational coefficients, this
299  *  returns g/l where g is the GCD of the coefficients' numerators and l
300  *  is the LCM of the coefficients' denominators.
301  *
302  *  @return integer content */
303 numeric ex::integer_content() const
304 {
305         return bp->integer_content();
306 }
307
308 numeric basic::integer_content() const
309 {
310         return *_num1_p;
311 }
312
313 numeric numeric::integer_content() const
314 {
315         return abs(*this);
316 }
317
318 numeric add::integer_content() const
319 {
320         numeric c = *_num0_p, l = *_num1_p;
321         for (auto & it : seq) {
322                 GINAC_ASSERT(!is_exactly_a<numeric>(it.rest));
323                 GINAC_ASSERT(is_exactly_a<numeric>(it.coeff));
324                 c = gcd(ex_to<numeric>(it.coeff).numer(), c);
325                 l = lcm(ex_to<numeric>(it.coeff).denom(), l);
326         }
327         GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
328         c = gcd(ex_to<numeric>(overall_coeff).numer(), c);
329         l = lcm(ex_to<numeric>(overall_coeff).denom(), l);
330         return c/l;
331 }
332
333 numeric mul::integer_content() const
334 {
335 #ifdef DO_GINAC_ASSERT
336         for (auto & it : seq) {
337                 GINAC_ASSERT(!is_exactly_a<numeric>(recombine_pair_to_ex(it)));
338         }
339 #endif // def DO_GINAC_ASSERT
340         GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
341         return abs(ex_to<numeric>(overall_coeff));
342 }
343
344
345 /*
346  *  Polynomial quotients and remainders
347  */
348
349 /** Quotient q(x) of polynomials a(x) and b(x) in Q[x].
350  *  It satisfies a(x)=b(x)*q(x)+r(x).
351  *
352  *  @param a  first polynomial in x (dividend)
353  *  @param b  second polynomial in x (divisor)
354  *  @param x  a and b are polynomials in x
355  *  @param check_args  check whether a and b are polynomials with rational
356  *         coefficients (defaults to "true")
357  *  @return quotient of a and b in Q[x] */
358 ex quo(const ex &a, const ex &b, const ex &x, bool check_args)
359 {
360         if (b.is_zero())
361                 throw(std::overflow_error("quo: division by zero"));
362         if (is_exactly_a<numeric>(a) && is_exactly_a<numeric>(b))
363                 return a / b;
364 #if FAST_COMPARE
365         if (a.is_equal(b))
366                 return _ex1;
367 #endif
368         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
369                 throw(std::invalid_argument("quo: arguments must be polynomials over the rationals"));
370
371         // Polynomial long division
372         ex r = a.expand();
373         if (r.is_zero())
374                 return r;
375         int bdeg = b.degree(x);
376         int rdeg = r.degree(x);
377         ex blcoeff = b.expand().coeff(x, bdeg);
378         bool blcoeff_is_numeric = is_exactly_a<numeric>(blcoeff);
379         exvector v; v.reserve(std::max(rdeg - bdeg + 1, 0));
380         while (rdeg >= bdeg) {
381                 ex term, rcoeff = r.coeff(x, rdeg);
382                 if (blcoeff_is_numeric)
383                         term = rcoeff / blcoeff;
384                 else {
385                         if (!divide(rcoeff, blcoeff, term, false))
386                                 return (new fail())->setflag(status_flags::dynallocated);
387                 }
388                 term *= power(x, rdeg - bdeg);
389                 v.push_back(term);
390                 r -= (term * b).expand();
391                 if (r.is_zero())
392                         break;
393                 rdeg = r.degree(x);
394         }
395         return (new add(v))->setflag(status_flags::dynallocated);
396 }
397
398
399 /** Remainder r(x) of polynomials a(x) and b(x) in Q[x].
400  *  It satisfies a(x)=b(x)*q(x)+r(x).
401  *
402  *  @param a  first polynomial in x (dividend)
403  *  @param b  second polynomial in x (divisor)
404  *  @param x  a and b are polynomials in x
405  *  @param check_args  check whether a and b are polynomials with rational
406  *         coefficients (defaults to "true")
407  *  @return remainder of a(x) and b(x) in Q[x] */
408 ex rem(const ex &a, const ex &b, const ex &x, bool check_args)
409 {
410         if (b.is_zero())
411                 throw(std::overflow_error("rem: division by zero"));
412         if (is_exactly_a<numeric>(a)) {
413                 if  (is_exactly_a<numeric>(b))
414                         return _ex0;
415                 else
416                         return a;
417         }
418 #if FAST_COMPARE
419         if (a.is_equal(b))
420                 return _ex0;
421 #endif
422         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
423                 throw(std::invalid_argument("rem: arguments must be polynomials over the rationals"));
424
425         // Polynomial long division
426         ex r = a.expand();
427         if (r.is_zero())
428                 return r;
429         int bdeg = b.degree(x);
430         int rdeg = r.degree(x);
431         ex blcoeff = b.expand().coeff(x, bdeg);
432         bool blcoeff_is_numeric = is_exactly_a<numeric>(blcoeff);
433         while (rdeg >= bdeg) {
434                 ex term, rcoeff = r.coeff(x, rdeg);
435                 if (blcoeff_is_numeric)
436                         term = rcoeff / blcoeff;
437                 else {
438                         if (!divide(rcoeff, blcoeff, term, false))
439                                 return (new fail())->setflag(status_flags::dynallocated);
440                 }
441                 term *= power(x, rdeg - bdeg);
442                 r -= (term * b).expand();
443                 if (r.is_zero())
444                         break;
445                 rdeg = r.degree(x);
446         }
447         return r;
448 }
449
450
451 /** Decompose rational function a(x)=N(x)/D(x) into P(x)+n(x)/D(x)
452  *  with degree(n, x) < degree(D, x).
453  *
454  *  @param a rational function in x
455  *  @param x a is a function of x
456  *  @return decomposed function. */
457 ex decomp_rational(const ex &a, const ex &x)
458 {
459         ex nd = numer_denom(a);
460         ex numer = nd.op(0), denom = nd.op(1);
461         ex q = quo(numer, denom, x);
462         if (is_exactly_a<fail>(q))
463                 return a;
464         else
465                 return q + rem(numer, denom, x) / denom;
466 }
467
468
469 /** Pseudo-remainder of polynomials a(x) and b(x) in Q[x].
470  *
471  *  @param a  first polynomial in x (dividend)
472  *  @param b  second polynomial in x (divisor)
473  *  @param x  a and b are polynomials in x
474  *  @param check_args  check whether a and b are polynomials with rational
475  *         coefficients (defaults to "true")
476  *  @return pseudo-remainder of a(x) and b(x) in Q[x] */
477 ex prem(const ex &a, const ex &b, const ex &x, bool check_args)
478 {
479         if (b.is_zero())
480                 throw(std::overflow_error("prem: division by zero"));
481         if (is_exactly_a<numeric>(a)) {
482                 if (is_exactly_a<numeric>(b))
483                         return _ex0;
484                 else
485                         return b;
486         }
487         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
488                 throw(std::invalid_argument("prem: arguments must be polynomials over the rationals"));
489
490         // Polynomial long division
491         ex r = a.expand();
492         ex eb = b.expand();
493         int rdeg = r.degree(x);
494         int bdeg = eb.degree(x);
495         ex blcoeff;
496         if (bdeg <= rdeg) {
497                 blcoeff = eb.coeff(x, bdeg);
498                 if (bdeg == 0)
499                         eb = _ex0;
500                 else
501                         eb -= blcoeff * power(x, bdeg);
502         } else
503                 blcoeff = _ex1;
504
505         int delta = rdeg - bdeg + 1, i = 0;
506         while (rdeg >= bdeg && !r.is_zero()) {
507                 ex rlcoeff = r.coeff(x, rdeg);
508                 ex term = (power(x, rdeg - bdeg) * eb * rlcoeff).expand();
509                 if (rdeg == 0)
510                         r = _ex0;
511                 else
512                         r -= rlcoeff * power(x, rdeg);
513                 r = (blcoeff * r).expand() - term;
514                 rdeg = r.degree(x);
515                 i++;
516         }
517         return power(blcoeff, delta - i) * r;
518 }
519
520
521 /** Sparse pseudo-remainder of polynomials a(x) and b(x) in Q[x].
522  *
523  *  @param a  first polynomial in x (dividend)
524  *  @param b  second polynomial in x (divisor)
525  *  @param x  a and b are polynomials in x
526  *  @param check_args  check whether a and b are polynomials with rational
527  *         coefficients (defaults to "true")
528  *  @return sparse pseudo-remainder of a(x) and b(x) in Q[x] */
529 ex sprem(const ex &a, const ex &b, const ex &x, bool check_args)
530 {
531         if (b.is_zero())
532                 throw(std::overflow_error("prem: division by zero"));
533         if (is_exactly_a<numeric>(a)) {
534                 if (is_exactly_a<numeric>(b))
535                         return _ex0;
536                 else
537                         return b;
538         }
539         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
540                 throw(std::invalid_argument("prem: arguments must be polynomials over the rationals"));
541
542         // Polynomial long division
543         ex r = a.expand();
544         ex eb = b.expand();
545         int rdeg = r.degree(x);
546         int bdeg = eb.degree(x);
547         ex blcoeff;
548         if (bdeg <= rdeg) {
549                 blcoeff = eb.coeff(x, bdeg);
550                 if (bdeg == 0)
551                         eb = _ex0;
552                 else
553                         eb -= blcoeff * power(x, bdeg);
554         } else
555                 blcoeff = _ex1;
556
557         while (rdeg >= bdeg && !r.is_zero()) {
558                 ex rlcoeff = r.coeff(x, rdeg);
559                 ex term = (power(x, rdeg - bdeg) * eb * rlcoeff).expand();
560                 if (rdeg == 0)
561                         r = _ex0;
562                 else
563                         r -= rlcoeff * power(x, rdeg);
564                 r = (blcoeff * r).expand() - term;
565                 rdeg = r.degree(x);
566         }
567         return r;
568 }
569
570
571 /** Exact polynomial division of a(X) by b(X) in Q[X].
572  *  
573  *  @param a  first multivariate polynomial (dividend)
574  *  @param b  second multivariate polynomial (divisor)
575  *  @param q  quotient (returned)
576  *  @param check_args  check whether a and b are polynomials with rational
577  *         coefficients (defaults to "true")
578  *  @return "true" when exact division succeeds (quotient returned in q),
579  *          "false" otherwise (q left untouched) */
580 bool divide(const ex &a, const ex &b, ex &q, bool check_args)
581 {
582         if (b.is_zero())
583                 throw(std::overflow_error("divide: division by zero"));
584         if (a.is_zero()) {
585                 q = _ex0;
586                 return true;
587         }
588         if (is_exactly_a<numeric>(b)) {
589                 q = a / b;
590                 return true;
591         } else if (is_exactly_a<numeric>(a))
592                 return false;
593 #if FAST_COMPARE
594         if (a.is_equal(b)) {
595                 q = _ex1;
596                 return true;
597         }
598 #endif
599         if (check_args && (!a.info(info_flags::rational_polynomial) ||
600                            !b.info(info_flags::rational_polynomial)))
601                 throw(std::invalid_argument("divide: arguments must be polynomials over the rationals"));
602
603         // Find first symbol
604         ex x;
605         if (!get_first_symbol(a, x) && !get_first_symbol(b, x))
606                 throw(std::invalid_argument("invalid expression in divide()"));
607
608         // Try to avoid expanding partially factored expressions.
609         if (is_exactly_a<mul>(b)) {
610         // Divide sequentially by each term
611                 ex rem_new, rem_old = a;
612                 for (size_t i=0; i < b.nops(); i++) {
613                         if (! divide(rem_old, b.op(i), rem_new, false))
614                                 return false;
615                         rem_old = rem_new;
616                 }
617                 q = rem_new;
618                 return true;
619         } else if (is_exactly_a<power>(b)) {
620                 const ex& bb(b.op(0));
621                 int exp_b = ex_to<numeric>(b.op(1)).to_int();
622                 ex rem_new, rem_old = a;
623                 for (int i=exp_b; i>0; i--) {
624                         if (! divide(rem_old, bb, rem_new, false))
625                                 return false;
626                         rem_old = rem_new;
627                 }
628                 q = rem_new;
629                 return true;
630         } 
631         
632         if (is_exactly_a<mul>(a)) {
633                 // Divide sequentially each term. If some term in a is divisible 
634                 // by b we are done... and if not, we can't really say anything.
635                 size_t i;
636                 ex rem_i;
637                 bool divisible_p = false;
638                 for (i=0; i < a.nops(); ++i) {
639                         if (divide(a.op(i), b, rem_i, false)) {
640                                 divisible_p = true;
641                                 break;
642                         }
643                 }
644                 if (divisible_p) {
645                         exvector resv;
646                         resv.reserve(a.nops());
647                         for (size_t j=0; j < a.nops(); j++) {
648                                 if (j==i)
649                                         resv.push_back(rem_i);
650                                 else
651                                         resv.push_back(a.op(j));
652                         }
653                         q = (new mul(resv))->setflag(status_flags::dynallocated);
654                         return true;
655                 }
656         } else if (is_exactly_a<power>(a)) {
657                 // The base itself might be divisible by b, in that case we don't
658                 // need to expand a
659                 const ex& ab(a.op(0));
660                 int a_exp = ex_to<numeric>(a.op(1)).to_int();
661                 ex rem_i;
662                 if (divide(ab, b, rem_i, false)) {
663                         q = rem_i*power(ab, a_exp - 1);
664                         return true;
665                 }
666 // code below is commented-out because it leads to a significant slowdown
667 //              for (int i=2; i < a_exp; i++) {
668 //                      if (divide(power(ab, i), b, rem_i, false)) {
669 //                              q = rem_i*power(ab, a_exp - i);
670 //                              return true;
671 //                      }
672 //              } // ... so we *really* need to expand expression.
673         }
674         
675         // Polynomial long division (recursive)
676         ex r = a.expand();
677         if (r.is_zero()) {
678                 q = _ex0;
679                 return true;
680         }
681         int bdeg = b.degree(x);
682         int rdeg = r.degree(x);
683         ex blcoeff = b.expand().coeff(x, bdeg);
684         bool blcoeff_is_numeric = is_exactly_a<numeric>(blcoeff);
685         exvector v; v.reserve(std::max(rdeg - bdeg + 1, 0));
686         while (rdeg >= bdeg) {
687                 ex term, rcoeff = r.coeff(x, rdeg);
688                 if (blcoeff_is_numeric)
689                         term = rcoeff / blcoeff;
690                 else
691                         if (!divide(rcoeff, blcoeff, term, false))
692                                 return false;
693                 term *= power(x, rdeg - bdeg);
694                 v.push_back(term);
695                 r -= (term * b).expand();
696                 if (r.is_zero()) {
697                         q = (new add(v))->setflag(status_flags::dynallocated);
698                         return true;
699                 }
700                 rdeg = r.degree(x);
701         }
702         return false;
703 }
704
705
706 #if USE_REMEMBER
707 /*
708  *  Remembering
709  */
710
711 typedef std::pair<ex, ex> ex2;
712 typedef std::pair<ex, bool> exbool;
713
714 struct ex2_less {
715         bool operator() (const ex2 &p, const ex2 &q) const 
716         {
717                 int cmp = p.first.compare(q.first);
718                 return ((cmp<0) || (!(cmp>0) && p.second.compare(q.second)<0));
719         }
720 };
721
722 typedef std::map<ex2, exbool, ex2_less> ex2_exbool_remember;
723 #endif
724
725
726 /** Exact polynomial division of a(X) by b(X) in Z[X].
727  *  This functions works like divide() but the input and output polynomials are
728  *  in Z[X] instead of Q[X] (i.e. they have integer coefficients). Unlike
729  *  divide(), it doesn't check whether the input polynomials really are integer
730  *  polynomials, so be careful of what you pass in. Also, you have to run
731  *  get_symbol_stats() over the input polynomials before calling this function
732  *  and pass an iterator to the first element of the sym_desc vector. This
733  *  function is used internally by the heur_gcd().
734  *  
735  *  @param a  first multivariate polynomial (dividend)
736  *  @param b  second multivariate polynomial (divisor)
737  *  @param q  quotient (returned)
738  *  @param var  iterator to first element of vector of sym_desc structs
739  *  @return "true" when exact division succeeds (the quotient is returned in
740  *          q), "false" otherwise.
741  *  @see get_symbol_stats, heur_gcd */
742 static bool divide_in_z(const ex &a, const ex &b, ex &q, sym_desc_vec::const_iterator var)
743 {
744         q = _ex0;
745         if (b.is_zero())
746                 throw(std::overflow_error("divide_in_z: division by zero"));
747         if (b.is_equal(_ex1)) {
748                 q = a;
749                 return true;
750         }
751         if (is_exactly_a<numeric>(a)) {
752                 if (is_exactly_a<numeric>(b)) {
753                         q = a / b;
754                         return q.info(info_flags::integer);
755                 } else
756                         return false;
757         }
758 #if FAST_COMPARE
759         if (a.is_equal(b)) {
760                 q = _ex1;
761                 return true;
762         }
763 #endif
764
765 #if USE_REMEMBER
766         // Remembering
767         static ex2_exbool_remember dr_remember;
768         ex2_exbool_remember::const_iterator remembered = dr_remember.find(ex2(a, b));
769         if (remembered != dr_remember.end()) {
770                 q = remembered->second.first;
771                 return remembered->second.second;
772         }
773 #endif
774
775         if (is_exactly_a<power>(b)) {
776                 const ex& bb(b.op(0));
777                 ex qbar = a;
778                 int exp_b = ex_to<numeric>(b.op(1)).to_int();
779                 for (int i=exp_b; i>0; i--) {
780                         if (!divide_in_z(qbar, bb, q, var))
781                                 return false;
782                         qbar = q;
783                 }
784                 return true;
785         }
786
787         if (is_exactly_a<mul>(b)) {
788                 ex qbar = a;
789                 for (const auto & it : b) {
790                         sym_desc_vec sym_stats;
791                         get_symbol_stats(a, it, sym_stats);
792                         if (!divide_in_z(qbar, it, q, sym_stats.begin()))
793                                 return false;
794
795                         qbar = q;
796                 }
797                 return true;
798         }
799
800         // Main symbol
801         const ex &x = var->sym;
802
803         // Compare degrees
804         int adeg = a.degree(x), bdeg = b.degree(x);
805         if (bdeg > adeg)
806                 return false;
807
808 #if USE_TRIAL_DIVISION
809
810         // Trial division with polynomial interpolation
811         int i, k;
812
813         // Compute values at evaluation points 0..adeg
814         vector<numeric> alpha; alpha.reserve(adeg + 1);
815         exvector u; u.reserve(adeg + 1);
816         numeric point = *_num0_p;
817         ex c;
818         for (i=0; i<=adeg; i++) {
819                 ex bs = b.subs(x == point, subs_options::no_pattern);
820                 while (bs.is_zero()) {
821                         point += *_num1_p;
822                         bs = b.subs(x == point, subs_options::no_pattern);
823                 }
824                 if (!divide_in_z(a.subs(x == point, subs_options::no_pattern), bs, c, var+1))
825                         return false;
826                 alpha.push_back(point);
827                 u.push_back(c);
828                 point += *_num1_p;
829         }
830
831         // Compute inverses
832         vector<numeric> rcp; rcp.reserve(adeg + 1);
833         rcp.push_back(*_num0_p);
834         for (k=1; k<=adeg; k++) {
835                 numeric product = alpha[k] - alpha[0];
836                 for (i=1; i<k; i++)
837                         product *= alpha[k] - alpha[i];
838                 rcp.push_back(product.inverse());
839         }
840
841         // Compute Newton coefficients
842         exvector v; v.reserve(adeg + 1);
843         v.push_back(u[0]);
844         for (k=1; k<=adeg; k++) {
845                 ex temp = v[k - 1];
846                 for (i=k-2; i>=0; i--)
847                         temp = temp * (alpha[k] - alpha[i]) + v[i];
848                 v.push_back((u[k] - temp) * rcp[k]);
849         }
850
851         // Convert from Newton form to standard form
852         c = v[adeg];
853         for (k=adeg-1; k>=0; k--)
854                 c = c * (x - alpha[k]) + v[k];
855
856         if (c.degree(x) == (adeg - bdeg)) {
857                 q = c.expand();
858                 return true;
859         } else
860                 return false;
861
862 #else
863
864         // Polynomial long division (recursive)
865         ex r = a.expand();
866         if (r.is_zero())
867                 return true;
868         int rdeg = adeg;
869         ex eb = b.expand();
870         ex blcoeff = eb.coeff(x, bdeg);
871         exvector v; v.reserve(std::max(rdeg - bdeg + 1, 0));
872         while (rdeg >= bdeg) {
873                 ex term, rcoeff = r.coeff(x, rdeg);
874                 if (!divide_in_z(rcoeff, blcoeff, term, var+1))
875                         break;
876                 term = (term * power(x, rdeg - bdeg)).expand();
877                 v.push_back(term);
878                 r -= (term * eb).expand();
879                 if (r.is_zero()) {
880                         q = (new add(v))->setflag(status_flags::dynallocated);
881 #if USE_REMEMBER
882                         dr_remember[ex2(a, b)] = exbool(q, true);
883 #endif
884                         return true;
885                 }
886                 rdeg = r.degree(x);
887         }
888 #if USE_REMEMBER
889         dr_remember[ex2(a, b)] = exbool(q, false);
890 #endif
891         return false;
892
893 #endif
894 }
895
896
897 /*
898  *  Separation of unit part, content part and primitive part of polynomials
899  */
900
901 /** Compute unit part (= sign of leading coefficient) of a multivariate
902  *  polynomial in Q[x]. The product of unit part, content part, and primitive
903  *  part is the polynomial itself.
904  *
905  *  @param x  main variable
906  *  @return unit part
907  *  @see ex::content, ex::primpart, ex::unitcontprim */
908 ex ex::unit(const ex &x) const
909 {
910         ex c = expand().lcoeff(x);
911         if (is_exactly_a<numeric>(c))
912                 return c.info(info_flags::negative) ?_ex_1 : _ex1;
913         else {
914                 ex y;
915                 if (get_first_symbol(c, y))
916                         return c.unit(y);
917                 else
918                         throw(std::invalid_argument("invalid expression in unit()"));
919         }
920 }
921
922
923 /** Compute content part (= unit normal GCD of all coefficients) of a
924  *  multivariate polynomial in Q[x]. The product of unit part, content part,
925  *  and primitive part is the polynomial itself.
926  *
927  *  @param x  main variable
928  *  @return content part
929  *  @see ex::unit, ex::primpart, ex::unitcontprim */
930 ex ex::content(const ex &x) const
931 {
932         if (is_exactly_a<numeric>(*this))
933                 return info(info_flags::negative) ? -*this : *this;
934
935         ex e = expand();
936         if (e.is_zero())
937                 return _ex0;
938
939         // First, divide out the integer content (which we can calculate very efficiently).
940         // If the leading coefficient of the quotient is an integer, we are done.
941         ex c = e.integer_content();
942         ex r = e / c;
943         int deg = r.degree(x);
944         ex lcoeff = r.coeff(x, deg);
945         if (lcoeff.info(info_flags::integer))
946                 return c;
947
948         // GCD of all coefficients
949         int ldeg = r.ldegree(x);
950         if (deg == ldeg)
951                 return lcoeff * c / lcoeff.unit(x);
952         ex cont = _ex0;
953         for (int i=ldeg; i<=deg; i++)
954                 cont = gcd(r.coeff(x, i), cont, nullptr, nullptr, false);
955         return cont * c;
956 }
957
958
959 /** Compute primitive part of a multivariate polynomial in Q[x]. The result
960  *  will be a unit-normal polynomial with a content part of 1. The product
961  *  of unit part, content part, and primitive part is the polynomial itself.
962  *
963  *  @param x  main variable
964  *  @return primitive part
965  *  @see ex::unit, ex::content, ex::unitcontprim */
966 ex ex::primpart(const ex &x) const
967 {
968         // We need to compute the unit and content anyway, so call unitcontprim()
969         ex u, c, p;
970         unitcontprim(x, u, c, p);
971         return p;
972 }
973
974
975 /** Compute primitive part of a multivariate polynomial in Q[x] when the
976  *  content part is already known. This function is faster in computing the
977  *  primitive part than the previous function.
978  *
979  *  @param x  main variable
980  *  @param c  previously computed content part
981  *  @return primitive part */
982 ex ex::primpart(const ex &x, const ex &c) const
983 {
984         if (is_zero() || c.is_zero())
985                 return _ex0;
986         if (is_exactly_a<numeric>(*this))
987                 return _ex1;
988
989         // Divide by unit and content to get primitive part
990         ex u = unit(x);
991         if (is_exactly_a<numeric>(c))
992                 return *this / (c * u);
993         else
994                 return quo(*this, c * u, x, false);
995 }
996
997
998 /** Compute unit part, content part, and primitive part of a multivariate
999  *  polynomial in Q[x]. The product of the three parts is the polynomial
1000  *  itself.
1001  *
1002  *  @param x  main variable
1003  *  @param u  unit part (returned)
1004  *  @param c  content part (returned)
1005  *  @param p  primitive part (returned)
1006  *  @see ex::unit, ex::content, ex::primpart */
1007 void ex::unitcontprim(const ex &x, ex &u, ex &c, ex &p) const
1008 {
1009         // Quick check for zero (avoid expanding)
1010         if (is_zero()) {
1011                 u = _ex1;
1012                 c = p = _ex0;
1013                 return;
1014         }
1015
1016         // Special case: input is a number
1017         if (is_exactly_a<numeric>(*this)) {
1018                 if (info(info_flags::negative)) {
1019                         u = _ex_1;
1020                         c = abs(ex_to<numeric>(*this));
1021                 } else {
1022                         u = _ex1;
1023                         c = *this;
1024                 }
1025                 p = _ex1;
1026                 return;
1027         }
1028
1029         // Expand input polynomial
1030         ex e = expand();
1031         if (e.is_zero()) {
1032                 u = _ex1;
1033                 c = p = _ex0;
1034                 return;
1035         }
1036
1037         // Compute unit and content
1038         u = unit(x);
1039         c = content(x);
1040
1041         // Divide by unit and content to get primitive part
1042         if (c.is_zero()) {
1043                 p = _ex0;
1044                 return;
1045         }
1046         if (is_exactly_a<numeric>(c))
1047                 p = *this / (c * u);
1048         else
1049                 p = quo(e, c * u, x, false);
1050 }
1051
1052
1053 /*
1054  *  GCD of multivariate polynomials
1055  */
1056
1057 /** Compute GCD of multivariate polynomials using the subresultant PRS
1058  *  algorithm. This function is used internally by gcd().
1059  *
1060  *  @param a   first multivariate polynomial
1061  *  @param b   second multivariate polynomial
1062  *  @param var iterator to first element of vector of sym_desc structs
1063  *  @return the GCD as a new expression
1064  *  @see gcd */
1065
1066 static ex sr_gcd(const ex &a, const ex &b, sym_desc_vec::const_iterator var)
1067 {
1068 #if STATISTICS
1069         sr_gcd_called++;
1070 #endif
1071
1072         // The first symbol is our main variable
1073         const ex &x = var->sym;
1074
1075         // Sort c and d so that c has higher degree
1076         ex c, d;
1077         int adeg = a.degree(x), bdeg = b.degree(x);
1078         int cdeg, ddeg;
1079         if (adeg >= bdeg) {
1080                 c = a;
1081                 d = b;
1082                 cdeg = adeg;
1083                 ddeg = bdeg;
1084         } else {
1085                 c = b;
1086                 d = a;
1087                 cdeg = bdeg;
1088                 ddeg = adeg;
1089         }
1090
1091         // Remove content from c and d, to be attached to GCD later
1092         ex cont_c = c.content(x);
1093         ex cont_d = d.content(x);
1094         ex gamma = gcd(cont_c, cont_d, nullptr, nullptr, false);
1095         if (ddeg == 0)
1096                 return gamma;
1097         c = c.primpart(x, cont_c);
1098         d = d.primpart(x, cont_d);
1099
1100         // First element of subresultant sequence
1101         ex r = _ex0, ri = _ex1, psi = _ex1;
1102         int delta = cdeg - ddeg;
1103
1104         for (;;) {
1105
1106                 // Calculate polynomial pseudo-remainder
1107                 r = prem(c, d, x, false);
1108                 if (r.is_zero())
1109                         return gamma * d.primpart(x);
1110
1111                 c = d;
1112                 cdeg = ddeg;
1113                 if (!divide_in_z(r, ri * pow(psi, delta), d, var))
1114                         throw(std::runtime_error("invalid expression in sr_gcd(), division failed"));
1115                 ddeg = d.degree(x);
1116                 if (ddeg == 0) {
1117                         if (is_exactly_a<numeric>(r))
1118                                 return gamma;
1119                         else
1120                                 return gamma * r.primpart(x);
1121                 }
1122
1123                 // Next element of subresultant sequence
1124                 ri = c.expand().lcoeff(x);
1125                 if (delta == 1)
1126                         psi = ri;
1127                 else if (delta)
1128                         divide_in_z(pow(ri, delta), pow(psi, delta-1), psi, var+1);
1129                 delta = cdeg - ddeg;
1130         }
1131 }
1132
1133
1134 /** Return maximum (absolute value) coefficient of a polynomial.
1135  *  This function is used internally by heur_gcd().
1136  *
1137  *  @return maximum coefficient
1138  *  @see heur_gcd */
1139 numeric ex::max_coefficient() const
1140 {
1141         return bp->max_coefficient();
1142 }
1143
1144 /** Implementation ex::max_coefficient().
1145  *  @see heur_gcd */
1146 numeric basic::max_coefficient() const
1147 {
1148         return *_num1_p;
1149 }
1150
1151 numeric numeric::max_coefficient() const
1152 {
1153         return abs(*this);
1154 }
1155
1156 numeric add::max_coefficient() const
1157 {
1158         GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
1159         numeric cur_max = abs(ex_to<numeric>(overall_coeff));
1160         for (auto & it : seq) {
1161                 numeric a;
1162                 GINAC_ASSERT(!is_exactly_a<numeric>(it.rest));
1163                 a = abs(ex_to<numeric>(it.coeff));
1164                 if (a > cur_max)
1165                         cur_max = a;
1166         }
1167         return cur_max;
1168 }
1169
1170 numeric mul::max_coefficient() const
1171 {
1172 #ifdef DO_GINAC_ASSERT
1173         for (auto & it : seq) {
1174                 GINAC_ASSERT(!is_exactly_a<numeric>(recombine_pair_to_ex(it)));
1175         }
1176 #endif // def DO_GINAC_ASSERT
1177         GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
1178         return abs(ex_to<numeric>(overall_coeff));
1179 }
1180
1181
1182 /** Apply symmetric modular homomorphism to an expanded multivariate
1183  *  polynomial.  This function is usually used internally by heur_gcd().
1184  *
1185  *  @param xi  modulus
1186  *  @return mapped polynomial
1187  *  @see heur_gcd */
1188 ex basic::smod(const numeric &xi) const
1189 {
1190         return *this;
1191 }
1192
1193 ex numeric::smod(const numeric &xi) const
1194 {
1195         return GiNaC::smod(*this, xi);
1196 }
1197
1198 ex add::smod(const numeric &xi) const
1199 {
1200         epvector newseq;
1201         newseq.reserve(seq.size()+1);
1202         for (auto & it : seq) {
1203                 GINAC_ASSERT(!is_exactly_a<numeric>(it.rest));
1204                 numeric coeff = GiNaC::smod(ex_to<numeric>(it.coeff), xi);
1205                 if (!coeff.is_zero())
1206                         newseq.push_back(expair(it.rest, coeff));
1207         }
1208         GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
1209         numeric coeff = GiNaC::smod(ex_to<numeric>(overall_coeff), xi);
1210         return (new add(newseq,coeff))->setflag(status_flags::dynallocated);
1211 }
1212
1213 ex mul::smod(const numeric &xi) const
1214 {
1215 #ifdef DO_GINAC_ASSERT
1216         for (auto & it : seq) {
1217                 GINAC_ASSERT(!is_exactly_a<numeric>(recombine_pair_to_ex(it)));
1218         }
1219 #endif // def DO_GINAC_ASSERT
1220         mul * mulcopyp = new mul(*this);
1221         GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
1222         mulcopyp->overall_coeff = GiNaC::smod(ex_to<numeric>(overall_coeff),xi);
1223         mulcopyp->clearflag(status_flags::evaluated);
1224         mulcopyp->clearflag(status_flags::hash_calculated);
1225         return mulcopyp->setflag(status_flags::dynallocated);
1226 }
1227
1228
1229 /** xi-adic polynomial interpolation */
1230 static ex interpolate(const ex &gamma, const numeric &xi, const ex &x, int degree_hint = 1)
1231 {
1232         exvector g; g.reserve(degree_hint);
1233         ex e = gamma;
1234         numeric rxi = xi.inverse();
1235         for (int i=0; !e.is_zero(); i++) {
1236                 ex gi = e.smod(xi);
1237                 g.push_back(gi * power(x, i));
1238                 e = (e - gi) * rxi;
1239         }
1240         return (new add(g))->setflag(status_flags::dynallocated);
1241 }
1242
1243 /** Exception thrown by heur_gcd() to signal failure. */
1244 class gcdheu_failed {};
1245
1246 /** Compute GCD of multivariate polynomials using the heuristic GCD algorithm.
1247  *  get_symbol_stats() must have been called previously with the input
1248  *  polynomials and an iterator to the first element of the sym_desc vector
1249  *  passed in. This function is used internally by gcd().
1250  *
1251  *  @param a  first integer multivariate polynomial (expanded)
1252  *  @param b  second integer multivariate polynomial (expanded)
1253  *  @param ca  cofactor of polynomial a (returned), nullptr to suppress
1254  *             calculation of cofactor
1255  *  @param cb  cofactor of polynomial b (returned), nullptr to suppress
1256  *             calculation of cofactor
1257  *  @param var iterator to first element of vector of sym_desc structs
1258  *  @param res the GCD (returned)
1259  *  @return true if GCD was computed, false otherwise.
1260  *  @see gcd
1261  *  @exception gcdheu_failed() */
1262 static bool heur_gcd_z(ex& res, const ex &a, const ex &b, ex *ca, ex *cb,
1263                        sym_desc_vec::const_iterator var)
1264 {
1265 #if STATISTICS
1266         heur_gcd_called++;
1267 #endif
1268
1269         // Algorithm only works for non-vanishing input polynomials
1270         if (a.is_zero() || b.is_zero())
1271                 return false;
1272
1273         // GCD of two numeric values -> CLN
1274         if (is_exactly_a<numeric>(a) && is_exactly_a<numeric>(b)) {
1275                 numeric g = gcd(ex_to<numeric>(a), ex_to<numeric>(b));
1276                 if (ca)
1277                         *ca = ex_to<numeric>(a) / g;
1278                 if (cb)
1279                         *cb = ex_to<numeric>(b) / g;
1280                 res = g;
1281                 return true;
1282         }
1283
1284         // The first symbol is our main variable
1285         const ex &x = var->sym;
1286
1287         // Remove integer content
1288         numeric gc = gcd(a.integer_content(), b.integer_content());
1289         numeric rgc = gc.inverse();
1290         ex p = a * rgc;
1291         ex q = b * rgc;
1292         int maxdeg =  std::max(p.degree(x), q.degree(x));
1293         
1294         // Find evaluation point
1295         numeric mp = p.max_coefficient();
1296         numeric mq = q.max_coefficient();
1297         numeric xi;
1298         if (mp > mq)
1299                 xi = mq * (*_num2_p) + (*_num2_p);
1300         else
1301                 xi = mp * (*_num2_p) + (*_num2_p);
1302
1303         // 6 tries maximum
1304         for (int t=0; t<6; t++) {
1305                 if (xi.int_length() * maxdeg > 100000) {
1306                         throw gcdheu_failed();
1307                 }
1308
1309                 // Apply evaluation homomorphism and calculate GCD
1310                 ex cp, cq;
1311                 ex gamma;
1312                 bool found = heur_gcd_z(gamma,
1313                                         p.subs(x == xi, subs_options::no_pattern),
1314                                         q.subs(x == xi, subs_options::no_pattern),
1315                                         &cp, &cq, var+1);
1316                 if (found) {
1317                         gamma = gamma.expand();
1318                         // Reconstruct polynomial from GCD of mapped polynomials
1319                         ex g = interpolate(gamma, xi, x, maxdeg);
1320
1321                         // Remove integer content
1322                         g /= g.integer_content();
1323
1324                         // If the calculated polynomial divides both p and q, this is the GCD
1325                         ex dummy;
1326                         if (divide_in_z(p, g, ca ? *ca : dummy, var) && divide_in_z(q, g, cb ? *cb : dummy, var)) {
1327                                 g *= gc;
1328                                 res = g;
1329                                 return true;
1330                         }
1331                 }
1332
1333                 // Next evaluation point
1334                 xi = iquo(xi * isqrt(isqrt(xi)) * numeric(73794), numeric(27011));
1335         }
1336         return false;
1337 }
1338
1339 /** Compute GCD of multivariate polynomials using the heuristic GCD algorithm.
1340  *  get_symbol_stats() must have been called previously with the input
1341  *  polynomials and an iterator to the first element of the sym_desc vector
1342  *  passed in. This function is used internally by gcd().
1343  *
1344  *  @param a  first rational multivariate polynomial (expanded)
1345  *  @param b  second rational multivariate polynomial (expanded)
1346  *  @param ca  cofactor of polynomial a (returned), nullptr to suppress
1347  *             calculation of cofactor
1348  *  @param cb  cofactor of polynomial b (returned), nullptr to suppress
1349  *             calculation of cofactor
1350  *  @param var iterator to first element of vector of sym_desc structs
1351  *  @param res the GCD (returned)
1352  *  @return true if GCD was computed, false otherwise.
1353  *  @see heur_gcd_z
1354  *  @see gcd
1355  */
1356 static bool heur_gcd(ex& res, const ex& a, const ex& b, ex *ca, ex *cb,
1357                      sym_desc_vec::const_iterator var)
1358 {
1359         if (a.info(info_flags::integer_polynomial) && 
1360             b.info(info_flags::integer_polynomial)) {
1361                 try {
1362                         return heur_gcd_z(res, a, b, ca, cb, var);
1363                 } catch (gcdheu_failed) {
1364                         return false;
1365                 }
1366         }
1367
1368         // convert polynomials to Z[X]
1369         const numeric a_lcm = lcm_of_coefficients_denominators(a);
1370         const numeric ab_lcm = lcmcoeff(b, a_lcm);
1371
1372         const ex ai = a*ab_lcm;
1373         const ex bi = b*ab_lcm;
1374         if (!ai.info(info_flags::integer_polynomial))
1375                 throw std::logic_error("heur_gcd: not an integer polynomial [1]");
1376
1377         if (!bi.info(info_flags::integer_polynomial))
1378                 throw std::logic_error("heur_gcd: not an integer polynomial [2]");
1379
1380         bool found = false;
1381         try {
1382                 found = heur_gcd_z(res, ai, bi, ca, cb, var);
1383         } catch (gcdheu_failed) {
1384                 return false;
1385         }
1386         
1387         // GCD is not unique, it's defined up to a unit (i.e. invertible
1388         // element). If the coefficient ring is a field, every its element is
1389         // invertible, so one can multiply the polynomial GCD with any element
1390         // of the coefficient field. We use this ambiguity to make cofactors
1391         // integer polynomials.
1392         if (found)
1393                 res /= ab_lcm;
1394         return found;
1395 }
1396
1397
1398 // gcd helper to handle partially factored polynomials (to avoid expanding
1399 // large expressions). At least one of the arguments should be a power.
1400 static ex gcd_pf_pow(const ex& a, const ex& b, ex* ca, ex* cb);
1401
1402 // gcd helper to handle partially factored polynomials (to avoid expanding
1403 // large expressions). At least one of the arguments should be a product.
1404 static ex gcd_pf_mul(const ex& a, const ex& b, ex* ca, ex* cb);
1405
1406 /** Compute GCD (Greatest Common Divisor) of multivariate polynomials a(X)
1407  *  and b(X) in Z[X]. Optionally also compute the cofactors of a and b,
1408  *  defined by a = ca * gcd(a, b) and b = cb * gcd(a, b).
1409  *
1410  *  @param a  first multivariate polynomial
1411  *  @param b  second multivariate polynomial
1412  *  @param ca pointer to expression that will receive the cofactor of a, or nullptr
1413  *  @param cb pointer to expression that will receive the cofactor of b, or nullptr
1414  *  @param check_args  check whether a and b are polynomials with rational
1415  *         coefficients (defaults to "true")
1416  *  @return the GCD as a new expression */
1417 ex gcd(const ex &a, const ex &b, ex *ca, ex *cb, bool check_args, unsigned options)
1418 {
1419 #if STATISTICS
1420         gcd_called++;
1421 #endif
1422
1423         // GCD of numerics -> CLN
1424         if (is_exactly_a<numeric>(a) && is_exactly_a<numeric>(b)) {
1425                 numeric g = gcd(ex_to<numeric>(a), ex_to<numeric>(b));
1426                 if (ca || cb) {
1427                         if (g.is_zero()) {
1428                                 if (ca)
1429                                         *ca = _ex0;
1430                                 if (cb)
1431                                         *cb = _ex0;
1432                         } else {
1433                                 if (ca)
1434                                         *ca = ex_to<numeric>(a) / g;
1435                                 if (cb)
1436                                         *cb = ex_to<numeric>(b) / g;
1437                         }
1438                 }
1439                 return g;
1440         }
1441
1442         // Check arguments
1443         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial))) {
1444                 throw(std::invalid_argument("gcd: arguments must be polynomials over the rationals"));
1445         }
1446
1447         // Partially factored cases (to avoid expanding large expressions)
1448         if (!(options & gcd_options::no_part_factored)) {
1449                 if (is_exactly_a<mul>(a) || is_exactly_a<mul>(b))
1450                         return gcd_pf_mul(a, b, ca, cb);
1451 #if FAST_COMPARE
1452                 if (is_exactly_a<power>(a) || is_exactly_a<power>(b))
1453                         return gcd_pf_pow(a, b, ca, cb);
1454 #endif
1455         }
1456
1457         // Some trivial cases
1458         ex aex = a.expand(), bex = b.expand();
1459         if (aex.is_zero()) {
1460                 if (ca)
1461                         *ca = _ex0;
1462                 if (cb)
1463                         *cb = _ex1;
1464                 return b;
1465         }
1466         if (bex.is_zero()) {
1467                 if (ca)
1468                         *ca = _ex1;
1469                 if (cb)
1470                         *cb = _ex0;
1471                 return a;
1472         }
1473         if (aex.is_equal(_ex1) || bex.is_equal(_ex1)) {
1474                 if (ca)
1475                         *ca = a;
1476                 if (cb)
1477                         *cb = b;
1478                 return _ex1;
1479         }
1480 #if FAST_COMPARE
1481         if (a.is_equal(b)) {
1482                 if (ca)
1483                         *ca = _ex1;
1484                 if (cb)
1485                         *cb = _ex1;
1486                 return a;
1487         }
1488 #endif
1489
1490         if (is_a<symbol>(aex)) {
1491                 if (! bex.subs(aex==_ex0, subs_options::no_pattern).is_zero()) {
1492                         if (ca)
1493                                 *ca = a;
1494                         if (cb)
1495                                 *cb = b;
1496                         return _ex1;
1497                 }
1498         }
1499
1500         if (is_a<symbol>(bex)) {
1501                 if (! aex.subs(bex==_ex0, subs_options::no_pattern).is_zero()) {
1502                         if (ca)
1503                                 *ca = a;
1504                         if (cb)
1505                                 *cb = b;
1506                         return _ex1;
1507                 }
1508         }
1509
1510         if (is_exactly_a<numeric>(aex)) {
1511                 numeric bcont = bex.integer_content();
1512                 numeric g = gcd(ex_to<numeric>(aex), bcont);
1513                 if (ca)
1514                         *ca = ex_to<numeric>(aex)/g;
1515                 if (cb)
1516                         *cb = bex/g;
1517                 return g;
1518         }
1519
1520         if (is_exactly_a<numeric>(bex)) {
1521                 numeric acont = aex.integer_content();
1522                 numeric g = gcd(ex_to<numeric>(bex), acont);
1523                 if (ca)
1524                         *ca = aex/g;
1525                 if (cb)
1526                         *cb = ex_to<numeric>(bex)/g;
1527                 return g;
1528         }
1529
1530         // Gather symbol statistics
1531         sym_desc_vec sym_stats;
1532         get_symbol_stats(a, b, sym_stats);
1533
1534         // The symbol with least degree which is contained in both polynomials
1535         // is our main variable
1536         sym_desc_vec::iterator vari = sym_stats.begin();
1537         while ((vari != sym_stats.end()) && 
1538                (((vari->ldeg_b == 0) && (vari->deg_b == 0)) ||
1539                 ((vari->ldeg_a == 0) && (vari->deg_a == 0))))
1540                 vari++;
1541
1542         // No common symbols at all, just return 1:
1543         if (vari == sym_stats.end()) {
1544                 // N.B: keep cofactors factored
1545                 if (ca)
1546                         *ca = a;
1547                 if (cb)
1548                         *cb = b;
1549                 return _ex1;
1550         }
1551         // move symbols which contained only in one of the polynomials
1552         // to the end:
1553         rotate(sym_stats.begin(), vari, sym_stats.end());
1554
1555         sym_desc_vec::const_iterator var = sym_stats.begin();
1556         const ex &x = var->sym;
1557
1558         // Cancel trivial common factor
1559         int ldeg_a = var->ldeg_a;
1560         int ldeg_b = var->ldeg_b;
1561         int min_ldeg = std::min(ldeg_a,ldeg_b);
1562         if (min_ldeg > 0) {
1563                 ex common = power(x, min_ldeg);
1564                 return gcd((aex / common).expand(), (bex / common).expand(), ca, cb, false) * common;
1565         }
1566
1567         // Try to eliminate variables
1568         if (var->deg_a == 0 && var->deg_b != 0 ) {
1569                 ex bex_u, bex_c, bex_p;
1570                 bex.unitcontprim(x, bex_u, bex_c, bex_p);
1571                 ex g = gcd(aex, bex_c, ca, cb, false);
1572                 if (cb)
1573                         *cb *= bex_u * bex_p;
1574                 return g;
1575         } else if (var->deg_b == 0 && var->deg_a != 0) {
1576                 ex aex_u, aex_c, aex_p;
1577                 aex.unitcontprim(x, aex_u, aex_c, aex_p);
1578                 ex g = gcd(aex_c, bex, ca, cb, false);
1579                 if (ca)
1580                         *ca *= aex_u * aex_p;
1581                 return g;
1582         }
1583
1584         // Try heuristic algorithm first, fall back to PRS if that failed
1585         ex g;
1586         if (!(options & gcd_options::no_heur_gcd)) {
1587                 bool found = heur_gcd(g, aex, bex, ca, cb, var);
1588                 if (found) {
1589                         // heur_gcd have already computed cofactors...
1590                         if (g.is_equal(_ex1)) {
1591                                 // ... but we want to keep them factored if possible.
1592                                 if (ca)
1593                                         *ca = a;
1594                                 if (cb)
1595                                         *cb = b;
1596                         }
1597                         return g;
1598                 }
1599 #if STATISTICS
1600                 else {
1601                         heur_gcd_failed++;
1602                 }
1603 #endif
1604         }
1605         if (options & gcd_options::use_sr_gcd) {
1606                 g = sr_gcd(aex, bex, var);
1607         } else {
1608                 exvector vars;
1609                 for (std::size_t n = sym_stats.size(); n-- != 0; )
1610                         vars.push_back(sym_stats[n].sym);
1611                 g = chinrem_gcd(aex, bex, vars);
1612         }
1613
1614         if (g.is_equal(_ex1)) {
1615                 // Keep cofactors factored if possible
1616                 if (ca)
1617                         *ca = a;
1618                 if (cb)
1619                         *cb = b;
1620         } else {
1621                 if (ca)
1622                         divide(aex, g, *ca, false);
1623                 if (cb)
1624                         divide(bex, g, *cb, false);
1625         }
1626         return g;
1627 }
1628
1629 // gcd helper to handle partially factored polynomials (to avoid expanding
1630 // large expressions). Both arguments should be powers.
1631 static ex gcd_pf_pow_pow(const ex& a, const ex& b, ex* ca, ex* cb)
1632 {
1633         ex p = a.op(0);
1634         const ex& exp_a = a.op(1);
1635         ex pb = b.op(0);
1636         const ex& exp_b = b.op(1);
1637
1638         // a = p^n, b = p^m, gcd = p^min(n, m)
1639         if (p.is_equal(pb)) {
1640                 if (exp_a < exp_b) {
1641                         if (ca)
1642                                 *ca = _ex1;
1643                         if (cb)
1644                                 *cb = power(p, exp_b - exp_a);
1645                         return power(p, exp_a);
1646                 } else {
1647                         if (ca)
1648                                 *ca = power(p, exp_a - exp_b);
1649                         if (cb)
1650                                 *cb = _ex1;
1651                         return power(p, exp_b);
1652                 }
1653         }
1654
1655         ex p_co, pb_co;
1656         ex p_gcd = gcd(p, pb, &p_co, &pb_co, false);
1657         // a(x) = p(x)^n, b(x) = p_b(x)^m, gcd (p, p_b) = 1 ==> gcd(a,b) = 1
1658         if (p_gcd.is_equal(_ex1)) {
1659                         if (ca)
1660                                 *ca = a;
1661                         if (cb)
1662                                 *cb = b;
1663                         return _ex1;
1664                         // XXX: do I need to check for p_gcd = -1?
1665         }
1666
1667         // there are common factors:
1668         // a(x) = g(x)^n A(x)^n, b(x) = g(x)^m B(x)^m ==>
1669         // gcd(a, b) = g(x)^n gcd(A(x)^n, g(x)^(n-m) B(x)^m
1670         if (exp_a < exp_b) {
1671                 ex pg =  gcd(power(p_co, exp_a), power(p_gcd, exp_b-exp_a)*power(pb_co, exp_b), ca, cb, false);
1672                 return power(p_gcd, exp_a)*pg;
1673         } else {
1674                 ex pg = gcd(power(p_gcd, exp_a - exp_b)*power(p_co, exp_a), power(pb_co, exp_b), ca, cb, false);
1675                 return power(p_gcd, exp_b)*pg;
1676         }
1677 }
1678
1679 static ex gcd_pf_pow(const ex& a, const ex& b, ex* ca, ex* cb)
1680 {
1681         if (is_exactly_a<power>(a) && is_exactly_a<power>(b))
1682                 return gcd_pf_pow_pow(a, b, ca, cb);
1683
1684         if (is_exactly_a<power>(b) && (! is_exactly_a<power>(a)))
1685                 return gcd_pf_pow(b, a, cb, ca);
1686
1687         GINAC_ASSERT(is_exactly_a<power>(a));
1688
1689         ex p = a.op(0);
1690         const ex& exp_a = a.op(1);
1691         if (p.is_equal(b)) {
1692                 // a = p^n, b = p, gcd = p
1693                 if (ca)
1694                         *ca = power(p, a.op(1) - 1);
1695                 if (cb)
1696                         *cb = _ex1;
1697                 return p;
1698         } 
1699
1700         ex p_co, bpart_co;
1701         ex p_gcd = gcd(p, b, &p_co, &bpart_co, false);
1702
1703         // a(x) = p(x)^n, gcd(p, b) = 1 ==> gcd(a, b) = 1
1704         if (p_gcd.is_equal(_ex1)) {
1705                 if (ca)
1706                         *ca = a;
1707                 if (cb)
1708                         *cb = b;
1709                 return _ex1;
1710         }
1711         // a(x) = g(x)^n A(x)^n, b(x) = g(x) B(x) ==> gcd(a, b) = g(x) gcd(g(x)^(n-1) A(x)^n, B(x))
1712         ex rg = gcd(power(p_gcd, exp_a-1)*power(p_co, exp_a), bpart_co, ca, cb, false);
1713         return p_gcd*rg;
1714 }
1715
1716 static ex gcd_pf_mul(const ex& a, const ex& b, ex* ca, ex* cb)
1717 {
1718         if (is_exactly_a<mul>(a) && is_exactly_a<mul>(b)
1719                                  && (b.nops() >  a.nops()))
1720                 return gcd_pf_mul(b, a, cb, ca);
1721
1722         if (is_exactly_a<mul>(b) && (!is_exactly_a<mul>(a)))
1723                 return gcd_pf_mul(b, a, cb, ca);
1724
1725         GINAC_ASSERT(is_exactly_a<mul>(a));
1726         size_t num = a.nops();
1727         exvector g; g.reserve(num);
1728         exvector acc_ca; acc_ca.reserve(num);
1729         ex part_b = b;
1730         for (size_t i=0; i<num; i++) {
1731                 ex part_ca, part_cb;
1732                 g.push_back(gcd(a.op(i), part_b, &part_ca, &part_cb, false));
1733                 acc_ca.push_back(part_ca);
1734                 part_b = part_cb;
1735         }
1736         if (ca)
1737                 *ca = (new mul(acc_ca))->setflag(status_flags::dynallocated);
1738         if (cb)
1739                 *cb = part_b;
1740         return (new mul(g))->setflag(status_flags::dynallocated);
1741 }
1742
1743 /** Compute LCM (Least Common Multiple) of multivariate polynomials in Z[X].
1744  *
1745  *  @param a  first multivariate polynomial
1746  *  @param b  second multivariate polynomial
1747  *  @param check_args  check whether a and b are polynomials with rational
1748  *         coefficients (defaults to "true")
1749  *  @return the LCM as a new expression */
1750 ex lcm(const ex &a, const ex &b, bool check_args)
1751 {
1752         if (is_exactly_a<numeric>(a) && is_exactly_a<numeric>(b))
1753                 return lcm(ex_to<numeric>(a), ex_to<numeric>(b));
1754         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
1755                 throw(std::invalid_argument("lcm: arguments must be polynomials over the rationals"));
1756         
1757         ex ca, cb;
1758         ex g = gcd(a, b, &ca, &cb, false);
1759         return ca * cb * g;
1760 }
1761
1762
1763 /*
1764  *  Square-free factorization
1765  */
1766
1767 /** Compute square-free factorization of multivariate polynomial a(x) using
1768  *  Yun's algorithm.  Used internally by sqrfree().
1769  *
1770  *  @param a  multivariate polynomial over Z[X], treated here as univariate
1771  *            polynomial in x.
1772  *  @param x  variable to factor in
1773  *  @return   vector of factors sorted in ascending degree */
1774 static exvector sqrfree_yun(const ex &a, const symbol &x)
1775 {
1776         exvector res;
1777         ex w = a;
1778         ex z = w.diff(x);
1779         ex g = gcd(w, z);
1780         if (g.is_equal(_ex1)) {
1781                 res.push_back(a);
1782                 return res;
1783         }
1784         ex y;
1785         do {
1786                 w = quo(w, g, x);
1787                 y = quo(z, g, x);
1788                 z = y - w.diff(x);
1789                 g = gcd(w, z);
1790                 res.push_back(g);
1791         } while (!z.is_zero());
1792         return res;
1793 }
1794
1795
1796 /** Compute a square-free factorization of a multivariate polynomial in Q[X].
1797  *
1798  *  @param a  multivariate polynomial over Q[X]
1799  *  @param l  lst of variables to factor in, may be left empty for autodetection
1800  *  @return   a square-free factorization of \p a.
1801  *
1802  * \note
1803  * A polynomial \f$p(X) \in C[X]\f$ is said <EM>square-free</EM>
1804  * if, whenever any two polynomials \f$q(X)\f$ and \f$r(X)\f$
1805  * are such that
1806  * \f[
1807  *     p(X) = q(X)^2 r(X),
1808  * \f]
1809  * we have \f$q(X) \in C\f$.
1810  * This means that \f$p(X)\f$ has no repeated factors, apart
1811  * eventually from constants.
1812  * Given a polynomial \f$p(X) \in C[X]\f$, we say that the
1813  * decomposition
1814  * \f[
1815  *   p(X) = b \cdot p_1(X)^{a_1} \cdot p_2(X)^{a_2} \cdots p_r(X)^{a_r}
1816  * \f]
1817  * is a <EM>square-free factorization</EM> of \f$p(X)\f$ if the
1818  * following conditions hold:
1819  * -#  \f$b \in C\f$ and \f$b \neq 0\f$;
1820  * -#  \f$a_i\f$ is a positive integer for \f$i = 1, \ldots, r\f$;
1821  * -#  the degree of the polynomial \f$p_i\f$ is strictly positive
1822  *     for \f$i = 1, \ldots, r\f$;
1823  * -#  the polynomial \f$\Pi_{i=1}^r p_i(X)\f$ is square-free.
1824  *
1825  * Square-free factorizations need not be unique.  For example, if
1826  * \f$a_i\f$ is even, we could change the polynomial \f$p_i(X)\f$
1827  * into \f$-p_i(X)\f$.
1828  * Observe also that the factors \f$p_i(X)\f$ need not be irreducible
1829  * polynomials.
1830  */
1831 ex sqrfree(const ex &a, const lst &l)
1832 {
1833         if (is_exactly_a<numeric>(a) ||     // algorithm does not trap a==0
1834             is_a<symbol>(a))        // shortcut
1835                 return a;
1836
1837         // If no lst of variables to factorize in was specified we have to
1838         // invent one now.  Maybe one can optimize here by reversing the order
1839         // or so, I don't know.
1840         lst args;
1841         if (l.nops()==0) {
1842                 sym_desc_vec sdv;
1843                 get_symbol_stats(a, _ex0, sdv);
1844                 for (auto & it : sdv)
1845                         args.append(it.sym);
1846         } else {
1847                 args = l;
1848         }
1849
1850         // Find the symbol to factor in at this stage
1851         if (!is_a<symbol>(args.op(0)))
1852                 throw (std::runtime_error("sqrfree(): invalid factorization variable"));
1853         const symbol &x = ex_to<symbol>(args.op(0));
1854
1855         // convert the argument from something in Q[X] to something in Z[X]
1856         const numeric lcm = lcm_of_coefficients_denominators(a);
1857         const ex tmp = multiply_lcm(a,lcm);
1858
1859         // find the factors
1860         exvector factors = sqrfree_yun(tmp, x);
1861
1862         // construct the next list of symbols with the first element popped
1863         lst newargs = args;
1864         newargs.remove_first();
1865
1866         // recurse down the factors in remaining variables
1867         if (newargs.nops()>0) {
1868                 for (auto & it : factors)
1869                         it = sqrfree(it, newargs);
1870         }
1871
1872         // Done with recursion, now construct the final result
1873         ex result = _ex1;
1874         int p = 1;
1875         for (auto & it : factors)
1876                 result *= power(it, p++);
1877
1878         // Yun's algorithm does not account for constant factors.  (For univariate
1879         // polynomials it works only in the monic case.)  We can correct this by
1880         // inserting what has been lost back into the result.  For completeness
1881         // we'll also have to recurse down that factor in the remaining variables.
1882         if (newargs.nops()>0)
1883                 result *= sqrfree(quo(tmp, result, x), newargs);
1884         else
1885                 result *= quo(tmp, result, x);
1886
1887         // Put in the rational overall factor again and return
1888         return result * lcm.inverse();
1889 }
1890
1891
1892 /** Compute square-free partial fraction decomposition of rational function
1893  *  a(x).
1894  *
1895  *  @param a rational function over Z[x], treated as univariate polynomial
1896  *           in x
1897  *  @param x variable to factor in
1898  *  @return decomposed rational function */
1899 ex sqrfree_parfrac(const ex & a, const symbol & x)
1900 {
1901         // Find numerator and denominator
1902         ex nd = numer_denom(a);
1903         ex numer = nd.op(0), denom = nd.op(1);
1904 //clog << "numer = " << numer << ", denom = " << denom << endl;
1905
1906         // Convert N(x)/D(x) -> Q(x) + R(x)/D(x), so degree(R) < degree(D)
1907         ex red_poly = quo(numer, denom, x), red_numer = rem(numer, denom, x).expand();
1908 //clog << "red_poly = " << red_poly << ", red_numer = " << red_numer << endl;
1909
1910         // Factorize denominator and compute cofactors
1911         exvector yun = sqrfree_yun(denom, x);
1912 //clog << "yun factors: " << exprseq(yun) << endl;
1913         size_t num_yun = yun.size();
1914         exvector factor; factor.reserve(num_yun);
1915         exvector cofac; cofac.reserve(num_yun);
1916         for (size_t i=0; i<num_yun; i++) {
1917                 if (!yun[i].is_equal(_ex1)) {
1918                         for (size_t j=0; j<=i; j++) {
1919                                 factor.push_back(pow(yun[i], j+1));
1920                                 ex prod = _ex1;
1921                                 for (size_t k=0; k<num_yun; k++) {
1922                                         if (k == i)
1923                                                 prod *= pow(yun[k], i-j);
1924                                         else
1925                                                 prod *= pow(yun[k], k+1);
1926                                 }
1927                                 cofac.push_back(prod.expand());
1928                         }
1929                 }
1930         }
1931         size_t num_factors = factor.size();
1932 //clog << "factors  : " << exprseq(factor) << endl;
1933 //clog << "cofactors: " << exprseq(cofac) << endl;
1934
1935         // Construct coefficient matrix for decomposition
1936         int max_denom_deg = denom.degree(x);
1937         matrix sys(max_denom_deg + 1, num_factors);
1938         matrix rhs(max_denom_deg + 1, 1);
1939         for (int i=0; i<=max_denom_deg; i++) {
1940                 for (size_t j=0; j<num_factors; j++)
1941                         sys(i, j) = cofac[j].coeff(x, i);
1942                 rhs(i, 0) = red_numer.coeff(x, i);
1943         }
1944 //clog << "coeffs: " << sys << endl;
1945 //clog << "rhs   : " << rhs << endl;
1946
1947         // Solve resulting linear system
1948         matrix vars(num_factors, 1);
1949         for (size_t i=0; i<num_factors; i++)
1950                 vars(i, 0) = symbol();
1951         matrix sol = sys.solve(vars, rhs);
1952
1953         // Sum up decomposed fractions
1954         ex sum = 0;
1955         for (size_t i=0; i<num_factors; i++)
1956                 sum += sol(i, 0) / factor[i];
1957
1958         return red_poly + sum;
1959 }
1960
1961
1962 /*
1963  *  Normal form of rational functions
1964  */
1965
1966 /*
1967  *  Note: The internal normal() functions (= basic::normal() and overloaded
1968  *  functions) all return lists of the form {numerator, denominator}. This
1969  *  is to get around mul::eval()'s automatic expansion of numeric coefficients.
1970  *  E.g. (a+b)/3 is automatically converted to a/3+b/3 but we want to keep
1971  *  the information that (a+b) is the numerator and 3 is the denominator.
1972  */
1973
1974
1975 /** Create a symbol for replacing the expression "e" (or return a previously
1976  *  assigned symbol). The symbol and expression are appended to repl, for
1977  *  a later application of subs().
1978  *  @see ex::normal */
1979 static ex replace_with_symbol(const ex & e, exmap & repl, exmap & rev_lookup)
1980 {
1981         // Since the repl contains replaced expressions we should search for them
1982         ex e_replaced = e.subs(repl, subs_options::no_pattern);
1983
1984         // Expression already replaced? Then return the assigned symbol
1985         auto it = rev_lookup.find(e_replaced);
1986         if (it != rev_lookup.end())
1987                 return it->second;
1988
1989         // Otherwise create new symbol and add to list, taking care that the
1990         // replacement expression doesn't itself contain symbols from repl,
1991         // because subs() is not recursive
1992         ex es = (new symbol)->setflag(status_flags::dynallocated);
1993         repl.insert(std::make_pair(es, e_replaced));
1994         rev_lookup.insert(std::make_pair(e_replaced, es));
1995         return es;
1996 }
1997
1998 /** Create a symbol for replacing the expression "e" (or return a previously
1999  *  assigned symbol). The symbol and expression are appended to repl, and the
2000  *  symbol is returned.
2001  *  @see basic::to_rational
2002  *  @see basic::to_polynomial */
2003 static ex replace_with_symbol(const ex & e, exmap & repl)
2004 {
2005         // Since the repl contains replaced expressions we should search for them
2006         ex e_replaced = e.subs(repl, subs_options::no_pattern);
2007
2008         // Expression already replaced? Then return the assigned symbol
2009         for (auto & it : repl)
2010                 if (it.second.is_equal(e_replaced))
2011                         return it.first;
2012
2013         // Otherwise create new symbol and add to list, taking care that the
2014         // replacement expression doesn't itself contain symbols from repl,
2015         // because subs() is not recursive
2016         ex es = (new symbol)->setflag(status_flags::dynallocated);
2017         repl.insert(std::make_pair(es, e_replaced));
2018         return es;
2019 }
2020
2021
2022 /** Function object to be applied by basic::normal(). */
2023 struct normal_map_function : public map_function {
2024         int level;
2025         normal_map_function(int l) : level(l) {}
2026         ex operator()(const ex & e) { return normal(e, level); }
2027 };
2028
2029 /** Default implementation of ex::normal(). It normalizes the children and
2030  *  replaces the object with a temporary symbol.
2031  *  @see ex::normal */
2032 ex basic::normal(exmap & repl, exmap & rev_lookup, int level) const
2033 {
2034         if (nops() == 0)
2035                 return (new lst(replace_with_symbol(*this, repl, rev_lookup), _ex1))->setflag(status_flags::dynallocated);
2036         else {
2037                 if (level == 1)
2038                         return (new lst(replace_with_symbol(*this, repl, rev_lookup), _ex1))->setflag(status_flags::dynallocated);
2039                 else if (level == -max_recursion_level)
2040                         throw(std::runtime_error("max recursion level reached"));
2041                 else {
2042                         normal_map_function map_normal(level - 1);
2043                         return (new lst(replace_with_symbol(map(map_normal), repl, rev_lookup), _ex1))->setflag(status_flags::dynallocated);
2044                 }
2045         }
2046 }
2047
2048
2049 /** Implementation of ex::normal() for symbols. This returns the unmodified symbol.
2050  *  @see ex::normal */
2051 ex symbol::normal(exmap & repl, exmap & rev_lookup, int level) const
2052 {
2053         return (new lst(*this, _ex1))->setflag(status_flags::dynallocated);
2054 }
2055
2056
2057 /** Implementation of ex::normal() for a numeric. It splits complex numbers
2058  *  into re+I*im and replaces I and non-rational real numbers with a temporary
2059  *  symbol.
2060  *  @see ex::normal */
2061 ex numeric::normal(exmap & repl, exmap & rev_lookup, int level) const
2062 {
2063         numeric num = numer();
2064         ex numex = num;
2065
2066         if (num.is_real()) {
2067                 if (!num.is_integer())
2068                         numex = replace_with_symbol(numex, repl, rev_lookup);
2069         } else { // complex
2070                 numeric re = num.real(), im = num.imag();
2071                 ex re_ex = re.is_rational() ? re : replace_with_symbol(re, repl, rev_lookup);
2072                 ex im_ex = im.is_rational() ? im : replace_with_symbol(im, repl, rev_lookup);
2073                 numex = re_ex + im_ex * replace_with_symbol(I, repl, rev_lookup);
2074         }
2075
2076         // Denominator is always a real integer (see numeric::denom())
2077         return (new lst(numex, denom()))->setflag(status_flags::dynallocated);
2078 }
2079
2080
2081 /** Fraction cancellation.
2082  *  @param n  numerator
2083  *  @param d  denominator
2084  *  @return cancelled fraction {n, d} as a list */
2085 static ex frac_cancel(const ex &n, const ex &d)
2086 {
2087         ex num = n;
2088         ex den = d;
2089         numeric pre_factor = *_num1_p;
2090
2091 //std::clog << "frac_cancel num = " << num << ", den = " << den << std::endl;
2092
2093         // Handle trivial case where denominator is 1
2094         if (den.is_equal(_ex1))
2095                 return (new lst(num, den))->setflag(status_flags::dynallocated);
2096
2097         // Handle special cases where numerator or denominator is 0
2098         if (num.is_zero())
2099                 return (new lst(num, _ex1))->setflag(status_flags::dynallocated);
2100         if (den.expand().is_zero())
2101                 throw(std::overflow_error("frac_cancel: division by zero in frac_cancel"));
2102
2103         // Bring numerator and denominator to Z[X] by multiplying with
2104         // LCM of all coefficients' denominators
2105         numeric num_lcm = lcm_of_coefficients_denominators(num);
2106         numeric den_lcm = lcm_of_coefficients_denominators(den);
2107         num = multiply_lcm(num, num_lcm);
2108         den = multiply_lcm(den, den_lcm);
2109         pre_factor = den_lcm / num_lcm;
2110
2111         // Cancel GCD from numerator and denominator
2112         ex cnum, cden;
2113         if (gcd(num, den, &cnum, &cden, false) != _ex1) {
2114                 num = cnum;
2115                 den = cden;
2116         }
2117
2118         // Make denominator unit normal (i.e. coefficient of first symbol
2119         // as defined by get_first_symbol() is made positive)
2120         if (is_exactly_a<numeric>(den)) {
2121                 if (ex_to<numeric>(den).is_negative()) {
2122                         num *= _ex_1;
2123                         den *= _ex_1;
2124                 }
2125         } else {
2126                 ex x;
2127                 if (get_first_symbol(den, x)) {
2128                         GINAC_ASSERT(is_exactly_a<numeric>(den.unit(x)));
2129                         if (ex_to<numeric>(den.unit(x)).is_negative()) {
2130                                 num *= _ex_1;
2131                                 den *= _ex_1;
2132                         }
2133                 }
2134         }
2135
2136         // Return result as list
2137 //std::clog << " returns num = " << num << ", den = " << den << ", pre_factor = " << pre_factor << std::endl;
2138         return (new lst(num * pre_factor.numer(), den * pre_factor.denom()))->setflag(status_flags::dynallocated);
2139 }
2140
2141
2142 /** Implementation of ex::normal() for a sum. It expands terms and performs
2143  *  fractional addition.
2144  *  @see ex::normal */
2145 ex add::normal(exmap & repl, exmap & rev_lookup, int level) const
2146 {
2147         if (level == 1)
2148                 return (new lst(replace_with_symbol(*this, repl, rev_lookup), _ex1))->setflag(status_flags::dynallocated);
2149         else if (level == -max_recursion_level)
2150                 throw(std::runtime_error("max recursion level reached"));
2151
2152         // Normalize children and split each one into numerator and denominator
2153         exvector nums, dens;
2154         nums.reserve(seq.size()+1);
2155         dens.reserve(seq.size()+1);
2156         for (auto & it : seq) {
2157                 ex n = ex_to<basic>(recombine_pair_to_ex(it)).normal(repl, rev_lookup, level-1);
2158                 nums.push_back(n.op(0));
2159                 dens.push_back(n.op(1));
2160         }
2161         ex n = ex_to<numeric>(overall_coeff).normal(repl, rev_lookup, level-1);
2162         nums.push_back(n.op(0));
2163         dens.push_back(n.op(1));
2164         GINAC_ASSERT(nums.size() == dens.size());
2165
2166         // Now, nums is a vector of all numerators and dens is a vector of
2167         // all denominators
2168 //std::clog << "add::normal uses " << nums.size() << " summands:\n";
2169
2170         // Add fractions sequentially
2171         auto num_it = nums.begin(), num_itend = nums.end();
2172         auto den_it = dens.begin(), den_itend = dens.end();
2173 //std::clog << " num = " << *num_it << ", den = " << *den_it << std::endl;
2174         ex num = *num_it++, den = *den_it++;
2175         while (num_it != num_itend) {
2176 //std::clog << " num = " << *num_it << ", den = " << *den_it << std::endl;
2177                 ex next_num = *num_it++, next_den = *den_it++;
2178
2179                 // Trivially add sequences of fractions with identical denominators
2180                 while ((den_it != den_itend) && next_den.is_equal(*den_it)) {
2181                         next_num += *num_it;
2182                         num_it++; den_it++;
2183                 }
2184
2185                 // Addition of two fractions, taking advantage of the fact that
2186                 // the heuristic GCD algorithm computes the cofactors at no extra cost
2187                 ex co_den1, co_den2;
2188                 ex g = gcd(den, next_den, &co_den1, &co_den2, false);
2189                 num = ((num * co_den2) + (next_num * co_den1)).expand();
2190                 den *= co_den2;         // this is the lcm(den, next_den)
2191         }
2192 //std::clog << " common denominator = " << den << std::endl;
2193
2194         // Cancel common factors from num/den
2195         return frac_cancel(num, den);
2196 }
2197
2198
2199 /** Implementation of ex::normal() for a product. It cancels common factors
2200  *  from fractions.
2201  *  @see ex::normal() */
2202 ex mul::normal(exmap & repl, exmap & rev_lookup, int level) const
2203 {
2204         if (level == 1)
2205                 return (new lst(replace_with_symbol(*this, repl, rev_lookup), _ex1))->setflag(status_flags::dynallocated);
2206         else if (level == -max_recursion_level)
2207                 throw(std::runtime_error("max recursion level reached"));
2208
2209         // Normalize children, separate into numerator and denominator
2210         exvector num; num.reserve(seq.size());
2211         exvector den; den.reserve(seq.size());
2212         ex n;
2213         for (auto & it : seq) {
2214                 n = ex_to<basic>(recombine_pair_to_ex(it)).normal(repl, rev_lookup, level-1);
2215                 num.push_back(n.op(0));
2216                 den.push_back(n.op(1));
2217         }
2218         n = ex_to<numeric>(overall_coeff).normal(repl, rev_lookup, level-1);
2219         num.push_back(n.op(0));
2220         den.push_back(n.op(1));
2221
2222         // Perform fraction cancellation
2223         return frac_cancel((new mul(num))->setflag(status_flags::dynallocated),
2224                            (new mul(den))->setflag(status_flags::dynallocated));
2225 }
2226
2227
2228 /** Implementation of ex::normal([B) for powers. It normalizes the basis,
2229  *  distributes integer exponents to numerator and denominator, and replaces
2230  *  non-integer powers by temporary symbols.
2231  *  @see ex::normal */
2232 ex power::normal(exmap & repl, exmap & rev_lookup, int level) const
2233 {
2234         if (level == 1)
2235                 return (new lst(replace_with_symbol(*this, repl, rev_lookup), _ex1))->setflag(status_flags::dynallocated);
2236         else if (level == -max_recursion_level)
2237                 throw(std::runtime_error("max recursion level reached"));
2238
2239         // Normalize basis and exponent (exponent gets reassembled)
2240         ex n_basis = ex_to<basic>(basis).normal(repl, rev_lookup, level-1);
2241         ex n_exponent = ex_to<basic>(exponent).normal(repl, rev_lookup, level-1);
2242         n_exponent = n_exponent.op(0) / n_exponent.op(1);
2243
2244         if (n_exponent.info(info_flags::integer)) {
2245
2246                 if (n_exponent.info(info_flags::positive)) {
2247
2248                         // (a/b)^n -> {a^n, b^n}
2249                         return (new lst(power(n_basis.op(0), n_exponent), power(n_basis.op(1), n_exponent)))->setflag(status_flags::dynallocated);
2250
2251                 } else if (n_exponent.info(info_flags::negative)) {
2252
2253                         // (a/b)^-n -> {b^n, a^n}
2254                         return (new lst(power(n_basis.op(1), -n_exponent), power(n_basis.op(0), -n_exponent)))->setflag(status_flags::dynallocated);
2255                 }
2256
2257         } else {
2258
2259                 if (n_exponent.info(info_flags::positive)) {
2260
2261                         // (a/b)^x -> {sym((a/b)^x), 1}
2262                         return (new lst(replace_with_symbol(power(n_basis.op(0) / n_basis.op(1), n_exponent), repl, rev_lookup), _ex1))->setflag(status_flags::dynallocated);
2263
2264                 } else if (n_exponent.info(info_flags::negative)) {
2265
2266                         if (n_basis.op(1).is_equal(_ex1)) {
2267
2268                                 // a^-x -> {1, sym(a^x)}
2269                                 return (new lst(_ex1, replace_with_symbol(power(n_basis.op(0), -n_exponent), repl, rev_lookup)))->setflag(status_flags::dynallocated);
2270
2271                         } else {
2272
2273                                 // (a/b)^-x -> {sym((b/a)^x), 1}
2274                                 return (new lst(replace_with_symbol(power(n_basis.op(1) / n_basis.op(0), -n_exponent), repl, rev_lookup), _ex1))->setflag(status_flags::dynallocated);
2275                         }
2276                 }
2277         }
2278
2279         // (a/b)^x -> {sym((a/b)^x, 1}
2280         return (new lst(replace_with_symbol(power(n_basis.op(0) / n_basis.op(1), n_exponent), repl, rev_lookup), _ex1))->setflag(status_flags::dynallocated);
2281 }
2282
2283
2284 /** Implementation of ex::normal() for pseries. It normalizes each coefficient
2285  *  and replaces the series by a temporary symbol.
2286  *  @see ex::normal */
2287 ex pseries::normal(exmap & repl, exmap & rev_lookup, int level) const
2288 {
2289         epvector newseq;
2290         for (auto & it : seq) {
2291                 ex restexp = it.rest.normal();
2292                 if (!restexp.is_zero())
2293                         newseq.push_back(expair(restexp, it.coeff));
2294         }
2295         ex n = pseries(relational(var,point), std::move(newseq));
2296         return (new lst(replace_with_symbol(n, repl, rev_lookup), _ex1))->setflag(status_flags::dynallocated);
2297 }
2298
2299
2300 /** Normalization of rational functions.
2301  *  This function converts an expression to its normal form
2302  *  "numerator/denominator", where numerator and denominator are (relatively
2303  *  prime) polynomials. Any subexpressions which are not rational functions
2304  *  (like non-rational numbers, non-integer powers or functions like sin(),
2305  *  cos() etc.) are replaced by temporary symbols which are re-substituted by
2306  *  the (normalized) subexpressions before normal() returns (this way, any
2307  *  expression can be treated as a rational function). normal() is applied
2308  *  recursively to arguments of functions etc.
2309  *
2310  *  @param level maximum depth of recursion
2311  *  @return normalized expression */
2312 ex ex::normal(int level) const
2313 {
2314         exmap repl, rev_lookup;
2315
2316         ex e = bp->normal(repl, rev_lookup, level);
2317         GINAC_ASSERT(is_a<lst>(e));
2318
2319         // Re-insert replaced symbols
2320         if (!repl.empty())
2321                 e = e.subs(repl, subs_options::no_pattern);
2322
2323         // Convert {numerator, denominator} form back to fraction
2324         return e.op(0) / e.op(1);
2325 }
2326
2327 /** Get numerator of an expression. If the expression is not of the normal
2328  *  form "numerator/denominator", it is first converted to this form and
2329  *  then the numerator is returned.
2330  *
2331  *  @see ex::normal
2332  *  @return numerator */
2333 ex ex::numer() const
2334 {
2335         exmap repl, rev_lookup;
2336
2337         ex e = bp->normal(repl, rev_lookup, 0);
2338         GINAC_ASSERT(is_a<lst>(e));
2339
2340         // Re-insert replaced symbols
2341         if (repl.empty())
2342                 return e.op(0);
2343         else
2344                 return e.op(0).subs(repl, subs_options::no_pattern);
2345 }
2346
2347 /** Get denominator of an expression. If the expression is not of the normal
2348  *  form "numerator/denominator", it is first converted to this form and
2349  *  then the denominator is returned.
2350  *
2351  *  @see ex::normal
2352  *  @return denominator */
2353 ex ex::denom() const
2354 {
2355         exmap repl, rev_lookup;
2356
2357         ex e = bp->normal(repl, rev_lookup, 0);
2358         GINAC_ASSERT(is_a<lst>(e));
2359
2360         // Re-insert replaced symbols
2361         if (repl.empty())
2362                 return e.op(1);
2363         else
2364                 return e.op(1).subs(repl, subs_options::no_pattern);
2365 }
2366
2367 /** Get numerator and denominator of an expression. If the expression is not
2368  *  of the normal form "numerator/denominator", it is first converted to this
2369  *  form and then a list [numerator, denominator] is returned.
2370  *
2371  *  @see ex::normal
2372  *  @return a list [numerator, denominator] */
2373 ex ex::numer_denom() const
2374 {
2375         exmap repl, rev_lookup;
2376
2377         ex e = bp->normal(repl, rev_lookup, 0);
2378         GINAC_ASSERT(is_a<lst>(e));
2379
2380         // Re-insert replaced symbols
2381         if (repl.empty())
2382                 return e;
2383         else
2384                 return e.subs(repl, subs_options::no_pattern);
2385 }
2386
2387
2388 /** Rationalization of non-rational functions.
2389  *  This function converts a general expression to a rational function
2390  *  by replacing all non-rational subexpressions (like non-rational numbers,
2391  *  non-integer powers or functions like sin(), cos() etc.) to temporary
2392  *  symbols. This makes it possible to use functions like gcd() and divide()
2393  *  on non-rational functions by applying to_rational() on the arguments,
2394  *  calling the desired function and re-substituting the temporary symbols
2395  *  in the result. To make the last step possible, all temporary symbols and
2396  *  their associated expressions are collected in the map specified by the
2397  *  repl parameter, ready to be passed as an argument to ex::subs().
2398  *
2399  *  @param repl collects all temporary symbols and their replacements
2400  *  @return rationalized expression */
2401 ex ex::to_rational(exmap & repl) const
2402 {
2403         return bp->to_rational(repl);
2404 }
2405
2406 // GiNaC 1.1 compatibility function
2407 ex ex::to_rational(lst & repl_lst) const
2408 {
2409         // Convert lst to exmap
2410         exmap m;
2411         for (auto & it : repl_lst)
2412                 m.insert(std::make_pair(it.op(0), it.op(1)));
2413
2414         ex ret = bp->to_rational(m);
2415
2416         // Convert exmap back to lst
2417         repl_lst.remove_all();
2418         for (auto & it : m)
2419                 repl_lst.append(it.first == it.second);
2420
2421         return ret;
2422 }
2423
2424 ex ex::to_polynomial(exmap & repl) const
2425 {
2426         return bp->to_polynomial(repl);
2427 }
2428
2429 // GiNaC 1.1 compatibility function
2430 ex ex::to_polynomial(lst & repl_lst) const
2431 {
2432         // Convert lst to exmap
2433         exmap m;
2434         for (auto & it : repl_lst)
2435                 m.insert(std::make_pair(it.op(0), it.op(1)));
2436
2437         ex ret = bp->to_polynomial(m);
2438
2439         // Convert exmap back to lst
2440         repl_lst.remove_all();
2441         for (auto & it : m)
2442                 repl_lst.append(it.first == it.second);
2443
2444         return ret;
2445 }
2446
2447 /** Default implementation of ex::to_rational(). This replaces the object with
2448  *  a temporary symbol. */
2449 ex basic::to_rational(exmap & repl) const
2450 {
2451         return replace_with_symbol(*this, repl);
2452 }
2453
2454 ex basic::to_polynomial(exmap & repl) const
2455 {
2456         return replace_with_symbol(*this, repl);
2457 }
2458
2459
2460 /** Implementation of ex::to_rational() for symbols. This returns the
2461  *  unmodified symbol. */
2462 ex symbol::to_rational(exmap & repl) const
2463 {
2464         return *this;
2465 }
2466
2467 /** Implementation of ex::to_polynomial() for symbols. This returns the
2468  *  unmodified symbol. */
2469 ex symbol::to_polynomial(exmap & repl) const
2470 {
2471         return *this;
2472 }
2473
2474
2475 /** Implementation of ex::to_rational() for a numeric. It splits complex
2476  *  numbers into re+I*im and replaces I and non-rational real numbers with a
2477  *  temporary symbol. */
2478 ex numeric::to_rational(exmap & repl) const
2479 {
2480         if (is_real()) {
2481                 if (!is_rational())
2482                         return replace_with_symbol(*this, repl);
2483         } else { // complex
2484                 numeric re = real();
2485                 numeric im = imag();
2486                 ex re_ex = re.is_rational() ? re : replace_with_symbol(re, repl);
2487                 ex im_ex = im.is_rational() ? im : replace_with_symbol(im, repl);
2488                 return re_ex + im_ex * replace_with_symbol(I, repl);
2489         }
2490         return *this;
2491 }
2492
2493 /** Implementation of ex::to_polynomial() for a numeric. It splits complex
2494  *  numbers into re+I*im and replaces I and non-integer real numbers with a
2495  *  temporary symbol. */
2496 ex numeric::to_polynomial(exmap & repl) const
2497 {
2498         if (is_real()) {
2499                 if (!is_integer())
2500                         return replace_with_symbol(*this, repl);
2501         } else { // complex
2502                 numeric re = real();
2503                 numeric im = imag();
2504                 ex re_ex = re.is_integer() ? re : replace_with_symbol(re, repl);
2505                 ex im_ex = im.is_integer() ? im : replace_with_symbol(im, repl);
2506                 return re_ex + im_ex * replace_with_symbol(I, repl);
2507         }
2508         return *this;
2509 }
2510
2511
2512 /** Implementation of ex::to_rational() for powers. It replaces non-integer
2513  *  powers by temporary symbols. */
2514 ex power::to_rational(exmap & repl) const
2515 {
2516         if (exponent.info(info_flags::integer))
2517                 return power(basis.to_rational(repl), exponent);
2518         else
2519                 return replace_with_symbol(*this, repl);
2520 }
2521
2522 /** Implementation of ex::to_polynomial() for powers. It replaces non-posint
2523  *  powers by temporary symbols. */
2524 ex power::to_polynomial(exmap & repl) const
2525 {
2526         if (exponent.info(info_flags::posint))
2527                 return power(basis.to_rational(repl), exponent);
2528         else if (exponent.info(info_flags::negint))
2529         {
2530                 ex basis_pref = collect_common_factors(basis);
2531                 if (is_exactly_a<mul>(basis_pref) || is_exactly_a<power>(basis_pref)) {
2532                         // (A*B)^n will be automagically transformed to A^n*B^n
2533                         ex t = power(basis_pref, exponent);
2534                         return t.to_polynomial(repl);
2535                 }
2536                 else
2537                         return power(replace_with_symbol(power(basis, _ex_1), repl), -exponent);
2538         } 
2539         else
2540                 return replace_with_symbol(*this, repl);
2541 }
2542
2543
2544 /** Implementation of ex::to_rational() for expairseqs. */
2545 ex expairseq::to_rational(exmap & repl) const
2546 {
2547         epvector s;
2548         s.reserve(seq.size());
2549         for (auto & it : seq)
2550                 s.push_back(split_ex_to_pair(recombine_pair_to_ex(it).to_rational(repl)));
2551
2552         ex oc = overall_coeff.to_rational(repl);
2553         if (oc.info(info_flags::numeric))
2554                 return thisexpairseq(std::move(s), overall_coeff);
2555         else
2556                 s.push_back(combine_ex_with_coeff_to_pair(oc, _ex1));
2557         return thisexpairseq(std::move(s), default_overall_coeff());
2558 }
2559
2560 /** Implementation of ex::to_polynomial() for expairseqs. */
2561 ex expairseq::to_polynomial(exmap & repl) const
2562 {
2563         epvector s;
2564         s.reserve(seq.size());
2565         for (auto & it : seq)
2566                 s.push_back(split_ex_to_pair(recombine_pair_to_ex(it).to_polynomial(repl)));
2567
2568         ex oc = overall_coeff.to_polynomial(repl);
2569         if (oc.info(info_flags::numeric))
2570                 return thisexpairseq(std::move(s), overall_coeff);
2571         else
2572                 s.push_back(combine_ex_with_coeff_to_pair(oc, _ex1));
2573         return thisexpairseq(std::move(s), default_overall_coeff());
2574 }
2575
2576
2577 /** Remove the common factor in the terms of a sum 'e' by calculating the GCD,
2578  *  and multiply it into the expression 'factor' (which needs to be initialized
2579  *  to 1, unless you're accumulating factors). */
2580 static ex find_common_factor(const ex & e, ex & factor, exmap & repl)
2581 {
2582         if (is_exactly_a<add>(e)) {
2583
2584                 size_t num = e.nops();
2585                 exvector terms; terms.reserve(num);
2586                 ex gc;
2587
2588                 // Find the common GCD
2589                 for (size_t i=0; i<num; i++) {
2590                         ex x = e.op(i).to_polynomial(repl);
2591
2592                         if (is_exactly_a<add>(x) || is_exactly_a<mul>(x) || is_a<power>(x)) {
2593                                 ex f = 1;
2594                                 x = find_common_factor(x, f, repl);
2595                                 x *= f;
2596                         }
2597
2598                         if (i == 0)
2599                                 gc = x;
2600                         else
2601                                 gc = gcd(gc, x);
2602
2603                         terms.push_back(x);
2604                 }
2605
2606                 if (gc.is_equal(_ex1))
2607                         return e;
2608
2609                 // The GCD is the factor we pull out
2610                 factor *= gc;
2611
2612                 // Now divide all terms by the GCD
2613                 for (size_t i=0; i<num; i++) {
2614                         ex x;
2615
2616                         // Try to avoid divide() because it expands the polynomial
2617                         ex &t = terms[i];
2618                         if (is_exactly_a<mul>(t)) {
2619                                 for (size_t j=0; j<t.nops(); j++) {
2620                                         if (t.op(j).is_equal(gc)) {
2621                                                 exvector v; v.reserve(t.nops());
2622                                                 for (size_t k=0; k<t.nops(); k++) {
2623                                                         if (k == j)
2624                                                                 v.push_back(_ex1);
2625                                                         else
2626                                                                 v.push_back(t.op(k));
2627                                                 }
2628                                                 t = (new mul(v))->setflag(status_flags::dynallocated);
2629                                                 goto term_done;
2630                                         }
2631                                 }
2632                         }
2633
2634                         divide(t, gc, x);
2635                         t = x;
2636 term_done:      ;
2637                 }
2638                 return (new add(terms))->setflag(status_flags::dynallocated);
2639
2640         } else if (is_exactly_a<mul>(e)) {
2641
2642                 size_t num = e.nops();
2643                 exvector v; v.reserve(num);
2644
2645                 for (size_t i=0; i<num; i++)
2646                         v.push_back(find_common_factor(e.op(i), factor, repl));
2647
2648                 return (new mul(v))->setflag(status_flags::dynallocated);
2649
2650         } else if (is_exactly_a<power>(e)) {
2651                 const ex e_exp(e.op(1));
2652                 if (e_exp.info(info_flags::integer)) {
2653                         ex eb = e.op(0).to_polynomial(repl);
2654                         ex factor_local(_ex1);
2655                         ex pre_res = find_common_factor(eb, factor_local, repl);
2656                         factor *= power(factor_local, e_exp);
2657                         return power(pre_res, e_exp);
2658                         
2659                 } else
2660                         return e.to_polynomial(repl);
2661
2662         } else
2663                 return e;
2664 }
2665
2666
2667 /** Collect common factors in sums. This converts expressions like
2668  *  'a*(b*x+b*y)' to 'a*b*(x+y)'. */
2669 ex collect_common_factors(const ex & e)
2670 {
2671         if (is_exactly_a<add>(e) || is_exactly_a<mul>(e) || is_exactly_a<power>(e)) {
2672
2673                 exmap repl;
2674                 ex factor = 1;
2675                 ex r = find_common_factor(e, factor, repl);
2676                 return factor.subs(repl, subs_options::no_pattern) * r.subs(repl, subs_options::no_pattern);
2677
2678         } else
2679                 return e;
2680 }
2681
2682
2683 /** Resultant of two expressions e1,e2 with respect to symbol s.
2684  *  Method: Compute determinant of Sylvester matrix of e1,e2,s.  */
2685 ex resultant(const ex & e1, const ex & e2, const ex & s)
2686 {
2687         const ex ee1 = e1.expand();
2688         const ex ee2 = e2.expand();
2689         if (!ee1.info(info_flags::polynomial) ||
2690             !ee2.info(info_flags::polynomial))
2691                 throw(std::runtime_error("resultant(): arguments must be polynomials"));
2692
2693         const int h1 = ee1.degree(s);
2694         const int l1 = ee1.ldegree(s);
2695         const int h2 = ee2.degree(s);
2696         const int l2 = ee2.ldegree(s);
2697
2698         const int msize = h1 + h2;
2699         matrix m(msize, msize);
2700
2701         for (int l = h1; l >= l1; --l) {
2702                 const ex e = ee1.coeff(s, l);
2703                 for (int k = 0; k < h2; ++k)
2704                         m(k, k+h1-l) = e;
2705         }
2706         for (int l = h2; l >= l2; --l) {
2707                 const ex e = ee2.coeff(s, l);
2708                 for (int k = 0; k < h1; ++k)
2709                         m(k+h2, k+h2-l) = e;
2710         }
2711
2712         return m.determinant();
2713 }
2714
2715
2716 } // namespace GiNaC