GiNaC 1.8.10
inifcns_gamma.cpp
Go to the documentation of this file.
1
6/*
7 * GiNaC Copyright (C) 1999-2026 Johannes Gutenberg University Mainz, Germany
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
23#include "inifcns.h"
24#include "constant.h"
25#include "pseries.h"
26#include "numeric.h"
27#include "power.h"
28#include "relational.h"
29#include "operators.h"
30#include "symbol.h"
31#include "symmetry.h"
32#include "utils.h"
33
34#include <stdexcept>
35#include <vector>
36
37namespace GiNaC {
38
40// Logarithm of Gamma function
42
43static ex lgamma_evalf(const ex & x)
44{
45 if (is_exactly_a<numeric>(x)) {
46 try {
47 return lgamma(ex_to<numeric>(x));
48 } catch (const dunno &e) { }
49 }
50
51 return lgamma(x).hold();
52}
53
54
59static ex lgamma_eval(const ex & x)
60{
62 // trap integer arguments:
64 // lgamma(n) -> log((n-1)!) for postitive n
66 return log(factorial(x + _ex_1));
67 else
68 throw (pole_error("lgamma_eval(): logarithmic pole",0));
69 }
70 if (!ex_to<numeric>(x).is_rational())
71 return lgamma(ex_to<numeric>(x));
72 }
73
74 return lgamma(x).hold();
75}
76
77
78static ex lgamma_deriv(const ex & x, unsigned deriv_param)
79{
80 GINAC_ASSERT(deriv_param==0);
81
82 // d/dx lgamma(x) -> psi(x)
83 return psi(x);
84}
85
86
87static ex lgamma_series(const ex & arg,
88 const relational & rel,
89 int order,
90 unsigned options)
91{
92 // method:
93 // Taylor series where there is no pole falls back to psi function
94 // evaluation.
95 // On a pole at -m we could use the recurrence relation
96 // lgamma(x) == lgamma(x+1)-log(x)
97 // from which follows
98 // series(lgamma(x),x==-m,order) ==
99 // series(lgamma(x+m+1)-log(x)...-log(x+m)),x==-m,order);
100 const ex arg_pt = arg.subs(rel, subs_options::no_pattern);
101 if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
102 throw do_taylor(); // caught by function::series()
103 // if we got here we have to care for a simple pole of tgamma(-m):
104 numeric m = -ex_to<numeric>(arg_pt);
105 ex recur;
106 for (numeric p = 0; p<=m; ++p)
107 recur += log(arg+p);
108 return (lgamma(arg+m+_ex1)-recur).series(rel, order, options);
109}
110
111
112static ex lgamma_conjugate(const ex & x)
113{
114 // conjugate(lgamma(x))==lgamma(conjugate(x)) unless on the branch cut
115 // which runs along the negative real axis.
117 return lgamma(x);
118 }
119 if (is_exactly_a<numeric>(x) &&
120 !x.imag_part().is_zero()) {
121 return lgamma(x.conjugate());
122 }
123 return conjugate_function(lgamma(x)).hold();
124}
125
126
128 evalf_func(lgamma_evalf).
129 derivative_func(lgamma_deriv).
130 series_func(lgamma_series).
131 conjugate_func(lgamma_conjugate).
132 latex_name("\\log \\Gamma"));
133
134
136// true Gamma function
138
139static ex tgamma_evalf(const ex & x)
140{
141 if (is_exactly_a<numeric>(x)) {
142 try {
143 return tgamma(ex_to<numeric>(x));
144 } catch (const dunno &e) { }
145 }
146
147 return tgamma(x).hold();
148}
149
150
156static ex tgamma_eval(const ex & x)
157{
159 // trap integer arguments:
160 const numeric two_x = (*_num2_p)*ex_to<numeric>(x);
161 if (two_x.is_even()) {
162 // tgamma(n) -> (n-1)! for postitive n
163 if (two_x.is_positive()) {
164 return factorial(ex_to<numeric>(x).sub(*_num1_p));
165 } else {
166 throw (pole_error("tgamma_eval(): simple pole",1));
167 }
168 }
169 // trap half integer arguments:
170 if (two_x.is_integer()) {
171 // trap positive x==(n+1/2)
172 // tgamma(n+1/2) -> Pi^(1/2)*(1*3*..*(2*n-1))/(2^n)
173 if (two_x.is_positive()) {
174 const numeric n = ex_to<numeric>(x).sub(*_num1_2_p);
175 return (doublefactorial(n.mul(*_num2_p).sub(*_num1_p)).div(pow(*_num2_p,n))) * sqrt(Pi);
176 } else {
177 // trap negative x==(-n+1/2)
178 // tgamma(-n+1/2) -> Pi^(1/2)*(-2)^n/(1*3*..*(2*n-1))
179 const numeric n = abs(ex_to<numeric>(x).sub(*_num1_2_p));
180 return (pow(*_num_2_p, n).div(doublefactorial(n.mul(*_num2_p).sub(*_num1_p))))*sqrt(Pi);
181 }
182 }
183 if (!ex_to<numeric>(x).is_rational())
184 return tgamma(ex_to<numeric>(x));
185 }
186
187 return tgamma(x).hold();
188}
189
190
191static ex tgamma_deriv(const ex & x, unsigned deriv_param)
192{
193 GINAC_ASSERT(deriv_param==0);
194
195 // d/dx tgamma(x) -> psi(x)*tgamma(x)
196 return psi(x)*tgamma(x);
197}
198
199
200static ex tgamma_series(const ex & arg,
201 const relational & rel,
202 int order,
203 unsigned options)
204{
205 // method:
206 // Taylor series where there is no pole falls back to psi function
207 // evaluation.
208 // On a pole at -m use the recurrence relation
209 // tgamma(x) == tgamma(x+1) / x
210 // from which follows
211 // series(tgamma(x),x==-m,order) ==
212 // series(tgamma(x+m+1)/(x*(x+1)*...*(x+m)),x==-m,order);
213 const ex arg_pt = arg.subs(rel, subs_options::no_pattern);
214 if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
215 throw do_taylor(); // caught by function::series()
216 // if we got here we have to care for a simple pole at -m:
217 const numeric m = -ex_to<numeric>(arg_pt);
218 ex ser_denom = _ex1;
219 for (numeric p; p<=m; ++p)
220 ser_denom *= arg+p;
221 return (tgamma(arg+m+_ex1)/ser_denom).series(rel, order, options);
222}
223
224
225static ex tgamma_conjugate(const ex & x)
226{
227 // conjugate(tgamma(x))==tgamma(conjugate(x))
228 return tgamma(x.conjugate());
229}
230
231
233 evalf_func(tgamma_evalf).
234 derivative_func(tgamma_deriv).
235 series_func(tgamma_series).
236 conjugate_func(tgamma_conjugate).
237 latex_name("\\Gamma"));
238
239
241// beta-function
243
244static ex beta_evalf(const ex & x, const ex & y)
245{
246 if (is_exactly_a<numeric>(x) && is_exactly_a<numeric>(y)) {
247 try {
248 return exp(lgamma(ex_to<numeric>(x))+lgamma(ex_to<numeric>(y))-lgamma(ex_to<numeric>(x+y)));
249 } catch (const dunno &e) { }
250 }
251
252 return beta(x,y).hold();
253}
254
255
256static ex beta_eval(const ex & x, const ex & y)
257{
258 if (x.is_equal(_ex1))
259 return 1/y;
260 if (y.is_equal(_ex1))
261 return 1/x;
263 // treat all problematic x and y that may not be passed into tgamma,
264 // because they would throw there although beta(x,y) is well-defined
265 // using the formula beta(x,y) == (-1)^y * beta(1-x-y, y)
266 const numeric &nx = ex_to<numeric>(x);
267 const numeric &ny = ex_to<numeric>(y);
268 if (nx.is_real() && nx.is_integer() &&
269 ny.is_real() && ny.is_integer()) {
270 if (nx.is_negative()) {
271 if (nx<=-ny)
272 return pow(*_num_1_p, ny)*beta(1-x-y, y);
273 else
274 throw (pole_error("beta_eval(): simple pole",1));
275 }
276 if (ny.is_negative()) {
277 if (ny<=-nx)
278 return pow(*_num_1_p, nx)*beta(1-y-x, x);
279 else
280 throw (pole_error("beta_eval(): simple pole",1));
281 }
282 return tgamma(x)*tgamma(y)/tgamma(x+y);
283 }
284 // no problem in numerator, but denominator has pole:
285 if ((nx+ny).is_real() &&
286 (nx+ny).is_integer() &&
287 !(nx+ny).is_positive())
288 return _ex0;
289 if (!ex_to<numeric>(x).is_rational() || !ex_to<numeric>(x).is_rational())
290 return evalf(beta(x, y).hold());
291 }
292
293 return beta(x,y).hold();
294}
295
296
297static ex beta_deriv(const ex & x, const ex & y, unsigned deriv_param)
298{
299 GINAC_ASSERT(deriv_param<2);
300 ex retval;
301
302 // d/dx beta(x,y) -> (psi(x)-psi(x+y)) * beta(x,y)
303 if (deriv_param==0)
304 retval = (psi(x)-psi(x+y))*beta(x,y);
305 // d/dy beta(x,y) -> (psi(y)-psi(x+y)) * beta(x,y)
306 if (deriv_param==1)
307 retval = (psi(y)-psi(x+y))*beta(x,y);
308 return retval;
309}
310
311
312static ex beta_series(const ex & arg1,
313 const ex & arg2,
314 const relational & rel,
315 int order,
316 unsigned options)
317{
318 // method:
319 // Taylor series where there is no pole of one of the tgamma functions
320 // falls back to beta function evaluation. Otherwise, fall back to
321 // tgamma series directly.
322 const ex arg1_pt = arg1.subs(rel, subs_options::no_pattern);
323 const ex arg2_pt = arg2.subs(rel, subs_options::no_pattern);
324 GINAC_ASSERT(is_a<symbol>(rel.lhs()));
325 const symbol &s = ex_to<symbol>(rel.lhs());
326 ex arg1_ser, arg2_ser, arg1arg2_ser;
327 if ((!arg1_pt.info(info_flags::integer) || arg1_pt.info(info_flags::positive)) &&
328 (!arg2_pt.info(info_flags::integer) || arg2_pt.info(info_flags::positive)))
329 throw do_taylor(); // caught by function::series()
330 // trap the case where arg1 is on a pole:
332 arg1_ser = tgamma(arg1+s);
333 else
334 arg1_ser = tgamma(arg1);
335 // trap the case where arg2 is on a pole:
337 arg2_ser = tgamma(arg2+s);
338 else
339 arg2_ser = tgamma(arg2);
340 // trap the case where arg1+arg2 is on a pole:
341 if ((arg1+arg2).info(info_flags::integer) && !(arg1+arg2).info(info_flags::positive))
342 arg1arg2_ser = tgamma(arg2+arg1+s);
343 else
344 arg1arg2_ser = tgamma(arg2+arg1);
345 // compose the result (expanding all the terms):
346 return (arg1_ser*arg2_ser/arg1arg2_ser).series(rel, order, options).expand();
347}
348
349
351 evalf_func(beta_evalf).
352 derivative_func(beta_deriv).
353 series_func(beta_series).
354 latex_name("\\mathrm{B}").
355 set_symmetry(sy_symm(0, 1)));
356
357
359// Psi-function (aka digamma-function)
361
362static ex psi1_evalf(const ex & x)
363{
364 if (is_exactly_a<numeric>(x)) {
365 try {
366 return psi(ex_to<numeric>(x));
367 } catch (const dunno &e) { }
368 }
369
370 return psi(x).hold();
371}
372
375static ex psi1_eval(const ex & x)
376{
378 const numeric &nx = ex_to<numeric>(x);
379 if (nx.is_integer()) {
380 // integer case
381 if (nx.is_positive()) {
382 // psi(n) -> 1 + 1/2 +...+ 1/(n-1) - Euler
383 numeric rat = 0;
384 for (numeric i(nx+(*_num_1_p)); i>0; --i)
385 rat += i.inverse();
386 return rat-Euler;
387 } else {
388 // for non-positive integers there is a pole:
389 throw (pole_error("psi_eval(): simple pole",1));
390 }
391 }
392 if (((*_num2_p)*nx).is_integer()) {
393 // half integer case
394 if (nx.is_positive()) {
395 // psi((2m+1)/2) -> 2/(2m+1) + 2/2m +...+ 2/1 - Euler - 2log(2)
396 numeric rat = 0;
397 for (numeric i = (nx+(*_num_1_p))*(*_num2_p); i>0; i-=(*_num2_p))
398 rat += (*_num2_p)*i.inverse();
399 return rat-Euler-_ex2*log(_ex2);
400 } else {
401 // use the recurrence relation
402 // psi(-m-1/2) == psi(-m-1/2+1) - 1 / (-m-1/2)
403 // to relate psi(-m-1/2) to psi(1/2):
404 // psi(-m-1/2) == psi(1/2) + r
405 // where r == ((-1/2)^(-1) + ... + (-m-1/2)^(-1))
406 numeric recur = 0;
407 for (numeric p = nx; p<0; ++p)
408 recur -= pow(p, *_num_1_p);
409 return recur+psi(_ex1_2);
410 }
411 }
412 // psi1_evalf should be called here once it becomes available
413 }
414
415 return psi(x).hold();
416}
417
418static ex psi1_deriv(const ex & x, unsigned deriv_param)
419{
420 GINAC_ASSERT(deriv_param==0);
421
422 // d/dx psi(x) -> psi(1,x)
423 return psi(_ex1, x);
424}
425
426static ex psi1_series(const ex & arg,
427 const relational & rel,
428 int order,
429 unsigned options)
430{
431 // method:
432 // Taylor series where there is no pole falls back to polygamma function
433 // evaluation.
434 // On a pole at -m use the recurrence relation
435 // psi(x) == psi(x+1) - 1/z
436 // from which follows
437 // series(psi(x),x==-m,order) ==
438 // series(psi(x+m+1) - 1/x - 1/(x+1) - 1/(x+m)),x==-m,order);
439 const ex arg_pt = arg.subs(rel, subs_options::no_pattern);
440 if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
441 throw do_taylor(); // caught by function::series()
442 // if we got here we have to care for a simple pole at -m:
443 const numeric m = -ex_to<numeric>(arg_pt);
444 ex recur;
445 for (numeric p; p<=m; ++p)
446 recur += power(arg+p,_ex_1);
447 return (psi(arg+m+_ex1)-recur).series(rel, order, options);
448}
449
450unsigned psi1_SERIAL::serial =
451 function::register_new(function_options("psi", 1).
452 eval_func(psi1_eval).
453 evalf_func(psi1_evalf).
454 derivative_func(psi1_deriv).
455 series_func(psi1_series).
456 latex_name("\\psi").
457 overloaded(2));
458
460// Psi-functions (aka polygamma-functions) psi(0,x)==psi(x)
462
463static ex psi2_evalf(const ex & n, const ex & x)
464{
465 if (is_exactly_a<numeric>(n) && is_exactly_a<numeric>(x)) {
466 try {
467 return psi(ex_to<numeric>(n),ex_to<numeric>(x));
468 } catch (const dunno &e) { }
469 }
470
471 return psi(n,x).hold();
472}
473
476static ex psi2_eval(const ex & n, const ex & x)
477{
478 // psi(0,x) -> psi(x)
479 if (n.is_zero())
480 return psi(x);
481 // psi(-1,x) -> log(tgamma(x))
482 if (n.is_equal(_ex_1))
483 return log(tgamma(x));
484 if (n.info(info_flags::numeric) && n.info(info_flags::posint) &&
486 const numeric &nn = ex_to<numeric>(n);
487 const numeric &nx = ex_to<numeric>(x);
488 if (nx.is_integer()) {
489 // integer case
490 if (nx.is_equal(*_num1_p))
491 // use psi(n,1) == (-)^(n+1) * n! * zeta(n+1)
492 return pow(*_num_1_p,nn+(*_num1_p))*factorial(nn)*zeta(ex(nn+(*_num1_p)));
493 if (nx.is_positive()) {
494 // use the recurrence relation
495 // psi(n,m) == psi(n,m+1) - (-)^n * n! / m^(n+1)
496 // to relate psi(n,m) to psi(n,1):
497 // psi(n,m) == psi(n,1) + r
498 // where r == (-)^n * n! * (1^(-n-1) + ... + (m-1)^(-n-1))
499 numeric recur = 0;
500 for (numeric p = 1; p<nx; ++p)
501 recur += pow(p, -nn+(*_num_1_p));
502 recur *= factorial(nn)*pow((*_num_1_p), nn);
503 return recur+psi(n,_ex1);
504 } else {
505 // for non-positive integers there is a pole:
506 throw (pole_error("psi2_eval(): pole",1));
507 }
508 }
509 if (((*_num2_p)*nx).is_integer()) {
510 // half integer case
511 if (nx.is_equal(*_num1_2_p))
512 // use psi(n,1/2) == (-)^(n+1) * n! * (2^(n+1)-1) * zeta(n+1)
513 return pow(*_num_1_p,nn+(*_num1_p))*factorial(nn)*(pow(*_num2_p,nn+(*_num1_p)) + (*_num_1_p))*zeta(ex(nn+(*_num1_p)));
514 if (nx.is_positive()) {
515 const numeric m = nx - (*_num1_2_p);
516 // use the multiplication formula
517 // psi(n,2*m) == (psi(n,m) + psi(n,m+1/2)) / 2^(n+1)
518 // to revert to positive integer case
519 return psi(n,(*_num2_p)*m)*pow((*_num2_p),nn+(*_num1_p))-psi(n,m);
520 } else {
521 // use the recurrence relation
522 // psi(n,-m-1/2) == psi(n,-m-1/2+1) - (-)^n * n! / (-m-1/2)^(n+1)
523 // to relate psi(n,-m-1/2) to psi(n,1/2):
524 // psi(n,-m-1/2) == psi(n,1/2) + r
525 // where r == (-)^(n+1) * n! * ((-1/2)^(-n-1) + ... + (-m-1/2)^(-n-1))
526 numeric recur = 0;
527 for (numeric p = nx; p<0; ++p)
528 recur += pow(p, -nn+(*_num_1_p));
529 recur *= factorial(nn)*pow(*_num_1_p, nn+(*_num_1_p));
530 return recur+psi(n,_ex1_2);
531 }
532 }
533 // psi2_evalf should be called here once it becomes available
534 }
535
536 return psi(n, x).hold();
537}
538
539static ex psi2_deriv(const ex & n, const ex & x, unsigned deriv_param)
540{
541 GINAC_ASSERT(deriv_param<2);
542
543 if (deriv_param==0) {
544 // d/dn psi(n,x)
545 throw(std::logic_error("cannot diff psi(n,x) with respect to n"));
546 }
547 // d/dx psi(n,x) -> psi(n+1,x)
548 return psi(n+_ex1, x);
549}
550
551static ex psi2_series(const ex & n,
552 const ex & arg,
553 const relational & rel,
554 int order,
555 unsigned options)
556{
557 // method:
558 // Taylor series where there is no pole falls back to polygamma function
559 // evaluation.
560 // On a pole at -m use the recurrence relation
561 // psi(n,x) == psi(n,x+1) - (-)^n * n! / x^(n+1)
562 // from which follows
563 // series(psi(x),x==-m,order) ==
564 // series(psi(x+m+1) - (-1)^n * n! * ((x)^(-n-1) + (x+1)^(-n-1) + ...
565 // ... + (x+m)^(-n-1))),x==-m,order);
566 const ex arg_pt = arg.subs(rel, subs_options::no_pattern);
567 if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
568 throw do_taylor(); // caught by function::series()
569 // if we got here we have to care for a pole of order n+1 at -m:
570 const numeric m = -ex_to<numeric>(arg_pt);
571 ex recur;
572 for (numeric p; p<=m; ++p)
573 recur += power(arg+p,-n+_ex_1);
574 recur *= factorial(n)*power(_ex_1,n);
575 return (psi(n, arg+m+_ex1)-recur).series(rel, order, options);
576}
577
578unsigned psi2_SERIAL::serial =
579 function::register_new(function_options("psi", 2).
580 eval_func(psi2_eval).
581 evalf_func(psi2_evalf).
582 derivative_func(psi2_deriv).
583 series_func(psi2_series).
584 latex_name("\\psi").
585 overloaded(2));
586
587
588} // namespace GiNaC
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
Definition assertion.h:32
const basic & hold() const
Stop further evaluation.
Definition basic.cpp:886
virtual ex series(const relational &r, int order, unsigned options=0) const
Default implementation of ex::series().
Definition pseries.cpp:610
Exception class thrown by classes which provide their own series expansion to signal that ordinary Ta...
Definition function.h:667
Exception class thrown by functions to signal unimplemented functionality so the expression may just ...
Definition utils.h:36
Lightweight wrapper for GiNaC's symbolic objects.
Definition ex.h:72
bool is_equal(const ex &other) const
Definition ex.h:345
ex conjugate() const
Definition ex.h:146
ex series(const ex &r, int order, unsigned options=0) const
Compute the truncated series expansion of an expression.
Definition pseries.cpp:1271
ex imag_part() const
Definition ex.h:148
ex subs(const exmap &m, unsigned options=0) const
Definition ex.h:841
bool info(unsigned inf) const
Definition ex.h:132
bool is_zero() const
Definition ex.h:213
static unsigned register_new(function_options const &opt)
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
Definition numeric.h:81
const numeric sub(const numeric &other) const
Numerical subtraction method.
Definition numeric.cpp:871
bool is_positive() const
True if object is not complex and greater than zero.
Definition numeric.cpp:1135
bool is_real() const
True if object is a real integer, rational or float (but not complex).
Definition numeric.cpp:1207
bool is_integer() const
True if object is a non-complex integer.
Definition numeric.cpp:1153
bool is_negative() const
True if object is not complex and less than zero.
Definition numeric.cpp:1144
bool is_even() const
True if object is an exact even integer.
Definition numeric.cpp:1174
bool is_equal(const numeric &other) const
Definition numeric.cpp:1121
const numeric inverse() const
Inverse of a number.
Definition numeric.cpp:1052
const numeric div(const numeric &other) const
Numerical division method.
Definition numeric.cpp:889
Exception class thrown when a singularity is encountered.
Definition numeric.h:69
This class holds a two-component object, a basis and and exponent representing exponentiation.
Definition power.h:38
ex series(const relational &s, int order, unsigned options=0) const override
Implementation of ex::series() for powers.
Definition pseries.cpp:1084
static unsigned serial
Definition inifcns.h:162
static unsigned serial
Definition inifcns.h:168
This class holds a relation consisting of two expressions and a logical relation between them.
Definition relational.h:34
ex lhs() const
Definition relational.h:80
@ no_pattern
disable pattern matching
Definition flags.h:50
Basic CAS symbol.
Definition symbol.h:38
Interface to GiNaC's constant types and some special constants.
unsigned options
Definition factor.cpp:2473
size_t n
Definition factor.cpp:1431
ex x
Definition factor.cpp:1609
mvec m
Definition factor.cpp:757
#define REGISTER_FUNCTION(NAME, OPT)
Definition function.h:119
Interface to GiNaC's initially known functions.
Definition add.cpp:35
static ex lgamma_deriv(const ex &x, unsigned deriv_param)
const numeric * _num_1_p
Definition utils.cpp:350
const ex _ex2
Definition utils.cpp:388
const numeric pow(const numeric &x, const numeric &y)
Definition numeric.h:250
const ex _ex1_2
Definition utils.cpp:380
static ex beta_series(const ex &arg1, const ex &arg2, const relational &rel, int order, unsigned options)
symmetry sy_symm()
Definition symmetry.h:120
const numeric abs(const numeric &x)
Absolute value.
Definition numeric.cpp:2319
const constant Euler("Euler", EulerEvalf, "\\gamma_E", domain::positive)
Euler's constant.
Definition constant.h:86
const numeric * _num1_2_p
Definition utils.cpp:379
function zeta(const T1 &p1)
Definition inifcns.h:110
const ex _ex1
Definition utils.cpp:384
const numeric doublefactorial(const numeric &n)
The double factorial combinatorial function.
Definition numeric.cpp:2126
static ex lgamma_eval(const ex &x)
Evaluation of lgamma(x), the natural logarithm of the Gamma function.
bool is_rational(const numeric &x)
Definition numeric.h:289
static ex psi2_eval(const ex &n, const ex &x)
Evaluation of polygamma-function psi(n,x).
static ex beta_deriv(const ex &x, const ex &y, unsigned deriv_param)
function psi(const T1 &p1)
Definition inifcns.h:164
const numeric sqrt(const numeric &x)
Numeric square root.
Definition numeric.cpp:2479
const cln::cl_N tgamma(const cln::cl_N &x)
Definition numeric.cpp:2066
static ex psi1_eval(const ex &x)
Evaluation of digamma-function psi(x).
const numeric * _num_2_p
Definition utils.cpp:346
const numeric * _num2_p
Definition utils.cpp:387
static ex tgamma_deriv(const ex &x, unsigned deriv_param)
const numeric exp(const numeric &x)
Exponential function.
Definition numeric.cpp:1438
const numeric factorial(const numeric &n)
Factorial combinatorial function.
Definition numeric.cpp:2112
const ex _ex_1
Definition utils.cpp:351
static ex beta_eval(const ex &x, const ex &y)
const constant Pi("Pi", PiEvalf, "\\pi", domain::positive)
Pi.
Definition constant.h:84
static ex tgamma_evalf(const ex &x)
static ex psi2_deriv(const ex &n, const ex &x, unsigned deriv_param)
const numeric log(const numeric &x)
Natural logarithm.
Definition numeric.cpp:1449
ex evalf(const ex &thisex)
Definition ex.h:784
static ex tgamma_eval(const ex &x)
Evaluation of tgamma(x), the true Gamma function.
bool is_real(const numeric &x)
Definition numeric.h:292
const numeric * _num1_p
Definition utils.cpp:383
static ex lgamma_series(const ex &arg, const relational &rel, int order, unsigned options)
static ex lgamma_conjugate(const ex &x)
static ex tgamma_conjugate(const ex &x)
static ex psi1_deriv(const ex &x, unsigned deriv_param)
bool is_integer(const numeric &x)
Definition numeric.h:271
static ex psi2_series(const ex &n, const ex &arg, const relational &rel, int order, unsigned options)
static ex psi2_evalf(const ex &n, const ex &x)
static ex psi1_evalf(const ex &x)
static ex beta_evalf(const ex &x, const ex &y)
const cln::cl_N lgamma(const cln::cl_N &x)
The Gamma function.
Definition numeric.cpp:2038
static ex lgamma_evalf(const ex &x)
bool is_positive(const numeric &x)
Definition numeric.h:265
const ex _ex0
Definition utils.cpp:368
static ex tgamma_series(const ex &arg, const relational &rel, int order, unsigned options)
static ex psi1_series(const ex &arg, const relational &rel, int order, unsigned options)
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.
Interface to relations between expressions.
Interface to GiNaC's symbolic objects.
Interface to GiNaC's symmetry definitions.
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.