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;
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;
}
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).
real_part_func(exp_real_part).
imag_part_func(exp_imag_part).
conjugate_func(exp_conjugate).
+ power_func(exp_power).
latex_name("\\exp"));
//////////