if (num_exponent->is_pos_integer() &&
ebasis.return_type() != return_types::commutative &&
!is_a<matrix>(ebasis)) {
- return ncmul(exvector(num_exponent->to_int(), ebasis), true);
+ return ncmul(exvector(num_exponent->to_int(), ebasis));
}
}
newseq.reserve(2);
newseq.push_back(expair(basis, exponent - _ex1));
newseq.push_back(expair(basis.diff(s), _ex1));
- return mul(newseq, exponent);
+ return mul(std::move(newseq), exponent);
} else {
// D(b^e) = b^e * (D(e)*ln(b) + e*D(b)/b)
return mul(*this,
// In either case we set a flag to avoid the second run on a part
// which does not have positive/negative terms.
if (prodseq.size() > 0) {
- ex newbasis = coeff*mul(powseq);
+ ex newbasis = coeff*mul(std::move(powseq));
ex_to<basic>(newbasis).setflag(status_flags::purely_indefinite);
- return ((new mul(prodseq))->setflag(status_flags::dynallocated)*(new power(newbasis, exponent))->setflag(status_flags::dynallocated).expand(options)).expand(options);
+ return ((new mul(std::move(prodseq)))->setflag(status_flags::dynallocated)*(new power(newbasis, exponent))->setflag(status_flags::dynallocated).expand(options)).expand(options);
} else
ex_to<basic>(basis).setflag(status_flags::purely_indefinite);
}
// Make sure that e.g. (x+y)^(2+a) expands the (x+y)^2 factor
if (ex_to<numeric>(a.overall_coeff).is_integer()) {
const numeric &num_exponent = ex_to<numeric>(a.overall_coeff);
- int int_exponent = num_exponent.to_int();
+ long int_exponent = num_exponent.to_int();
if (int_exponent > 0 && is_exactly_a<add>(expanded_basis))
distrseq.push_back(expand_add(ex_to<add>(expanded_basis), int_exponent, options));
else
// integer numeric exponent
const numeric & num_exponent = ex_to<numeric>(expanded_exponent);
- int int_exponent = num_exponent.to_int();
+ long int_exponent = num_exponent.to_long();
// (x+y)^n, n>0
if (int_exponent > 0 && is_exactly_a<add>(expanded_basis))
* where n = p1+p2+...+pk, i.e. p is a partition of n.
*/
const numeric
-multinomial_coefficient(const std::vector<int> p)
+multinomial_coefficient(const std::vector<int> & p)
{
numeric n = 0, d = 1;
for (auto & it : p) {
/** expand a^n where a is an add and n is a positive integer.
* @see power::expand */
-ex power::expand_add(const add & a, int n, unsigned options) const
+ex power::expand_add(const add & a, long n, unsigned options) const
{
// The special case power(+(x,...y;x),2) can be optimized better.
if (n==2)
// i.e. the number of unordered arrangements of m nonnegative integers
// which sum up to n. It is frequently written as C_n(m) and directly
// related with binomial coefficients: binomial(n+m-1,m-1).
- size_t result_size = binomial(numeric(n+a.nops()-1), numeric(a.nops()-1)).to_int();
+ size_t result_size = binomial(numeric(n+a.nops()-1), numeric(a.nops()-1)).to_long();
if (!a.overall_coeff.is_zero()) {
// the result's overall_coeff is one of the terms
--result_size;
GINAC_ASSERT(result.size() == result_size);
if (a.overall_coeff.is_zero()) {
- return (new add(result))->setflag(status_flags::dynallocated |
- status_flags::expanded);
+ return (new add(std::move(result)))->setflag(status_flags::dynallocated |
+ status_flags::expanded);
} else {
- return (new add(result, ex_to<numeric>(a.overall_coeff).power(n)))->setflag(status_flags::dynallocated |
- status_flags::expanded);
+ return (new add(std::move(result), ex_to<numeric>(a.overall_coeff).power(n)))->setflag(status_flags::dynallocated |
+ status_flags::expanded);
}
}
* @see power::expand_add */
ex power::expand_add_2(const add & a, unsigned options) const
{
- epvector sum;
- size_t a_nops = a.nops();
- sum.reserve((a_nops*(a_nops+1))/2);
+ epvector result;
+ size_t result_size = (a.nops() * (a.nops()+1)) / 2;
+ if (!a.overall_coeff.is_zero()) {
+ // the result's overall_coeff is one of the terms
+ --result_size;
+ }
+ result.reserve(result_size);
+
epvector::const_iterator last = a.seq.end();
// power(+(x,...,z;c),2)=power(+(x,...,z;0),2)+2*c*+(x,...,z;0)+c*c
if (c.is_equal(_ex1)) {
if (is_exactly_a<mul>(r)) {
- sum.push_back(a.combine_ex_with_coeff_to_pair(expand_mul(ex_to<mul>(r), *_num2_p, options, true),
- _ex1));
+ result.push_back(a.combine_ex_with_coeff_to_pair(expand_mul(ex_to<mul>(r), *_num2_p, options, true),
+ _ex1));
} else {
- sum.push_back(a.combine_ex_with_coeff_to_pair((new power(r,_ex2))->setflag(status_flags::dynallocated),
- _ex1));
+ result.push_back(a.combine_ex_with_coeff_to_pair((new power(r,_ex2))->setflag(status_flags::dynallocated),
+ _ex1));
}
} else {
if (is_exactly_a<mul>(r)) {
- sum.push_back(a.combine_ex_with_coeff_to_pair(expand_mul(ex_to<mul>(r), *_num2_p, options, true),
- ex_to<numeric>(c).power_dyn(*_num2_p)));
+ result.push_back(a.combine_ex_with_coeff_to_pair(expand_mul(ex_to<mul>(r), *_num2_p, options, true),
+ ex_to<numeric>(c).power_dyn(*_num2_p)));
} else {
- sum.push_back(a.combine_ex_with_coeff_to_pair((new power(r,_ex2))->setflag(status_flags::dynallocated),
- ex_to<numeric>(c).power_dyn(*_num2_p)));
+ result.push_back(a.combine_ex_with_coeff_to_pair((new power(r,_ex2))->setflag(status_flags::dynallocated),
+ ex_to<numeric>(c).power_dyn(*_num2_p)));
}
}
for (epvector::const_iterator cit1=cit0+1; cit1!=last; ++cit1) {
const ex & r1 = cit1->rest;
const ex & c1 = cit1->coeff;
- sum.push_back(a.combine_ex_with_coeff_to_pair(mul(r,r1).expand(options),
- _num2_p->mul(ex_to<numeric>(c)).mul_dyn(ex_to<numeric>(c1))));
+ result.push_back(a.combine_ex_with_coeff_to_pair(mul(r,r1).expand(options),
+ _num2_p->mul(ex_to<numeric>(c)).mul_dyn(ex_to<numeric>(c1))));
}
}
- GINAC_ASSERT(sum.size()==(a.seq.size()*(a.seq.size()+1))/2);
-
// second part: add terms coming from overall_coeff (if != 0)
if (!a.overall_coeff.is_zero()) {
- epvector::const_iterator i = a.seq.begin(), end = a.seq.end();
- while (i != end) {
- sum.push_back(a.combine_pair_with_coeff_to_pair(*i, ex_to<numeric>(a.overall_coeff).mul_dyn(*_num2_p)));
- ++i;
- }
- sum.push_back(expair(ex_to<numeric>(a.overall_coeff).power_dyn(*_num2_p),_ex1));
+ for (auto & i : a.seq)
+ result.push_back(a.combine_pair_with_coeff_to_pair(i, ex_to<numeric>(a.overall_coeff).mul_dyn(*_num2_p)));
+ }
+
+ GINAC_ASSERT(result.size() == result_size);
+
+ if (a.overall_coeff.is_zero()) {
+ return (new add(std::move(result)))->setflag(status_flags::dynallocated |
+ status_flags::expanded);
+ } else {
+ return (new add(std::move(result), ex_to<numeric>(a.overall_coeff).power(2)))->setflag(status_flags::dynallocated |
+ status_flags::expanded);
}
-
- GINAC_ASSERT(sum.size()==(a_nops*(a_nops+1))/2);
-
- return (new add(sum))->setflag(status_flags::dynallocated | status_flags::expanded);
}
/** Expand factors of m in m^n where m is a mul and n is an integer.