+ex power::evalm() const
+{
+ const ex ebasis = basis.evalm();
+ const ex eexponent = exponent.evalm();
+ if (is_a<matrix>(ebasis)) {
+ if (is_exactly_a<numeric>(eexponent)) {
+ return (new matrix(ex_to<matrix>(ebasis).pow(eexponent)))->setflag(status_flags::dynallocated);
+ }
+ }
+ return (new power(ebasis, eexponent))->setflag(status_flags::dynallocated);
+}
+
+bool power::has(const ex & other, unsigned options) const
+{
+ if (!(options & has_options::algebraic))
+ return basic::has(other, options);
+ if (!is_a<power>(other))
+ return basic::has(other, options);
+ if (!exponent.info(info_flags::integer)
+ || !other.op(1).info(info_flags::integer))
+ return basic::has(other, options);
+ if (exponent.info(info_flags::posint)
+ && other.op(1).info(info_flags::posint)
+ && ex_to<numeric>(exponent).to_int()
+ > ex_to<numeric>(other.op(1)).to_int()
+ && basis.match(other.op(0)))
+ return true;
+ if (exponent.info(info_flags::negint)
+ && other.op(1).info(info_flags::negint)
+ && ex_to<numeric>(exponent).to_int()
+ < ex_to<numeric>(other.op(1)).to_int()
+ && basis.match(other.op(0)))
+ return true;
+ return basic::has(other, options);
+}
+
+// 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