75 inherited::read_archive(
n, sym_lst);
76 n.find_ex(
"basis",
basis, sym_lst);
82 inherited::archive(
n);
97 c.s << openbrace <<
'(';
104 c.s <<
')' << closebrace;
147 }
else if (
exp == 2) {
151 }
else if (
exp & 1) {
183 (is_a<symbol>(
basis) || is_a<constant>(
basis))) {
217 c.s << class_name() <<
'(';
260 return inherited::info(inf);
277 const ex &mapped_basis = f(
basis);
282 return dynallocate<power>(mapped_basis, mapped_exponent);
307 return ex_to<numeric>(
exponent).to_int();
311 throw(std::runtime_error(
"power::degree(): undefined degree because of non-integer exponent"));
322 return ex_to<numeric>(
exponent).to_int();
326 throw(std::runtime_error(
"power::ldegree(): undefined degree because of non-integer exponent"));
379 const numeric *num_basis =
nullptr;
380 const numeric *num_exponent =
nullptr;
382 if (is_exactly_a<numeric>(
basis)) {
383 num_basis = &ex_to<numeric>(
basis);
385 if (is_exactly_a<numeric>(
exponent)) {
386 num_exponent = &ex_to<numeric>(
exponent);
392 throw (std::domain_error(
"power::eval(): pow(0,0) is undefined"));
404 throw (std::domain_error(
"power::eval(): pow(0,I) is undefined"));
406 throw (
pole_error(
"power::eval(): division by zero",1));
416 if (is_exactly_a<function>(
basis))
423 if ( num_exponent ) {
428 const bool basis_is_crational = num_basis->
is_crational();
429 const bool exponent_is_crational = num_exponent->
is_crational();
430 if (!basis_is_crational || !exponent_is_crational) {
432 return dynallocate<numeric>(num_basis->
power(*num_exponent));
442 if (basis_is_crational && exponent_is_crational
449 if (
r.is_negative()) {
480 if (is_exactly_a<power>(
basis)) {
481 const power & sub_power = ex_to<power>(
basis);
482 const ex & sub_basis = sub_power.
basis;
484 if (is_exactly_a<numeric>(sub_exponent)) {
485 const numeric & num_sub_exponent = ex_to<numeric>(sub_exponent);
489 return dynallocate<power>(sub_basis, num_sub_exponent.
mul(*num_exponent));
503 ex_to<numeric>(ex_to<add>(
basis).seq.begin()->coeff).div(icont);
505 const bool canonicalizable = lead_coeff.
is_integer();
507 if (canonicalizable && (! unit_normal))
510 if (canonicalizable && (icont != *
_num1_p)) {
511 const add& addref = ex_to<add>(
basis);
512 add & addp = dynallocate<add>(addref);
514 addp.overall_coeff = ex_to<numeric>(addp.overall_coeff).div_dyn(icont);
515 for (
auto & i : addp.seq)
516 i.coeff = ex_to<numeric>(i.coeff).div_dyn(icont);
520 return dynallocate<mul>(dynallocate<power>(addp, *num_exponent),
c);
522 return dynallocate<power>(addp, *num_exponent);
528 if (is_exactly_a<mul>(
basis)) {
530 const mul & mulref = ex_to<mul>(
basis);
531 if (!mulref.overall_coeff.is_equal(
_ex1)) {
532 const numeric & num_coeff = ex_to<numeric>(mulref.overall_coeff);
535 mul & mulp = dynallocate<mul>(mulref);
538 return dynallocate<mul>(dynallocate<power>(mulp,
exponent),
539 dynallocate<power>(num_coeff, *num_exponent));
543 mul & mulp = dynallocate<mul>(mulref);
546 return dynallocate<mul>(dynallocate<power>(mulp,
exponent),
547 dynallocate<power>(
abs(num_coeff), *num_exponent));
557 !is_a<matrix>(
basis)) {
570 if (!is_exactly_a<numeric>(
exponent))
575 return dynallocate<power>(ebasis, eexponent);
582 if (is_a<matrix>(ebasis)) {
583 if (is_exactly_a<numeric>(eexponent)) {
584 return dynallocate<matrix>(ex_to<matrix>(ebasis).
pow(eexponent));
587 return dynallocate<power>(ebasis, eexponent);
594 if (!is_a<power>(other))
601 ex_to<numeric>(
exponent) > ex_to<numeric>(other.
op(1)) &&
606 ex_to<numeric>(
exponent) < ex_to<numeric>(other.
op(1)) &&
622 return power(subsed_basis, subsed_exponent).subs_one_level(
m,
options);
627 for (
auto & it :
m) {
628 int nummatches = std::numeric_limits<int>::max();
630 if (
tryfactsubs(*
this, it.first, nummatches, repls)) {
633 ex result = (*this) *
pow(anum/aden, nummatches);
634 return (ex_to<basic>(result)).subs_one_level(
m,
options);
643 return inherited::eval_ncmul(v);
655 return dynallocate<power>(
basis, newexponent);
662 return dynallocate<power>(newbasis,
exponent);
664 return conjugate_function(*this).hold();
681 long N = ex_to<numeric>(
c).
to_long();
684 long NN = N > 0 ? N : -N;
687 for (
long n = 0;
n <= NN;
n += 2) {
717 long N = ex_to<numeric>(
c).
to_long();
720 long p = N > 0 ? 1 : 3;
721 long NN = N > 0 ? N : -N;
724 for (
long n = 1;
n <= NN;
n += 2) {
749 return dynallocate<mul>(std::move(newseq),
exponent);
759 const power &o =
static_cast<const power &
>(other);
792 prodseq.reserve(
m.seq.size() + 1);
793 powseq.reserve(
m.seq.size() + 1);
797 for (
auto & cit :
m.seq) {
798 ex e=
m.recombine_pair_to_ex(cit);
805 powseq.push_back(cit);
821 if (prodseq.size() > 0) {
822 ex newbasis = dynallocate<mul>(std::move(powseq),
coeff);
824 return dynallocate<mul>(std::move(prodseq)) *
pow(newbasis,
exponent);
833 if (is_exactly_a<add>(expanded_exponent)) {
834 const add &a = ex_to<add>(expanded_exponent);
836 distrseq.reserve(a.
seq.size() + 1);
837 for (
auto & cit : a.
seq) {
844 long int_exponent = num_exponent.
to_int();
845 if (int_exponent > 0 && is_exactly_a<add>(expanded_basis))
846 distrseq.push_back(
expand_add(ex_to<add>(expanded_basis), int_exponent,
options));
853 ex r = dynallocate<mul>(distrseq);
857 if (!is_exactly_a<numeric>(expanded_exponent) ||
858 !ex_to<numeric>(expanded_exponent).
is_integer()) {
867 const numeric & num_exponent = ex_to<numeric>(expanded_exponent);
868 long int_exponent = num_exponent.
to_long();
871 if (int_exponent > 0 && is_exactly_a<add>(expanded_basis))
875 if (is_exactly_a<mul>(expanded_basis))
964 result.reserve(result_size);
969 for (
int k = 1;
k <=
n; ++
k) {
974 binomial_coefficient = 1;
987 const std::vector<unsigned>& partition = partitions.
get();
989 const unsigned msize = std::count_if(partition.begin(), partition.end(), [](
int i) {
return i > 0; });
995 const std::vector<unsigned>&
exponent = compositions.
get();
997 monomial.reserve(msize);
999 for (
unsigned i = 0; i <
exponent.size(); ++i) {
1000 const ex &
r = a.
seq[i].rest;
1003 !is_exactly_a<numeric>(ex_to<power>(
r).
exponent) ||
1005 !is_exactly_a<add>(ex_to<power>(
r).
basis) ||
1006 !is_exactly_a<mul>(ex_to<power>(
r).
basis) ||
1007 !is_exactly_a<power>(ex_to<power>(
r).
basis));
1009 const numeric &
c = ex_to<numeric>(a.
seq[i].coeff);
1024 }
while (compositions.
next());
1025 }
while (partitions.next());
1042 size_t result_size = (a.
nops() * (a.
nops()+1)) / 2;
1047 result.reserve(result_size);
1053 for (
auto cit0=a.
seq.begin(); cit0!=
last; ++cit0) {
1054 const ex &
r = cit0->rest;
1055 const ex &
c = cit0->coeff;
1059 !is_exactly_a<numeric>(ex_to<power>(
r).
exponent) ||
1061 !is_exactly_a<add>(ex_to<power>(
r).
basis) ||
1062 !is_exactly_a<mul>(ex_to<power>(
r).
basis) ||
1063 !is_exactly_a<power>(ex_to<power>(
r).
basis));
1065 if (
c.is_equal(
_ex1)) {
1066 if (is_exactly_a<mul>(
r)) {
1070 result.emplace_back(
expair(dynallocate<power>(
r,
_ex2),
1074 if (is_exactly_a<mul>(
r)) {
1076 ex_to<numeric>(
c).power_dyn(*
_num2_p)));
1078 result.emplace_back(
expair(dynallocate<power>(
r,
_ex2),
1079 ex_to<numeric>(
c).power_dyn(*
_num2_p)));
1083 for (
auto cit1=cit0+1; cit1!=
last; ++cit1) {
1084 const ex & r1 = cit1->rest;
1093 for (
auto & i : a.
seq)
1127 for (
int i=1; i <
n.to_int(); i++)
1133 distrseq.reserve(
m.seq.size());
1134 bool need_reexpand =
false;
1136 for (
auto & cit :
m.seq) {
1137 expair p =
m.combine_pair_with_coeff_to_pair(cit,
n);
1138 if (from_expand && is_exactly_a<add>(cit.rest) && ex_to<numeric>(p.
coeff).is_pos_integer()) {
1141 need_reexpand =
true;
1143 distrseq.push_back(p);
1146 const mul & result = dynallocate<mul>(std::move(distrseq), ex_to<numeric>(
m.overall_coeff).power_dyn(
n));
bool is_crational() const
True if object is an exact rational number, may even be complex (denominator may be unity)...
bool is_pos_integer(const numeric &x)
const numeric exp(const numeric &x)
Exponential function.
void do_print_csrc(const print_csrc &c, unsigned level) const
void do_print_latex(const print_latex &c, unsigned level) const
exvector get_all_dummy_indices(const ex &e)
Returns all dummy indices from the exvector.
Interface to GiNaC's symbolic exponentiation (basis^exponent).
Non-commutative product of expressions.
Interface to GiNaC's indexed expressions.
ex coeff(const ex &s, int n=1) const
Interface to GiNaC's symbolic objects.
long to_long(const numeric &x)
int to_int(const numeric &x)
print_func< print_dflt >(&diracone::do_print). print_func< print_latex >(&diracone
int compare(const ex &other) const
ex subs(const exmap &m, unsigned options=0) const
virtual bool has(const ex &other, unsigned options=0) const
Test for occurrence of a pattern.
bool is_pos_integer() const
True if object is an exact integer greater than zero.
const basic & hold() const
Stop further evaluation.
void do_print_csrc_cl_N(const print_csrc_cl_N &c, unsigned level) const
bool is_equal(const ex &other) const
Generate all bounded combinatorial partitions of an integer n with exactly m parts (including zero pa...
const basic & setflag(unsigned f) const
Set some status_flags.
ex expand(unsigned options=0) const
unsigned precedence() const override
Return relative operator precedence (for parenthezing output).
Interface to GiNaC's constant types and some special constants.
bool has(const ex &pattern, unsigned options=0) const
ex imag_part() const override
ex evalm() const override
Evaluate sums, products and integer powers of matrices.
unsigned return_type() const override
const numeric sin(const numeric &x)
Numeric sine (trigonometric function).
return_type_t return_type_tinfo() const override
const numeric power(const numeric &other) const
Numerical exponentiation.
Archiving of GiNaC expressions.
const numeric multinomial_coefficient(const std::vector< unsigned > &p)
Compute the multinomial coefficient n!/(p1!*p2!*...*pk!) where n = p1+p2+...+pk, i.e.
Interface to GiNaC's sums of expressions.
bool is_negative(const numeric &x)
Interface to sequences of expression pairs.
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
Context for python-parsable output.
const numeric denom() const
Denominator.
bool are_ex_trivially_equal(const ex &e1, const ex &e2)
Compare two objects of class quickly without doing a deep tree traversal.
int degree(const ex &s) const
Interface to GiNaC's products of expressions.
Generate all compositions of a partition of an integer n, starting with the compositions which has no...
bool is_integer(const numeric &x)
int compare(const numeric &other) const
This method establishes a canonical order on all numbers.
ex coeff(const ex &s, int n=1) const override
Return coefficient of degree n in object s.
int ldegree(const ex &s) const override
Return degree of lowest power in object s.
used internally by mul::expand()
bool info(unsigned inf) const
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...
bool is_equal(const numeric &other) const
Context for python pretty-print output.
bool is_zero(const ex &thisex)
int to_int() const
Converts numeric types to machine's int.
int ldegree(const ex &s) const
ex numer(const ex &thisex)
Context for default (ginsh-parsable) output.
Definition of optimizing macros.
ex subs(const exmap &m, unsigned options=0) const override
Substitute a set of objects by arbitrary expressions.
int degree(const ex &s) const override
Return degree of highest power in object s.
power(const ex &lh, const ex &rh)
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
Context for latex-parsable output.
const std::vector< unsigned > & get() const
size_t nops() const override
Number of operands/members.
bool is_integer() const
True if object is a non-complex integer.
const numeric mul(const numeric &other) const
Numerical multiplication method.
static ex expand_add(const add &a, long n, unsigned options)
expand a^n where a is an add and n is a positive integer.
bool match(const ex &pattern) const
Check whether expression matches a specified pattern.
bool is_positive() const
True if object is not complex and greater than zero.
const numeric div(const numeric &other) const
Numerical division method.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
ex subs_one_level(const exmap &m, unsigned options) const
Helper function for subs().
long to_long() const
Converts numeric types to machine's long.
expair combine_pair_with_coeff_to_pair(const expair &p, const ex &c) const override
ex derivative(const symbol &s) const override
Implementation of ex::diff() for a power.
ex map(map_function &f) const override
Construct new expression by applying the specified function to all sub-expressions (one level only...
const numeric log(const numeric &x)
Natural logarithm.
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(add, expairseq, print_func< print_context >(&add::do_print). print_func< print_latex >(&add::do_print_latex). print_func< print_csrc >(&add::do_print_csrc). print_func< print_tree >(&add::do_print_tree). print_func< print_python_repr >(&add::do_print_python_repr)) add
To distinguish between different kinds of non-commutative objects.
const numeric real() const
Real part of a number.
Interface to symbolic matrices.
static ex expand_mul(const mul &m, const numeric &n, unsigned options, bool from_expand=false)
Expand factors of m in m^n where m is a mul and n is an integer.
const numeric numer() const
Numerator.
ex diff(const symbol &s, unsigned nth=1) const
Compute partial derivative of an expression.
const numeric abs(const numeric &x)
Absolute value.
bool tryfactsubs(const ex &origfactor, const ex &patternfactor, int &nummatches, exmap &repls)
std::vector< ex > exvector
std::map< ex, ex, ex_is_less > exmap
Interface to GiNaC's overloaded operators.
bool is_real() const
True if object is a real integer, rational or float (but not complex).
const numeric & mul_dyn(const numeric &other) const
Numerical multiplication method.
enable algebraic substitutions
enable algebraic matching
const numeric binomial(const numeric &n, const numeric &k)
The Binomial coefficients.
Function object for map().
return_type_t return_type_tinfo() const
ex factor(const ex &poly, unsigned options)
Interface function to the outside world.
Base class for print_contexts.
Definition of GiNaC's lst.
const numeric cos(const numeric &x)
Numeric cosine (trigonometric function).
ex eval() const override
Perform automatic term rewriting rules in this class.
const numeric pow(const numeric &x, const numeric &y)
Exception class thrown when a singularity is encountered.
void read_archive(const archive_node &n, lst &syms) override
Read (a.k.a.
bool info(unsigned inf) const override
Information about the object.
bool is_zero() const
True if object is zero.
void archive(archive_node &n) const override
Save (a.k.a.
ex evalf() const override
Evaluate object numerically.
const basic & clearflag(unsigned f) const
Clear some status_flags.
ex coeff
second member of pair, must be numeric
void print(const print_context &c, unsigned level=0) const
Print expression to stream.
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
Lightweight wrapper for GiNaC's symbolic objects.
This class holds a two-component object, a basis and and exponent representing exponentiation.
Interface to GiNaC's non-commutative products of expressions.
numeric integer_content() const
Compute the integer content (= GCD of all numeric coefficients) of an expanded polynomial.
static ex expand_add_2(const add &a, unsigned options)
Special case of power::expand_add.
lst rename_dummy_indices_uniquely(const exvector &va, const exvector &vb)
Similar to above, where va and vb are the same and the return value is a list of two lists for substi...
Interface to GiNaC's initially known functions.
void do_print_python_repr(const print_python_repr &c, unsigned level) const
void do_print_python(const print_python &c, unsigned level) const
void do_print_dflt(const print_dflt &c, unsigned level) const
ex recombine_pair_to_ex(const expair &p) const override
.calchash() has already done its job
bool is_equal(const basic &other) const
Test for syntactic equality.
ex eval_ncmul(const exvector &v) const override
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
unsigned return_type() const
Context for C source output using CLN numbers.
Wrapper template for making GiNaC classes out of STL containers.
.expand(0) has already done its job (other expand() options ignore this flag)
ex real_part() const override
Base context for C source output.
Interface to relations between expressions.
Makes the interface to the underlying bignum package available.
std::vector< expair > epvector
expair-vector
static void print_sym_pow(const print_context &c, const symbol &x, int exp)
ex expand(unsigned options=0) const override
Expand expression, i.e.
const numeric inverse() const
Inverse of a number.
ex op(size_t i) const override
Return operand/member at position i.
void print_power(const print_context &c, const char *powersymbol, const char *openbrace, const char *closebrace, unsigned level) const
bool is_rational() const
True if object is an exact rational number, may even be complex (denominator may be unity)...
size_t nops() const override
Number of operands/members.
.eval() has already done its job
const std::vector< unsigned > & get() const
bool is_polynomial(const ex &vars) const
Check whether expression is a polynomial.
bool is_polynomial(const ex &var) const override
Check whether this is a polynomial in the given variables.
unsigned flags
of type status_flags
bool has(const ex &other, unsigned options=0) const override
Test for occurrence of a pattern.
GINAC_BIND_UNARCHIVER(add)
ex conjugate() const override
const numeric iquo(const numeric &a, const numeric &b)
Numeric integer quotient.