Coverage for /usr/lib/python3/dist-packages/sympy/functions/special/zeta_functions.py: 18%

292 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1""" Riemann zeta and related function. """ 

2 

3from sympy.core.add import Add 

4from sympy.core.cache import cacheit 

5from sympy.core.function import ArgumentIndexError, expand_mul, Function 

6from sympy.core.numbers import pi, I, Integer 

7from sympy.core.relational import Eq 

8from sympy.core.singleton import S 

9from sympy.core.symbol import Dummy 

10from sympy.core.sympify import sympify 

11from sympy.functions.combinatorial.numbers import bernoulli, factorial, genocchi, harmonic 

12from sympy.functions.elementary.complexes import re, unpolarify, Abs, polar_lift 

13from sympy.functions.elementary.exponential import log, exp_polar, exp 

14from sympy.functions.elementary.integers import ceiling, floor 

15from sympy.functions.elementary.miscellaneous import sqrt 

16from sympy.functions.elementary.piecewise import Piecewise 

17from sympy.polys.polytools import Poly 

18 

19############################################################################### 

20###################### LERCH TRANSCENDENT ##################################### 

21############################################################################### 

22 

23 

24class lerchphi(Function): 

25 r""" 

26 Lerch transcendent (Lerch phi function). 

27 

28 Explanation 

29 =========== 

30 

31 For $\operatorname{Re}(a) > 0$, $|z| < 1$ and $s \in \mathbb{C}$, the 

32 Lerch transcendent is defined as 

33 

34 .. math :: \Phi(z, s, a) = \sum_{n=0}^\infty \frac{z^n}{(n + a)^s}, 

35 

36 where the standard branch of the argument is used for $n + a$, 

37 and by analytic continuation for other values of the parameters. 

38 

39 A commonly used related function is the Lerch zeta function, defined by 

40 

41 .. math:: L(q, s, a) = \Phi(e^{2\pi i q}, s, a). 

42 

43 **Analytic Continuation and Branching Behavior** 

44 

45 It can be shown that 

46 

47 .. math:: \Phi(z, s, a) = z\Phi(z, s, a+1) + a^{-s}. 

48 

49 This provides the analytic continuation to $\operatorname{Re}(a) \le 0$. 

50 

51 Assume now $\operatorname{Re}(a) > 0$. The integral representation 

52 

53 .. math:: \Phi_0(z, s, a) = \int_0^\infty \frac{t^{s-1} e^{-at}}{1 - ze^{-t}} 

54 \frac{\mathrm{d}t}{\Gamma(s)} 

55 

56 provides an analytic continuation to $\mathbb{C} - [1, \infty)$. 

57 Finally, for $x \in (1, \infty)$ we find 

58 

59 .. math:: \lim_{\epsilon \to 0^+} \Phi_0(x + i\epsilon, s, a) 

60 -\lim_{\epsilon \to 0^+} \Phi_0(x - i\epsilon, s, a) 

61 = \frac{2\pi i \log^{s-1}{x}}{x^a \Gamma(s)}, 

62 

63 using the standard branch for both $\log{x}$ and 

64 $\log{\log{x}}$ (a branch of $\log{\log{x}}$ is needed to 

65 evaluate $\log{x}^{s-1}$). 

66 This concludes the analytic continuation. The Lerch transcendent is thus 

67 branched at $z \in \{0, 1, \infty\}$ and 

68 $a \in \mathbb{Z}_{\le 0}$. For fixed $z, a$ outside these 

69 branch points, it is an entire function of $s$. 

70 

71 Examples 

72 ======== 

73 

74 The Lerch transcendent is a fairly general function, for this reason it does 

75 not automatically evaluate to simpler functions. Use ``expand_func()`` to 

76 achieve this. 

77 

78 If $z=1$, the Lerch transcendent reduces to the Hurwitz zeta function: 

79 

80 >>> from sympy import lerchphi, expand_func 

81 >>> from sympy.abc import z, s, a 

82 >>> expand_func(lerchphi(1, s, a)) 

83 zeta(s, a) 

84 

85 More generally, if $z$ is a root of unity, the Lerch transcendent 

86 reduces to a sum of Hurwitz zeta functions: 

87 

88 >>> expand_func(lerchphi(-1, s, a)) 

89 zeta(s, a/2)/2**s - zeta(s, a/2 + 1/2)/2**s 

90 

91 If $a=1$, the Lerch transcendent reduces to the polylogarithm: 

92 

93 >>> expand_func(lerchphi(z, s, 1)) 

94 polylog(s, z)/z 

95 

96 More generally, if $a$ is rational, the Lerch transcendent reduces 

97 to a sum of polylogarithms: 

98 

99 >>> from sympy import S 

100 >>> expand_func(lerchphi(z, s, S(1)/2)) 

101 2**(s - 1)*(polylog(s, sqrt(z))/sqrt(z) - 

102 polylog(s, sqrt(z)*exp_polar(I*pi))/sqrt(z)) 

103 >>> expand_func(lerchphi(z, s, S(3)/2)) 

104 -2**s/z + 2**(s - 1)*(polylog(s, sqrt(z))/sqrt(z) - 

105 polylog(s, sqrt(z)*exp_polar(I*pi))/sqrt(z))/z 

106 

107 The derivatives with respect to $z$ and $a$ can be computed in 

108 closed form: 

109 

110 >>> lerchphi(z, s, a).diff(z) 

111 (-a*lerchphi(z, s, a) + lerchphi(z, s - 1, a))/z 

112 >>> lerchphi(z, s, a).diff(a) 

113 -s*lerchphi(z, s + 1, a) 

114 

115 See Also 

116 ======== 

117 

118 polylog, zeta 

119 

120 References 

121 ========== 

122 

123 .. [1] Bateman, H.; Erdelyi, A. (1953), Higher Transcendental Functions, 

124 Vol. I, New York: McGraw-Hill. Section 1.11. 

125 .. [2] https://dlmf.nist.gov/25.14 

126 .. [3] https://en.wikipedia.org/wiki/Lerch_transcendent 

127 

128 """ 

