+// from mul.cpp
+extern bool tryfactsubs(const ex &, const ex &, int &, lst &);
+
+ex power::subs(const exmap & m, unsigned options) const
+{
+ const ex &subsed_basis = basis.subs(m, options);
+ const ex &subsed_exponent = exponent.subs(m, options);
+
+ if (!are_ex_trivially_equal(basis, subsed_basis)
+ || !are_ex_trivially_equal(exponent, subsed_exponent))
+ return power(subsed_basis, subsed_exponent).subs_one_level(m, options);
+
+ if (!(options & subs_options::algebraic))
+ return subs_one_level(m, options);
+
+ for (exmap::const_iterator it = m.begin(); it != m.end(); ++it) {
+ int nummatches = std::numeric_limits<int>::max();
+ lst repls;
+ if (tryfactsubs(*this, it->first, nummatches, repls))
+ return (ex_to<basic>((*this) * power(it->second.subs(ex(repls), subs_options::no_pattern) / it->first.subs(ex(repls), subs_options::no_pattern), nummatches))).subs_one_level(m, options);
+ }
+
+ return subs_one_level(m, options);
+}
+
+ex power::eval_ncmul(const exvector & v) const
+{
+ return inherited::eval_ncmul(v);
+}
+
+ex power::conjugate() const
+{
+ ex newbasis = basis.conjugate();
+ ex newexponent = exponent.conjugate();
+ if (are_ex_trivially_equal(basis, newbasis) && are_ex_trivially_equal(exponent, newexponent)) {
+ return *this;
+ }
+ return (new power(newbasis, newexponent))->setflag(status_flags::dynallocated);
+}
+
+ex power::real_part() const
+{
+ if (exponent.info(info_flags::integer)) {
+ ex basis_real = basis.real_part();
+ if (basis_real == basis)
+ return *this;
+ realsymbol a("a"),b("b");
+ ex result;
+ if (exponent.info(info_flags::posint))
+ result = power(a+I*b,exponent);
+ else
+ result = power(a/(a*a+b*b)-I*b/(a*a+b*b),-exponent);
+ result = result.expand();
+ result = result.real_part();
+ result = result.subs(lst( a==basis_real, b==basis.imag_part() ));
+ return result;
+ }
+
+ ex a = basis.real_part();
+ 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))*cos(c*atan2(b,a)+d*log(abs(basis)));