From: Vladimir V. Kisil Date: Sun, 11 Oct 2020 16:33:32 +0000 (+0200) Subject: [PATCH 1/3] Automatic evaluation of (e^t)^s = e^(ts). X-Git-Tag: release_1-8-0~8 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=88cb1bc239cf2e52038a5111ba39117ce23093bb [PATCH 1/3] Automatic evaluation of (e^t)^s = e^(ts). If it safe to evaluate (e^t)^s = e^(ts) at least in two cases: a) t and s are reals, the respective formula can be found in any analysis textbook. b) if s is an integer, then the ambiguity of t up to the term 2*Pi*k does not cause a different value. Signed-off-by: Vladimir V. Kisil --- diff --git a/check/exam_misc.cpp b/check/exam_misc.cpp index 93b6f8e7..8c28fb53 100644 --- a/check/exam_misc.cpp +++ b/check/exam_misc.cpp @@ -255,6 +255,29 @@ static unsigned exam_subs_algebraic() return result; } +/* Test suitable cases of the exponent power law: (e^t)^s=e^(ts). */ +static unsigned exam_exponent_power_law() +{ + unsigned result = 0; + symbol x("x"); + realsymbol s("s"); + possymbol t("t"); + + exmap pwr_exp = + { {pow(exp(x), 2), exp(2*x)}, + {pow(exp(s), t), exp(s*t)}, + {exp(x)*pow(exp(x),-1), 1} }; + + for (auto e : pwr_exp) { + if (! (e.first.is_equal(e.second)) ) { + clog << "power of exponent " << e.first << " produces error.\n"; + ++result; + } + } + + return result; +} + unsigned exam_misc() { unsigned result = 0; @@ -268,6 +291,7 @@ unsigned exam_misc() result += exam_subs(); cout << '.' << flush; result += exam_joris(); cout << '.' << flush; result += exam_subs_algebraic(); cout << '.' << flush; + result += exam_exponent_power_law(); cout << '.' << flush; return result; } diff --git a/ginac/inifcns_trans.cpp b/ginac/inifcns_trans.cpp index 49e30047..f6550f6d 100644 --- a/ginac/inifcns_trans.cpp +++ b/ginac/inifcns_trans.cpp @@ -128,6 +128,24 @@ static ex exp_conjugate(const ex & x) return exp(x.conjugate()); } +static ex exp_power(const ex & x, const ex & a) +{ + /* + * The power law (e^x)^a=e^(x*a) is used in two cases: + * a) a is an integer and x may be complex; + * b) both x and a are reals. + * Negative a is excluded to keep automatic simplifications like exp(x)/exp(x)=1. + */ + if (a.info(info_flags::nonnegative) + && (a.info(info_flags::integer) || (x.info(info_flags::real) && a.info(info_flags::real)))) + return exp(x*a); + else if (a.info(info_flags::negative) + && (a.info(info_flags::integer) || (x.info(info_flags::real) && a.info(info_flags::real)))) + return power(exp(-x*a), _ex_1).hold(); + + return power(exp(x), a).hold(); +} + REGISTER_FUNCTION(exp, eval_func(exp_eval). evalf_func(exp_evalf). expand_func(exp_expand). @@ -135,6 +153,7 @@ REGISTER_FUNCTION(exp, eval_func(exp_eval). real_part_func(exp_real_part). imag_part_func(exp_imag_part). conjugate_func(exp_conjugate). + power_func(exp_power). latex_name("\\exp")); //////////