GiNaC 1.8.9
integration_kernel.cpp
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2025 Johannes Gutenberg University Mainz, Germany
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "integration_kernel.h"
24#include "add.h"
25#include "mul.h"
26#include "operators.h"
27#include "power.h"
28#include "relational.h"
29#include "symbol.h"
30#include "constant.h"
31#include "numeric.h"
32#include "function.h"
33#include "pseries.h"
34#include "utils.h"
35#include "inifcns.h"
36
37#include <iostream>
38#include <stdexcept>
39#include <cln/cln.h>
40
41
42namespace GiNaC {
43
44// anonymous namespace for helper function
45namespace {
46
61numeric kronecker_symbol_prime(const numeric & a, const numeric & n)
62{
63 if ( n == 1 ) {
64 return 1;
65 }
66 else if ( n == -1 ) {
67 if ( a >= 0 ) {
68 return 1;
69 }
70 else {
71 return -1;
72 }
73 }
74 else if ( n == 2 ) {
75 if ( GiNaC::smod(a,8) == 1 ) {
76 return 1;
77 }
78 else if ( GiNaC::smod(a,8) == -1 ) {
79 return 1;
80 }
81 else if ( GiNaC::smod(a,8) == 3 ) {
82 return -1;
83 }
84 else if ( GiNaC::smod(a,8) == -3 ) {
85 return -1;
86 }
87 else {
88 return 0;
89 }
90 }
91
92 // n is an odd prime number
93 return GiNaC::smod( pow(a,(n-1)/2), n);
94}
95
117numeric divisor_function(const numeric & n, const numeric & a, const numeric & b, const numeric & k)
118{
119 ex res = 0;
120
121 for (numeric i1=1; i1<=n; i1++) {
122 if ( irem(n,i1) == 0 ) {
123 numeric ratio = n/i1;
125 }
126 }
127
128 return ex_to<numeric>(res);
129}
130
147numeric coefficient_a0(const numeric & k, const numeric & a, const numeric & b)
148{
149 ex conductor = abs(a);
150
151 numeric a0;
152 if ( conductor == 1 ) {
153 a0 = -numeric(1,2)/k*generalised_Bernoulli_number(k,b);
154 }
155 else {
156 a0 = 0;
157 }
158
159 return a0;
160}
161
181ex eisenstein_series(const numeric & k, const ex & q, const numeric & a, const numeric & b, const numeric & N)
182{
183 ex res = coefficient_a0(k,a,b);
184
185 for (numeric i1=1; i1<N; i1++) {
186 res += divisor_function(i1,a,b,k) * pow(q,i1);
187 }
188
189 return res;
190}
191
197ex E_eisenstein_series(const ex & q, const numeric & k, const numeric & N_level, const numeric & a, const numeric & b, const numeric & K, const numeric & N_order)
198{
199 int N_order_int = N_order.to_int();
200
201 ex res = eisenstein_series(k,pow(q,K),a,b,iquo(N_order,K));
202
203 res += Order(pow(q,N_order_int));
204 res = res.series(q,N_order_int);
205
206 return res;
207}
208
215ex B_eisenstein_series(const ex & q, const numeric & N_level, const numeric & K, const numeric & N_order)
216{
217 int N_order_int = N_order.to_int();
218
219 ex res = eisenstein_series(2,q,1,1,N_order) - K*eisenstein_series(2,pow(q,K),1,1,iquo(N_order,K));
220
221 res += Order(pow(q,N_order_int));
222 res = res.series(q,N_order_int);
223
224 return res;
225}
226
232struct subs_q_expansion : public map_function
233{
234 subs_q_expansion(const ex & arg_qbar, int arg_order) : qbar(arg_qbar), order(arg_order)
235 {}
236
237 ex operator()(const ex & e)
238 {
239 if ( is_a<Eisenstein_kernel>(e) || is_a<Eisenstein_h_kernel>(e) ) {
240 return series_to_poly(e.series(qbar,order));
241 }
242 else {
243 return e.map(*this);
244 }
245 }
246
248 int order;
249};
250
262class Li_negative
263{
264 // ctors
265public:
266 Li_negative();
267
268 // non-virtual functions
269public:
270 ex get_symbolic_value(int n, const ex & x_val);
271 ex get_numerical_value(int n, const ex & x_val);
272
273 // member variables :
274protected:
275 static std::vector<ex> cache_vec;
276 static symbol x;
277};
278
279
280Li_negative::Li_negative() {}
281
282ex Li_negative::get_symbolic_value(int n, const ex & x_val)
283{
284 int n_cache = cache_vec.size();
285
286 if ( n >= n_cache ) {
287 for (int j=n_cache; j<=n; j++) {
288 ex f;
289 if ( j == 0 ) {
290 f = x/(1-x);
291 }
292 else {
293 f = normal( x*diff(cache_vec[j-1],x));
294 }
295 cache_vec.push_back( f );
296 }
297 }
298
299 return cache_vec[n].subs(x==x_val);
300}
301
302ex Li_negative::get_numerical_value(int n, const ex & x_val)
303{
304 symbol x_symb("x_symb");
305
306 ex f = this->get_symbolic_value(n,x_symb);
307
308 ex res = f.subs(x_symb==x_val).evalf();
309
310 return res;
311}
312
313// initialise static data members
314std::vector<ex> Li_negative::cache_vec;
315symbol Li_negative::x = symbol("x");
316
317
318} // end of anonymous namespace
319
330{
331 if ( !n.is_pos_integer() ) throw (std::runtime_error("ifactor(): argument not a positive integer"));
332
333 lst p_lst, exp_lst;
334
335 // implementation for small integers
336 numeric n_temp = n;
337 for (numeric p=2; p<=n; p++) {
338 if ( p.info(info_flags::prime) ) {
339 numeric exp_temp = 0;
340 while ( irem(n_temp, p) == 0 ) {
341 n_temp = n_temp/p;
342 exp_temp++;
343 }
344 if ( exp_temp>0 ) {
345 p_lst.append(p);
346 exp_lst.append(exp_temp);
347 }
348 }
349 if ( n_temp == 1 ) break;
350 }
351
352 if ( n_temp != 1 ) throw (std::runtime_error("ifactor(): probabilistic primality test failed"));
353
354 lst res = {p_lst,exp_lst};
355
356 return res;
357}
358
369{
370 if ( n == 0 ) {
371 return false;
372 }
373
374 if ( n == 1 ) {
375 return true;
376 }
377
378 lst prime_factorisation = ex_to<lst>(ifactor(abs(n)));
379 lst p_lst = ex_to<lst>(prime_factorisation.op(0));
380 lst e_lst = ex_to<lst>(prime_factorisation.op(1));
381
382 size_t n_primes = p_lst.nops();
383
384 if ( n_primes > 0 ) {
385 // take the last prime
386 numeric p = ex_to<numeric>(p_lst.op(n_primes-1));
387
388 if ( p.is_odd() ) {
389 if ( e_lst.op(n_primes-1) != 1 ) {
390 return false;
391 }
392
393 numeric pstar = p;
394 if ( mod(p,4) == 3 ) {
395 pstar = -p;
396 }
398 }
399 }
400 // power of two now
401 if ( (n==-4) || (n==-8) || (n==8) || (n==-32) || (n==32) || (n==-64) || (n==128) ) {
402 return true;
403 }
404
405 return false;
406}
407
426{
427 // case n=0 first, include kronecker_symbol(0,0)=0
428 if ( n == 0 ) {
429 if ( (a == 1) || (a == -1) ) {
430 return 1;
431 }
432 else {
433 return 0;
434 }
435 }
436
437 numeric unit = 1;
438 numeric n_pos = n;
439 if ( n_pos<0 ) {
440 unit = -1;
441 n_pos = -n;
442 }
443
444 ex res = kronecker_symbol_prime(a,unit);
445
446 numeric n_odd = n_pos;
447 numeric alpha = 0;
448 while ( n_odd.is_even() ) {
449 alpha++;
450 n_odd = n_odd/2;
451 }
452 if ( alpha>0 ) {
453 res *= pow(kronecker_symbol_prime(a,2),alpha);
454 }
455
456 lst temp_lst = ex_to<lst>(ifactor(n_odd));
457 lst prime_lst = ex_to<lst>(temp_lst.op(0));
458 lst expo_lst = ex_to<lst>(temp_lst.op(1));
459
460 for (auto it_p = prime_lst.begin(), it_e = expo_lst.begin(); it_p != prime_lst.end(); it_p++, it_e++) {
461 res *= pow(kronecker_symbol_prime(a,ex_to<numeric>(*it_p)),ex_to<numeric>(*it_e));
462 }
463
464 return ex_to<numeric>(res);
465}
466
479{
480 return kronecker_symbol(a,n);
481}
482
495numeric dirichlet_character(const numeric & n, const numeric & a, const numeric & N)
496{
497 if ( gcd(n,N) == 1 ) {
499 }
500
501 return 0;
502}
503
518{
519 int k_int = k.to_int();
520
521 symbol x("x");
522
523 numeric conductor = abs(b);
524
525 ex gen_fct = 0;
526 for (numeric i1=1; i1<=conductor; i1++) {
527 gen_fct += primitive_dirichlet_character(i1,b) * x*exp(i1*x)/(exp(conductor*x)-1);
528 }
529
530 gen_fct = series_to_poly(gen_fct.series(x,k_int+1));
531
532 ex B = factorial(k) * gen_fct.coeff(x,k_int);
533
534 return ex_to<numeric>(B);
535}
536
543{
544 int k_int = k.to_int();
545
546 symbol t("t");
547
548 ex gen_fct = t*exp(x*t)/(exp(t)-1);
549
550 gen_fct = series_to_poly(gen_fct.series(t,k_int+1));
551
552 ex B = factorial(k) * gen_fct.coeff(t,k_int);
553
554 return B;
555}
556
557
558
561
562integration_kernel::integration_kernel() : inherited(), cache_step_size(100), series_vec()
563{
564}
565
566int integration_kernel::compare_same_type(const basic &other) const
567{
568 return 0;
569}
570
571ex integration_kernel::series(const relational & r, int order, unsigned options) const
572{
573 if ( r.rhs() != 0 ) {
574 throw (std::runtime_error("integration_kernel::series: non-zero expansion point not implemented"));
575 }
576
577 return Laurent_series(r.lhs(),order);
578}
579
585bool integration_kernel::has_trailing_zero(void) const
586{
587 if ( cln::zerop( series_coeff(0) ) ) {
588 return false;
589 }
590
591 return true;
592}
593
599bool integration_kernel::is_numeric(void) const
600{
601 return true;
602}
603
616cln::cl_N integration_kernel::series_coeff(int i) const
617{
618 int n_vec = series_vec.size();
619
620 if ( i >= n_vec ) {
621 int N = cache_step_size*(i/cache_step_size+1);
622
623 if ( uses_Laurent_series() ) {
624 symbol x("x");
625 // series_vec[0] gives coefficient of 1/z, series_vec[N-1] coefficient of z^(N-2),
626 // thus expansion up to order (N-1) is required
627 ex temp = Laurent_series(x, N-1);
628 for (int j=n_vec; j<N; j++) {
629 series_vec.push_back( ex_to<numeric>(temp.coeff(x,j-1).evalf()).to_cl_N() );
630 }
631 }
632 else {
633 for (int j=n_vec; j<N; j++) {
634 series_vec.push_back( series_coeff_impl(j) );
635 }
636 }
637 }
638
639 return series_vec[i];
640}
641
649cln::cl_N integration_kernel::series_coeff_impl(int i) const
650{
651 if ( i == 1 ) {
652 return 1;
653 }
654
655 return 0;
656}
657
664ex integration_kernel::Laurent_series(const ex & x, int order) const
665{
666 ex res = 0;
667 for (int n=-1; n<order; n++) {
668 res += numeric(series_coeff(n+1)) * pow(x,n);
669 }
670 res += Order(pow(x,order));
671 res = res.series(x,order);
672
673 return res;
674}
675
681ex integration_kernel::get_numerical_value(const ex & lambda, int N_trunc) const
682{
683 return get_numerical_value_impl(lambda, 1, 0, N_trunc);
684}
685
695bool integration_kernel::uses_Laurent_series() const
696{
697 return false;
698}
699
705size_t integration_kernel::get_cache_size(void) const
706{
707 return series_vec.size();
708}
709
715void integration_kernel::set_cache_step(int cache_steps) const
716{
717 cache_step_size = cache_steps;
718}
719
725ex integration_kernel::get_series_coeff(int i) const
726{
727 return numeric(series_coeff(i));
728}
729
735ex integration_kernel::get_numerical_value_impl(const ex & lambda, const ex & pre, int shift, int N_trunc) const
736{
737 cln::cl_N lambda_cln = ex_to<numeric>(lambda.evalf()).to_cl_N();
738 cln::cl_N pre_cln = ex_to<numeric>(pre.evalf()).to_cl_N();
739
740 cln::cl_F one = cln::cl_float(1, cln::float_format(Digits));
741
742 cln::cl_N res = 0;
743 cln::cl_N resbuf;
744 cln::cl_N subexpr;
745
746 if ( N_trunc == 0 ) {
747 // sum until precision is reached
748 bool flag_accidental_zero = false;
749
750 int N = 0;
751
752 do {
753 resbuf = res;
754
755 subexpr = series_coeff(N);
756
757 res += pre_cln * subexpr * cln::expt(lambda_cln,N-1+shift);
758
759 flag_accidental_zero = cln::zerop(subexpr);
760
761 N++;
762 } while ( (res != resbuf) || flag_accidental_zero );
763 }
764 else {
765 // N_trunc > 0, sum up the first N_trunc terms
766 for (int N=0; N<N_trunc; N++) {
767 subexpr = series_coeff(N);
768
769 res += pre_cln * subexpr * cln::expt(lambda_cln,N-1+shift);
770 }
771 }
772
773 return numeric(res);
774}
775
776void integration_kernel::do_print(const print_context & c, unsigned level) const
777{
778 c.s << "integration_kernel()";
779}
780
782
783
785 print_func<print_context>(&basic_log_kernel::do_print))
786
787basic_log_kernel::basic_log_kernel() : inherited()
788{
789}
790
791int basic_log_kernel::compare_same_type(const basic &other) const
792{
793 return 0;
794}
795
796cln::cl_N basic_log_kernel::series_coeff_impl(int i) const
797{
798 if ( i == 0 ) {
799 return 1;
800 }
801
802 return 0;
803}
804
805void basic_log_kernel::do_print(const print_context & c, unsigned level) const
806{
807 c.s << "basic_log_kernel()";
808}
809
811
812
814 print_func<print_context>(&multiple_polylog_kernel::do_print))
815
816multiple_polylog_kernel::multiple_polylog_kernel() : inherited(), z(_ex1)
817{
818}
819
820multiple_polylog_kernel::multiple_polylog_kernel(const ex & arg_z) : inherited(), z(arg_z)
821{
822}
823
825{
826 const multiple_polylog_kernel &o = static_cast<const multiple_polylog_kernel &>(other);
827
828 return z.compare(o.z);
829}
830
832{
833 return 1;
834}
835
837{
838 if ( i != 0 ) {
839 throw(std::range_error("multiple_polylog_kernel::op(): out of range"));
840 }
841
842 return z;
843}
844
846{
848
849 if ( i != 0 ) {
850 throw(std::range_error("multiple_polylog_kernel::let_op(): out of range"));
851 }
852
853 return z;
854}
855
857{
859}
860
862{
863 if ( i == 0 ) {
864 return 0;
865 }
866
867 return -cln::expt(ex_to<numeric>(z.evalf()).to_cl_N(),-i);
868}
869
870void multiple_polylog_kernel::do_print(const print_context & c, unsigned level) const
871{
872 c.s << "multiple_polylog_kernel(";
873 z.print(c);
874 c.s << ")";
875}
876
878
879
886
887ELi_kernel::ELi_kernel(const ex & arg_n, const ex & arg_m, const ex & arg_x, const ex & arg_y) : inherited(), n(arg_n), m(arg_m), x(arg_x), y(arg_y)
888{
889}
890
891int ELi_kernel::compare_same_type(const basic &other) const
892{
893 const ELi_kernel &o = static_cast<const ELi_kernel &>(other);
894 int cmpval;
895
896 cmpval = n.compare(o.n);
897 if ( cmpval) {
898 return cmpval;
899 }
900
901 cmpval = m.compare(o.m);
902 if ( cmpval) {
903 return cmpval;
904 }
905
906 cmpval = x.compare(o.x);
907 if ( cmpval) {
908 return cmpval;
909 }
910
911 return y.compare(o.y);
912}
913
914size_t ELi_kernel::nops() const
915{
916 return 4;
917}
918
919ex ELi_kernel::op(size_t i) const
920{
921 switch (i) {
922 case 0:
923 return n;
924 case 1:
925 return m;
926 case 2:
927 return x;
928 case 3:
929 return y;
930 default:
931 throw (std::out_of_range("ELi_kernel::op() out of range"));
932 }
933}
934
936{
938
939 switch (i) {
940 case 0:
941 return n;
942 case 1:
943 return m;
944 case 2:
945 return x;
946 case 3:
947 return y;
948 default:
949 throw (std::out_of_range("ELi_kernel::let_op() out of range"));
950 }
951}
952
957
958cln::cl_N ELi_kernel::series_coeff_impl(int i) const
959{
960 if ( i == 0 ) {
961 return 0;
962 }
963
964 int n_int = ex_to<numeric>(n).to_int();
965 int m_int = ex_to<numeric>(m).to_int();
966
967 cln::cl_N x_cln = ex_to<numeric>(x.evalf()).to_cl_N();
968 cln::cl_N y_cln = ex_to<numeric>(y.evalf()).to_cl_N();
969
970 cln::cl_N res_cln = 0;
971
972 for (int j=1; j<=i; j++) {
973 if ( (i % j) == 0 ) {
974 int k = i/j;
975
976 res_cln += cln::expt(x_cln,j)/cln::expt(cln::cl_I(j),n_int) * cln::expt(y_cln,k)/cln::expt(cln::cl_I(k),m_int);
977 }
978 }
979
980 return res_cln;
981}
982
988ex ELi_kernel::get_numerical_value(const ex & qbar, int N_trunc) const
989{
990 return get_numerical_value_impl(qbar, 1, 1, N_trunc);
991}
992
993void ELi_kernel::do_print(const print_context & c, unsigned level) const
994{
995 c.s << "ELi_kernel(";
996 n.print(c);
997 c.s << ",";
998 m.print(c);
999 c.s << ",";
1000 x.print(c);
1001 c.s << ",";
1002 y.print(c);
1003 c.s << ")";
1004}
1005
1007
1008
1015
1016Ebar_kernel::Ebar_kernel(const ex & arg_n, const ex & arg_m, const ex & arg_x, const ex & arg_y) : inherited(), n(arg_n), m(arg_m), x(arg_x), y(arg_y)
1017{
1018}
1019
1020int Ebar_kernel::compare_same_type(const basic &other) const
1021{
1022 const Ebar_kernel &o = static_cast<const Ebar_kernel &>(other);
1023 int cmpval;
1024
1025 cmpval = n.compare(o.n);
1026 if ( cmpval) {
1027 return cmpval;
1028 }
1029
1030 cmpval = m.compare(o.m);
1031 if ( cmpval) {
1032 return cmpval;
1033 }
1034
1035 cmpval = x.compare(o.x);
1036 if ( cmpval) {
1037 return cmpval;
1038 }
1039
1040 return y.compare(o.y);
1041}
1042
1043size_t Ebar_kernel::nops() const
1044{
1045 return 4;
1046}
1047
1048ex Ebar_kernel::op(size_t i) const
1049{
1050 switch (i) {
1051 case 0:
1052 return n;
1053 case 1:
1054 return m;
1055 case 2:
1056 return x;
1057 case 3:
1058 return y;
1059 default:
1060 throw (std::out_of_range("Ebar_kernel::op() out of range"));
1061 }
1062}
1063
1065{
1067
1068 switch (i) {
1069 case 0:
1070 return n;
1071 case 1:
1072 return m;
1073 case 2:
1074 return x;
1075 case 3:
1076 return y;
1077 default:
1078 throw (std::out_of_range("Ebar_kernel::let_op() out of range"));
1079 }
1080}
1081
1086
1088{
1089 if ( i == 0 ) {
1090 return 0;
1091 }
1092
1093 int n_int = ex_to<numeric>(n).to_int();
1094 int m_int = ex_to<numeric>(m).to_int();
1095
1096 cln::cl_N x_cln = ex_to<numeric>(x.evalf()).to_cl_N();
1097 cln::cl_N y_cln = ex_to<numeric>(y.evalf()).to_cl_N();
1098
1099 cln::cl_N res_cln = 0;
1100
1101 for (int j=1; j<=i; j++) {
1102 if ( (i % j) == 0 ) {
1103 int k = i/j;
1104
1105 res_cln += (cln::expt(x_cln,j)*cln::expt(y_cln,k)-cln::expt(cln::cl_I(-1),n_int+m_int)*cln::expt(x_cln,-j)*cln::expt(y_cln,-k))/cln::expt(cln::cl_I(j),n_int)/cln::expt(cln::cl_I(k),m_int);
1106 }
1107 }
1108
1109 return res_cln;
1110}
1111
1117ex Ebar_kernel::get_numerical_value(const ex & qbar, int N_trunc) const
1118{
1119 return get_numerical_value_impl(qbar, 1, 1, N_trunc);
1120}
1121
1122void Ebar_kernel::do_print(const print_context & c, unsigned level) const
1123{
1124 c.s << "Ebar_kernel(";
1125 n.print(c);
1126 c.s << ",";
1127 m.print(c);
1128 c.s << ",";
1129 x.print(c);
1130 c.s << ",";
1131 y.print(c);
1132 c.s << ")";
1133}
1134
1136
1137
1144
1145Kronecker_dtau_kernel::Kronecker_dtau_kernel(const ex & arg_n, const ex & arg_z, const ex & arg_K, const ex & arg_C_norm) : inherited(), n(arg_n), z(arg_z), K(arg_K), C_norm(arg_C_norm)
1146{
1147}
1148
1149int Kronecker_dtau_kernel::compare_same_type(const basic &other) const
1150{
1151 const Kronecker_dtau_kernel &o = static_cast<const Kronecker_dtau_kernel &>(other);
1152 int cmpval;
1153
1154 cmpval = n.compare(o.n);
1155 if ( cmpval) {
1156 return cmpval;
1157 }
1158
1159 cmpval = z.compare(o.z);
1160 if ( cmpval) {
1161 return cmpval;
1162 }
1163
1164 cmpval = K.compare(o.K);
1165 if ( cmpval) {
1166 return cmpval;
1167 }
1168
1169 return C_norm.compare(o.C_norm);
1170}
1171
1173{
1174 return 4;
1175}
1176
1178{
1179 switch (i) {
1180 case 0:
1181 return n;
1182 case 1:
1183 return z;
1184 case 2:
1185 return K;
1186 case 3:
1187 return C_norm;
1188 default:
1189 throw (std::out_of_range("Kronecker_dtau_kernel::op() out of range"));
1190 }
1191}
1192
1194{
1196
1197 switch (i) {
1198 case 0:
1199 return n;
1200 case 1:
1201 return z;
1202 case 2:
1203 return K;
1204 case 3:
1205 return C_norm;
1206 default:
1207 throw (std::out_of_range("Kronecker_dtau_kernel::let_op() out of range"));
1208 }
1209}
1210
1215
1217{
1218 numeric n_num = ex_to<numeric>(n);
1219 int n_int = n_num.to_int();
1220
1221 // case n=0
1222 if ( n_num == 0 ) {
1223 if ( i == 0 ) {
1224 ex res = -C_norm*K;
1225
1226 return ex_to<numeric>(res.evalf()).to_cl_N();
1227 }
1228
1229 return 0;
1230 }
1231
1232 // case n=1
1233 if ( n_num == 1 ) {
1234 return 0;
1235 }
1236
1237 // case n>1
1238 if ( i == 0 ) {
1239 ex res = C_norm*K / factorial(n_num-2) * bernoulli(n_num)/n_num;
1240
1241 return ex_to<numeric>(res.evalf()).to_cl_N();
1242 }
1243
1244 // n>1, i>0
1245
1246 // if K>1 the variable i needs to be a multiple of K
1247 int K_int = ex_to<numeric>(K).to_int();
1248
1249 if ( (i % K_int) != 0 ) {
1250 return 0;
1251 }
1252 int i_local = i/K_int;
1253
1254 ex w = exp(ex_to<numeric>((2*Pi*I*z).evalf()));
1255 cln::cl_N w_cln = ex_to<numeric>(w).to_cl_N();
1256 cln::cl_N res_cln = 0;
1257 for (int j=1; j<=i_local; j++) {
1258 if ( (i_local % j) == 0 ) {
1259 res_cln += (cln::expt(w_cln,j)+cln::expt(cln::cl_I(-1),n_int)*cln::expt(w_cln,-j)) * cln::expt(cln::cl_I(i_local/j),n_int-1);
1260 }
1261 }
1262 ex pre = -C_norm*K/factorial(n_num-2);
1263
1264 return ex_to<numeric>(pre.evalf()).to_cl_N() * res_cln;
1265}
1266
1273{
1274 numeric n_num = ex_to<numeric>(n);
1275
1276 if ( n_num == 0 ) {
1277 return 1;
1278 }
1279
1280 // use the direct formula here
1281 if ( n_num == 1 ) {
1282 ex wbar = exp(ex_to<numeric>((2*Pi*I*z).evalf()));
1283 ex res = -2*Pi*I*( numeric(1,2)*(1+wbar)/(1-wbar) + Ebar_kernel(0,0,wbar,1).get_numerical_value(pow(qbar,K),N_trunc));
1284
1285 return ex_to<numeric>(res.evalf());
1286 }
1287
1288 ex pre = pow(2*Pi*I,n_num)/C_norm/K/(n_num-1);
1289
1290 return get_numerical_value_impl(qbar, pre, 1, N_trunc);
1291}
1292
1293void Kronecker_dtau_kernel::do_print(const print_context & c, unsigned level) const
1294{
1295 c.s << "Kronecker_dtau_kernel(";
1296 n.print(c);
1297 c.s << ",";
1298 z.print(c);
1299 c.s << ",";
1300 K.print(c);
1301 c.s << ",";
1302 C_norm.print(c);
1303 c.s << ")";
1304}
1305
1307
1308
1315
1316Kronecker_dz_kernel::Kronecker_dz_kernel(const ex & arg_n, const ex & arg_z_j, const ex & arg_tau, const ex & arg_K, const ex & arg_C_norm) : inherited(), n(arg_n), z_j(arg_z_j), tau(arg_tau), K(arg_K), C_norm(arg_C_norm)
1317{
1318}
1319
1320int Kronecker_dz_kernel::compare_same_type(const basic &other) const
1321{
1322 const Kronecker_dz_kernel &o = static_cast<const Kronecker_dz_kernel &>(other);
1323 int cmpval;
1324
1325 cmpval = n.compare(o.n);
1326 if ( cmpval) {
1327 return cmpval;
1328 }
1329
1330 cmpval = z_j.compare(o.z_j);
1331 if ( cmpval) {
1332 return cmpval;
1333 }
1334
1335 cmpval = tau.compare(o.tau);
1336 if ( cmpval) {
1337 return cmpval;
1338 }
1339
1340 cmpval = K.compare(o.K);
1341 if ( cmpval) {
1342 return cmpval;
1343 }
1344
1345 return C_norm.compare(o.C_norm);
1346}
1347
1349{
1350 return 5;
1351}
1352
1354{
1355 switch (i) {
1356 case 0:
1357 return n;
1358 case 1:
1359 return z_j;
1360 case 2:
1361 return tau;
1362 case 3:
1363 return K;
1364 case 4:
1365 return C_norm;
1366 default:
1367 throw (std::out_of_range("Kronecker_dz_kernel::op() out of range"));
1368 }
1369}
1370
1372{
1374
1375 switch (i) {
1376 case 0:
1377 return n;
1378 case 1:
1379 return z_j;
1380 case 2:
1381 return tau;
1382 case 3:
1383 return K;
1384 case 4:
1385 return C_norm;
1386 default:
1387 throw (std::out_of_range("Kronecker_dz_kernel::let_op() out of range"));
1388 }
1389}
1390
1395
1397{
1398 numeric n_num = ex_to<numeric>(n);
1399
1400 ex w_j_inv = exp(ex_to<numeric>((-2*Pi*I*z_j).evalf()));
1401 cln::cl_N w_j_inv_cln = ex_to<numeric>(w_j_inv).to_cl_N();
1402
1403 ex qbar = exp(ex_to<numeric>((2*Pi*I*K*tau).evalf()));
1404
1405 // case n=0
1406 if ( n_num == 0 ) {
1407 return 0;
1408 }
1409
1410 // case n=1
1411 if ( n_num == 1 ) {
1412 if ( i == 1 ) {
1413 return ex_to<numeric>((C_norm * 2*Pi*I).evalf()).to_cl_N();
1414 }
1415
1416 return 0;
1417 }
1418
1419 // case n=2
1420 if ( n_num == 2 ) {
1421 if ( ex_to<numeric>(z_j.evalf()).is_zero() ) {
1422 if ( i == 0 ) {
1423 return ex_to<numeric>((C_norm).evalf()).to_cl_N();
1424 }
1425 else if ( i == 1 ) {
1426 return 0;
1427 }
1428 else {
1429 ex res = -bernoulli(i)/numeric(i);
1430 if ( numeric(i).is_even() ) {
1431 Ebar_kernel Ebar = Ebar_kernel( 1-i, 0, numeric(1), numeric(1) );
1432 res += Ebar.get_numerical_value(qbar);
1433 }
1434
1435 res *= -pow(2*Pi*I,i)*C_norm/factorial(i-1);
1436
1437 return ex_to<numeric>(res.evalf()).to_cl_N();
1438 }
1439 }
1440 else {
1441 // z_j is not zero
1442 if ( i == 0 ) {
1443 return 0;
1444 }
1445 else {
1446 Li_negative my_Li_negative;
1447
1448 ex res = 0;
1449 if ( i == 1 ) {
1450 res = numeric(1,2);
1451 }
1452
1453 Ebar_kernel Ebar = Ebar_kernel( 1-i, 0, w_j_inv, numeric(1) );
1454
1455 res += my_Li_negative.get_numerical_value(i-1,w_j_inv) + Ebar.get_numerical_value(qbar);
1456
1457 res *= -pow(2*Pi*I,i)*C_norm/factorial(i-1);
1458
1459 return ex_to<numeric>(res.evalf()).to_cl_N();
1460 }
1461 }
1462 }
1463
1464 // case n>2
1465 ex res = 0;
1466 if ( i == 1 ) {
1467 res += - bernoulli(n_num-1)/(n_num-1);
1468 }
1469 if ( i > 0 ) {
1470 if ( ex_to<numeric>(z_j.evalf()).is_zero() ) {
1471 if ( (numeric(i)+n_num).is_even() ) {
1472 Ebar_kernel Ebar = Ebar_kernel( 1-i, 2-n_num, numeric(1), numeric(1) );
1473
1474 res += pow(2*Pi*I,i-1)/factorial(i-1) * Ebar.get_numerical_value(qbar);
1475 }
1476 }
1477 else {
1478 // z_j is not zero
1479 Ebar_kernel Ebar = Ebar_kernel( 1-i, 2-n_num, w_j_inv, numeric(1) );
1480
1481 res += pow(2*Pi*I,i-1)/factorial(i-1) * Ebar.get_numerical_value(qbar);
1482 }
1483 }
1484
1485 res *= - C_norm * 2*Pi*I/factorial(n_num-2);
1486
1487 return ex_to<numeric>(res.evalf()).to_cl_N();
1488}
1489
1496{
1497 numeric n_num = ex_to<numeric>(n);
1498
1499 if ( n_num == 1 ) {
1500 return 1;
1501 }
1502
1503 ex pre = pow(2*Pi*I,n-2)/C_norm;
1504
1505 return get_numerical_value_impl(z, pre, 0, N_trunc);
1506}
1507
1508void Kronecker_dz_kernel::do_print(const print_context & c, unsigned level) const
1509{
1510 c.s << "Kronecker_dz_kernel(";
1511 n.print(c);
1512 c.s << ",";
1513 z_j.print(c);
1514 c.s << ",";
1515 tau.print(c);
1516 c.s << ",";
1517 K.print(c);
1518 c.s << ",";
1519 C_norm.print(c);
1520 c.s << ")";
1521}
1522
1524
1525
1532
1533Eisenstein_kernel::Eisenstein_kernel(const ex & arg_k, const ex & arg_N, const ex & arg_a, const ex & arg_b, const ex & arg_K, const ex & arg_C_norm) : inherited(), k(arg_k), N(arg_N), a(arg_a), b(arg_b), K(arg_K), C_norm(arg_C_norm)
1534{
1535}
1536
1537int Eisenstein_kernel::compare_same_type(const basic &other) const
1538{
1539 const Eisenstein_kernel &o = static_cast<const Eisenstein_kernel &>(other);
1540 int cmpval;
1541
1542 cmpval = k.compare(o.k);
1543 if ( cmpval) {
1544 return cmpval;
1545 }
1546
1547 cmpval = N.compare(o.N);
1548 if ( cmpval) {
1549 return cmpval;
1550 }
1551
1552 cmpval = a.compare(o.a);
1553 if ( cmpval) {
1554 return cmpval;
1555 }
1556
1557 cmpval = b.compare(o.b);
1558 if ( cmpval) {
1559 return cmpval;
1560 }
1561
1562 cmpval = K.compare(o.K);
1563 if ( cmpval) {
1564 return cmpval;
1565 }
1566
1567 return C_norm.compare(o.C_norm);
1568}
1569
1579{
1580 if ( r.rhs() != 0 ) {
1581 throw (std::runtime_error("integration_kernel::series: non-zero expansion point not implemented"));
1582 }
1583
1584 ex qbar = r.lhs();
1586 res = res.series(qbar,order);
1587
1588 return res;
1589}
1590
1592{
1593 return 6;
1594}
1595
1597{
1598 switch (i) {
1599 case 0:
1600 return k;
1601 case 1:
1602 return N;
1603 case 2:
1604 return a;
1605 case 3:
1606 return b;
1607 case 4:
1608 return K;
1609 case 5:
1610 return C_norm;
1611 default:
1612 throw (std::out_of_range("Eisenstein_kernel::op() out of range"));
1613 }
1614}
1615
1617{
1619
1620 switch (i) {
1621 case 0:
1622 return k;
1623 case 1:
1624 return N;
1625 case 2:
1626 return a;
1627 case 3:
1628 return b;
1629 case 4:
1630 return K;
1631 case 5:
1632 return C_norm;
1633 default:
1634 throw (std::out_of_range("Eisenstein_kernel::let_op() out of range"));
1635 }
1636}
1637
1642
1644{
1646 res = res.series(x,order);
1647
1648 return res;
1649}
1650
1657{
1658 ex pre = numeric(1)/C_norm;
1659
1660 return get_numerical_value_impl(qbar, pre, 1, N_trunc);
1661}
1662
1664{
1665 return true;
1666}
1667
1669{
1670 numeric k_num = ex_to<numeric>(k);
1671 numeric N_num = ex_to<numeric>(N);
1672 numeric a_num = ex_to<numeric>(a);
1673 numeric b_num = ex_to<numeric>(b);
1674 numeric K_num = ex_to<numeric>(K);
1675
1676 if ( (k==2) && (a==1) && (b==1) ) {
1677 return B_eisenstein_series(q, N_num, K_num, order);
1678 }
1679
1680 return E_eisenstein_series(q, k_num, N_num, a_num, b_num, K_num, order);
1681}
1682
1683void Eisenstein_kernel::do_print(const print_context & c, unsigned level) const
1684{
1685 c.s << "Eisenstein_kernel(";
1686 k.print(c);
1687 c.s << ",";
1688 N.print(c);
1689 c.s << ",";
1690 a.print(c);
1691 c.s << ",";
1692 b.print(c);
1693 c.s << ",";
1694 K.print(c);
1695 c.s << ",";
1696 C_norm.print(c);
1697 c.s << ")";
1698}
1699
1701
1702
1709
1710Eisenstein_h_kernel::Eisenstein_h_kernel(const ex & arg_k, const ex & arg_N, const ex & arg_r, const ex & arg_s, const ex & arg_C_norm) : inherited(), k(arg_k), N(arg_N), r(arg_r), s(arg_s), C_norm(arg_C_norm)
1711{
1712}
1713
1714int Eisenstein_h_kernel::compare_same_type(const basic &other) const
1715{
1716 const Eisenstein_h_kernel &o = static_cast<const Eisenstein_h_kernel &>(other);
1717 int cmpval;
1718
1719 cmpval = k.compare(o.k);
1720 if ( cmpval) {
1721 return cmpval;
1722 }
1723
1724 cmpval = N.compare(o.N);
1725 if ( cmpval) {
1726 return cmpval;
1727 }
1728
1729 cmpval = r.compare(o.r);
1730 if ( cmpval) {
1731 return cmpval;
1732 }
1733
1734 cmpval = s.compare(o.s);
1735 if ( cmpval) {
1736 return cmpval;
1737 }
1738
1739 return C_norm.compare(o.C_norm);
1740}
1741
1751{
1752 if ( r.rhs() != 0 ) {
1753 throw (std::runtime_error("integration_kernel::series: non-zero expansion point not implemented"));
1754 }
1755
1756 ex qbar = r.lhs();
1758 res = res.series(qbar,order);
1759
1760 return res;
1761}
1762
1764{
1765 return 5;
1766}
1767
1769{
1770 switch (i) {
1771 case 0:
1772 return k;
1773 case 1:
1774 return N;
1775 case 2:
1776 return r;
1777 case 3:
1778 return s;
1779 case 4:
1780 return C_norm;
1781 default:
1782 throw (std::out_of_range("Eisenstein_h_kernel::op() out of range"));
1783 }
1784}
1785
1787{
1789
1790 switch (i) {
1791 case 0:
1792 return k;
1793 case 1:
1794 return N;
1795 case 2:
1796 return r;
1797 case 3:
1798 return s;
1799 case 4:
1800 return C_norm;
1801 default:
1802 throw (std::out_of_range("Eisenstein_h_kernel::let_op() out of range"));
1803 }
1804}
1805
1810
1812{
1814 res = res.series(x,order);
1815
1816 return res;
1817}
1818
1825{
1826 ex pre = numeric(1)/C_norm;
1827
1828 return get_numerical_value_impl(qbar, pre, 1, N_trunc);
1829}
1830
1832{
1833 return true;
1834}
1835
1841ex Eisenstein_h_kernel::coefficient_a0(const numeric & k, const numeric & r, const numeric & s, const numeric & N) const
1842{
1843 if ( k == 1 ) {
1844 if ( irem(s,N) != 0 ) {
1845 return numeric(1,4) - mod(s,N)/numeric(2)/N;
1846 }
1847 else if ( (irem(r,N)==0) && (irem(s,N)==0) ) {
1848 return 0;
1849 }
1850 else {
1851 return I*numeric(1,4)*cos(Pi*mod(r,N)/N)/sin(Pi*mod(r,N)/N);
1852 }
1853 }
1854
1855 // case k > 1
1856 return -Bernoulli_polynomial(k,mod(s,N)/N)/numeric(2)/k;
1857}
1858
1864ex Eisenstein_h_kernel::coefficient_an(const numeric & n, const numeric & k, const numeric & r, const numeric & s, const numeric & N) const
1865{
1866 ex res = 0;
1867
1868 for (numeric m=1; m<=n; m++) {
1869 if ( irem(n,m) == 0 ) {
1870 for (numeric c1=0; c1<N; c1++) {
1871 numeric c2 = n/m;
1872 res += pow(m,k-1)*exp(2*Pi*I/N*mod(r*c2-(s-m)*c1,N)) - pow(-m,k-1)*exp(2*Pi*I/N*mod(-r*c2+(s+m)*c1,N));
1873 }
1874 }
1875 }
1876
1877 return res/numeric(2)/pow(N,k);
1878}
1879
1881{
1882 numeric N_order_num = numeric(N_order);
1883
1884 numeric k_num = ex_to<numeric>(k);
1885 numeric r_num = ex_to<numeric>(r);
1886 numeric s_num = ex_to<numeric>(s);
1887 numeric N_num = ex_to<numeric>(N);
1888
1889 ex res = coefficient_a0(k_num,r_num,s_num,N_num);
1890
1891 for (numeric i1=1; i1<N_order_num; i1++) {
1892 res += coefficient_an(i1,k_num,r_num,s_num,N_num) * pow(q,i1);
1893 }
1894
1895 res += Order(pow(q,N_order));
1896 res = res.series(q,N_order);
1897
1898 return res;
1899}
1900
1901void Eisenstein_h_kernel::do_print(const print_context & c, unsigned level) const
1902{
1903 c.s << "Eisenstein_h_kernel(";
1904 k.print(c);
1905 c.s << ",";
1906 N.print(c);
1907 c.s << ",";
1908 r.print(c);
1909 c.s << ",";
1910 s.print(c);
1911 c.s << ",";
1912 C_norm.print(c);
1913 c.s << ")";
1914}
1915
1917
1918
1925
1926modular_form_kernel::modular_form_kernel(const ex & arg_k, const ex & arg_P, const ex & arg_C_norm) : inherited(), k(arg_k), P(arg_P), C_norm(arg_C_norm)
1927{
1928}
1929
1930int modular_form_kernel::compare_same_type(const basic &other) const
1931{
1932 const modular_form_kernel &o = static_cast<const modular_form_kernel &>(other);
1933 int cmpval;
1934
1935 cmpval = k.compare(o.k);
1936 if ( cmpval) {
1937 return cmpval;
1938 }
1939
1940 cmpval = P.compare(o.P);
1941 if ( cmpval) {
1942 return cmpval;
1943 }
1944
1945 return C_norm.compare(o.C_norm);
1946}
1947
1955{
1956 if ( r.rhs() != 0 ) {
1957 throw (std::runtime_error("integration_kernel::series: non-zero expansion point not implemented"));
1958 }
1959
1960 ex qbar = r.lhs();
1961
1962 subs_q_expansion do_subs_q_expansion(qbar, order);
1963
1964 ex res = do_subs_q_expansion(P).series(qbar,order);
1965 res += Order(pow(qbar,order));
1966 res = res.series(qbar,order);
1967
1968 return res;
1969}
1970
1972{
1973 return 3;
1974}
1975
1977{
1978 switch (i) {
1979 case 0:
1980 return k;
1981 case 1:
1982 return P;
1983 case 2:
1984 return C_norm;
1985 default:
1986 throw (std::out_of_range("modular_form_kernel::op() out of range"));
1987 }
1988}
1989
1991{
1993
1994 switch (i) {
1995 case 0:
1996 return k;
1997 case 1:
1998 return P;
1999 case 2:
2000 return C_norm;
2001 default:
2002 throw (std::out_of_range("modular_form_kernel::let_op() out of range"));
2003 }
2004}
2005
2007{
2009 if ( !flag ) {
2010 return false;
2011 }
2012
2013 symbol qbar("qbar");
2014
2015 // test with a random number and random expansion
2017}
2018
2020{
2022 res = C_norm * res/qbar;
2023 res = res.series(qbar,order);
2024 return res;
2025}
2026
2033{
2034 ex pre = numeric(1)/C_norm;
2035
2036 return get_numerical_value_impl(qbar, pre, 1, N_trunc);
2037}
2038
2040{
2041 return true;
2042}
2043
2045{
2046 return this->series(q==0,N_order);
2047}
2048
2049void modular_form_kernel::do_print(const print_context & c, unsigned level) const
2050{
2051 c.s << "modular_form_kernel(";
2052 k.print(c);
2053 c.s << ",";
2054 P.print(c);
2055 c.s << ",";
2056 C_norm.print(c);
2057 c.s << ")";
2058}
2059
2061
2062
2069
2070user_defined_kernel::user_defined_kernel(const ex & arg_f, const ex & arg_x) : inherited(), f(arg_f), x(arg_x)
2071{
2072}
2073
2074int user_defined_kernel::compare_same_type(const basic &other) const
2075{
2076 const user_defined_kernel &o = static_cast<const user_defined_kernel &>(other);
2077 int cmpval;
2078
2079 cmpval = f.compare(o.f);
2080 if ( cmpval) {
2081 return cmpval;
2082 }
2083
2084 return x.compare(o.x);
2085}
2086
2088{
2089 return 2;
2090}
2091
2093{
2094 switch (i) {
2095 case 0:
2096 return f;
2097 case 1:
2098 return x;
2099 default:
2100 throw (std::out_of_range("user_defined_kernel::op() out of range"));
2101 }
2102}
2103
2105{
2107
2108 switch (i) {
2109 case 0:
2110 return f;
2111 case 1:
2112 return x;
2113 default:
2114 throw (std::out_of_range("user_defined_kernel::let_op() out of range"));
2115 }
2116}
2117
2119{
2120 // test with a random number
2121 return f.subs(x==numeric(1,937)).evalf().info(info_flags::numeric);
2122}
2123
2125{
2126 ex res = f.series(x,order).subs(x==x_up);
2127
2128 return res;
2129}
2130
2132{
2133 return true;
2134}
2135
2136void user_defined_kernel::do_print(const print_context & c, unsigned level) const
2137{
2138 c.s << "user_defined_kernel(";
2139 f.print(c);
2140 c.s << ",";
2141 x.print(c);
2142 c.s << ")";
2143}
2144
2146
2147} // namespace GiNaC
Interface to GiNaC's sums of expressions.
#define GINAC_BIND_UNARCHIVER(classname)
Definition archive.h:230
ex & let_op(size_t i) override
Return modifiable operand/member at position i.
void do_print(const print_context &c, unsigned level) const
bool is_numeric(void) const override
This routine returns true, if the integration kernel can be evaluated numerically.
ELi_kernel(const ex &n, const ex &m, const ex &x, const ex &y)
size_t nops() const override
Number of operands/members.
ex op(size_t i) const override
Return operand/member at position i.
cln::cl_N series_coeff_impl(int i) const override
For only the coefficient of is non-zero.
ex get_numerical_value(const ex &qbar, int N_trunc=0) const override
Returns the value of ELi_{n,m}(x,y,qbar)
size_t nops() const override
Number of operands/members.
void do_print(const print_context &c, unsigned level) const
bool is_numeric(void) const override
This routine returns true, if the integration kernel can be evaluated numerically.
ex op(size_t i) const override
Return operand/member at position i.
Ebar_kernel(const ex &n, const ex &m, const ex &x, const ex &y)
ex & let_op(size_t i) override
Return modifiable operand/member at position i.
cln::cl_N series_coeff_impl(int i) const override
For only the coefficient of is non-zero.
ex get_numerical_value(const ex &qbar, int N_trunc=0) const override
Returns the value of Ebar_{n,m}(x,y,qbar)
The kernel corresponding to the Eisenstein series .
ex get_numerical_value(const ex &qbar, int N_trunc=0) const override
Returns the value of the modular form.
bool is_numeric(void) const override
This routine returns true, if the integration kernel can be evaluated numerically.
Eisenstein_h_kernel(const ex &k, const ex &N, const ex &r, const ex &s, const ex &C_norm=numeric(1))
size_t nops() const override
Number of operands/members.
ex op(size_t i) const override
Return operand/member at position i.
void do_print(const print_context &c, unsigned level) const
ex q_expansion_modular_form(const ex &q, int order) const
ex coefficient_an(const numeric &n, const numeric &k, const numeric &r, const numeric &s, const numeric &N) const
The higher coefficients in the Fourier expansion.
ex coefficient_a0(const numeric &k, const numeric &r, const numeric &s, const numeric &N) const
The constant coefficient in the Fourier expansion.
ex Laurent_series(const ex &x, int order) const override
Returns the Laurent series, starting possibly with the pole term.
ex & let_op(size_t i) override
Return modifiable operand/member at position i.
bool uses_Laurent_series() const override
Returns true, if the coefficients are computed from the Laurent series (in which case the method Laur...
ex series(const relational &r, int order, unsigned options=0) const override
The series method for this class returns the qbar-expansion of the modular form, without an additiona...
The kernel corresponding to the Eisenstein series .
ex get_numerical_value(const ex &qbar, int N_trunc=0) const override
Returns the value of the modular form.
ex Laurent_series(const ex &x, int order) const override
Returns the Laurent series, starting possibly with the pole term.
void do_print(const print_context &c, unsigned level) const
ex op(size_t i) const override
Return operand/member at position i.
ex q_expansion_modular_form(const ex &q, int order) const
ex & let_op(size_t i) override
Return modifiable operand/member at position i.
Eisenstein_kernel(const ex &k, const ex &N, const ex &a, const ex &b, const ex &K, const ex &C_norm=numeric(1))
size_t nops() const override
Number of operands/members.
bool uses_Laurent_series() const override
Returns true, if the coefficients are computed from the Laurent series (in which case the method Laur...
ex series(const relational &r, int order, unsigned options=0) const override
The series method for this class returns the qbar-expansion of the modular form, without an additiona...
bool is_numeric(void) const override
This routine returns true, if the integration kernel can be evaluated numerically.
The kernel corresponding to integrating the Kronecker coefficient function in (or equivalently in )...
size_t nops() const override
Number of operands/members.
Kronecker_dtau_kernel(const ex &n, const ex &z, const ex &K=numeric(1), const ex &C_norm=numeric(1))
ex op(size_t i) const override
Return operand/member at position i.
ex get_numerical_value(const ex &qbar, int N_trunc=0) const override
Returns the value of the g^(n)(z,K*tau), where tau is given by qbar.
void do_print(const print_context &c, unsigned level) const
cln::cl_N series_coeff_impl(int i) const override
For only the coefficient of is non-zero.
bool is_numeric(void) const override
This routine returns true, if the integration kernel can be evaluated numerically.
ex & let_op(size_t i) override
Return modifiable operand/member at position i.
The kernel corresponding to integrating the Kronecker coefficient function in .
Kronecker_dz_kernel(const ex &n, const ex &z_j, const ex &tau, const ex &K=numeric(1), const ex &C_norm=numeric(1))
bool is_numeric(void) const override
This routine returns true, if the integration kernel can be evaluated numerically.
size_t nops() const override
Number of operands/members.
void do_print(const print_context &c, unsigned level) const
cln::cl_N series_coeff_impl(int i) const override
For only the coefficient of is non-zero.
ex op(size_t i) const override
Return operand/member at position i.
ex get_numerical_value(const ex &z, int N_trunc=0) const override
Returns the value of the g^(n-1)(z-z_j,K*tau).
ex & let_op(size_t i) override
Return modifiable operand/member at position i.
The basic integration kernel with a logarithmic singularity at the origin.
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
Definition basic.h:105
void ensure_if_modifiable() const
Ensure the object may be modified without hurting others, throws if this is not the case.
Definition basic.cpp:894
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Definition basic.cpp:719
virtual ex evalf() const
Evaluate object numerically.
Definition basic.cpp:425
Wrapper template for making GiNaC classes out of STL containers.
Definition container.h:73
const_iterator end() const
Definition container.h:240
const_iterator begin() const
Definition container.h:239
size_t nops() const override
Number of operands/members.
Definition container.h:118
ex op(size_t i) const override
Return operand/member at position i.
Definition container.h:295
container & append(const ex &b)
Add element at back.
Definition container.h:391
Lightweight wrapper for GiNaC's symbolic objects.
Definition ex.h:73
ex evalf() const
Definition ex.h:122
ex series(const ex &r, int order, unsigned options=0) const
Compute the truncated series expansion of an expression.
Definition pseries.cpp:1272
ex subs(const exmap &m, unsigned options=0) const
Definition ex.h:842
bool info(unsigned inf) const
Definition ex.h:133
int compare(const ex &other) const
Definition ex.h:323
ex lhs() const
Left hand side of relational expression.
Definition ex.cpp:226
void print(const print_context &c, unsigned level=0) const
Print expression to stream.
Definition ex.cpp:55
ex rhs() const
Right hand side of relational expression.
Definition ex.cpp:234
ex coeff(const ex &s, int n=1) const
Definition ex.h:176
The base class for integration kernels for iterated integrals.
void do_print(const print_context &c, unsigned level) const
ex get_numerical_value_impl(const ex &lambda, const ex &pre, int shift, int N_trunc) const
The actual implementation for computing a numerical value for the integrand.
A kernel corresponding to a polynomial in Eisenstein series.
ex & let_op(size_t i) override
Return modifiable operand/member at position i.
ex series(const relational &r, int order, unsigned options=0) const override
The series method for this class returns the qbar-expansion of the modular form, without an additiona...
void do_print(const print_context &c, unsigned level) const
size_t nops() const override
Number of operands/members.
bool is_numeric(void) const override
This routine returns true, if the integration kernel can be evaluated numerically.
modular_form_kernel(const ex &k, const ex &P, const ex &C_norm=numeric(1))
ex op(size_t i) const override
Return operand/member at position i.
ex get_numerical_value(const ex &qbar, int N_trunc=0) const override
Returns the value of the modular form.
ex Laurent_series(const ex &qbar, int order) const override
Returns the Laurent series, starting possibly with the pole term.
bool uses_Laurent_series() const override
Returns true, if the coefficients are computed from the Laurent series (in which case the method Laur...
ex q_expansion_modular_form(const ex &q, int order) const
The integration kernel for multiple polylogarithms.
cln::cl_N series_coeff_impl(int i) const override
For only the coefficient of is non-zero.
ex & let_op(size_t i) override
Return modifiable operand/member at position i.
size_t nops() const override
Number of operands/members.
void do_print(const print_context &c, unsigned level) const
ex op(size_t i) const override
Return operand/member at position i.
bool is_numeric(void) const override
This routine returns true, if the integration kernel can be evaluated numerically.
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
Definition numeric.h:82
bool is_odd() const
True if object is an exact odd integer.
Definition numeric.cpp:1182
cln::cl_N to_cl_N() const
Returns a new CLN object of type cl_N, representing the value of *this.
Definition numeric.cpp:1332
bool is_even() const
True if object is an exact even integer.
Definition numeric.cpp:1175
int to_int() const
Converts numeric types to machine's int.
Definition numeric.cpp:1303
Base class for print_contexts.
Definition print.h:102
This class holds a relation consisting of two expressions and a logical relation between them.
Definition relational.h:35
Basic CAS symbol.
Definition symbol.h:39
A user-defined integration kernel.
user_defined_kernel(const ex &f, const ex &x)
ex Laurent_series(const ex &x, int order) const override
Returns the Laurent series, starting possibly with the pole term.
bool is_numeric(void) const override
This routine returns true, if the integration kernel can be evaluated numerically.
ex op(size_t i) const override
Return operand/member at position i.
bool uses_Laurent_series() const override
Returns true, if the coefficients are computed from the Laurent series (in which case the method Laur...
void do_print(const print_context &c, unsigned level) const
ex & let_op(size_t i) override
Return modifiable operand/member at position i.
size_t nops() const override
Number of operands/members.
Interface to GiNaC's constant types and some special constants.
ex unit
Definition factor.cpp:2191
unsigned options
Definition factor.cpp:2474
vector< int > k
Definition factor.cpp:1435
size_t n
Definition factor.cpp:1432
size_t c
Definition factor.cpp:757
ex x
Definition factor.cpp:1610
size_t r
Definition factor.cpp:757
umodpoly one
Definition factor.cpp:1431
mvec m
Definition factor.cpp:758
Interface to class of symbolic functions.
Interface to GiNaC's initially known functions.
static std::vector< ex > cache_vec
static symbol x
Interface to GiNaC's integration kernels for iterated integrals.
Interface to GiNaC's products of expressions.
Definition add.cpp:36
const numeric I
Imaginary unit.
Definition numeric.cpp:1433
const numeric pow(const numeric &x, const numeric &y)
Definition numeric.h:251
bool is_discriminant_of_quadratic_number_field(const numeric &n)
Returns true if the integer n is either one or the discriminant of a quadratic number field.
const numeric bernoulli(const numeric &nn)
Bernoulli number.
Definition numeric.cpp:2171
const numeric mod(const numeric &a, const numeric &b)
Modulus (in positive representation).
Definition numeric.cpp:2333
const numeric abs(const numeric &x)
Absolute value.
Definition numeric.cpp:2320
const ex _ex1
Definition utils.cpp:385
ex gcd(const ex &a, const ex &b, ex *ca, ex *cb, bool check_args, unsigned options)
Compute GCD (Greatest Common Divisor) of multivariate polynomials a(X) and b(X) in Z[X].
Definition normal.cpp:1433
ex series_to_poly(const ex &e)
Convert the pseries object embedded in an expression to an ordinary polynomial in the expansion varia...
Definition pseries.h:136
const numeric irem(const numeric &a, const numeric &b)
Numeric integer remainder.
Definition numeric.cpp:2368
numeric dirichlet_character(const numeric &n, const numeric &a, const numeric &N)
Defines a Dirichlet character through the Kronecker symbol.
ex diff(const ex &thisex, const symbol &s, unsigned nth=1)
Definition ex.h:794
const numeric exp(const numeric &x)
Exponential function.
Definition numeric.cpp:1439
numeric kronecker_symbol(const numeric &a, const numeric &n)
Returns the Kronecker symbol a: integer n: integer.
ex Bernoulli_polynomial(const numeric &k, const ex &x)
The Bernoulli polynomials.
const numeric factorial(const numeric &n)
Factorial combinatorial function.
Definition numeric.cpp:2113
const numeric cos(const numeric &x)
Numeric cosine (trigonometric function).
Definition numeric.cpp:1470
bool is_even(const numeric &x)
Definition numeric.h:281
const numeric smod(const numeric &a_, const numeric &b_)
Modulus (in symmetric representation).
Definition numeric.cpp:2346
const constant Pi("Pi", PiEvalf, "\\pi", domain::positive)
Pi.
Definition constant.h:82
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
Definition idx.cpp:44
const numeric iquo(const numeric &a, const numeric &b)
Numeric integer quotient.
Definition numeric.cpp:2409
_numeric_digits Digits
Accuracy in decimal digits.
Definition numeric.cpp:2591
const numeric sin(const numeric &x)
Numeric sine (trigonometric function).
Definition numeric.cpp:1461
ex normal(const ex &thisex)
Definition ex.h:770
numeric primitive_dirichlet_character(const numeric &n, const numeric &a)
Defines a primitive Dirichlet character through the Kronecker symbol.
ex ifactor(const numeric &n)
Returns the decomposition of the positive integer n into prime numbers in the form lst( lst(p1,...
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.
Definition lst.cpp:42
numeric generalised_Bernoulli_number(const numeric &k, const numeric &b)
The generalised Bernoulli number.
const ex _ex0
Definition utils.cpp:369
Makes the interface to the underlying bignum package available.
Interface to GiNaC's overloaded operators.
Interface to GiNaC's symbolic exponentiation (basis^exponent).
Interface to class for extended truncated power series.
#define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(classname, supername, options)
Macro for inclusion in the implementation of each registered class.
Definition registrar.h:184
Interface to relations between expressions.
Interface to GiNaC's symbolic objects.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...

This page is part of the GiNaC developer's reference. It was generated automatically by doxygen. For an introduction, see the tutorial.