129 

130 def _eval_expand_func(self, **hints): 

131 z, s, a = self.args 

132 if z == 1: 

133 return zeta(s, a) 

134 if s.is_Integer and s <= 0: 

135 t = Dummy('t') 

136 p = Poly((t + a)**(-s), t) 

137 start = 1/(1 - t) 

138 res = S.Zero 

139 for c in reversed(p.all_coeffs()): 

140 res += c*start 

141 start = t*start.diff(t) 

142 return res.subs(t, z) 

143 

144 if a.is_Rational: 

145 # See section 18 of 

146 # Kelly B. Roach. Hypergeometric Function Representations. 

147 # In: Proceedings of the 1997 International Symposium on Symbolic and 

148 # Algebraic Computation, pages 205-211, New York, 1997. ACM. 

149 # TODO should something be polarified here? 

150 add = S.Zero 

151 mul = S.One 

152 # First reduce a to the interaval (0, 1] 

153 if a > 1: 

154 n = floor(a) 

155 if n == a: 

156 n -= 1 

157 a -= n 

158 mul = z**(-n) 

159 add = Add(*[-z**(k - n)/(a + k)**s for k in range(n)]) 

160 elif a <= 0: 

161 n = floor(-a) + 1 

162 a += n 

163 mul = z**n 

164 add = Add(*[z**(n - 1 - k)/(a - k - 1)**s for k in range(n)]) 

165 

166 m, n = S([a.p, a.q]) 

167 zet = exp_polar(2*pi*I/n) 

168 root = z**(1/n) 

169 up_zet = unpolarify(zet) 

170 addargs = [] 

171 for k in range(n): 

172 p = polylog(s, zet**k*root) 

173 if isinstance(p, polylog): 

174 p = p._eval_expand_func(**hints) 

175 addargs.append(p/(up_zet**k*root)**m) 

176 return add + mul*n**(s - 1)*Add(*addargs) 

177 

178 # TODO use minpoly instead of ad-hoc methods when issue 5888 is fixed 

179 if isinstance(z, exp) and (z.args[0]/(pi*I)).is_Rational or z in [-1, I, -I]: 

180 # TODO reference? 

181 if z == -1: 

182 p, q = S([1, 2]) 

183 elif z == I: 

184 p, q = S([1, 4]) 

185 elif z == -I: 

186 p, q = S([-1, 4]) 

187 else: 

188 arg = z.args[0]/(2*pi*I) 

189 p, q = S([arg.p, arg.q]) 

190 return Add(*[exp(2*pi*I*k*p/q)/q**s*zeta(s, (k + a)/q) 

191 for k in range(q)]) 

192 

193 return lerchphi(z, s, a) 

194 

