X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fpower.cpp;h=f5ab330d450f0c76ac2207ef0a047b7f1b6a39bb;hp=c6bf7b9770d2fa939eb242fef780f6aa84286dc5;hb=cca88b51436e4b654d16a4d60cd0d1c66fcf5dd6;hpb=5f896fa7f59bbce727e4bba23df9c4bbdbb55c29 diff --git a/ginac/power.cpp b/ginac/power.cpp index c6bf7b97..f5ab330d 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -3,7 +3,7 @@ * Implementation of GiNaC's symbolic exponentiation (basis^exponent). */ /* - * GiNaC Copyright (C) 1999-2010 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2014 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -242,6 +242,8 @@ bool power::info(unsigned inf) const return (flags & status_flags::expanded); case info_flags::positive: return basis.info(info_flags::positive) && exponent.info(info_flags::real); + case info_flags::nonnegative: + return basis.info(info_flags::real) && exponent.info(info_flags::integer) && exponent.info(info_flags::even); case info_flags::has_indices: { if (flags & status_flags::has_indices) return true; @@ -287,11 +289,16 @@ ex power::map(map_function & f) const bool power::is_polynomial(const ex & var) const { - if (exponent.has(var)) - return false; - if (!exponent.info(info_flags::nonnegint)) - return false; - return basis.is_polynomial(var); + if (basis.is_polynomial(var)) { + if (basis.has(var)) + // basis is non-constant polynomial in var + return exponent.info(info_flags::nonnegint); + else + // basis is constant in var + return !exponent.has(var); + } + // basis is a non-polynomial function of var + return false; } int power::degree(const ex & s) const @@ -362,7 +369,7 @@ ex power::coeff(const ex & s, int n) const * - ^(1,x) -> 1 * - ^(c1,c2) -> *(c1^n,c1^(c2-n)) (so that 0<(c2-n)<1, try to evaluate roots, possibly in numerator and denominator of c1) * - ^(^(x,c1),c2) -> ^(x,c1*c2) if x is positive and c1 is real. - * - ^(^(x,c1),c2) -> ^(x,c1*c2) (c2 integer or -1 < c1 <= 1, case c1=1 should not happen, see below!) + * - ^(^(x,c1),c2) -> ^(x,c1*c2) (c2 integer or -1 < c1 <= 1 or (c1=-1 and c2>0), case c1=1 should not happen, see below!) * - ^(*(x,y,z),c) -> *(x^c,y^c,z^c) (if c integer) * - ^(*(x,c1),c2) -> ^(x,c2)*c1^c2 (c1>0) * - ^(*(x,c1),c2) -> ^(-x,c2)*c1^c2 (c1<0) @@ -480,7 +487,7 @@ ex power::eval(int level) const } // ^(^(x,c1),c2) -> ^(x,c1*c2) - // (c1, c2 numeric(), c2 integer or -1 < c1 <= 1, + // (c1, c2 numeric(), c2 integer or -1 < c1 <= 1 or (c1=-1 and c2>0), // case c1==1 should not happen, see below!) if (is_exactly_a(ebasis)) { const power & sub_power = ex_to(ebasis); @@ -489,7 +496,8 @@ ex power::eval(int level) const if (is_exactly_a(sub_exponent)) { const numeric & num_sub_exponent = ex_to(sub_exponent); GINAC_ASSERT(num_sub_exponent!=numeric(1)); - if (num_exponent->is_integer() || (abs(num_sub_exponent) - (*_num1_p)).is_negative()) { + if (num_exponent->is_integer() || (abs(num_sub_exponent) - (*_num1_p)).is_negative() + || (num_sub_exponent == *_num_1_p && num_exponent->is_positive())) { return power(sub_basis,num_sub_exponent.mul(*num_exponent)); } } @@ -735,8 +743,7 @@ ex power::imag_part() const ex b=basis.imag_part(); ex c=exponent.real_part(); ex d=exponent.imag_part(); - return - power(abs(basis),c)*exp(-d*atan2(b,a))*sin(c*atan2(b,a)+d*log(abs(basis))); + return power(abs(basis),c)*exp(-d*atan2(b,a))*sin(c*atan2(b,a)+d*log(abs(basis))); } // protected