70 if (arg.
nops() != 2 && arg.
nops() != 3)
71 throw std::invalid_argument(
"Gt: first argument must be a list of tuples");
86 if (
zi.evalf().is_zero())
113 throw std::runtime_error(
"Gt: Im(tau) needs to be greater than 0 b");
115 throw std::runtime_error(
"Gt: Too many kernels");
123 throw std::invalid_argument(
"Gt: first argument must be a non-empty list");
127 throw std::runtime_error(
"Gt: Im(tau) needs to be greater than 0 a");
130 throw std::runtime_error(
"Gt: Too many kernels");
136 throw std::invalid_argument(
"Gt: first argument must be a list");
140 throw std::invalid_argument(
"Gt: first argument must be a non-empty list");
144 for (
size_t i = 0; i <
nargs; i++) {
148 throw std::invalid_argument(
"Gt: first argument must be a list of tuples");
158 inherited::read_archive(n, sym_lst);
168 inherited::archive(n);
170 for (
size_t i = 0; i <
nargs; i++)
171 lst_args.
append(
lst{args[i].ni, args[i].zi, args[i].deform});
172 n.
add_ex(
"args", lst_args);
184 for (
size_t i = 0; i <
nargs; i++) {
185 c.
s << (i?
",":
"") <<
"{" <<
args[i].ni <<
"," <<
args[i].zi;
187 c.
s <<
"," <<
args[i].deform;
190 c.
s <<
"}," <<
z <<
"," <<
tau <<
")";
196 for (
size_t i = 0; i <
nargs; i++)
197 c.
s <<
"\\begin{matrix}" <<
args[i].ni <<
"\\\\" <<
args[i].zi <<
"\\end{matrix}";
198 c.
s <<
";" <<
z <<
"," <<
tau <<
"\\right)";
206 const Gt& o =
static_cast<const Gt&
>(other);
209 for (
size_t i = 0; i <
nargs; i++) {
210 if (
args[i].ni > o.
args[i].ni)
return +1;
211 if (
args[i].ni < o.
args[i].ni)
return -1;
212 const int cmp =
args[i].zi.compare(o.
args[i].zi);
213 if (cmp > 0)
return +1;
214 if (cmp < 0)
return -1;
215 if (
args[i].deform > o.
args[i].deform)
return +1;
216 if (
args[i].deform < o.
args[i].deform)
return -1;
219 if (cmp > 0)
return +1;
220 if (cmp < 0)
return -1;
230 for (
size_t i = 0; i <
nargs; i++)
233 else if (i ==
nargs-1)
238 bool all_kernels_equal =
true;
239 for (
size_t i = 1; i <
nargs && all_kernels_equal; i++)
241 if (all_kernels_equal)
258 bool already_evaluated =
true;
259 std::vector<kernel> new_args;
260 new_args.reserve(
nargs);
262 new_args.emplace_back(k.ni, k.zi.evalf(), k.deform);
265 const ex nz =
z.evalf();
266 const ex ntau =
tau.evalf();
270 if (already_evaluated)
277 std::vector<kernel> args_subs;
278 args_subs.reserve(
nargs);
280 args_subs.emplace_back(k.ni, k.zi.subs(m, options), k.deform);
281 return Gt(args_subs,
z.subs(m, options),
tau.subs(m, options));
288 unsigned v = make_hash_seed(
typeid(*
this));
308 if (k.zi.has(other, options))
310 return tau.has(other, options) ||
z.has(other, options);
317 throw std::logic_error(
"Gt::match not implemented\n");
324 if (
DEBUG_GT) std::cout <<
"zisToFundamental " << *
this << std::endl;
337 std::vector<ex> zis_shifted;
338 zis_shifted.reserve(
nargs);
345 std::vector<std::vector<std::pair<ex, size_t>>> shifted_kernels;
346 shifted_kernels.reserve(
nargs);
349 for (
size_t i = 0; i <
nargs; i++) {
356 const cln::cl_I shiftB = -cln::floor1(cln::realpart((B + 0.5).to_cl_N()));
358 const cln::cl_I shiftA = -cln::floor1(cln::realpart((A + 0.5).to_cl_N()));
361 zis_shifted.push_back(0);
363 zis_shifted.push_back(zi_shifted.
normal());
366 shifted_kernels.emplace_back();
367 std::vector<std::pair<ex, size_t>>& shifted_kernels_i = shifted_kernels.back();
370 if (cln::zerop(shiftB)) {
371 shifted_kernels_i.reserve(1);
372 shifted_kernels_i.emplace_back(1,
args[i].ni);
377 shifted_kernels_i.reserve(
args[i].ni + 1);
378 for (
size_t k = 0; k <=
args[i].ni; k++)
380 nterms *=
args[i].ni + 1;
386 std::vector<ex> result;
387 result.reserve(nterms);
388 std::function<void(
size_t,
ex,std::vector<kernel>&)> build_Gts = [&](
size_t i,
ex factor, std::vector<kernel>& new_args) ->
void {
391 new_args.emplace_back(-1, zis_shifted[i],
args[i].deform);
392 for (
size_t k = 0; k < shifted_kernels[i].size(); k++) {
393 new_args.back().ni = shifted_kernels[i][k].second;
394 build_Gts(i+1,
factor * shifted_kernels[i][k].
first, new_args);
403 for (
const kernel& k : new_args)
404 if (k.ni == 1 &&
to_numeric(k.zi, points) == nz)
405 throw std::logic_error((std::stringstream{} <<
"Gt: pole coincides with endpoint: " <<
Gt(new_args,
z,
tau)).str());
409 std::vector<kernel> new_args;
410 new_args.reserve(
nargs);
411 build_Gts(0,
ex{1}, new_args);
419 if (
DEBUG_GT) std::cout <<
"regularise " << *
this << std::endl;
426 for (n = 0; n <
nargs; n++)
435 const Gt singular{std::vector<kernel>(1,
kernel{1,0}),
z,
tau};
441 std::vector<ex> result;
442 result.reserve(
nargs);
443 for (
size_t i = 0; i <
nargs; i++) {
444 std::vector<kernel> new_args;
445 new_args.reserve(i+1);
446 for (
size_t j = 0; j < i; j++)
447 new_args.emplace_back(1,0);
448 new_args.emplace_back(
args[0].ni,
args[0].zi);
464 const size_t na =
nargs-n-1;
465 const std::vector<kernel> a(
args.begin(),
args.begin() + na);
467 std::vector<kernel> ci;
469 std::vector<ex> result;
470 for (
size_t i = 0; i <= n; i++) {
472 ci.emplace_back(1,0);
476 std::vector<kernel> new_args;
477 new_args.reserve(na + i);
479 new_args.emplace_back(k);
480 new_args.emplace_back(b);
493 throw std::runtime_error(
"Gt: Im(tau) <= 0");
494 matrix transform{{1,0},{0,1}};
501 const cln::cl_I shift{-round1(cln::realpart(ntau.
to_cl_N()))};
502 if (!cln::zerop(shift)) {
513 transform =
matrix{{0,-1},{1,0}}.
mul(transform);
524 if (
DEBUG_GT) std::cout <<
"tauToFundamental " << *
this << std::endl;
529 if (
DEBUG_GT>=5) std::cout <<
"transform " << transform << std::endl;
530 const ex& a = transform(0,0), b = transform(0,1), c = transform(1,0), d = transform(1,1);
531 const ex& ci = -c, di = a;
535 return Gt(std::vector<kernel>(1,
kernel{1,0}),
z*newTau1, newTau) -
log(newTau1) +
I*
Pi*ci/newTau1 *
pow(
z*newTau1,2);
538 struct integration_result {
541 std::vector<kernel>
args;
543 integration_result(
ex prefactor,
size_t power, std::vector<kernel>
args)
550 struct integrand_term {
554 std::vector<kernel>
args;
556 integrand_term(
ex prefactor,
size_t power,
kernel kern, std::vector<kernel>
args)
559 void integrate(std::vector<integration_result>& result) {
560 if (
args.empty() && kern.
ni==0)
561 result.emplace_back(prefactor/(
power+1),
power+1, std::vector<kernel>{});
565 result.emplace_back(prefactor,
power,
args);
567 prefactor *= -int(
power--);
569 result.emplace_back(prefactor,
power,
args);
575 std::vector<integration_result> result{1,integration_result{1,0,std::vector<kernel>{}}};
576 for (
size_t i = 0; i <
nargs; i++) {
578 const size_t ni =
args[
nargs - i - 1].ni;
579 const ex zi_scaled =
args[
nargs - i - 1].zi * newTau1;
581 size_t num_terms = 0;
582 std::vector<integrand_term> integrand;
585 for (
const integration_result& prev_result : result) {
587 integrand.emplace_back(prev_result.prefactor/newTau1, prev_result.power, kern, prev_result.args);
588 num_terms += 1 + prev_result.power * (kern.
ni && !prev_result.args.empty());
595 integrand.reserve(result.size()*(ni+1)*(ni+2)/2);
596 for (
size_t k = 0; k <= ni; k++) {
598 for (
size_t j = 0; j <= k; j++) {
600 const size_t power = k-j;
601 for (
const integration_result& prev_result : result) {
602 integrand.emplace_back(prev_result.prefactor*prefactor, prev_result.power+
power, kern, prev_result.args);
603 num_terms += 1 + (prev_result.power+
power) * (kern.
ni && !prev_result.args.empty());
610 result.reserve(num_terms);
611 for (integrand_term& term : integrand)
612 term.integrate(result);
615 std::vector<ex> result_ex;
616 result_ex.reserve(result.size());
617 for (integration_result& term : result)
618 result_ex.emplace_back(term.evaluate(newTau1*
z, newTau));
619 return add(result_ex);
625 if (
DEBUG_GT) std::cout <<
"cutIntegrationPath " << *
this << std::endl;
642 auto coincidesWithZi = [&](
const ex& e) {
655 std::vector<ex> cuts;
656 size_t nCuts = std::max<size_t>(std::abs(nA) / max_A, std::abs(nB) / max_B);
658 cuts.reserve(nCuts + 2);
659 cuts.emplace_back(
ex{0});
660 for (
size_t i = 1; i < nCuts+1; i++) {
661 cuts.emplace_back(i*
z/(nCuts+1));
662 if (coincidesWithZi(cuts.back())) {
672 cuts.emplace_back(
z);
685 return Gt(new_args, end - start,
tau);
692 if (
DEBUG_GT) std::cout <<
"qExpand " << *
this << std::endl;
696 std::vector<numeric> nzis, nqis;
699 for (
size_t i = 0; i <
nargs; i++) {
707 throw std::runtime_error(
"Gt: Cannot perform q-expansion if Im(tau) <= 0");
710 const bool singular = (
nargs == 1 &&
args[0].ni == 1 &&
args[0].zi.is_zero());
712 std::vector<std::pair<numeric,int>> path;
720 for (
size_t i = 0; i <
nargs; i++) {
721 if (
args[i].ni != 1)
continue;
722 if (nzis[i].
real() <= 0 || nzis[i].
real() >= nz.
real())
continue;
723 const numeric n1 = nzis[i].imag()*nz.
real(), n2 = nzis[i].real()*nz.
imag();
727 if (
args[i].deform >= 0)
728 path.emplace_back(nzis[i].
real(), -1);
738 path.emplace_back(nzis[i].
real(), 0);
740 std::sort(path.begin(), path.end());
741 path.erase(std::unique(path.begin(), path.end()), path.end());
744 for (
size_t i = 0; i <
nargs; i++) {
745 if (
args[i].ni != 1)
continue;
746 if (nzis[i].
real() <= nz.
real() || 0 <= nzis[i].real())
continue;
747 const numeric n1 = nzis[i].imag()*nz.
real(), n2 = nzis[i].real()*nz.
imag();
751 if (
args[i].deform < 0)
752 path.emplace_back(nzis[i].
real(), -1);
762 path.emplace_back(nzis[i].
real(), 0);
764 std::sort(path.rbegin(), path.rend());
765 path.erase(std::unique(path.begin(), path.end()), path.end());
770 std::vector<ex> wpath;
771 wpath.reserve(path.size() + 2);
772 wpath.emplace_back(1);
773 for (
size_t i = 0; i < path.size(); i++)
775 wpath.emplace_back(qz);
778 for (
size_t i = 0; i < path.size(); i++) {
779 if (path[i].second == 0)
781 if (path[i].second > 0)
784 else if (path[i].second < 0) {
795 for (
size_t j = 0; j <
nargs; j++) {
803 if (q.
real() < std::min(prev_fix_point.
real(), next_fix_point.
real()) || q.
real() > std::max(prev_fix_point.
real(), next_fix_point.
real()))
808 if (q.
real() < current_point.
real())
809 shift = std::min(shift, (next_fix_point.
imag()-current_point.
imag()) + (next_fix_point.
real()-current_point.
real()) / (q.
real()-current_point.
real()) * (q.
imag()-current_point.
imag()));
811 shift = std::min(shift, (prev_fix_point.
imag()-current_point.
imag()) + (prev_fix_point.
real()-current_point.
real()) / (q.
real()-current_point.
real()) * (q.
imag()-current_point.
imag()));
814 if (q.
real() < current_point.
real())
815 shift = std::max(shift, (next_fix_point.
imag()-current_point.
imag()) + (next_fix_point.
real()-current_point.
real()) / (q.
real()-current_point.
real()) * (q.
imag()-current_point.
imag()));
817 shift = std::max(shift, (prev_fix_point.
imag()-current_point.
imag()) + (prev_fix_point.
real()-current_point.
real()) / (q.
real()-current_point.
real()) * (q.
imag()-current_point.
imag()));
821 wpath[i+1] +=
I*shift/2;
836 std::vector<size_t> orders(
nargs,0);
837 std::vector<Terms> expansion(
nargs);
838 std::vector<Terms> results(
nargs+1);
839 results.rbegin()->add(1,0);
843 auto evaluate_numeric = [&](
const Terms& terms) ->
numeric {
845 for (
const Term& term : terms)
847 return result / norm;
851 auto LiNegIntOrd = [](
const ex& q,
const size_t k) ->
ex {
854 std::vector<ex> result;
856 for (
size_t i = 1; i <= k; i++) {
859 for (
size_t j = 0; j < i; j++)
861 result.emplace_back(
pow(q,i) *
add(en));
863 return add(result) /
pow(1 - q, k + 1);
869 constexpr size_t ALL_KERNELS = std::numeric_limits<size_t>::max();
870 auto expand_and_integrate_kernel = [&](
const size_t kernel_index,
const size_t num_extra_orders) ->
numeric {
873 for (
size_t i = (kernel_index==ALL_KERNELS ? 0 : kernel_index); i <
nargs; i++) {
877 if (kernel_index == ALL_KERNELS || kernel_index == i) {
878 const size_t ni =
args[
idx].ni;
879 const ex& zi = nzis[
idx];
880 const ex& qi = nqis[
idx];
881 const size_t order_min = (orders[
idx] + 1) - 1;
882 const size_t order_max = (orders[
idx] += num_extra_orders) - 1;
888 if (order_min == 0) {
890 new_terms.add(
I*
Pi, 0);
892 new_terms.add(2*
Pi*
I*qi, 0, std::vector<ex>{}, qi);
895 new_terms.add(-2*
zeta(ni), 0);
898 const int sign = ni%2 == 0 ? 1 : -1;
900 for (
size_t i = std::max((
size_t)1,order_min); i <= order_max; i++) {
901 const ex gSum = LiNegIntOrd(
pow(qtau,i), ni-1).evalf();
902 new_terms.add(
factor * gSum /
pow(qi, i), +i);
903 new_terms.add(
factor * gSum *
pow(qi, i) * sign, -i);
910 for (
const Term& new_integration_result : new_result)
911 for (
const Term& expansion_term : expansion[
idx])
912 new_integrand.add(expansion_term, new_integration_result, -1);
914 for (
const Term& new_expansion_term : new_terms)
915 for (
const Term& integration_result : results[
idx+1])
916 new_integrand.add(integration_result, new_expansion_term, -1);
920 if (!new_terms.empty() && i)
921 expansion[
idx].add(new_terms);
929 while (!new_integrand.empty())
930 new_integrand.pop().integrate(wpath[0], new_integrand, new_result);
931 results[
idx].add(new_result);
934 return evaluate_numeric(new_result);
940 for (
size_t i = 0; i <
nargs; i++) {
945 expand_and_integrate_kernel(i, 1);
952 const double dzi = nzis[
idx].imag().to_double();
953 const double conv = std::max({std::abs(dz),std::abs(dzi),std::abs(dz-dzi)});
961 uint64_t iterating = (uint64_t(1) <<
nargs) - uint64_t(1);
963 for (
size_t i = 0; i <
nargs; i++) {
964 if (iterating & (1 << i)) {
966 iterating ^= (delta < accuracy_goal) << i;
977 }
while (delta > accuracy_goal);
980 std::cout <<
"qExpand order:";
981 for (
size_t i = 0; i <
nargs; i++)
982 std::cout <<
" " << orders[i];
983 std::cout << std::endl;
989 return evaluate_numeric(results[0]);
1001 return Gt.zisToFundamental(points);
1007 return Gt.regularise(points);
1013 return Gt.tauToFundamental(points);
1019 return Gt.applyIntegrationPath(
Gt.decomposeIntegrationPath(points));
1025 return Gt.qExpand(points);
1034 if (
DEBUG_GT>=3) std::cout <<
"step1: " << result << std::endl;
1038 if (
DEBUG_GT>=3) std::cout <<
"step2: " << result << std::endl;
1044 if (
DEBUG_GT>=4) std::cout <<
"step3a: " << result << std::endl;
1046 if (
DEBUG_GT>=4) std::cout <<
"step3b: " << result << std::endl;
1048 if (
DEBUG_GT>=3) std::cout <<
"step3: " << result << std::endl;
1050 if (
DEBUG_GT>=2) std::cout <<
"(tauToFundamental skipped)" << std::endl;
1055 if (
DEBUG_GT>=4) std::cout <<
"step4a: " << result << std::endl;
1058 if (
DEBUG_GT>=2) std::cout <<
"prepared: " << result << std::endl;
1067 std::cout <<
"input: " << expr;
1069 std::cout <<
"; points=" << *points;
1070 std::cout << std::endl;
1074 if (
DEBUG_GT>=4) std::cout <<
"evaluated: " << result << std::endl;
1082 std::cout <<
"input: " << list;
1084 std::cout <<
"; points=" << *points;
1085 std::cout << std::endl;
1089 for (
size_t i = 0; i < prepared.
nops(); i++)
1091 if (
DEBUG_GT>=4) std::cout <<
"evaluated: " << result << std::endl;
1126 const ex replaced = (points ? expr.
subs(*points).
subs(*points) : expr).evalf();
1131 throw std::invalid_argument((std::stringstream{} <<
"Gt: argument '" << expr <<
"' is not numeric, evaluated to '" << replaced <<
"'").str());
1141 throw std::invalid_argument((std::stringstream{} <<
"Gt: argument '" << expr <<
"' is not " << (allow_negative ?
"an" :
"a non-negative") <<
" integer").str());
1153 Digits.add_callback([](
long change) ->
void {
1156 return Gt_detail::TransformExpressionWithCache<G2_SERIAL>{
1157 [](
const ex& obj) {
return obj.evalf();},
1158 [](
const ex& obj) {
return obj.evalf();}
Interface to GiNaC's elliptic multiple polylogarithms.
Interface to helper functions for elliptic multiple polylogarithms.
Interface to GiNaC's sums of expressions.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
Elliptic Multiple Polylogarithm.
std::vector< ex > decomposeIntegrationPath(const ex *points=nullptr) const
static void clear_polylog_cache()
std::vector< kernel > args
static ex ex_zisToFundamental(const ex &expr, const ex *points=nullptr)
static numeric ex_qExpand(const ex &expr, const ex *points=nullptr)
bool match(const ex &pattern, exmap &repl_lst) const override
Check whether the expression matches a given pattern.
static ex ex_prepare(const ex &expr, const ex *points=nullptr)
matrix findMoebiusTransform(const ex *points=nullptr) const
ex subs(const exmap &m, unsigned options=0) const override
Substitute a set of objects by arbitrary expressions.
static ex apply_function_recursive(const ex &input, const std::function< ex(const Gt &)> &func)
static ex ex_cutIntegrationPath(const ex &expr, const ex *points=nullptr)
void setArgs(const ex &args)
static long to_integer(const ex &expr, const bool allow_negative)
numeric qExpand(const ex *points=nullptr) const
unsigned calchash() const override
Compute the hash value of an object and if it makes sense to store it in the objects status_flags,...
static double cutIntegrationPath_threshold_imag
ex eval() const override
Perform automatic non-interruptive term rewriting rules.
void do_print_latex(const print_latex &c, unsigned level) const
ex regularise(const ex *points=nullptr) const
static lst lst_evaluate(const lst &list, const ex *points=nullptr)
static ex ex_tauToFundamental(const ex &expr, const ex *points=nullptr)
ex evalf() const override
Evaluate object numerically.
void do_print(const print_context &c, unsigned level) const
void archive(archive_node &n) const override
Save (a.k.a.
static Gt_detail::TransformExpressionWithCache< G2_SERIAL > nqexand_transformer
void read_archive(const archive_node &n, lst &syms) override
Read (a.k.a.
static size_t qExpand_minOrder
static numeric to_numeric(const ex &expr, const ex *points=nullptr)
static bool auto_clear_polylog_cache
static bool enable_tauToFundamental
ex tauToFundamental(const ex *points=nullptr) const
ex zisToFundamental(const ex *points=nullptr) const
static size_t qExpand_stepSize
numeric evaluate(const ex *points=nullptr) const
bool has(const ex &other, unsigned options=0) const override
Test for occurrence of a pattern.
static numeric ex_evaluate(const ex &expr, const ex *points=nullptr)
static double cutIntegrationPath_threshold_real
ex applyIntegrationPath(const std::vector< ex > &endpoints) const
Gt(const ex &args, const ex &z, const ex &tau)
static ex ex_regularise(const ex &expr, const ex *points=nullptr)
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
bool find_ex(const std::string &name, ex &ret, lst &sym_lst, unsigned index=0) const
Retrieve property of type "ex" from node.
void add_ex(const std::string &name, const ex &value)
Add property of type "ex" to node.
bool overflow(void) const
Return the overflow flag.
const std::vector< T > & get_vector(void) const
Returns a reference to the vector v.
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
const basic & setflag(unsigned f) const
Set some status_flags.
ex diff(const symbol &s, unsigned nth=1) const
Default interface of nth derivative ex::diff(s, n).
unsigned hashvalue
hash value
unsigned flags
of type status_flags
const basic & hold() const
Stop further evaluation.
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
virtual ex normal(exmap &repl, exmap &rev_lookup, lst &modifier) const
Default implementation of ex::normal().
size_t nops() const override
Number of operands/members.
ex op(size_t i) const override
Return operand/member at position i.
container & append(const ex &b)
Add element at back.
Lightweight wrapper for GiNaC's symbolic objects.
ex normal() const
Normalization of rational functions.
ex subs(const exmap &m, unsigned options=0) const
int compare(const ex &other) const
This class holds one index of an indexed object.
matrix mul(const matrix &other) const
Product of matrices.
The class multi_iterator_shuffle defines a multi_iterator, which runs over all shuffles of a and b.
basic_multi_iterator< T > & init(void)
Initialize the multi-index to the first shuffle.
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
const numeric real() const
Real part of a number.
long to_long() const
Converts numeric types to machine's long.
bool is_nonneg_integer() const
True if object is an exact integer greater or equal zero.
bool is_positive() const
True if object is not complex and greater than zero.
bool is_integer() const
True if object is a non-complex integer.
bool is_negative() const
True if object is not complex and less than zero.
cln::cl_N to_cl_N() const
Returns a new CLN object of type cl_N, representing the value of *this.
const numeric imag() const
Imaginary part of a number.
double to_double() const
Converts numeric types to machine's double.
This class holds a two-component object, a basis and and exponent representing exponentiation.
Base class for print_contexts.
std::ostream & s
stream to output to
Context for latex-parsable output.
@ evaluated
.eval() has already done its job
@ hash_calculated
.calchash() has already done its job
Interface to GiNaC's constant types and some special constants.
Interface to GiNaC's initially known functions.
Definition of GiNaC's lst.
Interface to symbolic matrices.
Interface to GiNaC's products of expressions.
ex deconcatenate_path(const std::vector< Kernel > &args, const std::vector< ex > &endpoints, const std::function< ex(std::vector< Kernel > &new_args, const ex &start, const ex &end)> &construct)
bool is_zero(const ex &thisex)
const numeric I
Imaginary unit.
const numeric pow(const numeric &x, const numeric &y)
container< std::list > lst
std::map< ex, ex, ex_is_less > exmap
B & dynallocate(Args &&... args)
Constructs a new (class basic or derived) B object on the heap.
const numeric abs(const numeric &x)
Absolute value.
function zeta(const T1 &p1)
bool are_ex_trivially_equal(const ex &e1, const ex &e2)
Compare two objects of class quickly without doing a deep tree traversal.
attribute_pure const T & ex_to(const ex &e)
Return a reference to the basic-derived class T object embedded in an expression.
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 ls GINAC_BIND_UNARCHIVER)(lst)
Specialization of container::info() for lst.
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 factorial(const numeric &n)
Factorial combinatorial function.
const constant Pi("Pi", PiEvalf, "\\pi", domain::positive)
Pi.
bool is_a(const basic &obj)
Check if obj is a T, including base classes.
const numeric log(const numeric &x)
Natural logarithm.
const numeric real(const numeric &x)
_numeric_digits Digits
Accuracy in decimal digits.
unsigned rotate_left(unsigned n)
Rotate bits of unsigned value by one bit to the left.
ex factor(const ex &poly, unsigned options)
Interface function to the outside world.
bool is_exactly_a(const basic &obj)
Check if obj is a T, not including base classes.
class_info< OPT > * class_info< OPT >::first
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.
Interface to GiNaC's symbolic objects.
Utilities for summing over multiple indices.