195 def fdiff(self, argindex=1): 

196 z, s, a = self.args 

197 if argindex == 3: 

198 return -s*lerchphi(z, s + 1, a) 

199 elif argindex == 1: 

200 return (lerchphi(z, s - 1, a) - a*lerchphi(z, s, a))/z 

201 else: 

202 raise ArgumentIndexError 

203 

204 def _eval_rewrite_helper(self, target): 

205 res = self._eval_expand_func() 

206 if res.has(target): 

207 return res 

208 else: 

209 return self 

210 

211 def _eval_rewrite_as_zeta(self, z, s, a, **kwargs): 

212 return self._eval_rewrite_helper(zeta) 

213 

214 def _eval_rewrite_as_polylog(self, z, s, a, **kwargs): 

215 return self._eval_rewrite_helper(polylog) 

216 

217############################################################################### 

218###################### POLYLOGARITHM ########################################## 

219############################################################################### 

220 

221 

222class polylog(Function): 

223 r""" 

224 Polylogarithm function. 

225 

226 Explanation 

227 =========== 

228 

229 For $|z| < 1$ and $s \in \mathbb{C}$, the polylogarithm is 

230 defined by 

231 

232 .. math:: \operatorname{Li}_s(z) = \sum_{n=1}^\infty \frac{z^n}{n^s}, 

233 

234 where the standard branch of the argument is used for $n$. It admits 

235 an analytic continuation which is branched at $z=1$ (notably not on the 

236 sheet of initial definition), $z=0$ and $z=\infty$. 

237 

238 The name polylogarithm comes from the fact that for $s=1$, the 

239 polylogarithm is related to the ordinary logarithm (see examples), and that 

240 

241 .. math:: \operatorname{Li}_{s+1}(z) = 

242 \int_0^z \frac{\operatorname{Li}_s(t)}{t} \mathrm{d}t. 

243 

244 The polylogarithm is a special case of the Lerch transcendent: 

245 

246 .. math:: \operatorname{Li}_{s}(z) = z \Phi(z, s, 1). 

247 

248 Examples 

249 ======== 

250 

251 For $z \in \{0, 1, -1\}$, the polylogarithm is automatically expressed 

252 using other functions: 

253 

254 >>> from sympy import polylog 

255 >>> from sympy.abc import s 

256 >>> polylog(s, 0) 

257 0 

258 >>> polylog(s, 1) 

259 zeta(s) 

260 >>> polylog(s, -1) 

261 -dirichlet_eta(s) 

262 

263 If $s$ is a negative integer, $0$ or $1$, the polylogarithm can be 

264 expressed using elementary functions. This can be done using 

265 ``expand_func()``: 

266 

267 >>> from sympy import expand_func 

268 >>> from sympy.abc import z 

269 >>> expand_func(polylog(1, z)) 

270 -log(1 - z) 

271 >>> expand_func(polylog(0, z)) 

272 z/(1 - z) 

273 

274 The derivative with respect to $z$ can be computed in closed form: 

275 

276 >>> polylog(s, z).diff(z) 

277 polylog(s - 1, z)/z 

278 

279 The polylogarithm can be expressed in terms of the lerch transcendent: 

280 

281 >>> from sympy import lerchphi 

282 >>> polylog(s, z).rewrite(lerchphi) 

283 z*lerchphi(z, s, 1) 

284 

285 See Also 

286 ======== 

287 

288 zeta, lerchphi 

289 

290 """ 

291 

292 @classmethod 

293 def eval(cls, s, z): 

294 if z.is_number: 

295 if z is S.One: 

296 return zeta(s) 

297 elif z is S.NegativeOne: 

298 return -dirichlet_eta(s) 

299 elif z is S.Zero: 

300 return S.Zero 

301 elif s == 2: 

302 dilogtable = _dilogtable() 

303 if z in dilogtable: 

304 return dilogtable[z] 

305 

306 if z.is_zero: 

307 return S.Zero 

308 

309 # Make an effort to determine if z is 1 to avoid replacing into 

310 # expression with singularity 

311 zone = z.equals(S.One) 

312 

313 if zone: 

314 return zeta(s) 

315 elif zone is False: 

316 # For s = 0 or -1 use explicit formulas to evaluate, but 

317 # automatically expanding polylog(1, z) to -log(1-z) seems 

318 # undesirable for summation methods based on hypergeometric 

319 # functions 

320 if s is S.Zero: 

