* Implementation of GiNaC's symbolic exponentiation (basis^exponent). */
/*
- * GiNaC Copyright (C) 1999-2017 Johannes Gutenberg University Mainz, Germany
+ * GiNaC Copyright (C) 1999-2020 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
// basis == a+I*b, exponent == c+I*d
const ex a = basis.real_part();
const ex c = exponent.real_part();
- if (basis.is_equal(a) && exponent.is_equal(c)) {
+ if (basis.is_equal(a) && exponent.is_equal(c) &&
+ (a.info(info_flags::nonnegative) || c.info(info_flags::integer))) {
// Re(a^c)
return *this;
}
// basis == a+I*b, exponent == c+I*d
const ex a = basis.real_part();
const ex c = exponent.real_part();
- if (basis.is_equal(a) && exponent.is_equal(c)) {
+ if (basis.is_equal(a) && exponent.is_equal(c) &&
+ (a.info(info_flags::nonnegative) || c.info(info_flags::integer))) {
// Im(a^c)
return 0;
}
ex coeff=(possign? _ex1 : _ex_1);
if (m.overall_coeff.info(info_flags::positive) && m.overall_coeff != _ex1)
prodseq.push_back(pow(m.overall_coeff, exponent));
- else if (m.overall_coeff.info(info_flags::negative) && m.overall_coeff != _ex_1)
+ else if (m.overall_coeff.info(info_flags::negative) && m.overall_coeff != _ex_1) {
prodseq.push_back(pow(-m.overall_coeff, exponent));
- else
+ coeff = -coeff;
+ } else
coeff *= m.overall_coeff;
// If positive/negative factors are found, then extract them.
// Multinomial expansion of power(+(x,...,z;0),k)*c^(n-k):
// Iterate over all partitions of k with exactly as many parts as
// there are symbolic terms in the basis (including zero parts).
- partition_generator partitions(k, a.seq.size());
+ partition_with_zero_parts_generator partitions(k, a.seq.size());
do {
- const std::vector<int>& partition = partitions.current();
+ const std::vector<unsigned>& partition = partitions.get();
// All monomials of this partition have the same number of terms and the same coefficient.
const unsigned msize = std::count_if(partition.begin(), partition.end(), [](int i) { return i > 0; });
const numeric coeff = multinomial_coefficient(partition) * binomial_coefficient;
// Iterate over all compositions of the current partition.
composition_generator compositions(partition);
do {
- const std::vector<int>& exponent = compositions.current();
+ const std::vector<unsigned>& exponent = compositions.get();
epvector monomial;
monomial.reserve(msize);
numeric factor = coeff;
// optimize away
} else if (exponent[i] == 1) {
// optimized
- monomial.push_back(expair(r, _ex1));
+ monomial.emplace_back(expair(r, _ex1));
if (c != *_num1_p)
factor = factor.mul(c);
} else { // general case exponent[i] > 1
- monomial.push_back(expair(r, exponent[i]));
+ monomial.emplace_back(expair(r, exponent[i]));
if (c != *_num1_p)
factor = factor.mul(c.power(exponent[i]));
}
}
- result.push_back(expair(mul(std::move(monomial)).expand(options), factor));
+ result.emplace_back(expair(mul(std::move(monomial)).expand(options), factor));
} while (compositions.next());
} while (partitions.next());
}
if (c.is_equal(_ex1)) {
if (is_exactly_a<mul>(r)) {
- result.push_back(expair(expand_mul(ex_to<mul>(r), *_num2_p, options, true),
- _ex1));
+ result.emplace_back(expair(expand_mul(ex_to<mul>(r), *_num2_p, options, true),
+ _ex1));
} else {
- result.push_back(expair(dynallocate<power>(r, _ex2),
- _ex1));
+ result.emplace_back(expair(dynallocate<power>(r, _ex2),
+ _ex1));
}
} else {
if (is_exactly_a<mul>(r)) {
- result.push_back(expair(expand_mul(ex_to<mul>(r), *_num2_p, options, true),
- ex_to<numeric>(c).power_dyn(*_num2_p)));
+ result.emplace_back(expair(expand_mul(ex_to<mul>(r), *_num2_p, options, true),
+ ex_to<numeric>(c).power_dyn(*_num2_p)));
} else {
- result.push_back(expair(dynallocate<power>(r, _ex2),
- ex_to<numeric>(c).power_dyn(*_num2_p)));
+ result.emplace_back(expair(dynallocate<power>(r, _ex2),
+ ex_to<numeric>(c).power_dyn(*_num2_p)));
}
}
for (auto cit1=cit0+1; cit1!=last; ++cit1) {
const ex & r1 = cit1->rest;
const ex & c1 = cit1->coeff;
- result.push_back(expair(mul(r,r1).expand(options),
- _num2_p->mul(ex_to<numeric>(c)).mul_dyn(ex_to<numeric>(c1))));
+ result.emplace_back(expair(mul(r,r1).expand(options),
+ _num2_p->mul(ex_to<numeric>(c)).mul_dyn(ex_to<numeric>(c1))));
}
}