]> www.ginac.de Git - ginac.git/blob - ginac/power.cpp
- matrix row/col made unsigned
[ginac.git] / ginac / power.cpp
1 /** @file power.cpp
2  *
3  *  Implementation of GiNaC's symbolic exponentiation (basis^exponent). */
4
5 /*
6  *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <vector>
24 #include <iostream>
25 #include <stdexcept>
26
27 #include "power.h"
28 #include "expairseq.h"
29 #include "add.h"
30 #include "mul.h"
31 #include "numeric.h"
32 #include "relational.h"
33 #include "symbol.h"
34 #include "debugmsg.h"
35 #include "utils.h"
36
37 #ifndef NO_GINAC_NAMESPACE
38 namespace GiNaC {
39 #endif // ndef NO_GINAC_NAMESPACE
40
41 typedef vector<int> intvector;
42
43 //////////
44 // default constructor, destructor, copy constructor assignment operator and helpers
45 //////////
46
47 // public
48
49 power::power() : basic(TINFO_power)
50 {
51     debugmsg("power default constructor",LOGLEVEL_CONSTRUCT);
52 }
53
54 power::~power()
55 {
56     debugmsg("power destructor",LOGLEVEL_DESTRUCT);
57     destroy(0);
58 }
59
60 power::power(power const & other)
61 {
62     debugmsg("power copy constructor",LOGLEVEL_CONSTRUCT);
63     copy(other);
64 }
65
66 power const & power::operator=(power const & other)
67 {
68     debugmsg("power operator=",LOGLEVEL_ASSIGNMENT);
69     if (this != &other) {
70         destroy(1);
71         copy(other);
72     }
73     return *this;
74 }
75
76 // protected
77
78 void power::copy(power const & other)
79 {
80     basic::copy(other);
81     basis=other.basis;
82     exponent=other.exponent;
83 }
84
85 void power::destroy(bool call_parent)
86 {
87     if (call_parent) basic::destroy(call_parent);
88 }
89
90 //////////
91 // other constructors
92 //////////
93
94 // public
95
96 power::power(ex const & lh, ex const & rh) : basic(TINFO_power), basis(lh), exponent(rh)
97 {
98     debugmsg("power constructor from ex,ex",LOGLEVEL_CONSTRUCT);
99     GINAC_ASSERT(basis.return_type()==return_types::commutative);
100 }
101
102 power::power(ex const & lh, numeric const & rh) : basic(TINFO_power), basis(lh), exponent(rh)
103 {
104     debugmsg("power constructor from ex,numeric",LOGLEVEL_CONSTRUCT);
105     GINAC_ASSERT(basis.return_type()==return_types::commutative);
106 }
107
108 //////////
109 // functions overriding virtual functions from bases classes
110 //////////
111
112 // public
113
114 basic * power::duplicate() const
115 {
116     debugmsg("power duplicate",LOGLEVEL_DUPLICATE);
117     return new power(*this);
118 }
119
120 void power::print(ostream & os, unsigned upper_precedence) const
121 {
122     debugmsg("power print",LOGLEVEL_PRINT);
123     if (exponent.is_equal(_ex1_2())) {
124         os << "sqrt(" << basis << ")";
125     } else {
126         if (precedence<=upper_precedence) os << "(";
127         basis.print(os,precedence);
128         os << "^";
129         exponent.print(os,precedence);
130         if (precedence<=upper_precedence) os << ")";
131     }
132 }
133
134 void power::printraw(ostream & os) const
135 {
136     debugmsg("power printraw",LOGLEVEL_PRINT);
137
138     os << "power(";
139     basis.printraw(os);
140     os << ",";
141     exponent.printraw(os);
142     os << ",hash=" << hashvalue << ",flags=" << flags << ")";
143 }
144
145 void power::printtree(ostream & os, unsigned indent) const
146 {
147     debugmsg("power printtree",LOGLEVEL_PRINT);
148
149     os << string(indent,' ') << "power: "
150        << "hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
151        << ", flags=" << flags << endl;
152     basis.printtree(os,indent+delta_indent);
153     exponent.printtree(os,indent+delta_indent);
154 }
155
156 static void print_sym_pow(ostream & os, unsigned type, const symbol &x, int exp)
157 {
158     // Optimal output of integer powers of symbols to aid compiler CSE
159     if (exp == 1) {
160         x.printcsrc(os, type, 0);
161     } else if (exp == 2) {
162         x.printcsrc(os, type, 0);
163         os << "*";
164         x.printcsrc(os, type, 0);
165     } else if (exp & 1) {
166         x.printcsrc(os, 0);
167         os << "*";
168         print_sym_pow(os, type, x, exp-1);
169     } else {
170         os << "(";
171         print_sym_pow(os, type, x, exp >> 1);
172         os << ")*(";
173         print_sym_pow(os, type, x, exp >> 1);
174         os << ")";
175     }
176 }
177
178 void power::printcsrc(ostream & os, unsigned type, unsigned upper_precedence) const
179 {
180     debugmsg("power print csrc", LOGLEVEL_PRINT);
181     
182     // Integer powers of symbols are printed in a special, optimized way
183     if (exponent.info(info_flags::integer) &&
184         (is_ex_exactly_of_type(basis, symbol) ||
185          is_ex_exactly_of_type(basis, constant))) {
186         int exp = ex_to_numeric(exponent).to_int();
187         if (exp > 0)
188             os << "(";
189         else {
190             exp = -exp;
191             if (type == csrc_types::ctype_cl_N)
192                 os << "recip(";
193             else
194                 os << "1.0/(";
195         }
196         print_sym_pow(os, type, static_cast<const symbol &>(*basis.bp), exp);
197         os << ")";
198
199     // <expr>^-1 is printed as "1.0/<expr>" or with the recip() function of CLN
200     } else if (exponent.compare(_num_1()) == 0) {
201         if (type == csrc_types::ctype_cl_N)
202             os << "recip(";
203         else
204             os << "1.0/(";
205         basis.bp->printcsrc(os, type, 0);
206         os << ")";
207
208     // Otherwise, use the pow() or expt() (CLN) functions
209     } else {
210         if (type == csrc_types::ctype_cl_N)
211             os << "expt(";
212         else
213             os << "pow(";
214         basis.bp->printcsrc(os, type, 0);
215         os << ",";
216         exponent.bp->printcsrc(os, type, 0);
217         os << ")";
218     }
219 }
220
221 bool power::info(unsigned inf) const
222 {
223     if (inf==info_flags::polynomial ||
224         inf==info_flags::integer_polynomial ||
225         inf==info_flags::cinteger_polynomial ||
226         inf==info_flags::rational_polynomial ||
227         inf==info_flags::crational_polynomial) {
228         return exponent.info(info_flags::nonnegint);
229     } else if (inf==info_flags::rational_function) {
230         return exponent.info(info_flags::integer);
231     } else {
232         return basic::info(inf);
233     }
234 }
235
236 int power::nops() const
237 {
238     return 2;
239 }
240
241 ex & power::let_op(int const i)
242 {
243     GINAC_ASSERT(i>=0);
244     GINAC_ASSERT(i<2);
245
246     return i==0 ? basis : exponent;
247 }
248
249 int power::degree(symbol const & s) const
250 {
251     if (is_exactly_of_type(*exponent.bp,numeric)) {
252         if ((*basis.bp).compare(s)==0)
253             return ex_to_numeric(exponent).to_int();
254         else
255             return basis.degree(s) * ex_to_numeric(exponent).to_int();
256     }
257     return 0;
258 }
259
260 int power::ldegree(symbol const & s) const 
261 {
262     if (is_exactly_of_type(*exponent.bp,numeric)) {
263         if ((*basis.bp).compare(s)==0)
264             return ex_to_numeric(exponent).to_int();
265         else
266             return basis.ldegree(s) * ex_to_numeric(exponent).to_int();
267     }
268     return 0;
269 }
270
271 ex power::coeff(symbol const & s, int const n) const
272 {
273     if ((*basis.bp).compare(s)!=0) {
274         // basis not equal to s
275         if (n==0) {
276             return *this;
277         } else {
278             return _ex0();
279         }
280     } else if (is_exactly_of_type(*exponent.bp,numeric)&&
281                (static_cast<numeric const &>(*exponent.bp).compare(numeric(n))==0)) {
282         return _ex1();
283     }
284
285     return _ex0();
286 }
287
288 ex power::eval(int level) const
289 {
290     // simplifications: ^(x,0) -> 1 (0^0 handled here)
291     //                  ^(x,1) -> x
292     //                  ^(0,x) -> 0 (except if x is real and negative, in which case an exception is thrown)
293     //                  ^(1,x) -> 1
294     //                  ^(c1,c2) -> *(c1^n,c1^(c2-n)) (c1, c2 numeric(), 0<(c2-n)<1 except if c1,c2 are rational, but c1^c2 is not)
295     //                  ^(^(x,c1),c2) -> ^(x,c1*c2) (c1, c2 numeric(), c2 integer or -1 < c1 <= 1, case c1=1 should not happen, see below!)
296     //                  ^(*(x,y,z),c1) -> *(x^c1,y^c1,z^c1) (c1 integer)
297     //                  ^(*(x,c1),c2) -> ^(x,c2)*c1^c2 (c1, c2 numeric(), c1>0)
298     //                  ^(*(x,c1),c2) -> ^(-x,c2)*c1^c2 (c1, c2 numeric(), c1<0)
299     
300     debugmsg("power eval",LOGLEVEL_MEMBER_FUNCTION);
301
302     if ((level==1)&&(flags & status_flags::evaluated)) {
303         return *this;
304     } else if (level == -max_recursion_level) {
305         throw(std::runtime_error("max recursion level reached"));
306     }
307     
308     ex const & ebasis    = level==1 ? basis    : basis.eval(level-1);
309     ex const & eexponent = level==1 ? exponent : exponent.eval(level-1);
310
311     bool basis_is_numerical=0;
312     bool exponent_is_numerical=0;
313     numeric * num_basis;
314     numeric * num_exponent;
315
316     if (is_exactly_of_type(*ebasis.bp,numeric)) {
317         basis_is_numerical=1;
318         num_basis=static_cast<numeric *>(ebasis.bp);
319     }
320     if (is_exactly_of_type(*eexponent.bp,numeric)) {
321         exponent_is_numerical=1;
322         num_exponent=static_cast<numeric *>(eexponent.bp);
323     }
324
325     // ^(x,0) -> 1 (0^0 also handled here)
326     if (eexponent.is_zero())
327         return _ex1();
328
329     // ^(x,1) -> x
330     if (eexponent.is_equal(_ex1()))
331         return ebasis;
332
333     // ^(0,x) -> 0 (except if x is real and negative)
334     if (ebasis.is_zero()) {
335         if (exponent_is_numerical && num_exponent->is_negative()) {
336             throw(std::overflow_error("power::eval(): division by zero"));
337         } else
338             return _ex0();
339     }
340
341     // ^(1,x) -> 1
342     if (ebasis.is_equal(_ex1()))
343         return _ex1();
344
345     if (basis_is_numerical && exponent_is_numerical) {
346         // ^(c1,c2) -> c1^c2 (c1, c2 numeric(),
347         // except if c1,c2 are rational, but c1^c2 is not)
348         bool basis_is_crational = num_basis->is_crational();
349         bool exponent_is_crational = num_exponent->is_crational();
350         numeric res = (*num_basis).power(*num_exponent);
351         
352         if ((!basis_is_crational || !exponent_is_crational)
353             || res.is_crational()) {
354             return res;
355         }
356         GINAC_ASSERT(!num_exponent->is_integer());  // has been handled by now
357         // ^(c1,n/m) -> *(c1^q,c1^(n/m-q)), 0<(n/m-h)<1, q integer
358         if (basis_is_crational && exponent_is_crational
359             && num_exponent->is_real()
360             && !num_exponent->is_integer()) {
361             numeric r, q, n, m;
362             n = num_exponent->numer();
363             m = num_exponent->denom();
364             q = iquo(n, m, r);
365             if (r.is_negative()) {
366                 r = r.add(m);
367                 q = q.sub(_num1());
368             }
369             if (q.is_zero())  // the exponent was in the allowed range 0<(n/m)<1
370                 return this->hold();
371             else {
372                 epvector res(2);
373                 res.push_back(expair(ebasis,r.div(m)));
374                 res.push_back(expair(ex(num_basis->power(q)),_ex1()));
375                 return (new mul(res))->setflag(status_flags::dynallocated | status_flags::evaluated);
376                 /*return mul(num_basis->power(q),
377                            power(ex(*num_basis),ex(r.div(m)))).hold();
378                 */
379                 /* return (new mul(num_basis->power(q),
380                    power(*num_basis,r.div(m)).hold()))->setflag(status_flags::dynallocated | status_flags::evaluated);
381                 */
382             }
383         }
384     }
385
386     // ^(^(x,c1),c2) -> ^(x,c1*c2)
387     // (c1, c2 numeric(), c2 integer or -1 < c1 <= 1,
388     // case c1=1 should not happen, see below!)
389     if (exponent_is_numerical && is_ex_exactly_of_type(ebasis,power)) {
390         power const & sub_power=ex_to_power(ebasis);
391         ex const & sub_basis=sub_power.basis;
392         ex const & sub_exponent=sub_power.exponent;
393         if (is_ex_exactly_of_type(sub_exponent,numeric)) {
394             numeric const & num_sub_exponent=ex_to_numeric(sub_exponent);
395             GINAC_ASSERT(num_sub_exponent!=numeric(1));
396             if (num_exponent->is_integer() || abs(num_sub_exponent)<1) {
397                 return power(sub_basis,num_sub_exponent.mul(*num_exponent));
398             }
399         }
400     }
401     
402     // ^(*(x,y,z),c1) -> *(x^c1,y^c1,z^c1) (c1 integer)
403     if (exponent_is_numerical && num_exponent->is_integer() &&
404         is_ex_exactly_of_type(ebasis,mul)) {
405         return expand_mul(ex_to_mul(ebasis), *num_exponent);
406     }
407
408     // ^(*(...,x;c1),c2) -> ^(*(...,x;1),c2)*c1^c2 (c1, c2 numeric(), c1>0)
409     // ^(*(...,x,c1),c2) -> ^(*(...,x;-1),c2)*(-c1)^c2 (c1, c2 numeric(), c1<0)
410     if (exponent_is_numerical && is_ex_exactly_of_type(ebasis,mul)) {
411         GINAC_ASSERT(!num_exponent->is_integer()); // should have been handled above
412         mul const & mulref=ex_to_mul(ebasis);
413         if (!mulref.overall_coeff.is_equal(_ex1())) {
414             numeric const & num_coeff=ex_to_numeric(mulref.overall_coeff);
415             if (num_coeff.is_real()) {
416                 if (num_coeff.is_positive()>0) {
417                     mul * mulp=new mul(mulref);
418                     mulp->overall_coeff=_ex1();
419                     mulp->clearflag(status_flags::evaluated);
420                     mulp->clearflag(status_flags::hash_calculated);
421                     return (new mul(power(*mulp,exponent),
422                                     power(num_coeff,*num_exponent)))->
423                         setflag(status_flags::dynallocated);
424                 } else {
425                     GINAC_ASSERT(num_coeff.compare(_num0())<0);
426                     if (num_coeff.compare(_num_1())!=0) {
427                         mul * mulp=new mul(mulref);
428                         mulp->overall_coeff=_ex_1();
429                         mulp->clearflag(status_flags::evaluated);
430                         mulp->clearflag(status_flags::hash_calculated);
431                         return (new mul(power(*mulp,exponent),
432                                         power(abs(num_coeff),*num_exponent)))->
433                             setflag(status_flags::dynallocated);
434                     }
435                 }
436             }
437         }
438     }
439         
440     if (are_ex_trivially_equal(ebasis,basis) &&
441         are_ex_trivially_equal(eexponent,exponent)) {
442         return this->hold();
443     }
444     return (new power(ebasis, eexponent))->setflag(status_flags::dynallocated |
445                                                    status_flags::evaluated);
446 }
447
448 ex power::evalf(int level) const
449 {
450     debugmsg("power evalf",LOGLEVEL_MEMBER_FUNCTION);
451
452     ex ebasis;
453     ex eexponent;
454     
455     if (level==1) {
456         ebasis=basis;
457         eexponent=exponent;
458     } else if (level == -max_recursion_level) {
459         throw(std::runtime_error("max recursion level reached"));
460     } else {
461         ebasis=basis.evalf(level-1);
462         eexponent=exponent.evalf(level-1);
463     }
464
465     return power(ebasis,eexponent);
466 }
467
468 ex power::subs(lst const & ls, lst const & lr) const
469 {
470     ex const & subsed_basis=basis.subs(ls,lr);
471     ex const & subsed_exponent=exponent.subs(ls,lr);
472
473     if (are_ex_trivially_equal(basis,subsed_basis)&&
474         are_ex_trivially_equal(exponent,subsed_exponent)) {
475         return *this;
476     }
477     
478     return power(subsed_basis, subsed_exponent);
479 }
480
481 ex power::simplify_ncmul(exvector const & v) const
482 {
483     return basic::simplify_ncmul(v);
484 }
485
486 // protected
487
488 int power::compare_same_type(basic const & other) const
489 {
490     GINAC_ASSERT(is_exactly_of_type(other, power));
491     power const & o=static_cast<power const &>(const_cast<basic &>(other));
492
493     int cmpval;
494     cmpval=basis.compare(o.basis);
495     if (cmpval==0) {
496         return exponent.compare(o.exponent);
497     }
498     return cmpval;
499 }
500
501 unsigned power::return_type(void) const
502 {
503     return basis.return_type();
504 }
505    
506 unsigned power::return_type_tinfo(void) const
507 {
508     return basis.return_type_tinfo();
509 }
510
511 ex power::expand(unsigned options) const
512 {
513     ex expanded_basis=basis.expand(options);
514
515     if (!is_ex_exactly_of_type(exponent,numeric)||
516         !ex_to_numeric(exponent).is_integer()) {
517         if (are_ex_trivially_equal(basis,expanded_basis)) {
518             return this->hold();
519         } else {
520             return (new power(expanded_basis,exponent))->
521                     setflag(status_flags::dynallocated);
522         }
523     }
524
525     // integer numeric exponent
526     numeric const & num_exponent=ex_to_numeric(exponent);
527     int int_exponent = num_exponent.to_int();
528
529     if (int_exponent > 0 && is_ex_exactly_of_type(expanded_basis,add)) {
530         return expand_add(ex_to_add(expanded_basis), int_exponent);
531     }
532
533     if (is_ex_exactly_of_type(expanded_basis,mul)) {
534         return expand_mul(ex_to_mul(expanded_basis), num_exponent);
535     }
536
537     // cannot expand further
538     if (are_ex_trivially_equal(basis,expanded_basis)) {
539         return this->hold();
540     } else {
541         return (new power(expanded_basis,exponent))->
542                setflag(status_flags::dynallocated);
543     }
544 }
545
546 //////////
547 // new virtual functions which can be overridden by derived classes
548 //////////
549
550 // none
551
552 //////////
553 // non-virtual functions in this class
554 //////////
555
556 ex power::expand_add(add const & a, int const n) const
557 {
558     // expand a^n where a is an add and n is an integer
559
560     if (n==2) {
561         return expand_add_2(a);
562     }
563     
564     int m=a.nops();
565     exvector sum;
566     sum.reserve((n+1)*(m-1));
567     intvector k(m-1);
568     intvector k_cum(m-1); // k_cum[l]:=sum(i=0,l,k[l]);
569     intvector upper_limit(m-1);
570     int l;
571     
572     for (int l=0; l<m-1; l++) {
573         k[l]=0;
574         k_cum[l]=0;
575         upper_limit[l]=n;
576     }
577
578     while (1) {
579         exvector term;
580         term.reserve(m+1);
581         for (l=0; l<m-1; l++) {
582             ex const & b=a.op(l);
583             GINAC_ASSERT(!is_ex_exactly_of_type(b,add));
584             GINAC_ASSERT(!is_ex_exactly_of_type(b,power)||
585                    !is_ex_exactly_of_type(ex_to_power(b).exponent,numeric)||
586                    !ex_to_numeric(ex_to_power(b).exponent).is_pos_integer());
587             if (is_ex_exactly_of_type(b,mul)) {
588                 term.push_back(expand_mul(ex_to_mul(b),numeric(k[l])));
589             } else {
590                 term.push_back(power(b,k[l]));
591             }
592         }
593
594         ex const & b=a.op(l);
595         GINAC_ASSERT(!is_ex_exactly_of_type(b,add));
596         GINAC_ASSERT(!is_ex_exactly_of_type(b,power)||
597                !is_ex_exactly_of_type(ex_to_power(b).exponent,numeric)||
598                !ex_to_numeric(ex_to_power(b).exponent).is_pos_integer());
599         if (is_ex_exactly_of_type(b,mul)) {
600             term.push_back(expand_mul(ex_to_mul(b),numeric(n-k_cum[m-2])));
601         } else {
602             term.push_back(power(b,n-k_cum[m-2]));
603         }
604
605         numeric f=binomial(numeric(n),numeric(k[0]));
606         for (l=1; l<m-1; l++) {
607             f=f*binomial(numeric(n-k_cum[l-1]),numeric(k[l]));
608         }
609         term.push_back(f);
610
611         /*
612         cout << "begin term" << endl;
613         for (int i=0; i<m-1; i++) {
614             cout << "k[" << i << "]=" << k[i] << endl;
615             cout << "k_cum[" << i << "]=" << k_cum[i] << endl;
616             cout << "upper_limit[" << i << "]=" << upper_limit[i] << endl;
617         }
618         for (exvector::const_iterator cit=term.begin(); cit!=term.end(); ++cit) {
619             cout << *cit << endl;
620         }
621         cout << "end term" << endl;
622         */
623
624         // TODO: optimize this
625         sum.push_back((new mul(term))->setflag(status_flags::dynallocated));
626         
627         // increment k[]
628         l=m-2;
629         while ((l>=0)&&((++k[l])>upper_limit[l])) {
630             k[l]=0;    
631             l--;
632         }
633         if (l<0) break;
634
635         // recalc k_cum[] and upper_limit[]
636         if (l==0) {
637             k_cum[0]=k[0];
638         } else {
639             k_cum[l]=k_cum[l-1]+k[l];
640         }
641         for (int i=l+1; i<m-1; i++) {
642             k_cum[i]=k_cum[i-1]+k[i];
643         }
644
645         for (int i=l+1; i<m-1; i++) {
646             upper_limit[i]=n-k_cum[i-1];
647         }   
648     }
649     return (new add(sum))->setflag(status_flags::dynallocated);
650 }
651
652 ex power::expand_add_2(add const & a) const
653 {
654     // special case: expand a^2 where a is an add
655
656     epvector sum;
657     unsigned a_nops=a.nops();
658     sum.reserve((a_nops*(a_nops+1))/2);
659     epvector::const_iterator last=a.seq.end();
660
661     // power(+(x,...,z;c),2)=power(+(x,...,z;0),2)+2*c*+(x,...,z;0)+c*c
662     // first part: ignore overall_coeff and expand other terms
663     for (epvector::const_iterator cit0=a.seq.begin(); cit0!=last; ++cit0) {
664         ex const & r=(*cit0).rest;
665         ex const & c=(*cit0).coeff;
666         
667         GINAC_ASSERT(!is_ex_exactly_of_type(r,add));
668         GINAC_ASSERT(!is_ex_exactly_of_type(r,power)||
669                !is_ex_exactly_of_type(ex_to_power(r).exponent,numeric)||
670                !ex_to_numeric(ex_to_power(r).exponent).is_pos_integer()||
671                !is_ex_exactly_of_type(ex_to_power(r).basis,add)||
672                !is_ex_exactly_of_type(ex_to_power(r).basis,mul)||
673                !is_ex_exactly_of_type(ex_to_power(r).basis,power));
674
675         if (are_ex_trivially_equal(c,_ex1())) {
676             if (is_ex_exactly_of_type(r,mul)) {
677                 sum.push_back(expair(expand_mul(ex_to_mul(r),_num2()),_ex1()));
678             } else {
679                 sum.push_back(expair((new power(r,_ex2()))->setflag(status_flags::dynallocated),
680                                      _ex1()));
681             }
682         } else {
683             if (is_ex_exactly_of_type(r,mul)) {
684                 sum.push_back(expair(expand_mul(ex_to_mul(r),_num2()),
685                                      ex_to_numeric(c).power_dyn(_num2())));
686             } else {
687                 sum.push_back(expair((new power(r,_ex2()))->setflag(status_flags::dynallocated),
688                                      ex_to_numeric(c).power_dyn(_num2())));
689             }
690         }
691             
692         for (epvector::const_iterator cit1=cit0+1; cit1!=last; ++cit1) {
693             ex const & r1=(*cit1).rest;
694             ex const & c1=(*cit1).coeff;
695             sum.push_back(a.combine_ex_with_coeff_to_pair((new mul(r,r1))->setflag(status_flags::dynallocated),
696                                                           _num2().mul(ex_to_numeric(c)).mul_dyn(ex_to_numeric(c1))));
697         }
698     }
699
700     GINAC_ASSERT(sum.size()==(a.seq.size()*(a.seq.size()+1))/2);
701
702     // second part: add terms coming from overall_factor (if != 0)
703     if (!a.overall_coeff.is_equal(_ex0())) {
704         for (epvector::const_iterator cit=a.seq.begin(); cit!=a.seq.end(); ++cit) {
705             sum.push_back(a.combine_pair_with_coeff_to_pair(*cit,ex_to_numeric(a.overall_coeff).mul_dyn(_num2())));
706         }
707         sum.push_back(expair(ex_to_numeric(a.overall_coeff).power_dyn(_num2()),_ex1()));
708     }
709         
710     GINAC_ASSERT(sum.size()==(a_nops*(a_nops+1))/2);
711     
712     return (new add(sum))->setflag(status_flags::dynallocated);
713 }
714
715 ex power::expand_mul(mul const & m, numeric const & n) const
716 {
717     // expand m^n where m is a mul and n is and integer
718
719     if (n.is_equal(_num0())) {
720         return _ex1();
721     }
722     
723     epvector distrseq;
724     distrseq.reserve(m.seq.size());
725     epvector::const_iterator last=m.seq.end();
726     epvector::const_iterator cit=m.seq.begin();
727     while (cit!=last) {
728         if (is_ex_exactly_of_type((*cit).rest,numeric)) {
729             distrseq.push_back(m.combine_pair_with_coeff_to_pair(*cit,n));
730         } else {
731             // it is safe not to call mul::combine_pair_with_coeff_to_pair()
732             // since n is an integer
733             distrseq.push_back(expair((*cit).rest,
734                                       ex_to_numeric((*cit).coeff).mul(n)));
735         }
736         ++cit;
737     }
738     return (new mul(distrseq,ex_to_numeric(m.overall_coeff).power_dyn(n)))
739                  ->setflag(status_flags::dynallocated);
740 }
741
742 /*
743 ex power::expand_commutative_3(ex const & basis, numeric const & exponent,
744                              unsigned options) const
745 {
746     // obsolete
747
748     exvector distrseq;
749     epvector splitseq;
750
751     add const & addref=static_cast<add const &>(*basis.bp);
752
753     splitseq=addref.seq;
754     splitseq.pop_back();
755     ex first_operands=add(splitseq);
756     ex last_operand=addref.recombine_pair_to_ex(*(addref.seq.end()-1));
757     
758     int n=exponent.to_int();
759     for (int k=0; k<=n; k++) {
760         distrseq.push_back(binomial(n,k)*power(first_operands,numeric(k))*
761                            power(last_operand,numeric(n-k)));
762     }
763     return ex((new add(distrseq))->setflag(status_flags::sub_expanded |
764                                            status_flags::expanded |
765                                            status_flags::dynallocated  )).
766            expand(options);
767 }
768 */
769
770 /*
771 ex power::expand_noncommutative(ex const & basis, numeric const & exponent,
772                                 unsigned options) const
773 {
774     ex rest_power=ex(power(basis,exponent.add(_num_1()))).
775                   expand(options | expand_options::internal_do_not_expand_power_operands);
776
777     return ex(mul(rest_power,basis),0).
778            expand(options | expand_options::internal_do_not_expand_mul_operands);
779 }
780 */
781
782 //////////
783 // static member variables
784 //////////
785
786 // protected
787
788 unsigned power::precedence=60;
789
790 //////////
791 // global constants
792 //////////
793
794 const power some_power;
795 type_info const & typeid_power=typeid(some_power);
796
797 // helper function
798
799 ex sqrt(ex const & a)
800 {
801     return power(a,_ex1_2());
802 }
803
804 #ifndef NO_GINAC_NAMESPACE
805 } // namespace GiNaC
806 #endif // ndef NO_GINAC_NAMESPACE