321 return z/(1 - z) 

322 elif s is S.NegativeOne: 

323 return z/(1 - z)**2 

324 if s.is_zero: 

325 return z/(1 - z) 

326 

327 # polylog is branched, but not over the unit disk 

328 if z.has(exp_polar, polar_lift) and (zone or (Abs(z) <= S.One) == True): 

329 return cls(s, unpolarify(z)) 

330 

331 def fdiff(self, argindex=1): 

332 s, z = self.args 

333 if argindex == 2: 

334 return polylog(s - 1, z)/z 

335 raise ArgumentIndexError 

336 

337 def _eval_rewrite_as_lerchphi(self, s, z, **kwargs): 

338 return z*lerchphi(z, s, 1) 

339 

340 def _eval_expand_func(self, **hints): 

341 s, z = self.args 

342 if s == 1: 

343 return -log(1 - z) 

344 if s.is_Integer and s <= 0: 

345 u = Dummy('u') 

346 start = u/(1 - u) 

347 for _ in range(-s): 

348 start = u*start.diff(u) 

349 return expand_mul(start).subs(u, z) 

350 return polylog(s, z) 

351 

352 def _eval_is_zero(self): 

353 z = self.args[1] 

354 if z.is_zero: 

355 return True 

356 

357 def _eval_nseries(self, x, n, logx, cdir=0): 

358 from sympy.series.order import Order 

359 nu, z = self.args 

360 

361 z0 = z.subs(x, 0) 

362 if z0 is S.NaN: 

363 z0 = z.limit(x, 0, dir='-' if re(cdir).is_negative else '+') 

364 

365 if z0.is_zero: 

366 # In case of powers less than 1, number of terms need to be computed 

367 # separately to avoid repeated callings of _eval_nseries with wrong n 

368 try: 

369 _, exp = z.leadterm(x) 

370 except (ValueError, NotImplementedError): 

371 return self 

372 

373 if exp.is_positive: 

374 newn = ceiling(n/exp) 

375 o = Order(x**n, x) 

376 r = z._eval_nseries(x, n, logx, cdir).removeO() 

377 if r is S.Zero: 

378 return o 

379 

380 term = r 

381 s = [term] 

382 for k in range(2, newn): 

383 term *= r 

384 s.append(term/k**nu) 

385 return Add(*s) + o 

386 

387 return super(polylog, self)._eval_nseries(x, n, logx, cdir) 

388 

389############################################################################### 

390###################### HURWITZ GENERALIZED ZETA FUNCTION ###################### 

391############################################################################### 

392 

393 

394class zeta(Function): 

