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