73 inherited::read_archive(
n, sym_lst);
74 n.find_ex(
"basis",
basis, sym_lst);
80 inherited::archive(
n);
95 c.s << openbrace <<
'(';
102 c.s <<
')' << closebrace;
145 }
else if (
exp == 2) {
149 }
else if (
exp & 1) {
181 (is_a<symbol>(
basis) || is_a<constant>(
basis))) {
215 c.s << class_name() <<
'(';
258 return inherited::info(inf);
275 const ex &mapped_basis = f(
basis);
280 return dynallocate<power>(mapped_basis, mapped_exponent);
305 return ex_to<numeric>(
exponent).to_int();
309 throw(std::runtime_error(
"power::degree(): undefined degree because of non-integer exponent"));
320 return ex_to<numeric>(
exponent).to_int();
324 throw(std::runtime_error(
"power::ldegree(): undefined degree because of non-integer exponent"));
343 int int_exp = ex_to<numeric>(
exponent).to_int();
377 const numeric *num_basis =
nullptr;
378 const numeric *num_exponent =
nullptr;
380 if (is_exactly_a<numeric>(
basis)) {
381 num_basis = &ex_to<numeric>(
basis);
383 if (is_exactly_a<numeric>(
exponent)) {
384 num_exponent = &ex_to<numeric>(
exponent);
390 throw (std::domain_error(
"power::eval(): pow(0,0) is undefined"));
401 if ((num_exponent->
real()).is_zero())
402 throw (std::domain_error(
"power::eval(): pow(0,I) is undefined"));
403 else if ((num_exponent->
real()).is_negative())
404 throw (
pole_error(
"power::eval(): division by zero",1));
414 if (is_exactly_a<function>(
basis))
421 if ( num_exponent ) {
426 const bool basis_is_crational = num_basis->
is_crational();
427 const bool exponent_is_crational = num_exponent->
is_crational();
428 if (!basis_is_crational || !exponent_is_crational) {
430 return dynallocate<numeric>(num_basis->
power(*num_exponent));
440 if (basis_is_crational && exponent_is_crational
447 if (
r.is_negative()) {
478 if (is_exactly_a<power>(
basis)) {
479 const power & sub_power = ex_to<power>(
basis);
480 const ex & sub_basis = sub_power.
basis;
482 if (is_exactly_a<numeric>(sub_exponent)) {
483 const numeric & num_sub_exponent = ex_to<numeric>(sub_exponent);
487 return dynallocate<power>(sub_basis, num_sub_exponent.
mul(*num_exponent));
501 ex_to<numeric>(ex_to<add>(
basis).seq.begin()->coeff).
div(icont);
503 const bool canonicalizable = lead_coeff.
is_integer();
505 if (canonicalizable && (! unit_normal))
508 if (canonicalizable && (icont != *
_num1_p)) {
509 const add& addref = ex_to<add>(
basis);
510 add & addp = dynallocate<add>(addref);
513 for (
auto & i : addp.
seq)
514 i.
coeff = ex_to<numeric>(i.coeff).div_dyn(icont);
518 return dynallocate<mul>(dynallocate<power>(addp, *num_exponent),
c);
520 return dynallocate<power>(addp, *num_exponent);
526 if (is_exactly_a<mul>(
basis)) {
528 const mul & mulref = ex_to<mul>(
basis);
533 mul & mulp = dynallocate<mul>(mulref);
536 return dynallocate<mul>(dynallocate<power>(mulp,
exponent),
537 dynallocate<power>(num_coeff, *num_exponent));
541 mul & mulp = dynallocate<mul>(mulref);
544 return dynallocate<mul>(dynallocate<power>(mulp,
exponent),
545 dynallocate<power>(
abs(num_coeff), *num_exponent));
555 !is_a<matrix>(
basis)) {
568 if (!is_exactly_a<numeric>(
exponent))
573 return dynallocate<power>(ebasis, eexponent);
580 if (is_a<matrix>(ebasis)) {
581 if (is_exactly_a<numeric>(eexponent)) {
582 return dynallocate<matrix>(ex_to<matrix>(ebasis).
pow(eexponent));
585 return dynallocate<power>(ebasis, eexponent);
592 if (!is_a<power>(other))
599 ex_to<numeric>(
exponent) > ex_to<numeric>(other.
op(1)) &&
604 ex_to<numeric>(
exponent) < ex_to<numeric>(other.
op(1)) &&
620 return dynallocate<power>(subsed_basis, subsed_exponent);
625 for (
auto & it :
m) {
626 int nummatches = std::numeric_limits<int>::max();
628 if (
tryfactsubs(*
this, it.first, nummatches, repls)) {
631 ex result = (*this) *
pow(anum/aden, nummatches);
632 return (ex_to<basic>(result)).subs_one_level(
m,
options);
641 return inherited::eval_ncmul(v);
653 return dynallocate<power>(
basis, newexponent);
660 return dynallocate<power>(newbasis,
exponent);
662 return conjugate_function(*this).hold();
679 long N = ex_to<numeric>(
c).to_long();
682 long NN = N > 0 ? N : -N;
685 for (
long n = 0;
n <= NN;
n += 2) {
715 long N = ex_to<numeric>(
c).to_long();
718 long p = N > 0 ? 1 : 3;
719 long NN = N > 0 ? N : -N;
722 for (
long n = 1;
n <= NN;
n += 2) {
747 return dynallocate<mul>(std::move(newseq),
exponent);
757 const power &o =
static_cast<const power &
>(other);
790 prodseq.reserve(
m.seq.size() + 1);
791 powseq.reserve(
m.seq.size() + 1);
795 for (
auto & cit :
m.seq) {
796 ex e=
m.recombine_pair_to_ex(cit);
803 powseq.push_back(cit);
819 if (prodseq.size() > 0) {
820 ex newbasis = dynallocate<mul>(std::move(powseq),
coeff);
822 return dynallocate<mul>(std::move(prodseq)) *
pow(newbasis,
exponent);
831 if (is_exactly_a<add>(expanded_exponent)) {
832 const add &a = ex_to<add>(expanded_exponent);
834 distrseq.reserve(a.
seq.size() + 1);
835 for (
auto & cit : a.
seq) {
842 long int_exponent = num_exponent.
to_int();
843 if (int_exponent > 0 && is_exactly_a<add>(expanded_basis))
844 distrseq.push_back(
expand_add(ex_to<add>(expanded_basis), int_exponent,
options));
851 ex r = dynallocate<mul>(distrseq);
855 if (!is_exactly_a<numeric>(expanded_exponent) ||
856 !ex_to<numeric>(expanded_exponent).
is_integer()) {
865 const numeric & num_exponent = ex_to<numeric>(expanded_exponent);
866 long int_exponent = num_exponent.
to_long();
869 if (int_exponent > 0 && is_exactly_a<add>(expanded_basis))
873 if (is_exactly_a<mul>(expanded_basis))
962 result.reserve(result_size);
967 for (
int k = 1;
k <=
n; ++
k) {
972 binomial_coefficient = 1;
985 const std::vector<unsigned>& partition = partitions.
get();
987 const unsigned msize = std::count_if(partition.begin(), partition.end(), [](
int i) { return i > 0; });
993 const std::vector<unsigned>&
exponent = compositions.
get();
995 monomial.reserve(msize);
997 for (
unsigned i = 0; i <
exponent.size(); ++i) {
998 const ex &
r = a.
seq[i].rest;
1001 !is_exactly_a<numeric>(ex_to<power>(
r).
exponent) ||
1003 !is_exactly_a<add>(ex_to<power>(
r).
basis) ||
1004 !is_exactly_a<mul>(ex_to<power>(
r).
basis) ||
1005 !is_exactly_a<power>(ex_to<power>(
r).
basis));
1007 const numeric &
c = ex_to<numeric>(a.
seq[i].coeff);
1022 }
while (compositions.
next());
1023 }
while (partitions.
next());
1040 size_t result_size = (a.
nops() * (a.
nops()+1)) / 2;
1045 result.reserve(result_size);
1051 for (
auto cit0=a.
seq.begin(); cit0!=
last; ++cit0) {
1052 const ex &
r = cit0->rest;
1057 !is_exactly_a<numeric>(ex_to<power>(
r).
exponent) ||
1059 !is_exactly_a<add>(ex_to<power>(
r).
basis) ||
1060 !is_exactly_a<mul>(ex_to<power>(
r).
basis) ||
1061 !is_exactly_a<power>(ex_to<power>(
r).
basis));
1063 if (
c.is_equal(
_ex1)) {
1064 if (is_exactly_a<mul>(
r)) {
1068 result.emplace_back(
expair(dynallocate<power>(
r,
_ex2),
1072 if (is_exactly_a<mul>(
r)) {
1074 ex_to<numeric>(
c).power_dyn(*
_num2_p)));
1076 result.emplace_back(
expair(dynallocate<power>(
r,
_ex2),
1077 ex_to<numeric>(
c).power_dyn(*
_num2_p)));
1081 for (
auto cit1=cit0+1; cit1!=
last; ++cit1) {
1082 const ex & r1 = cit1->rest;
1091 for (
auto & i : a.
seq)
1125 for (
int i=1; i <
n.to_int(); i++)
1131 distrseq.reserve(
m.seq.size());
1132 bool need_reexpand =
false;
1134 for (
auto & cit :
m.seq) {
1135 expair p =
m.combine_pair_with_coeff_to_pair(cit,
n);
1136 if (from_expand && is_exactly_a<add>(cit.rest) && ex_to<numeric>(p.
coeff).is_pos_integer()) {
1139 need_reexpand =
true;
1141 distrseq.push_back(p);
1144 const mul & result = dynallocate<mul>(std::move(distrseq), ex_to<numeric>(
m.overall_coeff).power_dyn(
n));
Interface to GiNaC's sums of expressions.
Archiving of GiNaC expressions.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
ex recombine_pair_to_ex(const expair &p) const override
Form an ex out of an expair, using the corresponding semantics.
expair combine_pair_with_coeff_to_pair(const expair &p, const ex &c) const override
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
const basic & clearflag(unsigned f) const
Clear some status_flags.
const basic & setflag(unsigned f) const
Set some status_flags.
virtual bool has(const ex &other, unsigned options=0) const
Test for occurrence of a pattern.
unsigned flags
of type status_flags
ex subs_one_level(const exmap &m, unsigned options) const
Helper function for subs().
const basic & hold() const
Stop further evaluation.
bool is_equal(const basic &other) const
Test for syntactic equality.
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
virtual ex expand(unsigned options=0) const
Expand expression, i.e.
Generate all compositions of a partition of an integer n, starting with the compositions which has no...
const std::vector< unsigned > & get() const
Wrapper template for making GiNaC classes out of STL containers.
Lightweight wrapper for GiNaC's symbolic objects.
numeric integer_content() const
Compute the integer content (= GCD of all numeric coefficients) of an expanded polynomial.
bool match(const ex &pattern) const
Check whether expression matches a specified pattern.
bool is_polynomial(const ex &vars) const
Check whether expression is a polynomial.
ex diff(const symbol &s, unsigned nth=1) const
Compute partial derivative of an expression.
ex expand(unsigned options=0) const
Expand an expression.
bool is_equal(const ex &other) const
int degree(const ex &s) const
bool has(const ex &pattern, unsigned options=0) const
unsigned return_type() const
return_type_t return_type_tinfo() const
ex subs(const exmap &m, unsigned options=0) const
bool info(unsigned inf) const
int compare(const ex &other) const
void print(const print_context &c, unsigned level=0) const
Print expression to stream.
int ldegree(const ex &s) const
ex coeff(const ex &s, int n=1) const
ex coeff
second member of pair, must be numeric
size_t nops() const override
Number of operands/members.
@ expand_rename_idx
used internally by mul::expand()
@ algebraic
enable algebraic matching
Non-commutative product of expressions.
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
bool is_pos_integer() const
True if object is an exact integer greater than zero.
const numeric & mul_dyn(const numeric &other) const
Numerical multiplication method.
bool is_crational() const
True if object is an exact rational number, may even be complex (denominator may be unity).
bool is_rational() const
True if object is an exact rational number, may even be complex (denominator may be unity).
const numeric real() const
Real part of a number.
long to_long() const
Converts numeric types to machine's long.
int compare(const numeric &other) const
This method establishes a canonical order on all numbers.
bool is_positive() const
True if object is not complex and greater than zero.
bool is_real() const
True if object is a real integer, rational or float (but not complex).
const numeric numer() const
Numerator.
bool is_integer() const
True if object is a non-complex integer.
const numeric power(const numeric &other) const
Numerical exponentiation.
const numeric denom() const
Denominator.
const numeric mul(const numeric &other) const
Numerical multiplication method.
bool is_equal(const numeric &other) const
int to_int() const
Converts numeric types to machine's int.
const numeric inverse() const
Inverse of a number.
bool is_zero() const
True if object is zero.
const numeric div(const numeric &other) const
Numerical division method.
Generate all bounded combinatorial partitions of an integer n with exactly m parts (including zero pa...
const std::vector< unsigned > & get() const
Exception class thrown when a singularity is encountered.
This class holds a two-component object, a basis and and exponent representing exponentiation.
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.
void do_print_dflt(const print_dflt &c, unsigned level) const
void do_print_csrc(const print_csrc &c, unsigned level) const
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.
int degree(const ex &s) const override
Return degree of highest power in object s.
void read_archive(const archive_node &n, lst &syms) override
Read (a.k.a.
ex subs(const exmap &m, unsigned options=0) const override
Substitute a set of objects by arbitrary expressions.
int ldegree(const ex &s) const override
Return degree of lowest power in object s.
static ex expand_add_2(const add &a, unsigned options)
Special case of power::expand_add.
ex real_part() const override
void archive(archive_node &n) const override
Save (a.k.a.
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,...
ex eval() const override
Perform automatic term rewriting rules in this class.
void do_print_python(const print_python &c, unsigned level) const
void print_power(const print_context &c, const char *powersymbol, const char *openbrace, const char *closebrace, unsigned level) const
void do_print_python_repr(const print_python_repr &c, unsigned level) const
unsigned precedence() const override
Return relative operator precedence (for parenthezing output).
ex op(size_t i) const override
Return operand/member at position i.
power(const ex &lh, const ex &rh)
void do_print_latex(const print_latex &c, unsigned level) const
ex conjugate() const override
ex coeff(const ex &s, int n=1) const override
Return coefficient of degree n in object s.
bool has(const ex &other, unsigned options=0) const override
Test for occurrence of a pattern.
ex evalm() const override
Evaluate sums, products and integer powers of matrices.
return_type_t return_type_tinfo() const override
size_t nops() const override
Number of operands/members.
ex expand(unsigned options=0) const override
Expand expression, i.e.
bool info(unsigned inf) const override
Information about the object.
ex eval_ncmul(const exvector &v) const override
void do_print_csrc_cl_N(const print_csrc_cl_N &c, unsigned level) const
unsigned return_type() const override
ex imag_part() const override
bool is_polynomial(const ex &var) const override
Check whether this is a polynomial in the given variables.
ex evalf() const override
Evaluate object numerically.
Base class for print_contexts.
Context for C source output using CLN numbers.
Base context for C source output.
Context for default (ginsh-parsable) output.
Context for latex-parsable output.
Context for python-parsable output.
Context for python pretty-print output.
@ expanded
.expand(0) has already done its job (other expand() options ignore this flag)
@ evaluated
.eval() has already done its job
@ hash_calculated
.calchash() has already done its job
@ no_pattern
disable pattern matching
@ algebraic
enable algebraic substitutions
Definition of optimizing macros.
Interface to GiNaC's constant types and some special constants.
Interface to sequences of expression pairs.
Interface to GiNaC's indexed expressions.
Interface to GiNaC's initially known functions.
Definition of GiNaC's lst.
Interface to symbolic matrices.
Interface to GiNaC's products of expressions.
const numeric pow(const numeric &x, const numeric &y)
std::map< ex, ex, ex_is_less > exmap
std::vector< expair > epvector
expair-vector
const numeric abs(const numeric &x)
Absolute value.
bool is_negative(const numeric &x)
bool are_ex_trivially_equal(const ex &e1, const ex &e2)
Compare two objects of class quickly without doing a deep tree traversal.
const numeric binomial(const numeric &n, const numeric &k)
The Binomial coefficients.
print_func< print_dflt >(&diracone::do_print). print_func< print_latex >(&diracone
const numeric exp(const numeric &x)
Exponential function.
const numeric cos(const numeric &x)
Numeric cosine (trigonometric function).
const numeric iquo(const numeric &a, const numeric &b)
Numeric integer quotient.
bool is_pos_integer(const numeric &x)
const numeric log(const numeric &x)
Natural logarithm.
const numeric sin(const numeric &x)
Numeric sine (trigonometric function).
ex numer(const ex &thisex)
ex factor(const ex &poly, unsigned options)
Interface function to the outside world.
bool is_integer(const numeric &x)
static void print_sym_pow(const print_context &c, const symbol &x, int exp)
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...
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT_T(lst, basic, print_func< print_context >(&lst::do_print). print_func< print_tree >(&lst::do_print_tree)) template<> bool lst GINAC_BIND_UNARCHIVER(lst)
Specialization of container::info() for lst.
bool tryfactsubs(const ex &origfactor, const ex &patternfactor, int &nummatches, exmap &repls)
std::vector< ex > exvector
exvector get_all_dummy_indices(const ex &e)
Returns all dummy indices from the exvector.
const numeric multinomial_coefficient(const std::vector< unsigned > &p)
Compute the multinomial coefficient n!/(p1!*p2!*...*pk!) where n = p1+p2+...+pk, i....
Interface to GiNaC's non-commutative products of expressions.
Makes the interface to the underlying bignum package available.
Interface to GiNaC's overloaded operators.
Interface to GiNaC's symbolic exponentiation (basis^exponent).
#define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(classname, supername, options)
Macro for inclusion in the implementation of each registered class.
Interface to relations between expressions.
Function object for map().
To distinguish between different kinds of non-commutative objects.
Interface to GiNaC's symbolic objects.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...