395 r""" 

396 Hurwitz zeta function (or Riemann zeta function). 

397 

398 Explanation 

399 =========== 

400 

401 For $\operatorname{Re}(a) > 0$ and $\operatorname{Re}(s) > 1$, this 

402 function is defined as 

403 

404 .. math:: \zeta(s, a) = \sum_{n=0}^\infty \frac{1}{(n + a)^s}, 

405 

406 where the standard choice of argument for $n + a$ is used. For fixed 

407 $a$ not a nonpositive integer the Hurwitz zeta function admits a 

408 meromorphic continuation to all of $\mathbb{C}$; it is an unbranched 

409 function with a simple pole at $s = 1$. 

410 

411 The Hurwitz zeta function is a special case of the Lerch transcendent: 

412 

413 .. math:: \zeta(s, a) = \Phi(1, s, a). 

414 

415 This formula defines an analytic continuation for all possible values of 

416 $s$ and $a$ (also $\operatorname{Re}(a) < 0$), see the documentation of 

417 :class:`lerchphi` for a description of the branching behavior. 

418 

419 If no value is passed for $a$ a default value of $a = 1$ is assumed, 

420 yielding the Riemann zeta function. 

421 

422 Examples 

423 ======== 

424 

425 For $a = 1$ the Hurwitz zeta function reduces to the famous Riemann 

426 zeta function: 

427 

428 .. math:: \zeta(s, 1) = \zeta(s) = \sum_{n=1}^\infty \frac{1}{n^s}. 

429 

430 >>> from sympy import zeta 

431 >>> from sympy.abc import s 

432 >>> zeta(s, 1) 

433 zeta(s) 

434 >>> zeta(s) 

435 zeta(s) 

436 

437 The Riemann zeta function can also be expressed using the Dirichlet eta 

438 function: 

439 

440 >>> from sympy import dirichlet_eta 

441 >>> zeta(s).rewrite(dirichlet_eta) 

442 dirichlet_eta(s)/(1 - 2**(1 - s)) 

443 

444 The Riemann zeta function at nonnegative even and negative integer 

445 values is related to the Bernoulli numbers and polynomials: 

446 

447 >>> zeta(2) 

448 pi**2/6 

449 >>> zeta(4) 

450 pi**4/90 

451 >>> zeta(0) 

452 -1/2 

453 >>> zeta(-1) 

454 -1/12 

455 >>> zeta(-4) 

456 0 

457 

458 The specific formulae are: 

459 

460 .. math:: \zeta(2n) = -\frac{(2\pi i)^{2n} B_{2n}}{2(2n)!} 

461 .. math:: \zeta(-n,a) = -\frac{B_{n+1}(a)}{n+1} 

462 

463 No closed-form expressions are known at positive odd integers, but 

464 numerical evaluation is possible: 

465 

466 >>> zeta(3).n() 

467 1.20205690315959 

468 

469 The derivative of $\zeta(s, a)$ with respect to $a$ can be computed: 

470 

471 >>> from sympy.abc import a 

472 >>> zeta(s, a).diff(a) 

473 -s*zeta(s + 1, a) 

474 

475 However the derivative with respect to $s$ has no useful closed form 

476 expression: 

477 

478 >>> zeta(s, a).diff(s) 

479 Derivative(zeta(s, a), s) 

480 

481 The Hurwitz zeta function can be expressed in terms of the Lerch 

482 transcendent, :class:`~.lerchphi`: 

483 

484 >>> from sympy import lerchphi 

485 >>> zeta(s, a).rewrite(lerchphi) 

486 lerchphi(1, s, a) 

487 

488 See Also 

489 ======== 

490 

491 dirichlet_eta, lerchphi, polylog 

492 

493 References 

494 ========== 

495 

496 .. [1] https://dlmf.nist.gov/25.11 

497 .. [2] https://en.wikipedia.org/wiki/Hurwitz_zeta_function 

498 

499 """ 

500 

501 @classmethod 

502 def eval(cls, s, a=None): 

503 if a is S.One: 

504 return cls(s) 

505 elif s is S.NaN or a is S.NaN: 

506 return S.NaN 

507 elif s is S.One: 

508 return S.ComplexInfinity 

509 elif s is S.Infinity: 

510 return S.One 

511 elif a is S.Infinity: 

512 return S.Zero 

513 

514 sint = s.is_Integer 

515 if a is None: 

516 a = S.One 

517 if sint and s.is_nonpositive: 

518 return bernoulli(1-s, a) / (s-1) 

519 elif a is S.One: 

520 if sint and s.is_even: 

521 return -(2*pi*I)**s * bernoulli(s) / (2*factorial(s)) 

522 elif sint and a.is_Integer and a.is_positive: 

523 return cls(s) - harmonic(a-1, s) 

524 elif a.is_Integer and a.is_nonpositive and \ 

525 (s.is_integer is False or s.is_nonpositive is False): 

526 return S.NaN 

527 

528 def _eval_rewrite_as_bernoulli(self, s, a=1, **kwargs): 

529 if a == 1 and s.is_integer and s.is_nonnegative and s.is_even: 

530 return -(2*pi*I)**s * bernoulli(s) / (2*factorial(s)) 

531 return bernoulli(1-s, a) / (s-1) 

532 

533 def _eval_rewrite_as_dirichlet_eta(self, s, a=1, **kwargs): 

534 if a != 1: 

535 return self 

536 s = self.args[0] 

537 return dirichlet_eta(s)/(1 - 2**(1 - s)) 

538 

539 def _eval_rewrite_as_lerchphi(self, s, a=1, **kwargs): 

540 return lerchphi(1, s, a) 

541 

542 def _eval_is_finite(self): 

543 arg_is_one = (self.args[0] - 1).is_zero 

544 if arg_is_one is not None: 

545 return not arg_is_one 

546 

547 def _eval_expand_func(self, **hints): 

548 s = self.args[0] 

549 a = self.args[1] if len(self.args) > 1 else S.One 

550 if a.is_integer: 

551 if a.is_positive: 

552 return zeta(s) - harmonic(a-1, s) 

553 if a.is_nonpositive and (s.is_integer is False or 

554 s.is_nonpositive is False): 

