]> www.ginac.de Git - ginac.git/blob - ginac/normal.cpp
* ginac/registrar.h: dtor is inlined now.
[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-2001 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "ncmul.h"
40 #include "numeric.h"
41 #include "power.h"
42 #include "relational.h"
43 #include "pseries.h"
44 #include "symbol.h"
45 #include "utils.h"
46
47 namespace GiNaC {
48
49 // If comparing expressions (ex::compare()) is fast, you can set this to 1.
50 // Some routines like quo(), rem() and gcd() will then return a quick answer
51 // when they are called with two identical arguments.
52 #define FAST_COMPARE 1
53
54 // Set this if you want divide_in_z() to use remembering
55 #define USE_REMEMBER 0
56
57 // Set this if you want divide_in_z() to use trial division followed by
58 // polynomial interpolation (always slower except for completely dense
59 // polynomials)
60 #define USE_TRIAL_DIVISION 0
61
62 // Set this to enable some statistical output for the GCD routines
63 #define STATISTICS 0
64
65
66 #if STATISTICS
67 // Statistics variables
68 static int gcd_called = 0;
69 static int sr_gcd_called = 0;
70 static int heur_gcd_called = 0;
71 static int heur_gcd_failed = 0;
72
73 // Print statistics at end of program
74 static struct _stat_print {
75         _stat_print() {}
76         ~_stat_print() {
77                 cout << "gcd() called " << gcd_called << " times\n";
78                 cout << "sr_gcd() called " << sr_gcd_called << " times\n";
79                 cout << "heur_gcd() called " << heur_gcd_called << " times\n";
80                 cout << "heur_gcd() failed " << heur_gcd_failed << " times\n";
81         }
82 } stat_print;
83 #endif
84
85
86 /** Return pointer to first symbol found in expression.  Due to GiNaCĀ“s
87  *  internal ordering of terms, it may not be obvious which symbol this
88  *  function returns for a given expression.
89  *
90  *  @param e  expression to search
91  *  @param x  pointer to first symbol found (returned)
92  *  @return "false" if no symbol was found, "true" otherwise */
93 static bool get_first_symbol(const ex &e, const symbol *&x)
94 {
95         if (is_ex_exactly_of_type(e, symbol)) {
96                 x = static_cast<symbol *>(e.bp);
97                 return true;
98         } else if (is_ex_exactly_of_type(e, add) || is_ex_exactly_of_type(e, mul)) {
99                 for (unsigned i=0; i<e.nops(); i++)
100                         if (get_first_symbol(e.op(i), x))
101                                 return true;
102         } else if (is_ex_exactly_of_type(e, power)) {
103                 if (get_first_symbol(e.op(0), x))
104                         return true;
105         }
106         return false;
107 }
108
109
110 /*
111  *  Statistical information about symbols in polynomials
112  */
113
114 /** This structure holds information about the highest and lowest degrees
115  *  in which a symbol appears in two multivariate polynomials "a" and "b".
116  *  A vector of these structures with information about all symbols in
117  *  two polynomials can be created with the function get_symbol_stats().
118  *
119  *  @see get_symbol_stats */
120 struct sym_desc {
121         /** Pointer to symbol */
122         const symbol *sym;
123
124         /** Highest degree of symbol in polynomial "a" */
125         int deg_a;
126
127         /** Highest degree of symbol in polynomial "b" */
128         int deg_b;
129
130         /** Lowest degree of symbol in polynomial "a" */
131         int ldeg_a;
132
133         /** Lowest degree of symbol in polynomial "b" */
134         int ldeg_b;
135
136         /** Maximum of deg_a and deg_b (Used for sorting) */
137         int max_deg;
138
139         /** Maximum number of terms of leading coefficient of symbol in both polynomials */
140         int max_lcnops;
141
142         /** Commparison operator for sorting */
143         bool operator<(const sym_desc &x) const
144         {
145                 if (max_deg == x.max_deg)
146                         return max_lcnops < x.max_lcnops;
147                 else
148                         return max_deg < x.max_deg;
149         }
150 };
151
152 // Vector of sym_desc structures
153 typedef std::vector<sym_desc> sym_desc_vec;
154
155 // Add symbol the sym_desc_vec (used internally by get_symbol_stats())
156 static void add_symbol(const symbol *s, sym_desc_vec &v)
157 {
158         sym_desc_vec::iterator it = v.begin(), itend = v.end();
159         while (it != itend) {
160                 if (it->sym->compare(*s) == 0)  // If it's already in there, don't add it a second time
161                         return;
162                 it++;
163         }
164         sym_desc d;
165         d.sym = s;
166         v.push_back(d);
167 }
168
169 // Collect all symbols of an expression (used internally by get_symbol_stats())
170 static void collect_symbols(const ex &e, sym_desc_vec &v)
171 {
172         if (is_ex_exactly_of_type(e, symbol)) {
173                 add_symbol(static_cast<symbol *>(e.bp), v);
174         } else if (is_ex_exactly_of_type(e, add) || is_ex_exactly_of_type(e, mul)) {
175                 for (unsigned i=0; i<e.nops(); i++)
176                         collect_symbols(e.op(i), v);
177         } else if (is_ex_exactly_of_type(e, power)) {
178                 collect_symbols(e.op(0), v);
179         }
180 }
181
182 /** Collect statistical information about symbols in polynomials.
183  *  This function fills in a vector of "sym_desc" structs which contain
184  *  information about the highest and lowest degrees of all symbols that
185  *  appear in two polynomials. The vector is then sorted by minimum
186  *  degree (lowest to highest). The information gathered by this
187  *  function is used by the GCD routines to identify trivial factors
188  *  and to determine which variable to choose as the main variable
189  *  for GCD computation.
190  *
191  *  @param a  first multivariate polynomial
192  *  @param b  second multivariate polynomial
193  *  @param v  vector of sym_desc structs (filled in) */
194 static void get_symbol_stats(const ex &a, const ex &b, sym_desc_vec &v)
195 {
196         collect_symbols(a.eval(), v);   // eval() to expand assigned symbols
197         collect_symbols(b.eval(), v);
198         sym_desc_vec::iterator it = v.begin(), itend = v.end();
199         while (it != itend) {
200                 int deg_a = a.degree(*(it->sym));
201                 int deg_b = b.degree(*(it->sym));
202                 it->deg_a = deg_a;
203                 it->deg_b = deg_b;
204                 it->max_deg = std::max(deg_a, deg_b);
205                 it->max_lcnops = std::max(a.lcoeff(*(it->sym)).nops(), b.lcoeff(*(it->sym)).nops());
206                 it->ldeg_a = a.ldegree(*(it->sym));
207                 it->ldeg_b = b.ldegree(*(it->sym));
208                 it++;
209         }
210         sort(v.begin(), v.end());
211 #if 0
212         std::clog << "Symbols:\n";
213         it = v.begin(); itend = v.end();
214         while (it != itend) {
215                 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;
216                 std::clog << "  lcoeff_a=" << a.lcoeff(*(it->sym)) << ", lcoeff_b=" << b.lcoeff(*(it->sym)) << endl;
217                 it++;
218         }
219 #endif
220 }
221
222
223 /*
224  *  Computation of LCM of denominators of coefficients of a polynomial
225  */
226
227 // Compute LCM of denominators of coefficients by going through the
228 // expression recursively (used internally by lcm_of_coefficients_denominators())
229 static numeric lcmcoeff(const ex &e, const numeric &l)
230 {
231         if (e.info(info_flags::rational))
232                 return lcm(ex_to_numeric(e).denom(), l);
233         else if (is_ex_exactly_of_type(e, add)) {
234                 numeric c = _num1();
235                 for (unsigned i=0; i<e.nops(); i++)
236                         c = lcmcoeff(e.op(i), c);
237                 return lcm(c, l);
238         } else if (is_ex_exactly_of_type(e, mul)) {
239                 numeric c = _num1();
240                 for (unsigned i=0; i<e.nops(); i++)
241                         c *= lcmcoeff(e.op(i), _num1());
242                 return lcm(c, l);
243         } else if (is_ex_exactly_of_type(e, power))
244                 return pow(lcmcoeff(e.op(0), l), ex_to_numeric(e.op(1)));
245         return l;
246 }
247
248 /** Compute LCM of denominators of coefficients of a polynomial.
249  *  Given a polynomial with rational coefficients, this function computes
250  *  the LCM of the denominators of all coefficients. This can be used
251  *  to bring a polynomial from Q[X] to Z[X].
252  *
253  *  @param e  multivariate polynomial (need not be expanded)
254  *  @return LCM of denominators of coefficients */
255 static numeric lcm_of_coefficients_denominators(const ex &e)
256 {
257         return lcmcoeff(e, _num1());
258 }
259
260 /** Bring polynomial from Q[X] to Z[X] by multiplying in the previously
261  *  determined LCM of the coefficient's denominators.
262  *
263  *  @param e  multivariate polynomial (need not be expanded)
264  *  @param lcm  LCM to multiply in */
265 static ex multiply_lcm(const ex &e, const numeric &lcm)
266 {
267         if (is_ex_exactly_of_type(e, mul)) {
268                 ex c = _ex1();
269                 numeric lcm_accum = _num1();
270                 for (unsigned i=0; i<e.nops(); i++) {
271                         numeric op_lcm = lcmcoeff(e.op(i), _num1());
272                         c *= multiply_lcm(e.op(i), op_lcm);
273                         lcm_accum *= op_lcm;
274                 }
275                 c *= lcm / lcm_accum;
276                 return c;
277         } else if (is_ex_exactly_of_type(e, add)) {
278                 ex c = _ex0();
279                 for (unsigned i=0; i<e.nops(); i++)
280                         c += multiply_lcm(e.op(i), lcm);
281                 return c;
282         } else if (is_ex_exactly_of_type(e, power)) {
283                 return pow(multiply_lcm(e.op(0), lcm.power(ex_to_numeric(e.op(1)).inverse())), e.op(1));
284         } else
285                 return e * lcm;
286 }
287
288
289 /** Compute the integer content (= GCD of all numeric coefficients) of an
290  *  expanded polynomial.
291  *
292  *  @param e  expanded polynomial
293  *  @return integer content */
294 numeric ex::integer_content(void) const
295 {
296         GINAC_ASSERT(bp!=0);
297         return bp->integer_content();
298 }
299
300 numeric basic::integer_content(void) const
301 {
302         return _num1();
303 }
304
305 numeric numeric::integer_content(void) const
306 {
307         return abs(*this);
308 }
309
310 numeric add::integer_content(void) const
311 {
312         epvector::const_iterator it = seq.begin();
313         epvector::const_iterator itend = seq.end();
314         numeric c = _num0();
315         while (it != itend) {
316                 GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
317                 GINAC_ASSERT(is_ex_exactly_of_type(it->coeff,numeric));
318                 c = gcd(ex_to_numeric(it->coeff), c);
319                 it++;
320         }
321         GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
322         c = gcd(ex_to_numeric(overall_coeff),c);
323         return c;
324 }
325
326 numeric mul::integer_content(void) const
327 {
328 #ifdef DO_GINAC_ASSERT
329         epvector::const_iterator it = seq.begin();
330         epvector::const_iterator itend = seq.end();
331         while (it != itend) {
332                 GINAC_ASSERT(!is_ex_exactly_of_type(recombine_pair_to_ex(*it),numeric));
333                 ++it;
334         }
335 #endif // def DO_GINAC_ASSERT
336         GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
337         return abs(ex_to_numeric(overall_coeff));
338 }
339
340
341 /*
342  *  Polynomial quotients and remainders
343  */
344
345 /** Quotient q(x) of polynomials a(x) and b(x) in Q[x].
346  *  It satisfies a(x)=b(x)*q(x)+r(x).
347  *
348  *  @param a  first polynomial in x (dividend)
349  *  @param b  second polynomial in x (divisor)
350  *  @param x  a and b are polynomials in x
351  *  @param check_args  check whether a and b are polynomials with rational
352  *         coefficients (defaults to "true")
353  *  @return quotient of a and b in Q[x] */
354 ex quo(const ex &a, const ex &b, const symbol &x, bool check_args)
355 {
356         if (b.is_zero())
357                 throw(std::overflow_error("quo: division by zero"));
358         if (is_ex_exactly_of_type(a, numeric) && is_ex_exactly_of_type(b, numeric))
359                 return a / b;
360 #if FAST_COMPARE
361         if (a.is_equal(b))
362                 return _ex1();
363 #endif
364         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
365                 throw(std::invalid_argument("quo: arguments must be polynomials over the rationals"));
366
367         // Polynomial long division
368         ex q = _ex0();
369         ex r = a.expand();
370         if (r.is_zero())
371                 return r;
372         int bdeg = b.degree(x);
373         int rdeg = r.degree(x);
374         ex blcoeff = b.expand().coeff(x, bdeg);
375         bool blcoeff_is_numeric = is_ex_exactly_of_type(blcoeff, numeric);
376         while (rdeg >= bdeg) {
377                 ex term, rcoeff = r.coeff(x, rdeg);
378                 if (blcoeff_is_numeric)
379                         term = rcoeff / blcoeff;
380                 else {
381                         if (!divide(rcoeff, blcoeff, term, false))
382                                 return *new ex(fail());
383                 }
384                 term *= power(x, rdeg - bdeg);
385                 q += term;
386                 r -= (term * b).expand();
387                 if (r.is_zero())
388                         break;
389                 rdeg = r.degree(x);
390         }
391         return q;
392 }
393
394
395 /** Remainder r(x) of polynomials a(x) and b(x) in Q[x].
396  *  It satisfies a(x)=b(x)*q(x)+r(x).
397  *
398  *  @param a  first polynomial in x (dividend)
399  *  @param b  second polynomial in x (divisor)
400  *  @param x  a and b are polynomials in x
401  *  @param check_args  check whether a and b are polynomials with rational
402  *         coefficients (defaults to "true")
403  *  @return remainder of a(x) and b(x) in Q[x] */
404 ex rem(const ex &a, const ex &b, const symbol &x, bool check_args)
405 {
406         if (b.is_zero())
407                 throw(std::overflow_error("rem: division by zero"));
408         if (is_ex_exactly_of_type(a, numeric)) {
409                 if  (is_ex_exactly_of_type(b, numeric))
410                         return _ex0();
411                 else
412                         return b;
413         }
414 #if FAST_COMPARE
415         if (a.is_equal(b))
416                 return _ex0();
417 #endif
418         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
419                 throw(std::invalid_argument("rem: arguments must be polynomials over the rationals"));
420
421         // Polynomial long division
422         ex r = a.expand();
423         if (r.is_zero())
424                 return r;
425         int bdeg = b.degree(x);
426         int rdeg = r.degree(x);
427         ex blcoeff = b.expand().coeff(x, bdeg);
428         bool blcoeff_is_numeric = is_ex_exactly_of_type(blcoeff, numeric);
429         while (rdeg >= bdeg) {
430                 ex term, rcoeff = r.coeff(x, rdeg);
431                 if (blcoeff_is_numeric)
432                         term = rcoeff / blcoeff;
433                 else {
434                         if (!divide(rcoeff, blcoeff, term, false))
435                                 return *new ex(fail());
436                 }
437                 term *= power(x, rdeg - bdeg);
438                 r -= (term * b).expand();
439                 if (r.is_zero())
440                         break;
441                 rdeg = r.degree(x);
442         }
443         return r;
444 }
445
446
447 /** Pseudo-remainder of polynomials a(x) and b(x) in Z[x].
448  *
449  *  @param a  first polynomial in x (dividend)
450  *  @param b  second polynomial in x (divisor)
451  *  @param x  a and b are polynomials in x
452  *  @param check_args  check whether a and b are polynomials with rational
453  *         coefficients (defaults to "true")
454  *  @return pseudo-remainder of a(x) and b(x) in Z[x] */
455 ex prem(const ex &a, const ex &b, const symbol &x, bool check_args)
456 {
457         if (b.is_zero())
458                 throw(std::overflow_error("prem: division by zero"));
459         if (is_ex_exactly_of_type(a, numeric)) {
460                 if (is_ex_exactly_of_type(b, numeric))
461                         return _ex0();
462                 else
463                         return b;
464         }
465         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
466                 throw(std::invalid_argument("prem: arguments must be polynomials over the rationals"));
467
468         // Polynomial long division
469         ex r = a.expand();
470         ex eb = b.expand();
471         int rdeg = r.degree(x);
472         int bdeg = eb.degree(x);
473         ex blcoeff;
474         if (bdeg <= rdeg) {
475                 blcoeff = eb.coeff(x, bdeg);
476                 if (bdeg == 0)
477                         eb = _ex0();
478                 else
479                         eb -= blcoeff * power(x, bdeg);
480         } else
481                 blcoeff = _ex1();
482
483         int delta = rdeg - bdeg + 1, i = 0;
484         while (rdeg >= bdeg && !r.is_zero()) {
485                 ex rlcoeff = r.coeff(x, rdeg);
486                 ex term = (power(x, rdeg - bdeg) * eb * rlcoeff).expand();
487                 if (rdeg == 0)
488                         r = _ex0();
489                 else
490                         r -= rlcoeff * power(x, rdeg);
491                 r = (blcoeff * r).expand() - term;
492                 rdeg = r.degree(x);
493                 i++;
494         }
495         return power(blcoeff, delta - i) * r;
496 }
497
498
499 /** Sparse pseudo-remainder of polynomials a(x) and b(x) in Z[x].
500  *
501  *  @param a  first polynomial in x (dividend)
502  *  @param b  second polynomial in x (divisor)
503  *  @param x  a and b are polynomials in x
504  *  @param check_args  check whether a and b are polynomials with rational
505  *         coefficients (defaults to "true")
506  *  @return sparse pseudo-remainder of a(x) and b(x) in Z[x] */
507
508 ex sprem(const ex &a, const ex &b, const symbol &x, bool check_args)
509 {
510         if (b.is_zero())
511                 throw(std::overflow_error("prem: division by zero"));
512         if (is_ex_exactly_of_type(a, numeric)) {
513                 if (is_ex_exactly_of_type(b, numeric))
514                         return _ex0();
515                 else
516                         return b;
517         }
518         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
519                 throw(std::invalid_argument("prem: arguments must be polynomials over the rationals"));
520
521         // Polynomial long division
522         ex r = a.expand();
523         ex eb = b.expand();
524         int rdeg = r.degree(x);
525         int bdeg = eb.degree(x);
526         ex blcoeff;
527         if (bdeg <= rdeg) {
528                 blcoeff = eb.coeff(x, bdeg);
529                 if (bdeg == 0)
530                         eb = _ex0();
531                 else
532                         eb -= blcoeff * power(x, bdeg);
533         } else
534                 blcoeff = _ex1();
535
536         while (rdeg >= bdeg && !r.is_zero()) {
537                 ex rlcoeff = r.coeff(x, rdeg);
538                 ex term = (power(x, rdeg - bdeg) * eb * rlcoeff).expand();
539                 if (rdeg == 0)
540                         r = _ex0();
541                 else
542                         r -= rlcoeff * power(x, rdeg);
543                 r = (blcoeff * r).expand() - term;
544                 rdeg = r.degree(x);
545         }
546         return r;
547 }
548
549
550 /** Exact polynomial division of a(X) by b(X) in Q[X].
551  *  
552  *  @param a  first multivariate polynomial (dividend)
553  *  @param b  second multivariate polynomial (divisor)
554  *  @param q  quotient (returned)
555  *  @param check_args  check whether a and b are polynomials with rational
556  *         coefficients (defaults to "true")
557  *  @return "true" when exact division succeeds (quotient returned in q),
558  *          "false" otherwise */
559 bool divide(const ex &a, const ex &b, ex &q, bool check_args)
560 {
561         q = _ex0();
562         if (b.is_zero())
563                 throw(std::overflow_error("divide: division by zero"));
564         if (a.is_zero())
565                 return true;
566         if (is_ex_exactly_of_type(b, numeric)) {
567                 q = a / b;
568                 return true;
569         } else if (is_ex_exactly_of_type(a, numeric))
570                 return false;
571 #if FAST_COMPARE
572         if (a.is_equal(b)) {
573                 q = _ex1();
574                 return true;
575         }
576 #endif
577         if (check_args && (!a.info(info_flags::rational_polynomial) ||
578                            !b.info(info_flags::rational_polynomial)))
579                 throw(std::invalid_argument("divide: arguments must be polynomials over the rationals"));
580
581         // Find first symbol
582         const symbol *x;
583         if (!get_first_symbol(a, x) && !get_first_symbol(b, x))
584                 throw(std::invalid_argument("invalid expression in divide()"));
585
586         // Polynomial long division (recursive)
587         ex r = a.expand();
588         if (r.is_zero())
589                 return true;
590         int bdeg = b.degree(*x);
591         int rdeg = r.degree(*x);
592         ex blcoeff = b.expand().coeff(*x, bdeg);
593         bool blcoeff_is_numeric = is_ex_exactly_of_type(blcoeff, numeric);
594         while (rdeg >= bdeg) {
595                 ex term, rcoeff = r.coeff(*x, rdeg);
596                 if (blcoeff_is_numeric)
597                         term = rcoeff / blcoeff;
598                 else
599                         if (!divide(rcoeff, blcoeff, term, false))
600                                 return false;
601                 term *= power(*x, rdeg - bdeg);
602                 q += term;
603                 r -= (term * b).expand();
604                 if (r.is_zero())
605                         return true;
606                 rdeg = r.degree(*x);
607         }
608         return false;
609 }
610
611
612 #if USE_REMEMBER
613 /*
614  *  Remembering
615  */
616
617 typedef std::pair<ex, ex> ex2;
618 typedef std::pair<ex, bool> exbool;
619
620 struct ex2_less {
621         bool operator() (const ex2 &p, const ex2 &q) const 
622         {
623                 int cmp = p.first.compare(q.first);
624                 return ((cmp<0) || (!(cmp>0) && p.second.compare(q.second)<0));
625         }
626 };
627
628 typedef std::map<ex2, exbool, ex2_less> ex2_exbool_remember;
629 #endif
630
631
632 /** Exact polynomial division of a(X) by b(X) in Z[X].
633  *  This functions works like divide() but the input and output polynomials are
634  *  in Z[X] instead of Q[X] (i.e. they have integer coefficients). Unlike
635  *  divide(), it doesnĀ“t check whether the input polynomials really are integer
636  *  polynomials, so be careful of what you pass in. Also, you have to run
637  *  get_symbol_stats() over the input polynomials before calling this function
638  *  and pass an iterator to the first element of the sym_desc vector. This
639  *  function is used internally by the heur_gcd().
640  *  
641  *  @param a  first multivariate polynomial (dividend)
642  *  @param b  second multivariate polynomial (divisor)
643  *  @param q  quotient (returned)
644  *  @param var  iterator to first element of vector of sym_desc structs
645  *  @return "true" when exact division succeeds (the quotient is returned in
646  *          q), "false" otherwise.
647  *  @see get_symbol_stats, heur_gcd */
648 static bool divide_in_z(const ex &a, const ex &b, ex &q, sym_desc_vec::const_iterator var)
649 {
650         q = _ex0();
651         if (b.is_zero())
652                 throw(std::overflow_error("divide_in_z: division by zero"));
653         if (b.is_equal(_ex1())) {
654                 q = a;
655                 return true;
656         }
657         if (is_ex_exactly_of_type(a, numeric)) {
658                 if (is_ex_exactly_of_type(b, numeric)) {
659                         q = a / b;
660                         return q.info(info_flags::integer);
661                 } else
662                         return false;
663         }
664 #if FAST_COMPARE
665         if (a.is_equal(b)) {
666                 q = _ex1();
667                 return true;
668         }
669 #endif
670
671 #if USE_REMEMBER
672         // Remembering
673         static ex2_exbool_remember dr_remember;
674         ex2_exbool_remember::const_iterator remembered = dr_remember.find(ex2(a, b));
675         if (remembered != dr_remember.end()) {
676                 q = remembered->second.first;
677                 return remembered->second.second;
678         }
679 #endif
680
681         // Main symbol
682         const symbol *x = var->sym;
683
684         // Compare degrees
685         int adeg = a.degree(*x), bdeg = b.degree(*x);
686         if (bdeg > adeg)
687                 return false;
688
689 #if USE_TRIAL_DIVISION
690
691         // Trial division with polynomial interpolation
692         int i, k;
693
694         // Compute values at evaluation points 0..adeg
695         vector<numeric> alpha; alpha.reserve(adeg + 1);
696         exvector u; u.reserve(adeg + 1);
697         numeric point = _num0();
698         ex c;
699         for (i=0; i<=adeg; i++) {
700                 ex bs = b.subs(*x == point);
701                 while (bs.is_zero()) {
702                         point += _num1();
703                         bs = b.subs(*x == point);
704                 }
705                 if (!divide_in_z(a.subs(*x == point), bs, c, var+1))
706                         return false;
707                 alpha.push_back(point);
708                 u.push_back(c);
709                 point += _num1();
710         }
711
712         // Compute inverses
713         vector<numeric> rcp; rcp.reserve(adeg + 1);
714         rcp.push_back(_num0());
715         for (k=1; k<=adeg; k++) {
716                 numeric product = alpha[k] - alpha[0];
717                 for (i=1; i<k; i++)
718                         product *= alpha[k] - alpha[i];
719                 rcp.push_back(product.inverse());
720         }
721
722         // Compute Newton coefficients
723         exvector v; v.reserve(adeg + 1);
724         v.push_back(u[0]);
725         for (k=1; k<=adeg; k++) {
726                 ex temp = v[k - 1];
727                 for (i=k-2; i>=0; i--)
728                         temp = temp * (alpha[k] - alpha[i]) + v[i];
729                 v.push_back((u[k] - temp) * rcp[k]);
730         }
731
732         // Convert from Newton form to standard form
733         c = v[adeg];
734         for (k=adeg-1; k>=0; k--)
735                 c = c * (*x - alpha[k]) + v[k];
736
737         if (c.degree(*x) == (adeg - bdeg)) {
738                 q = c.expand();
739                 return true;
740         } else
741                 return false;
742
743 #else
744
745         // Polynomial long division (recursive)
746         ex r = a.expand();
747         if (r.is_zero())
748                 return true;
749         int rdeg = adeg;
750         ex eb = b.expand();
751         ex blcoeff = eb.coeff(*x, bdeg);
752         while (rdeg >= bdeg) {
753                 ex term, rcoeff = r.coeff(*x, rdeg);
754                 if (!divide_in_z(rcoeff, blcoeff, term, var+1))
755                         break;
756                 term = (term * power(*x, rdeg - bdeg)).expand();
757                 q += term;
758                 r -= (term * eb).expand();
759                 if (r.is_zero()) {
760 #if USE_REMEMBER
761                         dr_remember[ex2(a, b)] = exbool(q, true);
762 #endif
763                         return true;
764                 }
765                 rdeg = r.degree(*x);
766         }
767 #if USE_REMEMBER
768         dr_remember[ex2(a, b)] = exbool(q, false);
769 #endif
770         return false;
771
772 #endif
773 }
774
775
776 /*
777  *  Separation of unit part, content part and primitive part of polynomials
778  */
779
780 /** Compute unit part (= sign of leading coefficient) of a multivariate
781  *  polynomial in Z[x]. The product of unit part, content part, and primitive
782  *  part is the polynomial itself.
783  *
784  *  @param x  variable in which to compute the unit part
785  *  @return unit part
786  *  @see ex::content, ex::primpart */
787 ex ex::unit(const symbol &x) const
788 {
789         ex c = expand().lcoeff(x);
790         if (is_ex_exactly_of_type(c, numeric))
791                 return c < _ex0() ? _ex_1() : _ex1();
792         else {
793                 const symbol *y;
794                 if (get_first_symbol(c, y))
795                         return c.unit(*y);
796                 else
797                         throw(std::invalid_argument("invalid expression in unit()"));
798         }
799 }
800
801
802 /** Compute content part (= unit normal GCD of all coefficients) of a
803  *  multivariate polynomial in Z[x].  The product of unit part, content part,
804  *  and primitive part is the polynomial itself.
805  *
806  *  @param x  variable in which to compute the content part
807  *  @return content part
808  *  @see ex::unit, ex::primpart */
809 ex ex::content(const symbol &x) const
810 {
811         if (is_zero())
812                 return _ex0();
813         if (is_ex_exactly_of_type(*this, numeric))
814                 return info(info_flags::negative) ? -*this : *this;
815         ex e = expand();
816         if (e.is_zero())
817                 return _ex0();
818
819         // First, try the integer content
820         ex c = e.integer_content();
821         ex r = e / c;
822         ex lcoeff = r.lcoeff(x);
823         if (lcoeff.info(info_flags::integer))
824                 return c;
825
826         // GCD of all coefficients
827         int deg = e.degree(x);
828         int ldeg = e.ldegree(x);
829         if (deg == ldeg)
830                 return e.lcoeff(x) / e.unit(x);
831         c = _ex0();
832         for (int i=ldeg; i<=deg; i++)
833                 c = gcd(e.coeff(x, i), c, NULL, NULL, false);
834         return c;
835 }
836
837
838 /** Compute primitive part of a multivariate polynomial in Z[x].
839  *  The product of unit part, content part, and primitive part is the
840  *  polynomial itself.
841  *
842  *  @param x  variable in which to compute the primitive part
843  *  @return primitive part
844  *  @see ex::unit, ex::content */
845 ex ex::primpart(const symbol &x) const
846 {
847         if (is_zero())
848                 return _ex0();
849         if (is_ex_exactly_of_type(*this, numeric))
850                 return _ex1();
851
852         ex c = content(x);
853         if (c.is_zero())
854                 return _ex0();
855         ex u = unit(x);
856         if (is_ex_exactly_of_type(c, numeric))
857                 return *this / (c * u);
858         else
859                 return quo(*this, c * u, x, false);
860 }
861
862
863 /** Compute primitive part of a multivariate polynomial in Z[x] when the
864  *  content part is already known. This function is faster in computing the
865  *  primitive part than the previous function.
866  *
867  *  @param x  variable in which to compute the primitive part
868  *  @param c  previously computed content part
869  *  @return primitive part */
870 ex ex::primpart(const symbol &x, const ex &c) const
871 {
872         if (is_zero())
873                 return _ex0();
874         if (c.is_zero())
875                 return _ex0();
876         if (is_ex_exactly_of_type(*this, numeric))
877                 return _ex1();
878
879         ex u = unit(x);
880         if (is_ex_exactly_of_type(c, numeric))
881                 return *this / (c * u);
882         else
883                 return quo(*this, c * u, x, false);
884 }
885
886
887 /*
888  *  GCD of multivariate polynomials
889  */
890
891 /** Compute GCD of polynomials in Q[X] using the Euclidean algorithm (not
892  *  really suited for multivariate GCDs). This function is only provided for
893  *  testing purposes.
894  *
895  *  @param a  first multivariate polynomial
896  *  @param b  second multivariate polynomial
897  *  @param x  pointer to symbol (main variable) in which to compute the GCD in
898  *  @return the GCD as a new expression
899  *  @see gcd */
900
901 static ex eu_gcd(const ex &a, const ex &b, const symbol *x)
902 {
903 //std::clog << "eu_gcd(" << a << "," << b << ")\n";
904
905         // Sort c and d so that c has higher degree
906         ex c, d;
907         int adeg = a.degree(*x), bdeg = b.degree(*x);
908         if (adeg >= bdeg) {
909                 c = a;
910                 d = b;
911         } else {
912                 c = b;
913                 d = a;
914         }
915
916         // Normalize in Q[x]
917         c = c / c.lcoeff(*x);
918         d = d / d.lcoeff(*x);
919
920         // Euclidean algorithm
921         ex r;
922         for (;;) {
923 //std::clog << " d = " << d << endl;
924                 r = rem(c, d, *x, false);
925                 if (r.is_zero())
926                         return d / d.lcoeff(*x);
927                 c = d;
928                 d = r;
929         }
930 }
931
932
933 /** Compute GCD of multivariate polynomials using the Euclidean PRS algorithm
934  *  with pseudo-remainders ("World's Worst GCD Algorithm", staying in Z[X]).
935  *  This function is only provided for testing purposes.
936  *
937  *  @param a  first multivariate polynomial
938  *  @param b  second multivariate polynomial
939  *  @param x  pointer to symbol (main variable) in which to compute the GCD in
940  *  @return the GCD as a new expression
941  *  @see gcd */
942
943 static ex euprem_gcd(const ex &a, const ex &b, const symbol *x)
944 {
945 //std::clog << "euprem_gcd(" << a << "," << b << ")\n";
946
947         // Sort c and d so that c has higher degree
948         ex c, d;
949         int adeg = a.degree(*x), bdeg = b.degree(*x);
950         if (adeg >= bdeg) {
951                 c = a;
952                 d = b;
953         } else {
954                 c = b;
955                 d = a;
956         }
957
958         // Calculate GCD of contents
959         ex gamma = gcd(c.content(*x), d.content(*x), NULL, NULL, false);
960
961         // Euclidean algorithm with pseudo-remainders
962         ex r;
963         for (;;) {
964 //std::clog << " d = " << d << endl;
965                 r = prem(c, d, *x, false);
966                 if (r.is_zero())
967                         return d.primpart(*x) * gamma;
968                 c = d;
969                 d = r;
970         }
971 }
972
973
974 /** Compute GCD of multivariate polynomials using the primitive Euclidean
975  *  PRS algorithm (complete content removal at each step). This function is
976  *  only provided for testing purposes.
977  *
978  *  @param a  first multivariate polynomial
979  *  @param b  second multivariate polynomial
980  *  @param x  pointer to symbol (main variable) in which to compute the GCD in
981  *  @return the GCD as a new expression
982  *  @see gcd */
983
984 static ex peu_gcd(const ex &a, const ex &b, const symbol *x)
985 {
986 //std::clog << "peu_gcd(" << a << "," << b << ")\n";
987
988         // Sort c and d so that c has higher degree
989         ex c, d;
990         int adeg = a.degree(*x), bdeg = b.degree(*x);
991         int ddeg;
992         if (adeg >= bdeg) {
993                 c = a;
994                 d = b;
995                 ddeg = bdeg;
996         } else {
997                 c = b;
998                 d = a;
999                 ddeg = adeg;
1000         }
1001
1002         // Remove content from c and d, to be attached to GCD later
1003         ex cont_c = c.content(*x);
1004         ex cont_d = d.content(*x);
1005         ex gamma = gcd(cont_c, cont_d, NULL, NULL, false);
1006         if (ddeg == 0)
1007                 return gamma;
1008         c = c.primpart(*x, cont_c);
1009         d = d.primpart(*x, cont_d);
1010
1011         // Euclidean algorithm with content removal
1012         ex r;
1013         for (;;) {
1014 //std::clog << " d = " << d << endl;
1015                 r = prem(c, d, *x, false);
1016                 if (r.is_zero())
1017                         return gamma * d;
1018                 c = d;
1019                 d = r.primpart(*x);
1020         }
1021 }
1022
1023
1024 /** Compute GCD of multivariate polynomials using the reduced PRS algorithm.
1025  *  This function is only provided for testing purposes.
1026  *
1027  *  @param a  first multivariate polynomial
1028  *  @param b  second multivariate polynomial
1029  *  @param x  pointer to symbol (main variable) in which to compute the GCD in
1030  *  @return the GCD as a new expression
1031  *  @see gcd */
1032
1033 static ex red_gcd(const ex &a, const ex &b, const symbol *x)
1034 {
1035 //std::clog << "red_gcd(" << a << "," << b << ")\n";
1036
1037         // Sort c and d so that c has higher degree
1038         ex c, d;
1039         int adeg = a.degree(*x), bdeg = b.degree(*x);
1040         int cdeg, ddeg;
1041         if (adeg >= bdeg) {
1042                 c = a;
1043                 d = b;
1044                 cdeg = adeg;
1045                 ddeg = bdeg;
1046         } else {
1047                 c = b;
1048                 d = a;
1049                 cdeg = bdeg;
1050                 ddeg = adeg;
1051         }
1052
1053         // Remove content from c and d, to be attached to GCD later
1054         ex cont_c = c.content(*x);
1055         ex cont_d = d.content(*x);
1056         ex gamma = gcd(cont_c, cont_d, NULL, NULL, false);
1057         if (ddeg == 0)
1058                 return gamma;
1059         c = c.primpart(*x, cont_c);
1060         d = d.primpart(*x, cont_d);
1061
1062         // First element of divisor sequence
1063         ex r, ri = _ex1();
1064         int delta = cdeg - ddeg;
1065
1066         for (;;) {
1067                 // Calculate polynomial pseudo-remainder
1068 //std::clog << " d = " << d << endl;
1069                 r = prem(c, d, *x, false);
1070                 if (r.is_zero())
1071                         return gamma * d.primpart(*x);
1072                 c = d;
1073                 cdeg = ddeg;
1074
1075                 if (!divide(r, pow(ri, delta), d, false))
1076                         throw(std::runtime_error("invalid expression in red_gcd(), division failed"));
1077                 ddeg = d.degree(*x);
1078                 if (ddeg == 0) {
1079                         if (is_ex_exactly_of_type(r, numeric))
1080                                 return gamma;
1081                         else
1082                                 return gamma * r.primpart(*x);
1083                 }
1084
1085                 ri = c.expand().lcoeff(*x);
1086                 delta = cdeg - ddeg;
1087         }
1088 }
1089
1090
1091 /** Compute GCD of multivariate polynomials using the subresultant PRS
1092  *  algorithm. This function is used internally by gcd().
1093  *
1094  *  @param a   first multivariate polynomial
1095  *  @param b   second multivariate polynomial
1096  *  @param var iterator to first element of vector of sym_desc structs
1097  *  @return the GCD as a new expression
1098  *  @see gcd */
1099
1100 static ex sr_gcd(const ex &a, const ex &b, sym_desc_vec::const_iterator var)
1101 {
1102 //std::clog << "sr_gcd(" << a << "," << b << ")\n";
1103 #if STATISTICS
1104         sr_gcd_called++;
1105 #endif
1106
1107         // The first symbol is our main variable
1108         const symbol &x = *(var->sym);
1109
1110         // Sort c and d so that c has higher degree
1111         ex c, d;
1112         int adeg = a.degree(x), bdeg = b.degree(x);
1113         int cdeg, ddeg;
1114         if (adeg >= bdeg) {
1115                 c = a;
1116                 d = b;
1117                 cdeg = adeg;
1118                 ddeg = bdeg;
1119         } else {
1120                 c = b;
1121                 d = a;
1122                 cdeg = bdeg;
1123                 ddeg = adeg;
1124         }
1125
1126         // Remove content from c and d, to be attached to GCD later
1127         ex cont_c = c.content(x);
1128         ex cont_d = d.content(x);
1129         ex gamma = gcd(cont_c, cont_d, NULL, NULL, false);
1130         if (ddeg == 0)
1131                 return gamma;
1132         c = c.primpart(x, cont_c);
1133         d = d.primpart(x, cont_d);
1134 //std::clog << " content " << gamma << " removed, continuing with sr_gcd(" << c << "," << d << ")\n";
1135
1136         // First element of subresultant sequence
1137         ex r = _ex0(), ri = _ex1(), psi = _ex1();
1138         int delta = cdeg - ddeg;
1139
1140         for (;;) {
1141                 // Calculate polynomial pseudo-remainder
1142 //std::clog << " start of loop, psi = " << psi << ", calculating pseudo-remainder...\n";
1143 //std::clog << " d = " << d << endl;
1144                 r = prem(c, d, x, false);
1145                 if (r.is_zero())
1146                         return gamma * d.primpart(x);
1147                 c = d;
1148                 cdeg = ddeg;
1149 //std::clog << " dividing...\n";
1150                 if (!divide_in_z(r, ri * pow(psi, delta), d, var))
1151                         throw(std::runtime_error("invalid expression in sr_gcd(), division failed"));
1152                 ddeg = d.degree(x);
1153                 if (ddeg == 0) {
1154                         if (is_ex_exactly_of_type(r, numeric))
1155                                 return gamma;
1156                         else
1157                                 return gamma * r.primpart(x);
1158                 }
1159
1160                 // Next element of subresultant sequence
1161 //std::clog << " calculating next subresultant...\n";
1162                 ri = c.expand().lcoeff(x);
1163                 if (delta == 1)
1164                         psi = ri;
1165                 else if (delta)
1166                         divide_in_z(pow(ri, delta), pow(psi, delta-1), psi, var+1);
1167                 delta = cdeg - ddeg;
1168         }
1169 }
1170
1171
1172 /** Return maximum (absolute value) coefficient of a polynomial.
1173  *  This function is used internally by heur_gcd().
1174  *
1175  *  @param e  expanded multivariate polynomial
1176  *  @return maximum coefficient
1177  *  @see heur_gcd */
1178 numeric ex::max_coefficient(void) const
1179 {
1180         GINAC_ASSERT(bp!=0);
1181         return bp->max_coefficient();
1182 }
1183
1184 /** Implementation ex::max_coefficient().
1185  *  @see heur_gcd */
1186 numeric basic::max_coefficient(void) const
1187 {
1188         return _num1();
1189 }
1190
1191 numeric numeric::max_coefficient(void) const
1192 {
1193         return abs(*this);
1194 }
1195
1196 numeric add::max_coefficient(void) const
1197 {
1198         epvector::const_iterator it = seq.begin();
1199         epvector::const_iterator itend = seq.end();
1200         GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
1201         numeric cur_max = abs(ex_to_numeric(overall_coeff));
1202         while (it != itend) {
1203                 numeric a;
1204                 GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
1205                 a = abs(ex_to_numeric(it->coeff));
1206                 if (a > cur_max)
1207                         cur_max = a;
1208                 it++;
1209         }
1210         return cur_max;
1211 }
1212
1213 numeric mul::max_coefficient(void) const
1214 {
1215 #ifdef DO_GINAC_ASSERT
1216         epvector::const_iterator it = seq.begin();
1217         epvector::const_iterator itend = seq.end();
1218         while (it != itend) {
1219                 GINAC_ASSERT(!is_ex_exactly_of_type(recombine_pair_to_ex(*it),numeric));
1220                 it++;
1221         }
1222 #endif // def DO_GINAC_ASSERT
1223         GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
1224         return abs(ex_to_numeric(overall_coeff));
1225 }
1226
1227
1228 /** Apply symmetric modular homomorphism to a multivariate polynomial.
1229  *  This function is used internally by heur_gcd().
1230  *
1231  *  @param e  expanded multivariate polynomial
1232  *  @param xi  modulus
1233  *  @return mapped polynomial
1234  *  @see heur_gcd */
1235 ex ex::smod(const numeric &xi) const
1236 {
1237         GINAC_ASSERT(bp!=0);
1238         return bp->smod(xi);
1239 }
1240
1241 ex basic::smod(const numeric &xi) const
1242 {
1243         return *this;
1244 }
1245
1246 ex numeric::smod(const numeric &xi) const
1247 {
1248         return GiNaC::smod(*this, xi);
1249 }
1250
1251 ex add::smod(const numeric &xi) const
1252 {
1253         epvector newseq;
1254         newseq.reserve(seq.size()+1);
1255         epvector::const_iterator it = seq.begin();
1256         epvector::const_iterator itend = seq.end();
1257         while (it != itend) {
1258                 GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
1259                 numeric coeff = GiNaC::smod(ex_to_numeric(it->coeff), xi);
1260                 if (!coeff.is_zero())
1261                         newseq.push_back(expair(it->rest, coeff));
1262                 it++;
1263         }
1264         GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
1265         numeric coeff = GiNaC::smod(ex_to_numeric(overall_coeff), xi);
1266         return (new add(newseq,coeff))->setflag(status_flags::dynallocated);
1267 }
1268
1269 ex mul::smod(const numeric &xi) const
1270 {
1271 #ifdef DO_GINAC_ASSERT
1272         epvector::const_iterator it = seq.begin();
1273         epvector::const_iterator itend = seq.end();
1274         while (it != itend) {
1275                 GINAC_ASSERT(!is_ex_exactly_of_type(recombine_pair_to_ex(*it),numeric));
1276                 it++;
1277         }
1278 #endif // def DO_GINAC_ASSERT
1279         mul * mulcopyp=new mul(*this);
1280         GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
1281         mulcopyp->overall_coeff = GiNaC::smod(ex_to_numeric(overall_coeff),xi);
1282         mulcopyp->clearflag(status_flags::evaluated);
1283         mulcopyp->clearflag(status_flags::hash_calculated);
1284         return mulcopyp->setflag(status_flags::dynallocated);
1285 }
1286
1287
1288 /** xi-adic polynomial interpolation */
1289 static ex interpolate(const ex &gamma, const numeric &xi, const symbol &x)
1290 {
1291         ex g = _ex0();
1292         ex e = gamma;
1293         numeric rxi = xi.inverse();
1294         for (int i=0; !e.is_zero(); i++) {
1295                 ex gi = e.smod(xi);
1296                 g += gi * power(x, i);
1297                 e = (e - gi) * rxi;
1298         }
1299         return g;
1300 }
1301
1302 /** Exception thrown by heur_gcd() to signal failure. */
1303 class gcdheu_failed {};
1304
1305 /** Compute GCD of multivariate polynomials using the heuristic GCD algorithm.
1306  *  get_symbol_stats() must have been called previously with the input
1307  *  polynomials and an iterator to the first element of the sym_desc vector
1308  *  passed in. This function is used internally by gcd().
1309  *
1310  *  @param a  first multivariate polynomial (expanded)
1311  *  @param b  second multivariate polynomial (expanded)
1312  *  @param ca  cofactor of polynomial a (returned), NULL to suppress
1313  *             calculation of cofactor
1314  *  @param cb  cofactor of polynomial b (returned), NULL to suppress
1315  *             calculation of cofactor
1316  *  @param var iterator to first element of vector of sym_desc structs
1317  *  @return the GCD as a new expression
1318  *  @see gcd
1319  *  @exception gcdheu_failed() */
1320 static ex heur_gcd(const ex &a, const ex &b, ex *ca, ex *cb, sym_desc_vec::const_iterator var)
1321 {
1322 //std::clog << "heur_gcd(" << a << "," << b << ")\n";
1323 #if STATISTICS
1324         heur_gcd_called++;
1325 #endif
1326
1327         // Algorithms only works for non-vanishing input polynomials
1328         if (a.is_zero() || b.is_zero())
1329                 return *new ex(fail());
1330
1331         // GCD of two numeric values -> CLN
1332         if (is_ex_exactly_of_type(a, numeric) && is_ex_exactly_of_type(b, numeric)) {
1333                 numeric g = gcd(ex_to_numeric(a), ex_to_numeric(b));
1334                 if (ca)
1335                         *ca = ex_to_numeric(a) / g;
1336                 if (cb)
1337                         *cb = ex_to_numeric(b) / g;
1338                 return g;
1339         }
1340
1341         // The first symbol is our main variable
1342         const symbol &x = *(var->sym);
1343
1344         // Remove integer content
1345         numeric gc = gcd(a.integer_content(), b.integer_content());
1346         numeric rgc = gc.inverse();
1347         ex p = a * rgc;
1348         ex q = b * rgc;
1349         int maxdeg =  std::max(p.degree(x),q.degree(x));
1350         
1351         // Find evaluation point
1352         numeric mp = p.max_coefficient();
1353         numeric mq = q.max_coefficient();
1354         numeric xi;
1355         if (mp > mq)
1356                 xi = mq * _num2() + _num2();
1357         else
1358                 xi = mp * _num2() + _num2();
1359
1360         // 6 tries maximum
1361         for (int t=0; t<6; t++) {
1362                 if (xi.int_length() * maxdeg > 100000) {
1363 //std::clog << "giving up heur_gcd, xi.int_length = " << xi.int_length() << ", maxdeg = " << maxdeg << endl;
1364                         throw gcdheu_failed();
1365                 }
1366
1367                 // Apply evaluation homomorphism and calculate GCD
1368                 ex cp, cq;
1369                 ex gamma = heur_gcd(p.subs(x == xi), q.subs(x == xi), &cp, &cq, var+1).expand();
1370                 if (!is_ex_exactly_of_type(gamma, fail)) {
1371
1372                         // Reconstruct polynomial from GCD of mapped polynomials
1373                         ex g = interpolate(gamma, xi, x);
1374
1375                         // Remove integer content
1376                         g /= g.integer_content();
1377
1378                         // If the calculated polynomial divides both p and q, this is the GCD
1379                         ex dummy;
1380                         if (divide_in_z(p, g, ca ? *ca : dummy, var) && divide_in_z(q, g, cb ? *cb : dummy, var)) {
1381                                 g *= gc;
1382                                 ex lc = g.lcoeff(x);
1383                                 if (is_ex_exactly_of_type(lc, numeric) && ex_to_numeric(lc).is_negative())
1384                                         return -g;
1385                                 else
1386                                         return g;
1387                         }
1388 #if 0
1389                         cp = interpolate(cp, xi, x);
1390                         if (divide_in_z(cp, p, g, var)) {
1391                                 if (divide_in_z(g, q, cb ? *cb : dummy, var)) {
1392                                         g *= gc;
1393                                         if (ca)
1394                                                 *ca = cp;
1395                                         ex lc = g.lcoeff(x);
1396                                         if (is_ex_exactly_of_type(lc, numeric) && ex_to_numeric(lc).is_negative())
1397                                                 return -g;
1398                                         else
1399                                                 return g;
1400                                 }
1401                         }
1402                         cq = interpolate(cq, xi, x);
1403                         if (divide_in_z(cq, q, g, var)) {
1404                                 if (divide_in_z(g, p, ca ? *ca : dummy, var)) {
1405                                         g *= gc;
1406                                         if (cb)
1407                                                 *cb = cq;
1408                                         ex lc = g.lcoeff(x);
1409                                         if (is_ex_exactly_of_type(lc, numeric) && ex_to_numeric(lc).is_negative())
1410                                                 return -g;
1411                                         else
1412                                                 return g;
1413                                 }
1414                         }
1415 #endif
1416                 }
1417
1418                 // Next evaluation point
1419                 xi = iquo(xi * isqrt(isqrt(xi)) * numeric(73794), numeric(27011));
1420         }
1421         return *new ex(fail());
1422 }
1423
1424
1425 /** Compute GCD (Greatest Common Divisor) of multivariate polynomials a(X)
1426  *  and b(X) in Z[X].
1427  *
1428  *  @param a  first multivariate polynomial
1429  *  @param b  second multivariate polynomial
1430  *  @param check_args  check whether a and b are polynomials with rational
1431  *         coefficients (defaults to "true")
1432  *  @return the GCD as a new expression */
1433 ex gcd(const ex &a, const ex &b, ex *ca, ex *cb, bool check_args)
1434 {
1435 //std::clog << "gcd(" << a << "," << b << ")\n";
1436 #if STATISTICS
1437         gcd_called++;
1438 #endif
1439
1440         // GCD of numerics -> CLN
1441         if (is_ex_exactly_of_type(a, numeric) && is_ex_exactly_of_type(b, numeric)) {
1442                 numeric g = gcd(ex_to_numeric(a), ex_to_numeric(b));
1443                 if (ca || cb) {
1444                         if (g.is_zero()) {
1445                                 if (ca)
1446                                         *ca = _ex0();
1447                                 if (cb)
1448                                         *cb = _ex0();
1449                         } else {
1450                                 if (ca)
1451                                         *ca = ex_to_numeric(a) / g;
1452                                 if (cb)
1453                                         *cb = ex_to_numeric(b) / g;
1454                         }
1455                 }
1456                 return g;
1457         }
1458
1459         // Check arguments
1460         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial))) {
1461                 throw(std::invalid_argument("gcd: arguments must be polynomials over the rationals"));
1462         }
1463
1464         // Partially factored cases (to avoid expanding large expressions)
1465         if (is_ex_exactly_of_type(a, mul)) {
1466                 if (is_ex_exactly_of_type(b, mul) && b.nops() > a.nops())
1467                         goto factored_b;
1468 factored_a:
1469                 ex g = _ex1();
1470                 ex acc_ca = _ex1();
1471                 ex part_b = b;
1472                 for (unsigned i=0; i<a.nops(); i++) {
1473                         ex part_ca, part_cb;
1474                         g *= gcd(a.op(i), part_b, &part_ca, &part_cb, check_args);
1475                         acc_ca *= part_ca;
1476                         part_b = part_cb;
1477                 }
1478                 if (ca)
1479                         *ca = acc_ca;
1480                 if (cb)
1481                         *cb = part_b;
1482                 return g;
1483         } else if (is_ex_exactly_of_type(b, mul)) {
1484                 if (is_ex_exactly_of_type(a, mul) && a.nops() > b.nops())
1485                         goto factored_a;
1486 factored_b:
1487                 ex g = _ex1();
1488                 ex acc_cb = _ex1();
1489                 ex part_a = a;
1490                 for (unsigned i=0; i<b.nops(); i++) {
1491                         ex part_ca, part_cb;
1492                         g *= gcd(part_a, b.op(i), &part_ca, &part_cb, check_args);
1493                         acc_cb *= part_cb;
1494                         part_a = part_ca;
1495                 }
1496                 if (ca)
1497                         *ca = part_a;
1498                 if (cb)
1499                         *cb = acc_cb;
1500                 return g;
1501         }
1502
1503 #if FAST_COMPARE
1504         // Input polynomials of the form poly^n are sometimes also trivial
1505         if (is_ex_exactly_of_type(a, power)) {
1506                 ex p = a.op(0);
1507                 if (is_ex_exactly_of_type(b, power)) {
1508                         if (p.is_equal(b.op(0))) {
1509                                 // a = p^n, b = p^m, gcd = p^min(n, m)
1510                                 ex exp_a = a.op(1), exp_b = b.op(1);
1511                                 if (exp_a < exp_b) {
1512                                         if (ca)
1513                                                 *ca = _ex1();
1514                                         if (cb)
1515                                                 *cb = power(p, exp_b - exp_a);
1516                                         return power(p, exp_a);
1517                                 } else {
1518                                         if (ca)
1519                                                 *ca = power(p, exp_a - exp_b);
1520                                         if (cb)
1521                                                 *cb = _ex1();
1522                                         return power(p, exp_b);
1523                                 }
1524                         }
1525                 } else {
1526                         if (p.is_equal(b)) {
1527                                 // a = p^n, b = p, gcd = p
1528                                 if (ca)
1529                                         *ca = power(p, a.op(1) - 1);
1530                                 if (cb)
1531                                         *cb = _ex1();
1532                                 return p;
1533                         }
1534                 }
1535         } else if (is_ex_exactly_of_type(b, power)) {
1536                 ex p = b.op(0);
1537                 if (p.is_equal(a)) {
1538                         // a = p, b = p^n, gcd = p
1539                         if (ca)
1540                                 *ca = _ex1();
1541                         if (cb)
1542                                 *cb = power(p, b.op(1) - 1);
1543                         return p;
1544                 }
1545         }
1546 #endif
1547
1548         // Some trivial cases
1549         ex aex = a.expand(), bex = b.expand();
1550         if (aex.is_zero()) {
1551                 if (ca)
1552                         *ca = _ex0();
1553                 if (cb)
1554                         *cb = _ex1();
1555                 return b;
1556         }
1557         if (bex.is_zero()) {
1558                 if (ca)
1559                         *ca = _ex1();
1560                 if (cb)
1561                         *cb = _ex0();
1562                 return a;
1563         }
1564         if (aex.is_equal(_ex1()) || bex.is_equal(_ex1())) {
1565                 if (ca)
1566                         *ca = a;
1567                 if (cb)
1568                         *cb = b;
1569                 return _ex1();
1570         }
1571 #if FAST_COMPARE
1572         if (a.is_equal(b)) {
1573                 if (ca)
1574                         *ca = _ex1();
1575                 if (cb)
1576                         *cb = _ex1();
1577                 return a;
1578         }
1579 #endif
1580
1581         // Gather symbol statistics
1582         sym_desc_vec sym_stats;
1583         get_symbol_stats(a, b, sym_stats);
1584
1585         // The symbol with least degree is our main variable
1586         sym_desc_vec::const_iterator var = sym_stats.begin();
1587         const symbol &x = *(var->sym);
1588
1589         // Cancel trivial common factor
1590         int ldeg_a = var->ldeg_a;
1591         int ldeg_b = var->ldeg_b;
1592         int min_ldeg = std::min(ldeg_a,ldeg_b);
1593         if (min_ldeg > 0) {
1594                 ex common = power(x, min_ldeg);
1595 //std::clog << "trivial common factor " << common << endl;
1596                 return gcd((aex / common).expand(), (bex / common).expand(), ca, cb, false) * common;
1597         }
1598
1599         // Try to eliminate variables
1600         if (var->deg_a == 0) {
1601 //std::clog << "eliminating variable " << x << " from b" << endl;
1602                 ex c = bex.content(x);
1603                 ex g = gcd(aex, c, ca, cb, false);
1604                 if (cb)
1605                         *cb *= bex.unit(x) * bex.primpart(x, c);
1606                 return g;
1607         } else if (var->deg_b == 0) {
1608 //std::clog << "eliminating variable " << x << " from a" << endl;
1609                 ex c = aex.content(x);
1610                 ex g = gcd(c, bex, ca, cb, false);
1611                 if (ca)
1612                         *ca *= aex.unit(x) * aex.primpart(x, c);
1613                 return g;
1614         }
1615
1616         ex g;
1617 #if 1
1618         // Try heuristic algorithm first, fall back to PRS if that failed
1619         try {
1620                 g = heur_gcd(aex, bex, ca, cb, var);
1621         } catch (gcdheu_failed) {
1622                 g = *new ex(fail());
1623         }
1624         if (is_ex_exactly_of_type(g, fail)) {
1625 //std::clog << "heuristics failed" << endl;
1626 #if STATISTICS
1627                 heur_gcd_failed++;
1628 #endif
1629 #endif
1630 //              g = heur_gcd(aex, bex, ca, cb, var);
1631 //              g = eu_gcd(aex, bex, &x);
1632 //              g = euprem_gcd(aex, bex, &x);
1633 //              g = peu_gcd(aex, bex, &x);
1634 //              g = red_gcd(aex, bex, &x);
1635                 g = sr_gcd(aex, bex, var);
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 #if 1
1649         } else {
1650                 if (g.is_equal(_ex1())) {
1651                         // Keep cofactors factored if possible
1652                         if (ca)
1653                                 *ca = a;
1654                         if (cb)
1655                                 *cb = b;
1656                 }
1657         }
1658 #endif
1659         return g;
1660 }
1661
1662
1663 /** Compute LCM (Least Common Multiple) of multivariate polynomials in Z[X].
1664  *
1665  *  @param a  first multivariate polynomial
1666  *  @param b  second multivariate polynomial
1667  *  @param check_args  check whether a and b are polynomials with rational
1668  *         coefficients (defaults to "true")
1669  *  @return the LCM as a new expression */
1670 ex lcm(const ex &a, const ex &b, bool check_args)
1671 {
1672         if (is_ex_exactly_of_type(a, numeric) && is_ex_exactly_of_type(b, numeric))
1673                 return lcm(ex_to_numeric(a), ex_to_numeric(b));
1674         if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
1675                 throw(std::invalid_argument("lcm: arguments must be polynomials over the rationals"));
1676         
1677         ex ca, cb;
1678         ex g = gcd(a, b, &ca, &cb, false);
1679         return ca * cb * g;
1680 }
1681
1682
1683 /*
1684  *  Square-free factorization
1685  */
1686
1687 // Univariate GCD of polynomials in Q[x] (used internally by sqrfree()).
1688 // a and b can be multivariate polynomials but they are treated as univariate polynomials in x.
1689 static ex univariate_gcd(const ex &a, const ex &b, const symbol &x)
1690 {
1691         if (a.is_zero())
1692                 return b;
1693         if (b.is_zero())
1694                 return a;
1695         if (a.is_equal(_ex1()) || b.is_equal(_ex1()))
1696                 return _ex1();
1697         if (is_ex_of_type(a, numeric) && is_ex_of_type(b, numeric))
1698                 return gcd(ex_to_numeric(a), ex_to_numeric(b));
1699         if (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial))
1700                 throw(std::invalid_argument("univariate_gcd: arguments must be polynomials over the rationals"));
1701
1702         // Euclidean algorithm
1703         ex c, d, r;
1704         if (a.degree(x) >= b.degree(x)) {
1705                 c = a;
1706                 d = b;
1707         } else {
1708                 c = b;
1709                 d = a;
1710         }
1711         for (;;) {
1712                 r = rem(c, d, x, false);
1713                 if (r.is_zero())
1714                         break;
1715                 c = d;
1716                 d = r;
1717         }
1718         return d / d.lcoeff(x);
1719 }
1720
1721
1722 /** Compute square-free factorization of multivariate polynomial a(x) using
1723  *  YunĀ“s algorithm.
1724  *
1725  * @param a  multivariate polynomial
1726  * @param x  variable to factor in
1727  * @return factored polynomial */
1728 ex sqrfree(const ex &a, const symbol &x)
1729 {
1730         int i = 1;
1731         ex res = _ex1();
1732         ex b = a.diff(x);
1733         ex c = univariate_gcd(a, b, x);
1734         ex w;
1735         if (c.is_equal(_ex1())) {
1736                 w = a;
1737         } else {
1738                 w = quo(a, c, x);
1739                 ex y = quo(b, c, x);
1740                 ex z = y - w.diff(x);
1741                 while (!z.is_zero()) {
1742                         ex g = univariate_gcd(w, z, x);
1743                         res *= power(g, i);
1744                         w = quo(w, g, x);
1745                         y = quo(z, g, x);
1746                         z = y - w.diff(x);
1747                         i++;
1748                 }
1749         }
1750         return res * power(w, i);
1751 }
1752
1753
1754 /*
1755  *  Normal form of rational functions
1756  */
1757
1758 /*
1759  *  Note: The internal normal() functions (= basic::normal() and overloaded
1760  *  functions) all return lists of the form {numerator, denominator}. This
1761  *  is to get around mul::eval()'s automatic expansion of numeric coefficients.
1762  *  E.g. (a+b)/3 is automatically converted to a/3+b/3 but we want to keep
1763  *  the information that (a+b) is the numerator and 3 is the denominator.
1764  */
1765
1766 /** Create a symbol for replacing the expression "e" (or return a previously
1767  *  assigned symbol). The symbol is appended to sym_lst and returned, the
1768  *  expression is appended to repl_lst.
1769  *  @see ex::normal */
1770 static ex replace_with_symbol(const ex &e, lst &sym_lst, lst &repl_lst)
1771 {
1772         // Expression already in repl_lst? Then return the assigned symbol
1773         for (unsigned i=0; i<repl_lst.nops(); i++)
1774                 if (repl_lst.op(i).is_equal(e))
1775                         return sym_lst.op(i);
1776         
1777         // Otherwise create new symbol and add to list, taking care that the
1778         // replacement expression doesn't contain symbols from the sym_lst
1779         // because subs() is not recursive
1780         symbol s;
1781         ex es(s);
1782         ex e_replaced = e.subs(sym_lst, repl_lst);
1783         sym_lst.append(es);
1784         repl_lst.append(e_replaced);
1785         return es;
1786 }
1787
1788 /** Create a symbol for replacing the expression "e" (or return a previously
1789  *  assigned symbol). An expression of the form "symbol == expression" is added
1790  *  to repl_lst and the symbol is returned.
1791  *  @see ex::to_rational */
1792 static ex replace_with_symbol(const ex &e, lst &repl_lst)
1793 {
1794         // Expression already in repl_lst? Then return the assigned symbol
1795         for (unsigned i=0; i<repl_lst.nops(); i++)
1796                 if (repl_lst.op(i).op(1).is_equal(e))
1797                         return repl_lst.op(i).op(0);
1798         
1799         // Otherwise create new symbol and add to list, taking care that the
1800         // replacement expression doesn't contain symbols from the sym_lst
1801         // because subs() is not recursive
1802         symbol s;
1803         ex es(s);
1804         ex e_replaced = e.subs(repl_lst);
1805         repl_lst.append(es == e_replaced);
1806         return es;
1807 }
1808
1809 /** Default implementation of ex::normal(). It replaces the object with a
1810  *  temporary symbol.
1811  *  @see ex::normal */
1812 ex basic::normal(lst &sym_lst, lst &repl_lst, int level) const
1813 {
1814         return (new lst(replace_with_symbol(*this, sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
1815 }
1816
1817
1818 /** Implementation of ex::normal() for symbols. This returns the unmodified symbol.
1819  *  @see ex::normal */
1820 ex symbol::normal(lst &sym_lst, lst &repl_lst, int level) const
1821 {
1822         return (new lst(*this, _ex1()))->setflag(status_flags::dynallocated);
1823 }
1824
1825
1826 /** Implementation of ex::normal() for a numeric. It splits complex numbers
1827  *  into re+I*im and replaces I and non-rational real numbers with a temporary
1828  *  symbol.
1829  *  @see ex::normal */
1830 ex numeric::normal(lst &sym_lst, lst &repl_lst, int level) const
1831 {
1832         numeric num = numer();
1833         ex numex = num;
1834
1835         if (num.is_real()) {
1836                 if (!num.is_integer())
1837                         numex = replace_with_symbol(numex, sym_lst, repl_lst);
1838         } else { // complex
1839                 numeric re = num.real(), im = num.imag();
1840                 ex re_ex = re.is_rational() ? re : replace_with_symbol(re, sym_lst, repl_lst);
1841                 ex im_ex = im.is_rational() ? im : replace_with_symbol(im, sym_lst, repl_lst);
1842                 numex = re_ex + im_ex * replace_with_symbol(I, sym_lst, repl_lst);
1843         }
1844
1845         // Denominator is always a real integer (see numeric::denom())
1846         return (new lst(numex, denom()))->setflag(status_flags::dynallocated);
1847 }
1848
1849
1850 /** Fraction cancellation.
1851  *  @param n  numerator
1852  *  @param d  denominator
1853  *  @return cancelled fraction {n, d} as a list */
1854 static ex frac_cancel(const ex &n, const ex &d)
1855 {
1856         ex num = n;
1857         ex den = d;
1858         numeric pre_factor = _num1();
1859
1860 //std::clog << "frac_cancel num = " << num << ", den = " << den << endl;
1861
1862         // Handle trivial case where denominator is 1
1863         if (den.is_equal(_ex1()))
1864                 return (new lst(num, den))->setflag(status_flags::dynallocated);
1865
1866         // Handle special cases where numerator or denominator is 0
1867         if (num.is_zero())
1868                 return (new lst(num, _ex1()))->setflag(status_flags::dynallocated);
1869         if (den.expand().is_zero())
1870                 throw(std::overflow_error("frac_cancel: division by zero in frac_cancel"));
1871
1872         // Bring numerator and denominator to Z[X] by multiplying with
1873         // LCM of all coefficients' denominators
1874         numeric num_lcm = lcm_of_coefficients_denominators(num);
1875         numeric den_lcm = lcm_of_coefficients_denominators(den);
1876         num = multiply_lcm(num, num_lcm);
1877         den = multiply_lcm(den, den_lcm);
1878         pre_factor = den_lcm / num_lcm;
1879
1880         // Cancel GCD from numerator and denominator
1881         ex cnum, cden;
1882         if (gcd(num, den, &cnum, &cden, false) != _ex1()) {
1883                 num = cnum;
1884                 den = cden;
1885         }
1886
1887         // Make denominator unit normal (i.e. coefficient of first symbol
1888         // as defined by get_first_symbol() is made positive)
1889         const symbol *x;
1890         if (get_first_symbol(den, x)) {
1891                 GINAC_ASSERT(is_ex_exactly_of_type(den.unit(*x),numeric));
1892                 if (ex_to_numeric(den.unit(*x)).is_negative()) {
1893                         num *= _ex_1();
1894                         den *= _ex_1();
1895                 }
1896         }
1897
1898         // Return result as list
1899 //std::clog << " returns num = " << num << ", den = " << den << ", pre_factor = " << pre_factor << endl;
1900         return (new lst(num * pre_factor.numer(), den * pre_factor.denom()))->setflag(status_flags::dynallocated);
1901 }
1902
1903
1904 /** Implementation of ex::normal() for a sum. It expands terms and performs
1905  *  fractional addition.
1906  *  @see ex::normal */
1907 ex add::normal(lst &sym_lst, lst &repl_lst, int level) const
1908 {
1909         if (level == 1)
1910                 return (new lst(replace_with_symbol(*this, sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
1911         else if (level == -max_recursion_level)
1912                 throw(std::runtime_error("max recursion level reached"));
1913
1914         // Normalize children and split each one into numerator and denominator
1915         exvector nums, dens;
1916         nums.reserve(seq.size()+1);
1917         dens.reserve(seq.size()+1);
1918         epvector::const_iterator it = seq.begin(), itend = seq.end();
1919         while (it != itend) {
1920                 ex n = recombine_pair_to_ex(*it).bp->normal(sym_lst, repl_lst, level-1);
1921                 nums.push_back(n.op(0));
1922                 dens.push_back(n.op(1));
1923                 it++;
1924         }
1925         ex n = overall_coeff.bp->normal(sym_lst, repl_lst, level-1);
1926         nums.push_back(n.op(0));
1927         dens.push_back(n.op(1));
1928         GINAC_ASSERT(nums.size() == dens.size());
1929
1930         // Now, nums is a vector of all numerators and dens is a vector of
1931         // all denominators
1932 //std::clog << "add::normal uses " << nums.size() << " summands:\n";
1933
1934         // Add fractions sequentially
1935         exvector::const_iterator num_it = nums.begin(), num_itend = nums.end();
1936         exvector::const_iterator den_it = dens.begin(), den_itend = dens.end();
1937 //std::clog << " num = " << *num_it << ", den = " << *den_it << endl;
1938         ex num = *num_it++, den = *den_it++;
1939         while (num_it != num_itend) {
1940 //std::clog << " num = " << *num_it << ", den = " << *den_it << endl;
1941                 ex next_num = *num_it++, next_den = *den_it++;
1942
1943                 // Trivially add sequences of fractions with identical denominators
1944                 while ((den_it != den_itend) && next_den.is_equal(*den_it)) {
1945                         next_num += *num_it;
1946                         num_it++; den_it++;
1947                 }
1948
1949                 // Additiion of two fractions, taking advantage of the fact that
1950                 // the heuristic GCD algorithm computes the cofactors at no extra cost
1951                 ex co_den1, co_den2;
1952                 ex g = gcd(den, next_den, &co_den1, &co_den2, false);
1953                 num = ((num * co_den2) + (next_num * co_den1)).expand();
1954                 den *= co_den2;         // this is the lcm(den, next_den)
1955         }
1956 //std::clog << " common denominator = " << den << endl;
1957
1958         // Cancel common factors from num/den
1959         return frac_cancel(num, den);
1960 }
1961
1962
1963 /** Implementation of ex::normal() for a product. It cancels common factors
1964  *  from fractions.
1965  *  @see ex::normal() */
1966 ex mul::normal(lst &sym_lst, lst &repl_lst, int level) const
1967 {
1968         if (level == 1)
1969                 return (new lst(replace_with_symbol(*this, sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
1970         else if (level == -max_recursion_level)
1971                 throw(std::runtime_error("max recursion level reached"));
1972
1973         // Normalize children, separate into numerator and denominator
1974         ex num = _ex1();
1975         ex den = _ex1(); 
1976         ex n;
1977         epvector::const_iterator it = seq.begin(), itend = seq.end();
1978         while (it != itend) {
1979                 n = recombine_pair_to_ex(*it).bp->normal(sym_lst, repl_lst, level-1);
1980                 num *= n.op(0);
1981                 den *= n.op(1);
1982                 it++;
1983         }
1984         n = overall_coeff.bp->normal(sym_lst, repl_lst, level-1);
1985         num *= n.op(0);
1986         den *= n.op(1);
1987
1988         // Perform fraction cancellation
1989         return frac_cancel(num, den);
1990 }
1991
1992
1993 /** Implementation of ex::normal() for powers. It normalizes the basis,
1994  *  distributes integer exponents to numerator and denominator, and replaces
1995  *  non-integer powers by temporary symbols.
1996  *  @see ex::normal */
1997 ex power::normal(lst &sym_lst, lst &repl_lst, int level) const
1998 {
1999         if (level == 1)
2000                 return (new lst(replace_with_symbol(*this, sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
2001         else if (level == -max_recursion_level)
2002                 throw(std::runtime_error("max recursion level reached"));
2003
2004         // Normalize basis and exponent (exponent gets reassembled)
2005         ex n_basis = basis.bp->normal(sym_lst, repl_lst, level-1);
2006         ex n_exponent = exponent.bp->normal(sym_lst, repl_lst, level-1);
2007         n_exponent = n_exponent.op(0) / n_exponent.op(1);
2008
2009         if (n_exponent.info(info_flags::integer)) {
2010
2011                 if (n_exponent.info(info_flags::positive)) {
2012
2013                         // (a/b)^n -> {a^n, b^n}
2014                         return (new lst(power(n_basis.op(0), n_exponent), power(n_basis.op(1), n_exponent)))->setflag(status_flags::dynallocated);
2015
2016                 } else if (n_exponent.info(info_flags::negative)) {
2017
2018                         // (a/b)^-n -> {b^n, a^n}
2019                         return (new lst(power(n_basis.op(1), -n_exponent), power(n_basis.op(0), -n_exponent)))->setflag(status_flags::dynallocated);
2020                 }
2021
2022         } else {
2023
2024                 if (n_exponent.info(info_flags::positive)) {
2025
2026                         // (a/b)^x -> {sym((a/b)^x), 1}
2027                         return (new lst(replace_with_symbol(power(n_basis.op(0) / n_basis.op(1), n_exponent), sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
2028
2029                 } else if (n_exponent.info(info_flags::negative)) {
2030
2031                         if (n_basis.op(1).is_equal(_ex1())) {
2032
2033                                 // a^-x -> {1, sym(a^x)}
2034                                 return (new lst(_ex1(), replace_with_symbol(power(n_basis.op(0), -n_exponent), sym_lst, repl_lst)))->setflag(status_flags::dynallocated);
2035
2036                         } else {
2037
2038                                 // (a/b)^-x -> {sym((b/a)^x), 1}
2039                                 return (new lst(replace_with_symbol(power(n_basis.op(1) / n_basis.op(0), -n_exponent), sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
2040                         }
2041
2042                 } else {        // n_exponent not numeric
2043
2044                         // (a/b)^x -> {sym((a/b)^x, 1}
2045                         return (new lst(replace_with_symbol(power(n_basis.op(0) / n_basis.op(1), n_exponent), sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
2046                 }
2047         }
2048 }
2049
2050
2051 /** Implementation of ex::normal() for pseries. It normalizes each coefficient
2052  *  and replaces the series by a temporary symbol.
2053  *  @see ex::normal */
2054 ex pseries::normal(lst &sym_lst, lst &repl_lst, int level) const
2055 {
2056         epvector newseq;
2057         for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
2058                 ex restexp = i->rest.normal();
2059                 if (!restexp.is_zero())
2060                         newseq.push_back(expair(restexp, i->coeff));
2061         }
2062         ex n = pseries(relational(var,point), newseq);
2063         return (new lst(replace_with_symbol(n, sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
2064 }
2065
2066
2067 /** Implementation of ex::normal() for relationals. It normalizes both sides.
2068  *  @see ex::normal */
2069 ex relational::normal(lst &sym_lst, lst &repl_lst, int level) const
2070 {
2071         return (new lst(relational(lh.normal(), rh.normal(), o), _ex1()))->setflag(status_flags::dynallocated);
2072 }
2073
2074
2075 /** Normalization of rational functions.
2076  *  This function converts an expression to its normal form
2077  *  "numerator/denominator", where numerator and denominator are (relatively
2078  *  prime) polynomials. Any subexpressions which are not rational functions
2079  *  (like non-rational numbers, non-integer powers or functions like sin(),
2080  *  cos() etc.) are replaced by temporary symbols which are re-substituted by
2081  *  the (normalized) subexpressions before normal() returns (this way, any
2082  *  expression can be treated as a rational function). normal() is applied
2083  *  recursively to arguments of functions etc.
2084  *
2085  *  @param level maximum depth of recursion
2086  *  @return normalized expression */
2087 ex ex::normal(int level) const
2088 {
2089         lst sym_lst, repl_lst;
2090
2091         ex e = bp->normal(sym_lst, repl_lst, level);
2092         GINAC_ASSERT(is_ex_of_type(e, lst));
2093
2094         // Re-insert replaced symbols
2095         if (sym_lst.nops() > 0)
2096                 e = e.subs(sym_lst, repl_lst);
2097
2098         // Convert {numerator, denominator} form back to fraction
2099         return e.op(0) / e.op(1);
2100 }
2101
2102 /** Numerator of an expression. If the expression is not of the normal form
2103  *  "numerator/denominator", it is first converted to this form and then the
2104  *  numerator is returned.
2105  *
2106  *  @see ex::normal
2107  *  @return numerator */
2108 ex ex::numer(void) const
2109 {
2110         lst sym_lst, repl_lst;
2111
2112         ex e = bp->normal(sym_lst, repl_lst, 0);
2113         GINAC_ASSERT(is_ex_of_type(e, lst));
2114
2115         // Re-insert replaced symbols
2116         if (sym_lst.nops() > 0)
2117                 return e.op(0).subs(sym_lst, repl_lst);
2118         else
2119                 return e.op(0);
2120 }
2121
2122 /** Denominator of an expression. If the expression is not of the normal form
2123  *  "numerator/denominator", it is first converted to this form and then the
2124  *  denominator is returned.
2125  *
2126  *  @see ex::normal
2127  *  @return denominator */
2128 ex ex::denom(void) const
2129 {
2130         lst sym_lst, repl_lst;
2131
2132         ex e = bp->normal(sym_lst, repl_lst, 0);
2133         GINAC_ASSERT(is_ex_of_type(e, lst));
2134
2135         // Re-insert replaced symbols
2136         if (sym_lst.nops() > 0)
2137                 return e.op(1).subs(sym_lst, repl_lst);
2138         else
2139                 return e.op(1);
2140 }
2141
2142
2143 /** Default implementation of ex::to_rational(). It replaces the object with a
2144  *  temporary symbol.
2145  *  @see ex::to_rational */
2146 ex basic::to_rational(lst &repl_lst) const
2147 {
2148         return replace_with_symbol(*this, repl_lst);
2149 }
2150
2151
2152 /** Implementation of ex::to_rational() for symbols. This returns the
2153  *  unmodified symbol.
2154  *  @see ex::to_rational */
2155 ex symbol::to_rational(lst &repl_lst) const
2156 {
2157         return *this;
2158 }
2159
2160
2161 /** Implementation of ex::to_rational() for a numeric. It splits complex
2162  *  numbers into re+I*im and replaces I and non-rational real numbers with a
2163  *  temporary symbol.
2164  *  @see ex::to_rational */
2165 ex numeric::to_rational(lst &repl_lst) const
2166 {
2167         if (is_real()) {
2168                 if (!is_rational())
2169                         return replace_with_symbol(*this, repl_lst);
2170         } else { // complex
2171                 numeric re = real();
2172                 numeric im = imag();
2173                 ex re_ex = re.is_rational() ? re : replace_with_symbol(re, repl_lst);
2174                 ex im_ex = im.is_rational() ? im : replace_with_symbol(im, repl_lst);
2175                 return re_ex + im_ex * replace_with_symbol(I, repl_lst);
2176         }
2177         return *this;
2178 }
2179
2180
2181 /** Implementation of ex::to_rational() for powers. It replaces non-integer
2182  *  powers by temporary symbols.
2183  *  @see ex::to_rational */
2184 ex power::to_rational(lst &repl_lst) const
2185 {
2186         if (exponent.info(info_flags::integer))
2187                 return power(basis.to_rational(repl_lst), exponent);
2188         else
2189                 return replace_with_symbol(*this, repl_lst);
2190 }
2191
2192
2193 /** Implementation of ex::to_rational() for expairseqs.
2194  *  @see ex::to_rational */
2195 ex expairseq::to_rational(lst &repl_lst) const
2196 {
2197         epvector s;
2198         s.reserve(seq.size());
2199         for (epvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
2200                 s.push_back(split_ex_to_pair(recombine_pair_to_ex(*it).to_rational(repl_lst)));
2201                 // s.push_back(combine_ex_with_coeff_to_pair((*it).rest.to_rational(repl_lst),
2202         }
2203         ex oc = overall_coeff.to_rational(repl_lst);
2204         if (oc.info(info_flags::numeric))
2205                 return thisexpairseq(s, overall_coeff);
2206         else s.push_back(combine_ex_with_coeff_to_pair(oc,_ex1()));
2207         return thisexpairseq(s, default_overall_coeff());
2208 }
2209
2210
2211 /** Rationalization of non-rational functions.
2212  *  This function converts a general expression to a rational polynomial
2213  *  by replacing all non-rational subexpressions (like non-rational numbers,
2214  *  non-integer powers or functions like sin(), cos() etc.) to temporary
2215  *  symbols. This makes it possible to use functions like gcd() and divide()
2216  *  on non-rational functions by applying to_rational() on the arguments,
2217  *  calling the desired function and re-substituting the temporary symbols
2218  *  in the result. To make the last step possible, all temporary symbols and
2219  *  their associated expressions are collected in the list specified by the
2220  *  repl_lst parameter in the form {symbol == expression}, ready to be passed
2221  *  as an argument to ex::subs().
2222  *
2223  *  @param repl_lst collects a list of all temporary symbols and their replacements
2224  *  @return rationalized expression */
2225 ex ex::to_rational(lst &repl_lst) const
2226 {
2227         return bp->to_rational(repl_lst);
2228 }
2229
2230
2231 } // namespace GiNaC