GiNaC 1.8.10
integration_kernel.cpp
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2026 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, see <https://www.gnu.org/licenses/>.
20 */
21
22#include "integration_kernel.h"
23#include "add.h"
24#include "mul.h"
25#include "operators.h"
26#include "power.h"
27#include "relational.h"
28#include "symbol.h"
29#include "constant.h"
30#include "numeric.h"
31#include "function.h"
32#include "pseries.h"
33#include "utils.h"
34#include "inifcns.h"
35
36#include <iostream>
37#include <stdexcept>
38#include <cln/cln.h>
39
40
41namespace GiNaC {
42
43// anonymous namespace for helper function
44namespace {
45
60numeric kronecker_symbol_prime(const numeric & a, const numeric & n)
61{
62 if ( n == 1 ) {
63 return 1;
64 }
65 else if ( n == -1 ) {
66 if ( a >= 0 ) {
67 return 1;
68 }
69 else {
70 return -1;
71 }
72 }
73 else if ( n == 2 ) {
74 if ( GiNaC::smod(a,8) == 1 ) {
75 return 1;
76 }
77 else if ( GiNaC::smod(a,8) == -1 ) {
78 return 1;
79 }
80 else if ( GiNaC::smod(a,8) == 3 ) {
81 return -1;
82 }
83 else if ( GiNaC::smod(a,8) == -3 ) {
84 return -1;
85 }
86 else {
87 return 0;
88 }
89 }
90
91 // n is an odd prime number
92 return GiNaC::smod( pow(a,(n-1)/2), n);
93}
94
116numeric divisor_function(const numeric & n, const numeric & a, const numeric & b, const numeric & k)
117{
118 ex res = 0;
119
120 for (numeric i1=1; i1<=n; i1++) {
121 if ( irem(n,i1) == 0 ) {
122 numeric ratio = n/i1;
124 }
125 }
126
127 return ex_to<numeric>(res);
128}
129
146numeric coefficient_a0(const numeric & k, const numeric & a, const numeric & b)
147{
148 ex conductor = abs(a);
149
150 numeric a0;
151 if ( conductor == 1 ) {
152 a0 = -numeric(1,2)/k*generalised_Bernoulli_number(k,b);
153 }
154 else {
155 a0 = 0;
156 }
157
158 return a0;
159}
160
180ex eisenstein_series(const numeric & k, const ex & q, const numeric & a, const numeric & b, const numeric & N)
181{
182 ex res = coefficient_a0(k,a,b);
183
184 for (numeric i1=1; i1<N; i1++) {
185 res += divisor_function(i1,a,b,k) * pow(q,i1);
186 }
187
188 return res;
189}
190
196ex 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)
197{
198 int N_order_int = N_order.to_int();
199
200 ex res = eisenstein_series(k,pow(q,K),a,b,iquo(N_order,K));
201
202 res += Order(pow(q,N_order_int));
203 res = res.series(q,N_order_int);
204
205 return res;
206}
207
214ex B_eisenstein_series(const ex & q, const numeric & N_level, const numeric & K, const numeric & N_order)
215{
216 int N_order_int = N_order.to_int();
217
218 ex res = eisenstein_series(2,q,1,1,N_order) - K*eisenstein_series(2,pow(q,K),1,1,iquo(N_order,K));
219
220 res += Order(pow(q,N_order_int));
221 res = res.series(q,N_order_int);
222
223 return res;
224}
225
231struct subs_q_expansion : public map_function
232{
233 subs_q_expansion(const ex & arg_qbar, int arg_order) : qbar(arg_qbar), order(arg_order)
234 {}
235
236 ex operator()(const ex & e)
237 {
238 if ( is_a<Eisenstein_kernel>(e) || is_a<Eisenstein_h_kernel>(e) ) {
239 return series_to_poly(e.series(qbar,order));
240 }
241 else {
242 return e.map(*this);
243 }
244 }
245
247 int order;
248};
249
261class Li_negative
262{
263 // ctors
264public:
265 Li_negative();
266
267 // non-virtual functions
268public:
269 ex get_symbolic_value(int n, const ex & x_val);
270 ex get_numerical_value(int n, const ex & x_val);
271
272 // member variables :
273protected:
274 static std::vector<ex> cache_vec;
275 static symbol x;
276};
277
278
279Li_negative::Li_negative() {}
280
281ex Li_negative::get_symbolic_value(int n, const ex & x_val)
282{
283 int n_cache = cache_vec.size();
284
285 if ( n >= n_cache ) {
286 for (int j=n_cache; j<=n; j++) {
287 ex f;
288 if ( j == 0 ) {
289 f = x/(1-x);
290 }
291 else {
292 f = normal( x*diff(cache_vec[j-1],x));
293 }
294 cache_vec.push_back( f );
295 }
296 }
297
298 return cache_vec[n].subs(x==x_val);
299}
300
301ex Li_negative::get_numerical_value(int n, const ex & x_val)
302{
303 symbol x_symb("x_symb");
304
305 ex f = this->get_symbolic_value(n,x_symb);
306
307 ex res = f.subs(x_symb==x_val).evalf();
308
309 return res;
310}
311
312// initialise static data members
313std::vector<ex> Li_negative::cache_vec;
314symbol Li_negative::x = symbol("x");
315
316
317} // end of anonymous namespace
318
329{
330 if ( !n.is_pos_integer() ) throw (std::runtime_error("ifactor(): argument not a positive integer"));
331
332 lst p_lst, exp_lst;
333
334 // implementation for small integers
335 numeric n_temp = n;
336 for (numeric p=2; p<=n; p++) {
337 if ( p.info(info_flags::prime) ) {
338 numeric exp_temp = 0;
339 while ( irem(n_temp, p) == 0 ) {
340 n_temp = n_temp/p;
341 exp_temp++;
342 }
343 if ( exp_temp>0 ) {
344 p_lst.append(p);
345 exp_lst.append(exp_temp);
346 }
347 }
348 if ( n_temp == 1 ) break;
349 }
350
351 if ( n_temp != 1 ) throw (std::runtime_error("ifactor(): probabilistic primality test failed"));
352
353 lst res = {p_lst,exp_lst};
354
355 return res;
356}
357
368{
369 if ( n == 0 ) {
370 return false;
371 }
372
373 if ( n == 1 ) {
374 return true;
375 }
376
377 lst prime_factorisation = ex_to<lst>(ifactor(abs(n)));
378 lst p_lst = ex_to<lst>(prime_factorisation.op(0));
379 lst e_lst = ex_to<lst>(prime_factorisation.op(1));
380
381 size_t n_primes = p_lst.nops();
382
383 if ( n_primes > 0 ) {
384 // take the last prime
385 numeric p = ex_to<numeric>(p_lst.op(n_primes-1));
386
387 if ( p.is_odd() ) {
388 if ( e_lst.op(n_primes-1) != 1 ) {
389 return false;
390 }
391
392 numeric pstar = p;
393 if ( mod(p,4) == 3 ) {
394 pstar = -p;
395 }
397 }
398 }
399 // power of two now
400 if ( (n==-4) || (n==-8) || (n==8) || (n==-32) || (n==32) || (n==-64) || (n==128) ) {
401 return true;
402 }
403
404 return false;
405}
406
425{
426 // case n=0 first, include kronecker_symbol(0,0)=0
427 if ( n == 0 ) {
428 if ( (a == 1) || (a == -1) ) {
429 return 1;
430 }
431 else {
432 return 0;
433 }
434 }
435
436 numeric unit = 1;
437 numeric n_pos = n;
438 if ( n_pos<0 ) {
439 unit = -1;
440 n_pos = -n;
441 }
442
443 ex res = kronecker_symbol_prime(a,unit);
444
445 numeric n_odd = n_pos;
446 numeric alpha = 0;
447 while ( n_odd.is_even() ) {
448 alpha++;
449 n_odd = n_odd/2;
450 }
451 if ( alpha>0 ) {
452 res *= pow(kronecker_symbol_prime(a,2),alpha);
453 }
454
455 lst temp_lst = ex_to<lst>(ifactor(n_odd));
456 lst prime_lst = ex_to<lst>(temp_lst.op(0));
457 lst expo_lst = ex_to<lst>(temp_lst.op(1));
458
459 for (auto it_p = prime_lst.begin(), it_e = expo_lst.begin(); it_p != prime_lst.end(); it_p++, it_e++) {
460 res *= pow(kronecker_symbol_prime(a,ex_to<numeric>(*it_p)),ex_to<numeric>(*it_e));
461 }
462
463 return ex_to<numeric>(res);
464}
465
478{
479 return kronecker_symbol(a,n);
480}
481
494numeric dirichlet_character(const numeric & n, const numeric & a, const numeric & N)
495{
496 if ( gcd(n,N) == 1 ) {
498 }
499
500 return 0;
501}
502
517{
518 int k_int = k.to_int();
519
520 symbol x("x");
521
522 numeric conductor = abs(b);
523
524 ex gen_fct = 0;
525 for (numeric i1=1; i1<=conductor; i1++) {
526 gen_fct += primitive_dirichlet_character(i1,b) * x*exp(i1*x)/(exp(conductor*x)-1);
527 }
528
529 gen_fct = series_to_poly(gen_fct.series(x,k_int+1));
530
531 ex B = factorial(k) * gen_fct.coeff(x,k_int);
532
533 return ex_to<numeric>(B);
534}
535
542{
543 int k_int = k.to_int();
544
545 symbol t("t");
546
547 ex gen_fct = t*exp(x*t)/(exp(t)-1);
548
549 gen_fct = series_to_poly(gen_fct.series(t,k_int+1));
550
551 ex B = factorial(k) * gen_fct.coeff(t,k_int);
552
553 return B;
554}
555
556
557
560
561integration_kernel::integration_kernel() : inherited(), cache_step_size(100), series_vec()
562{
563}
564
565int integration_kernel::compare_same_type(const basic &other) const
566{
567 return 0;
568}
569
570ex integration_kernel::series(const relational & r, int order, unsigned options) const
571{
572 if ( r.rhs() != 0 ) {
573 throw (std::runtime_error("integration_kernel::series: non-zero expansion point not implemented"));
574 }
575
576 return Laurent_series(r.lhs(),order);
577}
578
584bool integration_kernel::has_trailing_zero(void) const
585{
586 if ( cln::zerop( series_coeff(0) ) ) {
587 return false;
588 }
589
590 return true;
591}
592
598bool integration_kernel::is_numeric(void) const
599{
600 return true;
601}
602
615cln::cl_N integration_kernel::series_coeff(int i) const
616{
617 int n_vec = series_vec.size();
618
619 if ( i >= n_vec ) {
620 int N = cache_step_size*(i/cache_step_size+1);
621
622 if ( uses_Laurent_series() ) {
623 symbol x("x");
624 // series_vec[0] gives coefficient of 1/z, series_vec[N-1] coefficient of z^(N-2),
625 // thus expansion up to order (N-1) is required
626 ex temp = Laurent_series(x, N-1);
627 for (int j=n_vec; j<N; j++) {
628 series_vec.push_back( ex_to<numeric>(temp.coeff(x,j-1).evalf()).to_cl_N() );
629 }
630 }
631 else {
632 for (int j=n_vec; j<N; j++) {
633 series_vec.push_back( series_coeff_impl(j) );
634 }
635 }
636 }
637
638 return series_vec[i];
639}
640
648cln::cl_N integration_kernel::series_coeff_impl(int i) const
649{
650 if ( i == 1 ) {
651 return 1;
652 }
653
654 return 0;
655}
656
663ex integration_kernel::Laurent_series(const ex & x, int order) const
664{
665 ex res = 0;
666 for (int n=-1; n<order; n++) {
667 res += numeric(series_coeff(n+1)) * pow(x,n);
668 }
669 res += Order(pow(x,order));
670 res = res.series(x,order);
671
672 return res;
673}
674
680ex integration_kernel::get_numerical_value(const ex & lambda, int N_trunc) const
681{
682 return get_numerical_value_impl(lambda, 1, 0, N_trunc);
683}
684
694bool integration_kernel::uses_Laurent_series() const
695{
696 return false;
697}
698
704size_t integration_kernel::get_cache_size(void) const
705{
706 return series_vec.size();
707}
708
714void integration_kernel::set_cache_step(int cache_steps) const
715{
716 cache_step_size = cache_steps;
717}
718
724ex integration_kernel::get_series_coeff(int i) const
725{
726 return numeric(series_coeff(i));
727}
728
734ex integration_kernel::get_numerical_value_impl(const ex & lambda, const ex & pre, int shift, int N_trunc) const
735{
736 cln::cl_N lambda_cln = ex_to<numeric>(lambda.evalf()).to_cl_N();
737 cln::cl_N pre_cln = ex_to<numeric>(pre.evalf()).to_cl_N();
738
739 cln::cl_F one = cln::cl_float(1, cln::float_format(Digits));
740
741 cln::cl_N res = 0;
742 cln::cl_N resbuf;
743 cln::cl_N subexpr;
744
745 if ( N_trunc == 0 ) {
746 // sum until precision is reached
747 bool flag_accidental_zero = false;
748
749 int N = 0;
750
751 do {
752 resbuf = res;
753
754 subexpr = series_coeff(N);
755
756 res += pre_cln * subexpr * cln::expt(lambda_cln,N-1+shift);
757
758 flag_accidental_zero = cln::zerop(subexpr);
759
760 N++;
761 } while ( (res != resbuf) || flag_accidental_zero );
762 }
763 else {
764 // N_trunc > 0, sum up the first N_trunc terms
765 for (int N=0; N<N_trunc; N++) {
766 subexpr = series_coeff(N);
767
768 res += pre_cln * subexpr * cln::expt(lambda_cln,N-1+shift);
769 }
770 }
771
772 return numeric(res);
773}
774
775void integration_kernel::do_print(const print_context & c, unsigned level) const
776{
777 c.s << "integration_kernel()";
778}
779
781
782
784 print_func<print_context>(&basic_log_kernel::do_print))
785
786basic_log_kernel::basic_log_kernel() : inherited()
787{
788}
789
790int basic_log_kernel::compare_same_type(const basic &other) const
791{
792 return 0;
793}
794
795cln::cl_N basic_log_kernel::series_coeff_impl(int i) const
796{
797 if ( i == 0 ) {
798 return 1;
799 }
800
801 return 0;
802}
803
804void basic_log_kernel::do_print(const print_context & c, unsigned level) const
805{
806 c.s << "basic_log_kernel()";
807}
808
810
811
813 print_func<print_context>(&multiple_polylog_kernel::do_print))
814
815multiple_polylog_kernel::multiple_polylog_kernel() : inherited(), z(_ex1)
816{
817}
818
819multiple_polylog_kernel::multiple_polylog_kernel(const ex & arg_z) : inherited(), z(arg_z)
820{
821}
822
824{
825 const multiple_polylog_kernel &o = static_cast<const multiple_polylog_kernel &>(other);
826
827 return z.compare(o.z);
828}
829
831{
832 return 1;
833}
834
836{
837 if ( i != 0 ) {
838 throw(std::range_error("multiple_polylog_kernel::op(): out of range"));
839 }
840
841 return z;
842}
843
845{
847
848 if ( i != 0 ) {
849 throw(std::range_error("multiple_polylog_kernel::let_op(): out of range"));
850 }
851
852 return z;
853}
854
856{
858}
859
861{
862 if ( i == 0 ) {
863 return 0;
864 }
865
866 return -cln::expt(ex_to<numeric>(z.evalf()).to_cl_N(),-i);
867}
868
869void multiple_polylog_kernel::do_print(const print_context & c, unsigned level) const
870{
871 c.s << "multiple_polylog_kernel(";
872 z.print(c);
873 c.s << ")";
874}
875
877
878
885
886ELi_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)
887{
888}
889
890int ELi_kernel::compare_same_type(const basic &other) const
891{
892 const ELi_kernel &o = static_cast<const ELi_kernel &>(other);
893 int cmpval;
894
895 cmpval = n.compare(o.n);
896 if ( cmpval) {
897 return cmpval;
898 }
899
900 cmpval = m.compare(o.m);
901 if ( cmpval) {
902 return cmpval;
903 }
904
905 cmpval = x.compare(o.x);
906 if ( cmpval) {
907 return cmpval;
908 }
909
910 return y.compare(o.y);
911}
912
913size_t ELi_kernel::nops() const
914{
915 return 4;
916}
917
918ex ELi_kernel::op(size_t i) const
919{
920 switch (i) {
921 case 0:
922 return n;
923 case 1:
924 return m;
925 case 2:
926 return x;
927 case 3:
928 return y;
929 default:
930 throw (std::out_of_range("ELi_kernel::op() out of range"));
931 }
932}
933
935{
937
938 switch (i) {
939 case 0:
940 return n;
941 case 1:
942 return m;
943 case 2:
944 return x;
945 case 3:
946 return y;
947 default:
948 throw (std::out_of_range("ELi_kernel::let_op() out of range"));
949 }
950}
951
956
957cln::cl_N ELi_kernel::series_coeff_impl(int i) const
958{
959 if ( i == 0 ) {
960 return 0;
961 }
962
963 int n_int = ex_to<numeric>(n).to_int();
964 int m_int = ex_to<numeric>(m).to_int();
965
966 cln::cl_N x_cln = ex_to<numeric>(x.evalf()).to_cl_N();
967 cln::cl_N y_cln = ex_to<numeric>(y.evalf()).to_cl_N();
968
969 cln::cl_N res_cln = 0;
970
971 for (int j=1; j<=i; j++) {
972 if ( (i % j) == 0 ) {
973 int k = i/j;
974
975 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);
976 }
977 }
978
979 return res_cln;
980}
981
987ex ELi_kernel::get_numerical_value(const ex & qbar, int N_trunc) const
988{
989 return get_numerical_value_impl(qbar, 1, 1, N_trunc);
990}
991
992void ELi_kernel::do_print(const print_context & c, unsigned level) const
993{
994 c.s << "ELi_kernel(";
995 n.print(c);
996 c.s << ",";
997 m.print(c);
998 c.s << ",";
999 x.print(c);
1000 c.s << ",";
1001 y.print(c);
1002 c.s << ")";
1003}
1004
1006
1007
1014
1015Ebar_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)
1016{
1017}
1018
1019int Ebar_kernel::compare_same_type(const basic &other) const
1020{
1021 const Ebar_kernel &o = static_cast<const Ebar_kernel &>(other);
1022 int cmpval;
1023
1024 cmpval = n.compare(o.n);
1025 if ( cmpval) {
1026 return cmpval;
1027 }
1028
1029 cmpval = m.compare(o.m);
1030 if ( cmpval) {
1031 return cmpval;
1032 }
1033
1034 cmpval = x.compare(o.x);
1035 if ( cmpval) {
1036 return cmpval;
1037 }
1038
1039 return y.compare(o.y);
1040}
1041
1042size_t Ebar_kernel::nops() const
1043{
1044 return 4;
1045}
1046
1047ex Ebar_kernel::op(size_t i) const
1048{
1049 switch (i) {
1050 case 0:
1051 return n;
1052 case 1:
1053 return m;
1054 case 2:
1055 return x;
1056 case 3:
1057 return y;
1058 default:
1059 throw (std::out_of_range("Ebar_kernel::op() out of range"));
1060 }
1061}
1062
1064{
1066
1067 switch (i) {
1068 case 0:
1069 return n;
1070 case 1:
1071 return m;
1072 case 2:
1073 return x;
1074 case 3:
1075 return y;
1076 default:
1077 throw (std::out_of_range("Ebar_kernel::let_op() out of range"));
1078 }
1079}
1080
1085
1087{
1088 if ( i == 0 ) {
1089 return 0;
1090 }
1091
1092 int n_int = ex_to<numeric>(n).to_int();
1093 int m_int = ex_to<numeric>(m).to_int();
1094
1095 cln::cl_N x_cln = ex_to<numeric>(x.evalf()).to_cl_N();
1096 cln::cl_N y_cln = ex_to<numeric>(y.evalf()).to_cl_N();
1097
1098 cln::cl_N res_cln = 0;
1099
1100 for (int j=1; j<=i; j++) {
1101 if ( (i % j) == 0 ) {
1102 int k = i/j;
1103
1104 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);
1105 }
1106 }
1107
1108 return res_cln;
1109}
1110
1116ex Ebar_kernel::get_numerical_value(const ex & qbar, int N_trunc) const
1117{
1118 return get_numerical_value_impl(qbar, 1, 1, N_trunc);
1119}
1120
1121void Ebar_kernel::do_print(const print_context & c, unsigned level) const
1122{
1123 c.s << "Ebar_kernel(";
1124 n.print(c);
1125 c.s << ",";
1126 m.print(c);
1127 c.s << ",";
1128 x.print(c);
1129 c.s << ",";
1130 y.print(c);
1131 c.s << ")";
1132}
1133
1135
1136
1143
1144Kronecker_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)
1145{
1146}
1147
1148int Kronecker_dtau_kernel::compare_same_type(const basic &other) const
1149{
1150 const Kronecker_dtau_kernel &o = static_cast<const Kronecker_dtau_kernel &>(other);
1151 int cmpval;
1152
1153 cmpval = n.compare(o.n);
1154 if ( cmpval) {
1155 return cmpval;
1156 }
1157
1158 cmpval = z.compare(o.z);
1159 if ( cmpval) {
1160 return cmpval;
1161 }
1162
1163 cmpval = K.compare(o.K);
1164 if ( cmpval) {
1165 return cmpval;
1166 }
1167
1168 return C_norm.compare(o.C_norm);
1169}
1170
1172{
1173 return 4;
1174}
1175
1177{
1178 switch (i) {
1179 case 0:
1180 return n;
1181 case 1:
1182 return z;
1183 case 2:
1184 return K;
1185 case 3:
1186 return C_norm;
1187 default:
1188 throw (std::out_of_range("Kronecker_dtau_kernel::op() out of range"));
1189 }
1190}
1191
1193{
1195
1196 switch (i) {
1197 case 0:
1198 return n;
1199 case 1:
1200 return z;
1201 case 2:
1202 return K;
1203 case 3:
1204 return C_norm;
1205 default:
1206 throw (std::out_of_range("Kronecker_dtau_kernel::let_op() out of range"));
1207 }
1208}
1209
1214
1216{
1217 numeric n_num = ex_to<numeric>(n);
1218 int n_int = n_num.to_int();
1219
1220 // case n=0
1221 if ( n_num == 0 ) {
1222 if ( i == 0 ) {
1223 ex res = -C_norm*K;
1224
1225 return ex_to<numeric>(res.evalf()).to_cl_N();
1226 }
1227
1228 return 0;
1229 }
1230
1231 // case n=1
1232 if ( n_num == 1 ) {
1233 return 0;
1234 }
1235
1236 // case n>1
1237 if ( i == 0 ) {
1238 ex res = C_norm*K / factorial(n_num-2) * bernoulli(n_num)/n_num;
1239
1240 return ex_to<numeric>(res.evalf()).to_cl_N();
1241 }
1242
1243 // n>1, i>0
1244
1245 // if K>1 the variable i needs to be a multiple of K
1246 int K_int = ex_to<numeric>(K).to_int();
1247
1248 if ( (i % K_int) != 0 ) {
1249 return 0;
1250 }
1251 int i_local = i/K_int;
1252
1253 ex w = exp(ex_to<numeric>((2*Pi*I*z).evalf()));
1254 cln::cl_N w_cln = ex_to<numeric>(w).to_cl_N();
1255 cln::cl_N res_cln = 0;
1256 for (int j=1; j<=i_local; j++) {
1257 if ( (i_local % j) == 0 ) {
1258 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);
1259 }
1260 }
1261 ex pre = -C_norm*K/factorial(n_num-2);
1262
1263 return ex_to<numeric>(pre.evalf()).to_cl_N() * res_cln;
1264}
1265
1272{
1273 numeric n_num = ex_to<numeric>(n);
1274
1275 if ( n_num == 0 ) {
1276 return 1;
1277 }
1278
1279 // use the direct formula here
1280 if ( n_num == 1 ) {
1281 ex wbar = exp(ex_to<numeric>((2*Pi*I*z).evalf()));
1282 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));
1283
1284 return ex_to<numeric>(res.evalf());
1285 }
1286
1287 ex pre = pow(2*Pi*I,n_num)/C_norm/K/(n_num-1);
1288
1289 return get_numerical_value_impl(qbar, pre, 1, N_trunc);
1290}
1291
1292void Kronecker_dtau_kernel::do_print(const print_context & c, unsigned level) const
1293{
1294 c.s << "Kronecker_dtau_kernel(";
1295 n.print(c);
1296 c.s << ",";
1297 z.print(c);
1298 c.s << ",";
1299 K.print(c);
1300 c.s << ",";
1301 C_norm.print(c);
1302 c.s << ")";
1303}
1304
1306
1307
1314
1315Kronecker_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)
1316{
1317}
1318
1319int Kronecker_dz_kernel::compare_same_type(const basic &other) const
1320{
1321 const Kronecker_dz_kernel &o = static_cast<const Kronecker_dz_kernel &>(other);
1322 int cmpval;
1323
1324 cmpval = n.compare(o.n);
1325 if ( cmpval) {
1326 return cmpval;
1327 }
1328
1329 cmpval = z_j.compare(o.z_j);
1330 if ( cmpval) {
1331 return cmpval;
1332 }
1333
1334 cmpval = tau.compare(o.tau);
1335 if ( cmpval) {
1336 return cmpval;
1337 }
1338
1339 cmpval = K.compare(o.K);
1340 if ( cmpval) {
1341 return cmpval;
1342 }
1343
1344 return C_norm.compare(o.C_norm);
1345}
1346
1348{
1349 return 5;
1350}
1351
1353{
1354 switch (i) {
1355 case 0:
1356 return n;
1357 case 1:
1358 return z_j;
1359 case 2:
1360 return tau;
1361 case 3:
1362 return K;
1363 case 4:
1364 return C_norm;
1365 default:
1366 throw (std::out_of_range("Kronecker_dz_kernel::op() out of range"));
1367 }
1368}
1369
1371{
1373
1374 switch (i) {
1375 case 0:
1376 return n;
1377 case 1:
1378 return z_j;
1379 case 2:
1380 return tau;
1381 case 3:
1382 return K;
1383 case 4:
1384 return C_norm;
1385 default:
1386 throw (std::out_of_range("Kronecker_dz_kernel::let_op() out of range"));
1387 }
1388}
1389
1394
1396{
1397 numeric n_num = ex_to<numeric>(n);
1398
1399 ex w_j_inv = exp(ex_to<numeric>((-2*Pi*I*z_j).evalf()));
1400 cln::cl_N w_j_inv_cln = ex_to<numeric>(w_j_inv).to_cl_N();
1401
1402 ex qbar = exp(ex_to<numeric>((2*Pi*I*K*tau).evalf()));
1403
1404 // case n=0
1405 if ( n_num == 0 ) {
1406 return 0;
1407 }
1408
1409 // case n=1
1410 if ( n_num == 1 ) {
1411 if ( i == 1 ) {
1412 return ex_to<numeric>((C_norm * 2*Pi*I).evalf()).to_cl_N();
1413 }
1414
1415 return 0;
1416 }
1417
1418 // case n=2
1419 if ( n_num == 2 ) {
1420 if ( ex_to<numeric>(z_j.evalf()).is_zero() ) {
1421 if ( i == 0 ) {
1422 return ex_to<numeric>((C_norm).evalf()).to_cl_N();
1423 }
1424 else if ( i == 1 ) {
1425 return 0;
1426 }
1427 else {
1428 ex res = -bernoulli(i)/numeric(i);
1429 if ( numeric(i).is_even() ) {
1430 Ebar_kernel Ebar = Ebar_kernel( 1-i, 0, numeric(1), numeric(1) );
1431 res += Ebar.get_numerical_value(qbar);
1432 }
1433
1434 res *= -pow(2*Pi*I,i)*C_norm/factorial(i-1);
1435
1436 return ex_to<numeric>(res.evalf()).to_cl_N();
1437 }
1438 }
1439 else {
1440 // z_j is not zero
1441 if ( i == 0 ) {
1442 return 0;
1443 }
1444 else {
1445 Li_negative my_Li_negative;
1446
1447 ex res = 0;
1448 if ( i == 1 ) {
1449 res = numeric(1,2);
1450 }
1451
1452 Ebar_kernel Ebar = Ebar_kernel( 1-i, 0, w_j_inv, numeric(1) );
1453
1454 res += my_Li_negative.get_numerical_value(i-1,w_j_inv) + Ebar.get_numerical_value(qbar);
1455
1456 res *= -pow(2*Pi*I,i)*C_norm/factorial(i-1);
1457
1458 return ex_to<numeric>(res.evalf()).to_cl_N();
1459 }
1460 }
1461 }
1462
1463 // case n>2
1464 ex res = 0;
1465 if ( i == 1 ) {
1466 res += - bernoulli(n_num-1)/(n_num-1);
1467 }
1468 if ( i > 0 ) {
1469 if ( ex_to<numeric>(z_j.evalf()).is_zero() ) {
1470 if ( (numeric(i)+n_num).is_even() ) {
1471 Ebar_kernel Ebar = Ebar_kernel( 1-i, 2-n_num, numeric(1), numeric(1) );
1472
1473 res += pow(2*Pi*I,i-1)/factorial(i-1) * Ebar.get_numerical_value(qbar);
1474 }
1475 }
1476 else {
1477 // z_j is not zero
1478 Ebar_kernel Ebar = Ebar_kernel( 1-i, 2-n_num, w_j_inv, numeric(1) );
1479
1480 res += pow(2*Pi*I,i-1)/factorial(i-1) * Ebar.get_numerical_value(qbar);
1481 }
1482 }
1483
1484 res *= - C_norm * 2*Pi*I/factorial(n_num-2);
1485
1486 return ex_to<numeric>(res.evalf()).to_cl_N();
1487}
1488
1495{
1496 numeric n_num = ex_to<numeric>(n);
1497
1498 if ( n_num == 1 ) {
1499 return 1;
1500 }
1501
1502 ex pre = pow(2*Pi*I,n-2)/C_norm;
1503
1504 return get_numerical_value_impl(z, pre, 0, N_trunc);
1505}
1506
1507void Kronecker_dz_kernel::do_print(const print_context & c, unsigned level) const
1508{
1509 c.s << "Kronecker_dz_kernel(";
1510 n.print(c);
1511 c.s << ",";
1512 z_j.print(c);
1513 c.s << ",";
1514 tau.print(c);
1515 c.s << ",";
1516 K.print(c);
1517 c.s << ",";
1518 C_norm.print(c);
1519 c.s << ")";
1520}
1521
1523
1524
1531
1532Eisenstein_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)
1533{
1534}
1535
1536int Eisenstein_kernel::compare_same_type(const basic &other) const
1537{
1538 const Eisenstein_kernel &o = static_cast<const Eisenstein_kernel &>(other);
1539 int cmpval;
1540
1541 cmpval = k.compare(o.k);
1542 if ( cmpval) {
1543 return cmpval;
1544 }
1545
1546 cmpval = N.compare(o.N);
1547 if ( cmpval) {
1548 return cmpval;
1549 }
1550
1551 cmpval = a.compare(o.a);
1552 if ( cmpval) {
1553 return cmpval;
1554 }
1555
1556 cmpval = b.compare(o.b);
1557 if ( cmpval) {
1558 return cmpval;
1559 }
1560
1561 cmpval = K.compare(o.K);
1562 if ( cmpval) {
1563 return cmpval;
1564 }
1565
1566 return C_norm.compare(o.C_norm);
1567}
1568
1578{
1579 if ( r.rhs() != 0 ) {
1580 throw (std::runtime_error("integration_kernel::series: non-zero expansion point not implemented"));
1581 }
1582
1583 ex qbar = r.lhs();
1585 res = res.series(qbar,order);
1586
1587 return res;
1588}
1589
1591{
1592 return 6;
1593}
1594
1596{
1597 switch (i) {
1598 case 0:
1599 return k;
1600 case 1:
1601 return N;
1602 case 2:
1603 return a;
1604 case 3:
1605 return b;
1606 case 4:
1607 return K;
1608 case 5:
1609 return C_norm;
1610 default:
1611 throw (std::out_of_range("Eisenstein_kernel::op() out of range"));
1612 }
1613}
1614
1616{
1618
1619 switch (i) {
1620 case 0:
1621 return k;
1622 case 1:
1623 return N;
1624 case 2:
1625 return a;
1626 case 3:
1627 return b;
1628 case 4:
1629 return K;
1630 case 5:
1631 return C_norm;
1632 default:
1633 throw (std::out_of_range("Eisenstein_kernel::let_op() out of range"));
1634 }
1635}
1636
1641
1643{
1645 res = res.series(x,order);
1646
1647 return res;
1648}
1649
1656{
1657 ex pre = numeric(1)/C_norm;
1658
1659 return get_numerical_value_impl(qbar, pre, 1, N_trunc);
1660}
1661
1663{
1664 return true;
1665}
1666
1668{
1669 numeric k_num = ex_to<numeric>(k);
1670 numeric N_num = ex_to<numeric>(N);
1671 numeric a_num = ex_to<numeric>(a);
1672 numeric b_num = ex_to<numeric>(b);
1673 numeric K_num = ex_to<numeric>(K);
1674
1675 if ( (k==2) && (a==1) && (b==1) ) {
1676 return B_eisenstein_series(q, N_num, K_num, order);
1677 }
1678
1679 return E_eisenstein_series(q, k_num, N_num, a_num, b_num, K_num, order);
1680}
1681
1682void Eisenstein_kernel::do_print(const print_context & c, unsigned level) const
1683{
1684 c.s << "Eisenstein_kernel(";
1685 k.print(c);
1686 c.s << ",";
1687 N.print(c);
1688 c.s << ",";
1689 a.print(c);
1690 c.s << ",";
1691 b.print(c);
1692 c.s << ",";
1693 K.print(c);
1694 c.s << ",";
1695 C_norm.print(c);
1696 c.s << ")";
1697}
1698
1700
1701
1708
1709Eisenstein_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)
1710{
1711}
1712
1713int Eisenstein_h_kernel::compare_same_type(const basic &other) const
1714{
1715 const Eisenstein_h_kernel &o = static_cast<const Eisenstein_h_kernel &>(other);
1716 int cmpval;
1717
1718 cmpval = k.compare(o.k);
1719 if ( cmpval) {
1720 return cmpval;
1721 }
1722
1723 cmpval = N.compare(o.N);
1724 if ( cmpval) {
1725 return cmpval;
1726 }
1727
1728 cmpval = r.compare(o.r);
1729 if ( cmpval) {
1730 return cmpval;
1731 }
1732
1733 cmpval = s.compare(o.s);
1734 if ( cmpval) {
1735 return cmpval;
1736 }
1737
1738 return C_norm.compare(o.C_norm);
1739}
1740
1750{
1751 if ( r.rhs() != 0 ) {
1752 throw (std::runtime_error("integration_kernel::series: non-zero expansion point not implemented"));
1753 }
1754
1755 ex qbar = r.lhs();
1757 res = res.series(qbar,order);
1758
1759 return res;
1760}
1761
1763{
1764 return 5;
1765}
1766
1768{
1769 switch (i) {
1770 case 0:
1771 return k;
1772 case 1:
1773 return N;
1774 case 2:
1775 return r;
1776 case 3:
1777 return s;
1778 case 4:
1779 return C_norm;
1780 default:
1781 throw (std::out_of_range("Eisenstein_h_kernel::op() out of range"));
1782 }
1783}
1784
1786{
1788
1789 switch (i) {
1790 case 0:
1791 return k;
1792 case 1:
1793 return N;
1794 case 2:
1795 return r;
1796 case 3:
1797 return s;
1798 case 4:
1799 return C_norm;
1800 default:
1801 throw (std::out_of_range("Eisenstein_h_kernel::let_op() out of range"));
1802 }
1803}
1804
1809
1811{
1813 res = res.series(x,order);
1814
1815 return res;
1816}
1817
1824{
1825 ex pre = numeric(1)/C_norm;
1826
1827 return get_numerical_value_impl(qbar, pre, 1, N_trunc);
1828}
1829
1831{
1832 return true;
1833}
1834
1840ex Eisenstein_h_kernel::coefficient_a0(const numeric & k, const numeric & r, const numeric & s, const numeric & N) const
1841{
1842 if ( k == 1 ) {
1843 if ( irem(s,N) != 0 ) {
1844 return numeric(1,4) - mod(s,N)/numeric(2)/N;
1845 }
1846 else if ( (irem(r,N)==0) && (irem(s,N)==0) ) {
1847 return 0;
1848 }
1849 else {
1850 return I*numeric(1,4)*cos(Pi*mod(r,N)/N)/sin(Pi*mod(r,N)/N);
1851 }
1852 }
1853
1854 // case k > 1
1855 return -Bernoulli_polynomial(k,mod(s,N)/N)/numeric(2)/k;
1856}
1857
1863ex Eisenstein_h_kernel::coefficient_an(const numeric & n, const numeric & k, const numeric & r, const numeric & s, const numeric & N) const
1864{
1865 ex res = 0;
1866
1867 for (numeric m=1; m<=n; m++) {
1868 if ( irem(n,m) == 0 ) {
1869 for (numeric c1=0; c1<N; c1++) {
1870 numeric c2 = n/m;
1871 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));
1872 }
1873 }
1874 }
1875
1876 return res/numeric(2)/pow(N,k);
1877}
1878
1880{
1881 numeric N_order_num = numeric(N_order);
1882
1883 numeric k_num = ex_to<numeric>(k);
1884 numeric r_num = ex_to<numeric>(r);
1885 numeric s_num = ex_to<numeric>(s);
1886 numeric N_num = ex_to<numeric>(N);
1887
1888 ex res = coefficient_a0(k_num,r_num,s_num,N_num);
1889
1890 for (numeric i1=1; i1<N_order_num; i1++) {
1891 res += coefficient_an(i1,k_num,r_num,s_num,N_num) * pow(q,i1);
1892 }
1893
1894 res += Order(pow(q,N_order));
1895 res = res.series(q,N_order);
1896
1897 return res;
1898}
1899
1900void Eisenstein_h_kernel::do_print(const print_context & c, unsigned level) const
1901{
1902 c.s << "Eisenstein_h_kernel(";
1903 k.print(c);
1904 c.s << ",";
1905 N.print(c);
1906 c.s << ",";
1907 r.print(c);
1908 c.s << ",";
1909 s.print(c);
1910 c.s << ",";
1911 C_norm.print(c);
1912 c.s << ")";
1913}
1914
1916
1917
1924
1925modular_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)
1926{
1927}
1928
1929int modular_form_kernel::compare_same_type(const basic &other) const
1930{
1931 const modular_form_kernel &o = static_cast<const modular_form_kernel &>(other);
1932 int cmpval;
1933
1934 cmpval = k.compare(o.k);
1935 if ( cmpval) {
1936 return cmpval;
1937 }
1938
1939 cmpval = P.compare(o.P);
1940 if ( cmpval) {
1941 return cmpval;
1942 }
1943
1944 return C_norm.compare(o.C_norm);
1945}
1946
1954{
1955 if ( r.rhs() != 0 ) {
1956 throw (std::runtime_error("integration_kernel::series: non-zero expansion point not implemented"));
1957 }
1958
1959 ex qbar = r.lhs();
1960
1961 subs_q_expansion do_subs_q_expansion(qbar, order);
1962
1963 ex res = do_subs_q_expansion(P).series(qbar,order);
1964 res += Order(pow(qbar,order));
1965 res = res.series(qbar,order);
1966
1967 return res;
1968}
1969
1971{
1972 return 3;
1973}
1974
1976{
1977 switch (i) {
1978 case 0:
1979 return k;
1980 case 1:
1981 return P;
1982 case 2:
1983 return C_norm;
1984 default:
1985 throw (std::out_of_range("modular_form_kernel::op() out of range"));
1986 }
1987}
1988
1990{
1992
1993 switch (i) {
1994 case 0:
1995 return k;
1996 case 1:
1997 return P;
1998 case 2:
1999 return C_norm;
2000 default:
2001 throw (std::out_of_range("modular_form_kernel::let_op() out of range"));
2002 }
2003}
2004
2006{
2008 if ( !flag ) {
2009 return false;
2010 }
2011
2012 symbol qbar("qbar");
2013
2014 // test with a random number and random expansion
2016}
2017
2019{
2021 res = C_norm * res/qbar;
2022 res = res.series(qbar,order);
2023 return res;
2024}
2025
2032{
2033 ex pre = numeric(1)/C_norm;
2034
2035 return get_numerical_value_impl(qbar, pre, 1, N_trunc);
2036}
2037
2039{
2040 return true;
2041}
2042
2044{
2045 return this->series(q==0,N_order);
2046}
2047
2048void modular_form_kernel::do_print(const print_context & c, unsigned level) const
2049{
2050 c.s << "modular_form_kernel(";
2051 k.print(c);
2052 c.s << ",";
2053 P.print(c);
2054 c.s << ",";
2055 C_norm.print(c);
2056 c.s << ")";
2057}
2058
2060
2061
2068
2069user_defined_kernel::user_defined_kernel(const ex & arg_f, const ex & arg_x) : inherited(), f(arg_f), x(arg_x)
2070{
2071}
2072
2073int user_defined_kernel::compare_same_type(const basic &other) const
2074{
2075 const user_defined_kernel &o = static_cast<const user_defined_kernel &>(other);
2076 int cmpval;
2077
2078 cmpval = f.compare(o.f);
2079 if ( cmpval) {
2080 return cmpval;
2081 }
2082
2083 return x.compare(o.x);
2084}
2085
2087{
2088 return 2;
2089}
2090
2092{
2093 switch (i) {
2094 case 0:
2095 return f;
2096 case 1:
2097 return x;
2098 default:
2099 throw (std::out_of_range("user_defined_kernel::op() out of range"));
2100 }
2101}
2102
2104{
2106
2107 switch (i) {
2108 case 0:
2109 return f;
2110 case 1:
2111 return x;
2112 default:
2113 throw (std::out_of_range("user_defined_kernel::let_op() out of range"));
2114 }
2115}
2116
2118{
2119 // test with a random number
2120 return f.subs(x==numeric(1,937)).evalf().info(info_flags::numeric);
2121}
2122
2124{
2125 ex res = f.series(x,order).subs(x==x_up);
2126
2127 return res;
2128}
2129
2131{
2132 return true;
2133}
2134
2135void user_defined_kernel::do_print(const print_context & c, unsigned level) const
2136{
2137 c.s << "user_defined_kernel(";
2138 f.print(c);
2139 c.s << ",";
2140 x.print(c);
2141 c.s << ")";
2142}
2143
2145
2146} // namespace GiNaC
Interface to GiNaC's sums of expressions.
#define GINAC_BIND_UNARCHIVER(classname)
Definition archive.h:229
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:104
void ensure_if_modifiable() const
Ensure the object may be modified without hurting others, throws if this is not the case.
Definition basic.cpp:893
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Definition basic.cpp:718
virtual ex evalf() const
Evaluate object numerically.
Definition basic.cpp:424
Wrapper template for making GiNaC classes out of STL containers.
Definition container.h:72
const_iterator end() const
Definition container.h:239
const_iterator begin() const
Definition container.h:238
size_t nops() const override
Number of operands/members.
Definition container.h:117
ex op(size_t i) const override
Return operand/member at position i.
Definition container.h:294
container & append(const ex &b)
Add element at back.
Definition container.h:390
Lightweight wrapper for GiNaC's symbolic objects.
Definition ex.h:72
ex evalf() const
Definition ex.h:121
ex series(const ex &r, int order, unsigned options=0) const
Compute the truncated series expansion of an expression.
Definition pseries.cpp:1271
ex subs(const exmap &m, unsigned options=0) const
Definition ex.h:841
bool info(unsigned inf) const
Definition ex.h:132
int compare(const ex &other) const
Definition ex.h:322
ex lhs() const
Left hand side of relational expression.
Definition ex.cpp:225
void print(const print_context &c, unsigned level=0) const
Print expression to stream.
Definition ex.cpp:54
ex rhs() const
Right hand side of relational expression.
Definition ex.cpp:233
ex coeff(const ex &s, int n=1) const
Definition ex.h:175
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:81
bool is_odd() const
True if object is an exact odd integer.
Definition numeric.cpp:1181
cln::cl_N to_cl_N() const
Returns a new CLN object of type cl_N, representing the value of *this.
Definition numeric.cpp:1331
bool is_even() const
True if object is an exact even integer.
Definition numeric.cpp:1174
int to_int() const
Converts numeric types to machine's int.
Definition numeric.cpp:1302
Base class for print_contexts.
Definition print.h:101
This class holds a relation consisting of two expressions and a logical relation between them.
Definition relational.h:34
Basic CAS symbol.
Definition symbol.h:38
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:2190
unsigned options
Definition factor.cpp:2473
vector< int > k
Definition factor.cpp:1434
size_t n
Definition factor.cpp:1431
size_t c
Definition factor.cpp:756
ex x
Definition factor.cpp:1609
size_t r
Definition factor.cpp:756
umodpoly one
Definition factor.cpp:1430
mvec m
Definition factor.cpp:757
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:35
const numeric I
Imaginary unit.
Definition numeric.cpp:1432
const numeric pow(const numeric &x, const numeric &y)
Definition numeric.h:250
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:2170
const numeric mod(const numeric &a, const numeric &b)
Modulus (in positive representation).
Definition numeric.cpp:2332
const numeric abs(const numeric &x)
Absolute value.
Definition numeric.cpp:2319
const ex _ex1
Definition utils.cpp:384
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:1432
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:135
const numeric irem(const numeric &a, const numeric &b)
Numeric integer remainder.
Definition numeric.cpp:2367
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:793
const numeric exp(const numeric &x)
Exponential function.
Definition numeric.cpp:1438
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:2112
const numeric cos(const numeric &x)
Numeric cosine (trigonometric function).
Definition numeric.cpp:1469
bool is_even(const numeric &x)
Definition numeric.h:280
const numeric smod(const numeric &a_, const numeric &b_)
Modulus (in symmetric representation).
Definition numeric.cpp:2345
const constant Pi("Pi", PiEvalf, "\\pi", domain::positive)
Pi.
Definition constant.h:84
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
Definition idx.cpp:43
const numeric iquo(const numeric &a, const numeric &b)
Numeric integer quotient.
Definition numeric.cpp:2408
_numeric_digits Digits
Accuracy in decimal digits.
Definition numeric.cpp:2590
const numeric sin(const numeric &x)
Numeric sine (trigonometric function).
Definition numeric.cpp:1460
ex normal(const ex &thisex)
Definition ex.h:769
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:41
numeric generalised_Bernoulli_number(const numeric &k, const numeric &b)
The generalised Bernoulli number.
const ex _ex0
Definition utils.cpp:368
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:183
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.