555 return S.NaN 

556 return self 

557 

558 def fdiff(self, argindex=1): 

559 if len(self.args) == 2: 

560 s, a = self.args 

561 else: 

562 s, a = self.args + (1,) 

563 if argindex == 2: 

564 return -s*zeta(s + 1, a) 

565 else: 

566 raise ArgumentIndexError 

567 

568 def _eval_as_leading_term(self, x, logx=None, cdir=0): 

569 if len(self.args) == 2: 

570 s, a = self.args 

571 else: 

572 s, a = self.args + (S.One,) 

573 

574 try: 

575 c, e = a.leadterm(x) 

576 except NotImplementedError: 

577 return self 

578 

579 if e.is_negative and not s.is_positive: 

580 raise NotImplementedError 

581 

582 return super(zeta, self)._eval_as_leading_term(x, logx, cdir) 

583 

584 

585class dirichlet_eta(Function): 

586 r""" 

587 Dirichlet eta function. 

588 

589 Explanation 

590 =========== 

591 

592 For $\operatorname{Re}(s) > 0$ and $0 < x \le 1$, this function is defined as 

593 

594 .. math:: \eta(s, a) = \sum_{n=0}^\infty \frac{(-1)^n}{(n+a)^s}. 

595 

596 It admits a unique analytic continuation to all of $\mathbb{C}$ for any 

597 fixed $a$ not a nonpositive integer. It is an entire, unbranched function. 

598 

599 It can be expressed using the Hurwitz zeta function as 

600 

601 .. math:: \eta(s, a) = \zeta(s,a) - 2^{1-s} \zeta\left(s, \frac{a+1}{2}\right) 

602 

603 and using the generalized Genocchi function as 

604 

605 .. math:: \eta(s, a) = \frac{G(1-s, a)}{2(s-1)}. 

606 

607 In both cases the limiting value of $\log2 - \psi(a) + \psi\left(\frac{a+1}{2}\right)$ 

608 is used when $s = 1$. 

609 

610 Examples 

611 ======== 

612 

613 >>> from sympy import dirichlet_eta, zeta 

614 >>> from sympy.abc import s 

615 >>> dirichlet_eta(s).rewrite(zeta) 

616 Piecewise((log(2), Eq(s, 1)), ((1 - 2**(1 - s))*zeta(s), True)) 

617 

618 See Also 

619 ======== 

620 

621 zeta 

622 

623 References 

624 ========== 

625 

626 .. [1] https://en.wikipedia.org/wiki/Dirichlet_eta_function 

627 .. [2] Peter Luschny, "An introduction to the Bernoulli function", 

628 https://arxiv.org/abs/2009.06743 

629 

630 """ 

631 

632 @classmethod 

633 def eval(cls, s, a=None): 

634 if a is S.One: 

635 return cls(s) 

636 if a is None: 

637 if s == 1: 

638 return log(2) 

639 z = zeta(s) 

640 if not z.has(zeta): 

641 return (1 - 2**(1-s)) * z 

642 return 

643 elif s == 1: 

644 from sympy.functions.special.gamma_functions import digamma 

645 return log(2) - digamma(a) + digamma((a+1)/2) 

646 z1 = zeta(s, a) 

647 z2 = zeta(s, (a+1)/2) 

648 if not z1.has(zeta) and not z2.has(zeta): 

649 return z1 - 2**(1-s) * z2 

650 

651 def _eval_rewrite_as_zeta(self, s, a=1, **kwargs): 

652 from sympy.functions.special.gamma_functions import digamma 

653 if a == 1: 

654 return Piecewise((log(2), Eq(s, 1)), ((1 - 2**(1-s)) * zeta(s), True)) 

655 return Piecewise((log(2) - digamma(a) + digamma((a+1)/2), Eq(s, 1)), 

656 (zeta(s, a) - 2**(1-s) * zeta(s, (a+1)/2), True)) 

657 

658 def _eval_rewrite_as_genocchi(self, s, a=S.One, **kwargs): 

659 from sympy.functions.special.gamma_functions import digamma 

660 return Piecewise((log(2) - digamma(a) + digamma((a+1)/2), Eq(s, 1)), 

661 (genocchi(1-s, a) / (2 * (s-1)), True)) 

662 

663 def _eval_evalf(self, prec): 

664 if all(i.is_number for i in self.args): 

665 return self.rewrite(zeta)._eval_evalf(prec) 

