ex add::expand(unsigned options) const
{
+ if (flags & status_flags::expanded)
+ return *this;
+
epvector * vp = expandchildren(options);
if (vp==0) {
return *this;
}
- return (new add(vp,overall_coeff))->setflag(status_flags::expanded |
- status_flags::dynallocated );
+ return (new add(vp,overall_coeff))->
+ setflag(status_flags::expanded |
+ status_flags::dynallocated);
}
//////////
ex ex::expand(unsigned options) const
{
GINAC_ASSERT(bp!=0);
- return bp->expand(options);
+ if (bp->flags & status_flags::expanded)
+ return *bp;
+ else
+ return bp->expand(options);
}
bool ex::has(const ex & other) const
ex expairseq::expand(unsigned options) const
{
- epvector * vp=expandchildren(options);
+ epvector * vp = expandchildren(options);
if (vp==0) {
return *this;
}
else
det += m[Pkey[r]*this->col+c]*A[Mkey];
}
- // prevent build-up of deep nesting of expressions saves some time:
+ // prevent build-up of deep nesting of expressions saves time:
det = det.expand();
// store the new determinant at its place in B:
B.insert(Rmap_value(Pkey,det));
int mul::degree(const symbol & s) const
{
- int deg_sum=0;
+ int deg_sum = 0;
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
deg_sum+=(*cit).rest.degree(s) * ex_to_numeric((*cit).coeff).to_int();
}
int mul::ldegree(const symbol & s) const
{
- int deg_sum=0;
+ int deg_sum = 0;
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
deg_sum+=(*cit).rest.ldegree(s) * ex_to_numeric((*cit).coeff).to_int();
}
return (new add(distrseq,
ex_to_numeric(addref.overall_coeff).
mul_dyn(ex_to_numeric(overall_coeff))))
- ->setflag(status_flags::dynallocated |
+ ->setflag(status_flags::dynallocated |
status_flags::evaluated );
}
return this->hold();
// D(a*b*c)=D(a)*b*c+a*D(b)*c+a*b*D(c)
for (unsigned i=0; i!=seq.size(); i++) {
- epvector sub_seq=seq;
+ epvector sub_seq = seq;
sub_seq[i] = split_ex_to_pair(sub_seq[i].coeff*
power(sub_seq[i].rest,sub_seq[i].coeff-1)*
sub_seq[i].rest.diff(s));
return return_types::commutative;
}
- bool all_commutative=1;
+ bool all_commutative = 1;
unsigned rt;
epvector::const_iterator cit_noncommutative_element; // point to first found nc element
if (rt==return_types::noncommutative_composite) return rt; // one ncc -> mul also ncc
if ((rt==return_types::noncommutative)&&(all_commutative)) {
// first nc element found, remember position
- cit_noncommutative_element=cit;
- all_commutative=0;
+ cit_noncommutative_element = cit;
+ all_commutative = 0;
}
if ((rt==return_types::noncommutative)&&(!all_commutative)) {
// another nc element found, compare type_infos
ex mul::expand(unsigned options) const
{
+ if (flags & status_flags::expanded)
+ return *this;
+
exvector sub_expanded_seq;
intvector positions_of_adds;
intvector number_of_add_operands;
-
+
epvector * expanded_seqp = expandchildren(options);
-
+
const epvector & expanded_seq = expanded_seqp==0 ? seq : *expanded_seqp;
-
+
positions_of_adds.resize(expanded_seq.size());
number_of_add_operands.resize(expanded_seq.size());
-
+
int number_of_adds = 0;
int number_of_expanded_terms = 1;
-
+
unsigned current_position = 0;
epvector::const_iterator last = expanded_seq.end();
for (epvector::const_iterator cit=expanded_seq.begin(); cit!=last; ++cit) {
}
current_position++;
}
-
+
if (number_of_adds==0) {
if (expanded_seqp==0) {
return this->setflag(status_flags::expanded);
}
return (new mul(expanded_seqp,overall_coeff))->
- setflag(status_flags::dynallocated ||
- status_flags::expanded);
+ setflag(status_flags::dynallocated |
+ status_flags::expanded);
}
-
+
exvector distrseq;
distrseq.reserve(number_of_expanded_terms);
-
+
intvector k;
k.resize(number_of_adds);
for (l=0; l<number_of_adds; l++) {
k[l]=0;
}
-
+
while (1) {
epvector term;
- term=expanded_seq;
+ term = expanded_seq;
for (l=0; l<number_of_adds; l++) {
const add & addref=ex_to_add(expanded_seq[positions_of_adds[l]].rest);
GINAC_ASSERT(term[positions_of_adds[l]].coeff.compare(_ex1())==0);
term[positions_of_adds[l]]=split_ex_to_pair(addref.op(k[l]));
}
- /*
- cout << "mul::expand() term begin" << endl;
- for (epvector::const_iterator cit=term.begin(); cit!=term.end(); ++cit) {
- cout << "rest" << endl;
- (*cit).rest.printtree(cout);
- cout << "coeff" << endl;
- (*cit).coeff.printtree(cout);
- }
- cout << "mul::expand() term end" << endl;
- */
distrseq.push_back((new mul(term,overall_coeff))->
- setflag(status_flags::dynallocated |
- status_flags::expanded));
-
+ setflag(status_flags::dynallocated |
+ status_flags::expanded));
+
// increment k[]
l=number_of_adds-1;
- while ((l>=0)&&((++k[l])>=number_of_add_operands[l])) {
+ while ((l>=0) && ((++k[l])>=number_of_add_operands[l])) {
k[l]=0;
l--;
}
if (l<0) break;
}
-
- if (expanded_seqp!=0) {
+
+ if (expanded_seqp!=0)
delete expanded_seqp;
- }
- /*
- cout << "mul::expand() distrseq begin" << endl;
- for (exvector::const_iterator cit=distrseq.begin(); cit!=distrseq.end(); ++cit) {
- (*cit).printtree(cout);
- }
- cout << "mul::expand() distrseq end" << endl;
- */
-
+
return (new add(distrseq))->setflag(status_flags::dynallocated |
status_flags::expanded);
}
const ex & factor = recombine_pair_to_ex(*cit);
const ex & expanded_factor = factor.expand(options);
if (!are_ex_trivially_equal(factor,expanded_factor)) {
-
+
// something changed, copy seq, eval and return it
epvector *s=new epvector;
s->reserve(seq.size());
-
+
// copy parts of seq which are known not to have changed
epvector::const_iterator cit2 = seq.begin();
while (cit2!=cit) {
{
debugmsg("numeric default constructor", LOGLEVEL_CONSTRUCT);
value = new cl_N;
- *value=cl_I(0);
+ *value = cl_I(0);
calchash();
- setflag(status_flags::evaluated|
+ setflag(status_flags::evaluated |
+ status_flags::expanded |
status_flags::hash_calculated);
}
debugmsg("power eval",LOGLEVEL_MEMBER_FUNCTION);
- if ((level==1)&&(flags & status_flags::evaluated)) {
+ if ((level==1) && (flags & status_flags::evaluated))
return *this;
- } else if (level == -max_recursion_level) {
+ else if (level == -max_recursion_level)
throw(std::runtime_error("max recursion level reached"));
- }
const ex & ebasis = level==1 ? basis : basis.eval(level-1);
const ex & eexponent = level==1 ? exponent : exponent.eval(level-1);
ex power::expand(unsigned options) const
{
+ if (flags & status_flags::expanded)
+ return *this;
+
ex expanded_basis = basis.expand(options);
- if (!is_ex_exactly_of_type(exponent,numeric)||
+ if (!is_ex_exactly_of_type(exponent,numeric) ||
!ex_to_numeric(exponent).is_integer()) {
if (are_ex_trivially_equal(basis,expanded_basis)) {
return this->hold();
} else {
return (new power(expanded_basis,exponent))->
- setflag(status_flags::dynallocated);
+ setflag(status_flags::dynallocated |
+ status_flags::expanded);
}
}
// integer numeric exponent
- const numeric & num_exponent=ex_to_numeric(exponent);
+ const numeric & num_exponent = ex_to_numeric(exponent);
int int_exponent = num_exponent.to_int();
if (int_exponent > 0 && is_ex_exactly_of_type(expanded_basis,add)) {
return this->hold();
} else {
return (new power(expanded_basis,exponent))->
- setflag(status_flags::dynallocated);
+ setflag(status_flags::dynallocated |
+ status_flags::expanded);
}
}
int l;
for (int l=0; l<m-1; l++) {
- k[l]=0;
- k_cum[l]=0;
- upper_limit[l]=n;
+ k[l] = 0;
+ k_cum[l] = 0;
+ upper_limit[l] = n;
}
while (1) {
exvector term;
term.reserve(m+1);
for (l=0; l<m-1; l++) {
- const ex & b=a.op(l);
+ const ex & b = a.op(l);
GINAC_ASSERT(!is_ex_exactly_of_type(b,add));
GINAC_ASSERT(!is_ex_exactly_of_type(b,power)||
- !is_ex_exactly_of_type(ex_to_power(b).exponent,numeric)||
- !ex_to_numeric(ex_to_power(b).exponent).is_pos_integer());
+ !is_ex_exactly_of_type(ex_to_power(b).exponent,numeric)||
+ !ex_to_numeric(ex_to_power(b).exponent).is_pos_integer());
if (is_ex_exactly_of_type(b,mul)) {
term.push_back(expand_mul(ex_to_mul(b),numeric(k[l])));
} else {
}
}
- const ex & b=a.op(l);
+ const ex & b = a.op(l);
GINAC_ASSERT(!is_ex_exactly_of_type(b,add));
GINAC_ASSERT(!is_ex_exactly_of_type(b,power)||
- !is_ex_exactly_of_type(ex_to_power(b).exponent,numeric)||
- !ex_to_numeric(ex_to_power(b).exponent).is_pos_integer());
+ !is_ex_exactly_of_type(ex_to_power(b).exponent,numeric)||
+ !ex_to_numeric(ex_to_power(b).exponent).is_pos_integer());
if (is_ex_exactly_of_type(b,mul)) {
term.push_back(expand_mul(ex_to_mul(b),numeric(n-k_cum[m-2])));
} else {
term.push_back(power(b,n-k_cum[m-2]));
}
- numeric f=binomial(numeric(n),numeric(k[0]));
+ numeric f = binomial(numeric(n),numeric(k[0]));
for (l=1; l<m-1; l++) {
f=f*binomial(numeric(n-k_cum[l-1]),numeric(k[l]));
}
upper_limit[i]=n-k_cum[i-1];
}
}
- return (new add(sum))->setflag(status_flags::dynallocated);
+ return (new add(sum))->setflag(status_flags::dynallocated |
+ status_flags::expanded );
}
-/** Special case of power::expand. Expands a^2 where a is an add.
+/** Special case of power::expand_add. Expands a^2 where a is an add.
* @see power::expand_add */
ex power::expand_add_2(const add & a) const
{
GINAC_ASSERT(sum.size()==(a_nops*(a_nops+1))/2);
- return (new add(sum))->setflag(status_flags::dynallocated);
+ return (new add(sum))->setflag(status_flags::dynallocated |
+ status_flags::expanded );
}
-/** Expand m^n where m is a mul and n is and integer
+/** Expand factors of m in m^n where m is a mul and n is and integer
* @see power::expand */
ex power::expand_mul(const mul & m, const numeric & n) const
{
epvector distrseq;
distrseq.reserve(m.seq.size());
- epvector::const_iterator last=m.seq.end();
- epvector::const_iterator cit=m.seq.begin();
+ epvector::const_iterator last = m.seq.end();
+ epvector::const_iterator cit = m.seq.begin();
while (cit!=last) {
if (is_ex_exactly_of_type((*cit).rest,numeric)) {
distrseq.push_back(m.combine_pair_with_coeff_to_pair(*cit,n));
++cit;
}
return (new mul(distrseq,ex_to_numeric(m.overall_coeff).power_dyn(n)))
- ->setflag(status_flags::dynallocated);
+ ->setflag(status_flags::dynallocated);
}
/*
distrseq.push_back(binomial(n,k)*power(first_operands,numeric(k))*
power(last_operand,numeric(n-k)));
}
- return ex((new add(distrseq))->setflag(status_flags::sub_expanded |
- status_flags::expanded |
- status_flags::dynallocated )).
+ return ex((new add(distrseq))->setflag(status_flags::expanded |
+ status_flags::dynallocated )).
expand(options);
}
*/
symbol::symbol() : inherited(TINFO_symbol)
{
debugmsg("symbol default constructor", LOGLEVEL_CONSTRUCT);
- serial=next_serial++;
- name=autoname_prefix()+ToString(serial);
- asexinfop=new assigned_ex_info;
+ serial = next_serial++;
+ name = autoname_prefix()+ToString(serial);
+ asexinfop = new assigned_ex_info;
setflag(status_flags::evaluated);
}
void symbol::copy(const symbol & other)
{
inherited::copy(other);
- name=other.name;
- serial=other.serial;
- asexinfop=other.asexinfop;
+ name = other.name;
+ serial = other.serial;
+ asexinfop = other.asexinfop;
++asexinfop->refcount;
}
symbol::symbol(const string & initname) : inherited(TINFO_symbol)
{
debugmsg("symbol constructor from string", LOGLEVEL_CONSTRUCT);
- name=initname;
- serial=next_serial++;
- asexinfop=new assigned_ex_info;
+ name = initname;
+ serial = next_serial++;
+ asexinfop = new assigned_ex_info;
setflag(status_flags::evaluated);
}