62Gt::kernel::kernel(
size_t ni,
ex zi,
int deform)
63 : ni(ni), zi(zi), deform(deform)
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())
88 if (std::abs(deform) > 1)
89 deform /= std::abs(deform);
112 if (is_a<numeric>(
tau.
evalf()) && !ex_to<numeric>(
tau.
evalf()).imag().is_positive())
113 throw std::runtime_error(
"Gt: Im(tau) needs to be greater than 0 b");
115 throw std::runtime_error(
"Gt: Too many kernels");
119 : nargs(args_.size()), args(args_), z(z_), tau(tau_)
123 throw std::invalid_argument(
"Gt: first argument must be a non-empty list");
126 if (is_a<numeric>(
tau.
evalf()) && !ex_to<numeric>(
tau.
evalf()).imag().is_positive())
127 throw std::runtime_error(
"Gt: Im(tau) needs to be greater than 0 a");
130 throw std::runtime_error(
"Gt: Too many kernels");
135 if (!is_a<lst>(new_args))
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++) {
145 if (is_a<lst>(new_args.
op(i)))
146 args.emplace_back(ex_to<lst>(new_args.
op(i)));
148 throw std::invalid_argument(
"Gt: first argument must be a list of tuples");
158 inherited::read_archive(
n, sym_lst);
160 n.find_ex(
"args",
args, sym_lst);
161 n.find_ex(
"z",
z, sym_lst);
162 n.find_ex(
"tau",
tau, 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);
174 n.add_ex(
"tau",
tau);
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;
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)
251 bool all_numeric = is_a<numeric>(
z) && is_a<numeric>(
tau);
253 all_numeric &= is_a<numeric>(
k.zi);
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);
270 if (already_evaluated)
272 return dynallocate<Gt>(new_args, nz, ntau);
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);
315 if (
typeid(*
this) !=
typeid(ex_to<basic>(pattern)))
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)
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;
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);
475 for (shuffle.init(); !shuffle.overflow(); shuffle++) {
476 std::vector<kernel> new_args;
477 new_args.reserve(na + i);
478 for (
const kernel&
k : shuffle.get_vector())
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)
544 : prefactor(prefactor),
power(
power), args(args) {}
546 ex evaluate(
const ex upper_bound,
const ex& tau) {
547 return prefactor *
pow(upper_bound,
power) * (args.empty() ?
ex{1} :
Gt(std::move(args), upper_bound, tau));
550 struct integrand_term {
554 std::vector<kernel> args;
556 integrand_term(
ex prefactor,
size_t power,
kernel kern, std::vector<kernel> args)
557 : prefactor(prefactor),
power(
power), kern(kern), args(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>{});
563 args.reserve(args.size() + 1 +
power);
564 args.emplace(args.begin(), kern);
565 result.emplace_back(prefactor,
power,args);
567 prefactor *= -int(
power--);
568 args.emplace(args.begin(),
kernel{0,0});
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++) {
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);
682 return Gt_detail::deconcatenate_path<kernel>(
args, endpoints, [
this](std::vector<kernel>& new_args,
const ex& start,
const ex& end) ->
ex {
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;
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;
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++)
774 wpath.emplace_back(
pow(qz,path[i].first/nz.
real()));
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)
783 wpath[i+1] -=
I*ex_to<numeric>(wpath[i+1].
evalf()).
imag()/2;
784 else if (path[i].second < 0) {
788 const numeric prev_fix_point = ex_to<numeric>(wpath[i].
evalf());
789 const numeric current_point = ex_to<numeric>(wpath[i+1].
evalf());
790 const numeric next_fix_point = ex_to<numeric>(wpath[i+2].
evalf());
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]);
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();
1128 if (is_a<numeric>(replaced))
1129 return ex_to<numeric>(replaced);
1131 throw std::invalid_argument((std::stringstream{} <<
"Gt: argument '" << expr <<
"' is not numeric, evaluated to '" << replaced <<
"'").str());
1135 if (is_a<numeric>(expr)) {
1136 const numeric n = ex_to<numeric>(expr);
1137 if (allow_negative ?
n.is_integer() :
n.is_nonneg_integer())
1141 throw std::invalid_argument((std::stringstream{} <<
"Gt: argument '" << expr <<
"' is not " << (allow_negative ?
"an" :
"a non-negative") <<
" integer").str());
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)
void add_callback(digits_changed_callback callback)
Add a new callback function.
add(const ex &lh, const ex &rh)
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 & 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().
int compare(const basic &other) const
Compare objects syntactically to establish canonical ordering.
Wrapper template for making GiNaC classes out of STL containers.
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.
bool has(const ex &pattern, unsigned options=0) const
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.
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
const numeric real() const
Real part of a number.
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.
const numeric mul(const numeric &other) const
Numerical multiplication method.
double to_double() const
Converts numeric types to machine's double.
bool is_zero() const
True if object is zero.
This class holds a two-component object, a basis and and exponent representing exponentiation.
Base class for print_contexts.
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.
bool is_zero(const ex &thisex)
const numeric I
Imaginary unit.
const numeric pow(const numeric &x, const numeric &y)
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.
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.
const numeric log(const numeric &x)
Natural logarithm.
const numeric real(const numeric &x)
_numeric_digits Digits
Accuracy in decimal digits.
static unsigned make_hash_seed(const std::type_info &tinfo)
We need a hash function which gives different values for objects of different types.
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.
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.
double to_double(const numeric &x)
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.