666 

667 

668class riemann_xi(Function): 

669 r""" 

670 Riemann Xi function. 

671 

672 Examples 

673 ======== 

674 

675 The Riemann Xi function is closely related to the Riemann zeta function. 

676 The zeros of Riemann Xi function are precisely the non-trivial zeros 

677 of the zeta function. 

678 

679 >>> from sympy import riemann_xi, zeta 

680 >>> from sympy.abc import s 

681 >>> riemann_xi(s).rewrite(zeta) 

682 s*(s - 1)*gamma(s/2)*zeta(s)/(2*pi**(s/2)) 

683 

684 References 

685 ========== 

686 

687 .. [1] https://en.wikipedia.org/wiki/Riemann_Xi_function 

688 

689 """ 

690 

691 

692 @classmethod 

693 def eval(cls, s): 

694 from sympy.functions.special.gamma_functions import gamma 

695 z = zeta(s) 

696 if s in (S.Zero, S.One): 

697 return S.Half 

698 

699 if not isinstance(z, zeta): 

700 return s*(s - 1)*gamma(s/2)*z/(2*pi**(s/2)) 

701 

702 def _eval_rewrite_as_zeta(self, s, **kwargs): 

703 from sympy.functions.special.gamma_functions import gamma 

704 return s*(s - 1)*gamma(s/2)*zeta(s)/(2*pi**(s/2)) 

705 

706 

707class stieltjes(Function): 

708 r""" 

709 Represents Stieltjes constants, $\gamma_{k}$ that occur in 

710 Laurent Series expansion of the Riemann zeta function. 

711 

712 Examples 

713 ======== 

714 

715 >>> from sympy import stieltjes 

716 >>> from sympy.abc import n, m 

717 >>> stieltjes(n) 

718 stieltjes(n) 

719 

720 The zero'th stieltjes constant: 

721 

722 >>> stieltjes(0) 

723 EulerGamma 

724 >>> stieltjes(0, 1) 

725 EulerGamma 

726 

727 For generalized stieltjes constants: 

728 

729 >>> stieltjes(n, m) 

730 stieltjes(n, m) 

731 

732 Constants are only defined for integers >= 0: 

733 

734 >>> stieltjes(-1) 

735 zoo 

736 

737 References 

738 ========== 

739 

740 .. [1] https://en.wikipedia.org/wiki/Stieltjes_constants 

741 

742 """ 

743 

744 @classmethod 

745 def eval(cls, n, a=None): 

746 if a is not None: 

747 a = sympify(a) 

748 if a is S.NaN: 

749 return S.NaN 

750 if a.is_Integer and a.is_nonpositive: 

751 return S.ComplexInfinity 

752 

753 if n.is_Number: 

754 if n is S.NaN: 

755 return S.NaN 

756 elif n < 0: 

757 return S.ComplexInfinity 

758 elif not n.is_Integer: 

759 return S.ComplexInfinity 

760 elif n is S.Zero and a in [None, 1]: 

761 return S.EulerGamma 

762 

763 if n.is_extended_negative: 

764 return S.ComplexInfinity 

765 

766 if n.is_zero and a in [None, 1]: 

767 return S.EulerGamma 

768 

769 if n.is_integer == False: 

770 return S.ComplexInfinity 

771 

772 

773@cacheit 

774def _dilogtable(): 

775 return { 

776 S.Half: pi**2/12 - log(2)**2/2, 

777 Integer(2) : pi**2/4 - I*pi*log(2), 

778 -(sqrt(5) - 1)/2 : -pi**2/15 + log((sqrt(5)-1)/2)**2/2, 

779 -(sqrt(5) + 1)/2 : -pi**2/10 - log((sqrt(5)+1)/2)**2, 

780 (3 - sqrt(5))/2 : pi**2/15 - log((sqrt(5)-1)/2)**2, 

781 (sqrt(5) - 1)/2 : pi**2/10 - log((sqrt(5)-1)/2)**2, 

782 I : I*S.Catalan - pi**2/48, 

783 -I : -I*S.Catalan - pi**2/48, 

784 1 - I : pi**2/16 - I*S.Catalan - pi*I/4*log(2), 

785 1 + I : pi**2/16 + I*S.Catalan + pi*I/4*log(2), 

786 (1 - I)/2 : -log(2)**2/8 + pi*I*log(2)/8 + 5*pi**2/96 - I*S.Catalan 

787 }