| 26 |
#include "add.h" |
#include "add.h" |
| 27 |
#include "mul.h" |
#include "mul.h" |
| 28 |
#include "debugmsg.h" |
#include "debugmsg.h" |
| 29 |
|
#include "utils.h" |
| 30 |
|
|
| 31 |
#ifndef NO_GINAC_NAMESPACE |
#ifndef NO_GINAC_NAMESPACE |
| 32 |
namespace GiNaC { |
namespace GiNaC { |
| 88 |
{ |
{ |
| 89 |
debugmsg("add constructor from ex,ex",LOGLEVEL_CONSTRUCT); |
debugmsg("add constructor from ex,ex",LOGLEVEL_CONSTRUCT); |
| 90 |
tinfo_key = TINFO_add; |
tinfo_key = TINFO_add; |
| 91 |
overall_coeff=exZERO(); |
overall_coeff=_ex0(); |
| 92 |
construct_from_2_ex(lh,rh); |
construct_from_2_ex(lh,rh); |
| 93 |
GINAC_ASSERT(is_canonical()); |
GINAC_ASSERT(is_canonical()); |
| 94 |
} |
} |
| 97 |
{ |
{ |
| 98 |
debugmsg("add constructor from exvector",LOGLEVEL_CONSTRUCT); |
debugmsg("add constructor from exvector",LOGLEVEL_CONSTRUCT); |
| 99 |
tinfo_key = TINFO_add; |
tinfo_key = TINFO_add; |
| 100 |
overall_coeff=exZERO(); |
overall_coeff=_ex0(); |
| 101 |
construct_from_exvector(v); |
construct_from_exvector(v); |
| 102 |
GINAC_ASSERT(is_canonical()); |
GINAC_ASSERT(is_canonical()); |
| 103 |
} |
} |
| 123 |
{ |
{ |
| 124 |
debugmsg("add constructor from epvector",LOGLEVEL_CONSTRUCT); |
debugmsg("add constructor from epvector",LOGLEVEL_CONSTRUCT); |
| 125 |
tinfo_key = TINFO_add; |
tinfo_key = TINFO_add; |
| 126 |
overall_coeff=exZERO(); |
overall_coeff=_ex0(); |
| 127 |
construct_from_epvector(v); |
construct_from_epvector(v); |
| 128 |
GINAC_ASSERT(is_canonical()); |
GINAC_ASSERT(is_canonical()); |
| 129 |
} |
} |
| 174 |
if (coeff.csgn()==-1) os << '-'; |
if (coeff.csgn()==-1) os << '-'; |
| 175 |
first=false; |
first=false; |
| 176 |
} |
} |
| 177 |
if (!coeff.is_equal(numONE()) && |
if (!coeff.is_equal(_num1()) && |
| 178 |
!coeff.is_equal(numMINUSONE())) { |
!coeff.is_equal(_num_1())) { |
| 179 |
if (coeff.csgn()==-1) |
if (coeff.csgn()==-1) |
| 180 |
(numMINUSONE()*coeff).print(os, precedence); |
(_num_1()*coeff).print(os, precedence); |
| 181 |
else |
else |
| 182 |
coeff.print(os, precedence); |
coeff.print(os, precedence); |
| 183 |
os << '*'; |
os << '*'; |
| 220 |
while (it != itend) { |
while (it != itend) { |
| 221 |
|
|
| 222 |
// If the coefficient is -1, it is replaced by a single minus sign |
// If the coefficient is -1, it is replaced by a single minus sign |
| 223 |
if (it->coeff.compare(numONE()) == 0) { |
if (it->coeff.compare(_num1()) == 0) { |
| 224 |
it->rest.bp->printcsrc(os, type, precedence); |
it->rest.bp->printcsrc(os, type, precedence); |
| 225 |
} else if (it->coeff.compare(numMINUSONE()) == 0) { |
} else if (it->coeff.compare(_num_1()) == 0) { |
| 226 |
os << "-"; |
os << "-"; |
| 227 |
it->rest.bp->printcsrc(os, type, precedence); |
it->rest.bp->printcsrc(os, type, precedence); |
| 228 |
} else if (ex_to_numeric(it->coeff).numer().compare(numONE()) == 0) { |
} else if (ex_to_numeric(it->coeff).numer().compare(_num1()) == 0) { |
| 229 |
it->rest.bp->printcsrc(os, type, precedence); |
it->rest.bp->printcsrc(os, type, precedence); |
| 230 |
os << "/"; |
os << "/"; |
| 231 |
ex_to_numeric(it->coeff).denom().printcsrc(os, type, precedence); |
ex_to_numeric(it->coeff).denom().printcsrc(os, type, precedence); |
| 232 |
} else if (ex_to_numeric(it->coeff).numer().compare(numMINUSONE()) == 0) { |
} else if (ex_to_numeric(it->coeff).numer().compare(_num_1()) == 0) { |
| 233 |
os << "-"; |
os << "-"; |
| 234 |
it->rest.bp->printcsrc(os, type, precedence); |
it->rest.bp->printcsrc(os, type, precedence); |
| 235 |
os << "/"; |
os << "/"; |
| 242 |
|
|
| 243 |
// Separator is "+", except if the following expression would have a leading minus sign |
// Separator is "+", except if the following expression would have a leading minus sign |
| 244 |
it++; |
it++; |
| 245 |
if (it != itend && !(it->coeff.compare(numZERO()) < 0 || (it->coeff.compare(numONE()) == 0 && is_ex_exactly_of_type(it->rest, numeric) && it->rest.compare(numZERO()) < 0))) |
if (it != itend && !(it->coeff.compare(_num0()) < 0 || (it->coeff.compare(_num1()) == 0 && is_ex_exactly_of_type(it->rest, numeric) && it->rest.compare(_num0()) < 0))) |
| 246 |
os << "+"; |
os << "+"; |
| 247 |
} |
} |
| 248 |
|
|
| 249 |
if (!overall_coeff.is_equal(exZERO())) { |
if (!overall_coeff.is_equal(_ex0())) { |
| 250 |
if (overall_coeff.info(info_flags::positive)) os << '+'; |
if (overall_coeff.info(info_flags::positive)) os << '+'; |
| 251 |
overall_coeff.bp->printcsrc(os,type,precedence); |
overall_coeff.bp->printcsrc(os,type,precedence); |
| 252 |
} |
} |
| 277 |
int add::degree(symbol const & s) const |
int add::degree(symbol const & s) const |
| 278 |
{ |
{ |
| 279 |
int deg=INT_MIN; |
int deg=INT_MIN; |
| 280 |
if (!overall_coeff.is_equal(exZERO())) { |
if (!overall_coeff.is_equal(_ex0())) { |
| 281 |
deg=0; |
deg=0; |
| 282 |
} |
} |
| 283 |
int cur_deg; |
int cur_deg; |
| 291 |
int add::ldegree(symbol const & s) const |
int add::ldegree(symbol const & s) const |
| 292 |
{ |
{ |
| 293 |
int deg=INT_MAX; |
int deg=INT_MAX; |
| 294 |
if (!overall_coeff.is_equal(exZERO())) { |
if (!overall_coeff.is_equal(_ex0())) { |
| 295 |
deg=0; |
deg=0; |
| 296 |
} |
} |
| 297 |
int cur_deg; |
int cur_deg; |
| 345 |
|
|
| 346 |
if (flags & status_flags::evaluated) { |
if (flags & status_flags::evaluated) { |
| 347 |
GINAC_ASSERT(seq.size()>0); |
GINAC_ASSERT(seq.size()>0); |
| 348 |
GINAC_ASSERT((seq.size()>1)||!overall_coeff.is_equal(exZERO())); |
GINAC_ASSERT((seq.size()>1)||!overall_coeff.is_equal(_ex0())); |
| 349 |
return *this; |
return *this; |
| 350 |
} |
} |
| 351 |
|
|
| 353 |
if (seq_size==0) { |
if (seq_size==0) { |
| 354 |
// +(;c) -> c |
// +(;c) -> c |
| 355 |
return overall_coeff; |
return overall_coeff; |
| 356 |
} else if ((seq_size==1)&&overall_coeff.is_equal(exZERO())) { |
} else if ((seq_size==1)&&overall_coeff.is_equal(_ex0())) { |
| 357 |
// +(x;0) -> x |
// +(x;0) -> x |
| 358 |
return recombine_pair_to_ex(*(seq.begin())); |
return recombine_pair_to_ex(*(seq.begin())); |
| 359 |
} |
} |
| 424 |
ex numfactor=mulref.overall_coeff; |
ex numfactor=mulref.overall_coeff; |
| 425 |
// mul * mulcopyp=static_cast<mul *>(mulref.duplicate()); |
// mul * mulcopyp=static_cast<mul *>(mulref.duplicate()); |
| 426 |
mul * mulcopyp=new mul(mulref); |
mul * mulcopyp=new mul(mulref); |
| 427 |
mulcopyp->overall_coeff=exONE(); |
mulcopyp->overall_coeff=_ex1(); |
| 428 |
mulcopyp->clearflag(status_flags::evaluated); |
mulcopyp->clearflag(status_flags::evaluated); |
| 429 |
mulcopyp->clearflag(status_flags::hash_calculated); |
mulcopyp->clearflag(status_flags::hash_calculated); |
| 430 |
return expair(mulcopyp->setflag(status_flags::dynallocated),numfactor); |
return expair(mulcopyp->setflag(status_flags::dynallocated),numfactor); |
| 431 |
} |
} |
| 432 |
return expair(e,exONE()); |
return expair(e,_ex1()); |
| 433 |
} |
} |
| 434 |
|
|
| 435 |
expair add::combine_ex_with_coeff_to_pair(ex const & e, |
expair add::combine_ex_with_coeff_to_pair(ex const & e, |
| 441 |
ex numfactor=mulref.overall_coeff; |
ex numfactor=mulref.overall_coeff; |
| 442 |
//mul * mulcopyp=static_cast<mul *>(mulref.duplicate()); |
//mul * mulcopyp=static_cast<mul *>(mulref.duplicate()); |
| 443 |
mul * mulcopyp=new mul(mulref); |
mul * mulcopyp=new mul(mulref); |
| 444 |
mulcopyp->overall_coeff=exONE(); |
mulcopyp->overall_coeff=_ex1(); |
| 445 |
mulcopyp->clearflag(status_flags::evaluated); |
mulcopyp->clearflag(status_flags::evaluated); |
| 446 |
mulcopyp->clearflag(status_flags::hash_calculated); |
mulcopyp->clearflag(status_flags::hash_calculated); |
| 447 |
if (are_ex_trivially_equal(c,exONE())) { |
if (are_ex_trivially_equal(c,_ex1())) { |
| 448 |
return expair(mulcopyp->setflag(status_flags::dynallocated),numfactor); |
return expair(mulcopyp->setflag(status_flags::dynallocated),numfactor); |
| 449 |
} else if (are_ex_trivially_equal(numfactor,exONE())) { |
} else if (are_ex_trivially_equal(numfactor,_ex1())) { |
| 450 |
return expair(mulcopyp->setflag(status_flags::dynallocated),c); |
return expair(mulcopyp->setflag(status_flags::dynallocated),c); |
| 451 |
} |
} |
| 452 |
return expair(mulcopyp->setflag(status_flags::dynallocated), |
return expair(mulcopyp->setflag(status_flags::dynallocated), |
| 453 |
ex_to_numeric(numfactor).mul_dyn(ex_to_numeric(c))); |
ex_to_numeric(numfactor).mul_dyn(ex_to_numeric(c))); |
| 454 |
} else if (is_ex_exactly_of_type(e,numeric)) { |
} else if (is_ex_exactly_of_type(e,numeric)) { |
| 455 |
if (are_ex_trivially_equal(c,exONE())) { |
if (are_ex_trivially_equal(c,_ex1())) { |
| 456 |
return expair(e,exONE()); |
return expair(e,_ex1()); |
| 457 |
} |
} |
| 458 |
return expair(ex_to_numeric(e).mul_dyn(ex_to_numeric(c)),exONE()); |
return expair(ex_to_numeric(e).mul_dyn(ex_to_numeric(c)),_ex1()); |
| 459 |
} |
} |
| 460 |
return expair(e,c); |
return expair(e,c); |
| 461 |
} |
} |
| 467 |
GINAC_ASSERT(is_ex_exactly_of_type(c,numeric)); |
GINAC_ASSERT(is_ex_exactly_of_type(c,numeric)); |
| 468 |
|
|
| 469 |
if (is_ex_exactly_of_type(p.rest,numeric)) { |
if (is_ex_exactly_of_type(p.rest,numeric)) { |
| 470 |
GINAC_ASSERT(ex_to_numeric(p.coeff).is_equal(numONE())); // should be normalized |
GINAC_ASSERT(ex_to_numeric(p.coeff).is_equal(_num1())); // should be normalized |
| 471 |
return expair(ex_to_numeric(p.rest).mul_dyn(ex_to_numeric(c)),exONE()); |
return expair(ex_to_numeric(p.rest).mul_dyn(ex_to_numeric(c)),_ex1()); |
| 472 |
} |
} |
| 473 |
|
|
| 474 |
return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c))); |
return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c))); |
| 476 |
|
|
| 477 |
ex add::recombine_pair_to_ex(expair const & p) const |
ex add::recombine_pair_to_ex(expair const & p) const |
| 478 |
{ |
{ |
| 479 |
//if (p.coeff.compare(exONE())==0) { |
//if (p.coeff.compare(_ex1())==0) { |
| 480 |
//if (are_ex_trivially_equal(p.coeff,exONE())) { |
//if (are_ex_trivially_equal(p.coeff,_ex1())) { |
| 481 |
if (ex_to_numeric(p.coeff).is_equal(numONE())) { |
if (ex_to_numeric(p.coeff).is_equal(_num1())) { |
| 482 |
return p.rest; |
return p.rest; |
| 483 |
} else { |
} else { |
| 484 |
return p.rest*p.coeff; |
return p.rest*p.coeff; |