1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancments. ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;; (c) Copyright 1980 Massachusetts Institute of Technology ;;;
9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13 (macsyma-module specfn
)
15 ;;*********************************************************************
16 ;;**************** ******************
17 ;;**************** Macsyma Special Function Routines ******************
18 ;;**************** ******************
19 ;;*********************************************************************
21 (load-macsyma-macros rzmac
)
22 (load-macsyma-macros mhayat
)
24 (defmacro mnumericalp
(arg)
25 `(or (floatp ,arg
) (and (or $numer $float
) (integerp ,arg
))))
27 ;; subtitle polylogarithm routines
29 (declare-top (special $zerobern tlist %e-val
))
31 (defun lisimp (expr vestigial z
)
32 (declare (ignore vestigial
))
33 (let ((s (simpcheck (car (subfunsubs expr
)) z
))
36 (subargcheck expr
1 1 '$li
)
37 (setq a
(simpcheck (car (subfunargs expr
)) z
))
38 (or (cond ((zerop1 a
) a
)
39 ((not (integerp s
)) ())
43 (intl:gettext
"li: li[~:M](~:M) is undefined.") s a
)
44 (neg (take '(%log
) (sub 1 a
)))))
45 ((= s
0) (div a
(sub 1 a
)))
46 ((< s
0) (lisimp-negative-integer s a
))
47 ((and (integerp a
) (> s
1)
48 (cond ((= a
1) (take '(%zeta
) s
))
50 ;; li[s](-1) = (2^(1-s)-1)*zeta(s)
51 (mul (add -
1 (inv (expt 2 (- s
1))))
52 (take '(%zeta
) s
))))))
55 ((or (complex-float-numerical-eval-p a
)
56 (complex-bigfloat-numerical-eval-p a
))
57 (cond ((bigfloat:= 1 (bigfloat:to a
))
58 ;; li[s](1) -> zeta(s)
59 (let ((result ($zeta s
)))
63 ((bigfloat:= -
1 (bigfloat:to a
))
64 ;; li[s](-1) = (2^(1-s)-1)*zeta(s)
65 (let ((result (mul (add -
1 (inv (expt 2 (- s
1))))
71 (to (bigfloat::li-s-simp s
(bigfloat:to a
)))))))
72 (eqtest (subfunmakes '$li
(ncons s
) (ncons a
))
75 ;; Expand the Polylogarithm li[s](z) for a negative integer parameter s.
76 (defun lisimp-negative-integer (s z
)
78 (mul (inv (power (sub 1 z
) (+ n
1)))
79 (let ((index1 (gensumindex))
83 (let ((index2 (gensumindex)))
85 (mul (power -
1 (add index2
1))
86 (take '(%binomial
) (+ n
1) (sub index2
1))
87 (power (add 1 (sub index1 index2
)) n
))
92 (cond ((mnumericalp arg
)
93 ;; When arg is a float or rational, use the original li2numer
94 ;; using Spences function.
95 (li2numer (float arg
)))
96 ((complex-float-numerical-eval-p arg
)
97 ;; For complex args that should should result in float
98 ;; answers, use bigfloat::li2numer.
99 (to (bigfloat::li2numer
(bigfloat:to
($rectform
($float arg
))))))
100 ((or (bigfloat-numerical-eval-p arg
)
101 (complex-bigfloat-numerical-eval-p arg
))
102 (to (bigfloat::li2numer
(bigfloat:to
($rectform
($bfloat arg
))))))
103 ((alike1 arg
'((rat) 1 2))
104 (add (div (take '(%zeta
) 2) 2)
105 (mul '((rat simp
) -
1 2)
106 (power (take '(%log
) 2) 2))))))
109 (cond ((or (float-numerical-eval-p arg
)
110 (complex-float-numerical-eval-p arg
))
111 (to (bigfloat::li3numer
(bigfloat:to
($rectform
($float arg
))))))
112 ((or (bigfloat-numerical-eval-p arg
)
113 (complex-bigfloat-numerical-eval-p arg
))
114 (to (bigfloat::li3numer
(bigfloat:to
($rectform
($bfloat arg
))))))
115 ((alike1 arg
'((rat) 1 2))
116 (add (mul '((rat simp
) 7 8) (take '(%zeta
) 3))
117 (mul (div (take '(%zeta
) 2) -
2) (take '(%log
) 2))
118 (mul '((rat simp
) 1 6) (power (take '(%log
) 2) 3))))))
120 ;; exponent in first term of taylor expansion of $li is one
122 (declare (ignore subl
))
125 ;; taylor expansion of $li is its definition:
126 ;; x + x^2/2^s + x^3/3^s + ...
127 (defun exp$li-fun
(pw subl l
) ; l is a irrelevant here
128 (setq subl
(car subl
)) ; subl is subscript of li
129 (prog ((e 0) ; e is exponent of current term
130 npw
) ; npw is exponent of last term needed
132 (setq npw
(/ (float (car pw
)) (float (cdr pw
))))
134 l
(cons '((0 .
1) 0 .
1)
137 (if (> e npw
) (return l
)
140 .
,(prep1 (m^ e
(m- subl
)))))))
144 ;; computes first pw terms of asymptotic expansion of $li[s](z)
146 ;; pw should be < (1/2)*s or gamma term is undefined
148 ;; Wood, D.C. (June 1992). The Computation of Polylogarithms. Technical Report 15-92
149 ;; University of Kent Computing Laboratory.
150 ;; http://www.cs.kent.ac.uk/pubs/1992/110
152 (defun li-asymptotic-expansion (pw s z
)
153 (m+l
(loop for k from
0 to pw collect
155 (m- 1 (m^
2 (m- 1 (m* 2 k
))))
156 (m^
(m* 2 '$%pi
) (m* 2 k
))
157 (m// ($bern
(m* 2 k
))
158 `((mfactorial) ,(m* 2 k
)))
159 (m// (m^
`((%log
) ,(m- z
)) (m- 2 (m* 2 k
)))
160 ($gamma
(m+ s
1 (m* -
2 k
))))))))
162 ;; Numerical evaluation for Chebyschev expansions of the first kind
164 (defun cheby (x chebarr
)
165 (let ((bn+2 0.0) (bn+1 0.0))
166 (do ((i (floor (aref chebarr
0)) (1- i
)))
167 ((< i
1) (- bn
+1 (* bn
+2 x
)))
169 (prog1 bn
+1 (setq bn
+1 (+ (aref chebarr i
)
170 (- (* 2.0 x bn
+1) bn
+2))))))))
172 (defun cheby-prime (x chebarr
)
174 (* (aref chebarr
1) 0.5)))
176 ;; These should really be calculated with minimax rational approximations.
177 ;; Someone has done LI[2] already, and this should be updated; I haven't
178 ;; seen any results for LI[3] yet.
181 ;; Spence's function can be used to compute li[2] for 0 <= x <= 1.
182 ;; To compute the rest, we need the following identities:
184 ;; li[2](x) = -li[2](1/x)-log(-x)^2/2-%pi^2/6
185 ;; li[2](x) = li[2](1/(1-x)) + log(1-x)*log((1-x)/x^2)/2 - %pi^2/6
187 ;; The first tells us how to compute li[2] for x > 1. The result is complex.
188 ;; For x < 0, the second can be used, and the result is real.
190 ;; (See http://functions.wolfram.com/ZetaFunctionsandPolylogarithms/PolyLog2/17/01/01/)
194 (* 0.5 (log (- 1 x
)) (log (/ (- 1 x
) (* x x
))))
195 (- (/ (cl:expt
(float pi
) 2) 6))))
199 (/ (cl:expt
(float pi
) 2) 6))
201 ;; li[2](x) = -li[2](1/x)-log(-x)^2/2-%pi^2/6
203 (/ (cl:expt
(cl:log
(- x
)) 2) 2)
204 (/ (cl:expt
(float pi
) 2) 6)))))))
205 (complexify (li2 y
))))
208 (defvar *li2
* (make-array 15.
:initial-contents
'(14.0
1.93506430 .166073033 2.48793229e-2
209 4.68636196e-3 1.0016275e-3 2.32002196e-4
210 5.68178227e-5 1.44963006e-5 3.81632946e-6
211 1.02990426e-6 2.83575385e-7 7.9387055e-8
212 2.2536705e-8 6.474338e-9)
213 :element-type
'flonum
))
216 (defvar *li3
* (make-array 15.
:initial-contents
'(14.0
1.95841721 8.51881315e-2 8.55985222e-3
217 1.21177214e-3 2.07227685e-4 3.99695869e-5
218 8.38064066e-6 1.86848945e-6 4.36660867e-7
219 1.05917334e-7 2.6478920e-8 6.787e-9
220 1.776536e-9 4.73417e-10)
221 :element-type
'flonum
))
223 (defvar *s12
* (make-array 18.
:initial-contents
'(17.0
1.90361778 .431311318 .100022507
224 2.44241560e-2 6.22512464e-3 1.64078831e-3
225 4.44079203e-4 1.22774942e-4 3.45398128e-5
226 9.85869565e-6 2.84856995e-6 8.31708473e-7
227 2.45039499e-7 7.2764962e-8 2.1758023e-8 6.546158e-9
229 :element-type
'flonum
))
232 (* x
(cheby-prime (/ (1+ (* x
4)) 3) *li2
*)))
235 (* x
(cheby-prime (/ (1+ (* 4 x
)) 3) *li3
*)))
239 (cheby-prime (/ (1+ (* 4 x
)) 3) *s12
*)))
241 ;; subtitle polygamma routines
243 ;; gross efficiency hack, exp is a function of *k*, *k* should be mbind'ed
245 (defun msum (exp lo hi
)
249 (do ((*k
* lo
(1+ *k
*)))
251 (declare (special *k
*))
252 (setq sum
(add2 sum
(meval exp
)))))))
255 (defun pole-err (exp)
256 (declare (special errorsw
))
257 (cond (errorsw (throw 'errorsw t
))
258 (t (merror (intl:gettext
"Pole encountered in: ~M") exp
))))
261 (declare-top (special $maxpsiposint $maxpsinegint $maxpsifracnum $maxpsifracdenom
))
263 (defprop $psi psisimp specsimp
)
265 ;; Integral of psi function psi[n](x)
271 ((and ($integerp n
) (>= n
0))
273 ((= n
0) `((%log_gamma
) ,x
))
274 (t `((mqapply) (($psi array
) ((mplus) -
1 ,n
)) ,x
))))
278 (mapcar #'(lambda (var val
)
279 (and (not (boundp var
)) (setf (symbol-value var
) val
)))
280 '($maxpsiposint $maxpsinegint $maxpsifracnum $maxpsifracdenom
)
283 (defun psisimp (expr a z
)
284 (let ((s (simpcheck (car (subfunsubs expr
)) z
)))
285 (subargcheck expr
1 1 '$psi
)
286 (setq a
(simpcheck (car (subfunargs expr
)) z
))
287 (and (setq z
(integer-representation-p a
))
290 (eqtest (psisimp1 s a
) expr
)))
292 ;; This gets pretty hairy now.
294 (defun psisimp1 (s a
)
296 (declare (special *k
*))
298 (and (integerp s
) (>= s
0) (mnumericalp a
)
299 (let (($float2bf t
)) ($float
(mfuncall '$bfpsi s a
18))))
300 (and (integerp s
) (>= s
0) ($bfloatp a
)
301 (mfuncall '$bfpsi s a $fpprec
))
302 (and (not $numer
) (not $float
) (integerp s
) (> s -
1)
305 (and (not (> a $maxpsiposint
)) ; integer values
306 (m*t
(expt -
1 s
) (factorial s
)
307 (m- (msum (inv (m^t
'*k
* (1+ s
))) 1 (1- a
))
308 (cond ((zerop s
) '$%gamma
)
309 (($zeta
(1+ s
))))))))
310 ((or (not (ratnump a
)) (ratgreaterp a $maxpsiposint
)) ())
314 (let* ((int ($entier a
)) ; reduction to fractional values
318 (if (> int $maxpsiposint
)
319 (subfunmakes '$psi
(ncons s
) (ncons int
))
320 (m*t
(expt -
1 s
) (factorial s
)
321 (msum (m^t
(m+t
(m-t a int
) '*k
*)
325 (let ((p (cadr a
)) (q (caddr a
)))
327 ((or (> p $maxpsifracnum
)
328 (> q $maxpsifracdenom
) (bignump p
) (bignump q
)) ())
331 (m+ (m* -
2 '((%log
) 2)) (m- '$%gamma
)))
333 (m+ (m* '((rat simp
) -
1 2)
334 (m^t
3 '((rat simp
) -
1 2)) '$%pi
)
335 (m* '((rat simp
) -
3 2) '((%log
) 3))
338 (m+ (m* '((rat simp
) -
1 2) '$%pi
)
339 (m* -
3 '((%log
) 2)) (m- '$%gamma
)))
341 (m- (m+ (m* '((rat simp
) 3 2) '((%log
) 3))
343 (m* '((rat simp
) 1 2) '$%pi
344 (m^t
3 '((rat simp
) 1 2)))
346 ((and (= p
2) (= q
3))
347 (m+ (m* '((rat simp
) 1 2)
348 (m^t
3 '((rat simp
) -
1 2)) '$%pi
)
349 (m* '((rat simp
) -
3 2) '((%log
) 3))
351 ((and (= p
3) (= q
4))
352 (m+ (m* '((rat simp
) 1 2) '$%pi
)
353 (m* -
3 '((%log
) 2)) (m- '$%gamma
)))
354 ((and (= p
5) (= q
6))
355 (m- (m* '((rat simp
) 1 2) '$%pi
356 (m^t
3 '((rat simp
) 1 2)))
357 (m+ (m* '((rat simp
) 3 2) '((%log
) 3))
361 ((let ((f (m* `((%cos
) ,(m* 2 a
'$%pi
'*k
*))
362 `((%log
) ,(m-t 2 (m* 2 `((%cos
)
363 ,(m//t
(m* 2 '$%pi
'*k
*)
365 (m+t
(msum f
1 (1- (truncate q
2)))
366 (let ((*k
* (truncate q
2)))
367 (declare (special *k
*))
370 ('((rat simp
) 1 2)))))
371 (m-t (m+ (m* '$%pi
'((rat simp
) 1 2)
372 `((%cot
) ((mtimes simp
) ,a $%pi
)))
375 ((alike1 a
'((rat) 1 2))
376 (m*t
(expt -
1 (1+ s
)) (factorial s
)
377 (1- (expt 2 (1+ s
))) (simplify ($zeta
(1+ s
)))))
378 ((and (ratgreaterp a
'((rat) 1 2))
382 (m+t
(psisimp1 s
(m- 1 a
))
384 ($diff
`((%cot
) ,(m* '$%pi
'$z
)) '$z s
)))
386 (declare (special $z
))
388 ((ratgreaterp a $maxpsinegint
) ;;; Reflection Formula
391 (m+t
(m+t
(psisimp1 s
(m- a
))
393 ($diff
`((%cot
) ,(m* '$%pi
'$z
)) '$z s
)))
395 (declare (special $z
))
397 (m*t
(factorial s
) (m^t
(m-t a
) (1- (- s
)))))))))
398 (subfunmakes '$psi
(ncons s
) (ncons a
)))))
401 ;; subtitle polygamma tayloring routines
403 ;; These routines are specially coded to be as fast as possible given the
404 ;; current $TAYLOR; too bad they have to be so ugly.
406 (declare-top (special var subl
*last
* sign last-exp
))
408 (defun expgam-fun (pw temp
)
409 (setq temp
(get-datum (get-key-var (car var
))))
412 (let-pw temp
(e1+ pw
)
413 (psexpt-fn (getexp-fun '(($psi
) -
1) var
(e1+ pw
))))
414 (make-ps var
(ncons pw
) '(((-1 .
1) 1 .
1))))))
416 (defun expplygam-funs (pw subl l
) ; l is a irrelevant here
417 (setq subl
(car subl
))
418 (if (or (not (integerp subl
)) (< subl -
1))
419 (tay-err "Unable to expand at a subscript in")
420 (prog ((e 0) (sign 0) npw
)
421 (declare (fixnum e
) (fixnum sign
))
422 (setq npw
(/ (float (car pw
)) (float (cdr pw
))))
425 `(((1 .
1) .
,(prep1 '((mtimes) -
1 $%gamma
)))))
427 (cons '((-1 .
1) -
1 .
1)
430 .
,(prep1 '((mtimes) -
1 $%gamma
)))))))
431 (t (setq *last
* (factorial subl
))
432 `(((,(- (1+ subl
)) .
1)
433 ,(* (expt -
1 (1+ subl
))
434 (factorial subl
)) .
1))))
435 e
(if (< subl
1) (- subl
) -
1)
436 sign
(if (< subl
1) -
1 (expt -
1 subl
)))
437 a
(setq e
(1+ e
) sign
(- sign
))
438 (if (> e npw
) (return l
)
441 .
,(rctimes (rcplygam e
)
442 (prep1 ($zeta
(+ (1+ subl
) e
))))))))
446 (declare (fixnum k
) )
447 (cond ((= subl -
1) (cons sign k
))
448 ((= subl
0) (cons sign
1))
450 (cons (* sign
*last
*) 1)
452 (quot (* *last
* (+ subl
(1+ k
)))
455 (defun plygam-ord (subl)
456 (if (equal (car subl
) -
1) (ncons (rcone))
457 `((,(m- (m1+ (car subl
))) .
1))))
459 (defun plygam-pole (a c func
)
461 (let ((ps (get-lexp (m- a
(rcdisrep c
)) () t
)))
462 (rplacd (cddr ps
) (cons `((0 .
1) .
,c
) (cdddr ps
)))
463 (if (atom func
) (gam-const a ps func
)
464 (plygam-const a ps func
)))
466 (if (atom func
) `((%gamma
) ,(rcdisrep c
))
467 `((mqapply) ,func
,(rcdisrep c
)))
470 (defun gam-const (a arg func
)
471 (let ((const (ps-lc* arg
)) (arg-c))
472 (cond ((not (rcintegerp const
))
473 (taylor2 (diff-expand `((%gamma
) ,a
) tlist
)))
475 (setq const
(car const
))
476 (if (pscoefp arg
) (setq arg-c
(get-lexp (m+t a
(- const
)) (rcone) (signp le const
))))
477 (if (and arg-c
(not (psp arg-c
)))
478 (taylor2 (simplify `((%gamma
) ,const
)))
479 (let ((datum (get-datum (get-key-var (gvar (or arg-c arg
)))))
480 (ord (if arg-c
(le (terms arg-c
)) (le (n-term (terms arg
))))))
481 (setq func
(current-trunc datum
))
483 (pstimes (let-pw datum
(e- func ord
) (expand (m+t a
(- const
)) '%gamma
))
484 (let-pw datum
(e+ func ord
)
485 (tsprsum (m+t a
(m-t '%%taylor-index%%
))
486 `(%%taylor-index%%
1 ,const
) '%product
)))
487 (pstimes (expand (m+t a
(- const
)) '%gamma
)
488 (let-pw datum
(e+ func ord
)
489 (psexpt (tsprsum (m+t a
'%%taylor-index%%
)
490 `(%%taylor-index%%
0 ,(- (1+ const
))) '%product
)
493 (defun plygam-const (a arg func
)
494 (let ((const (ps-lc* arg
)) (sub (cadr func
)))
496 ((or (not (integerp sub
)) (< sub -
1))
497 (tay-err "Unable to expand at a subscript in"))
498 ((not (rcintegerp const
))
499 (taylor2 (diff-expand `((mqapply) ,func
,a
) tlist
)))
500 (t (setq const
(car const
))
502 (expand (m+t a
(- const
)) func
)
505 (cons (* (expt -
1 sub
) (factorial sub
)) 1)
506 (tsprsum `((mexpt) ,(m+t a
(m-t '%%taylor-index%%
)) ,(- (1+ sub
)))
507 `(%%taylor-index%%
1 ,const
) '%sum
))
509 (cons (* (expt -
1 (1+ sub
)) (factorial sub
)) 1)
510 (tsprsum `((mexpt) ,(m+t a
'%%taylor-index%%
) ,(- (1+ sub
)))
511 `(%%taylor-index%%
0 ,(- (1+ const
))) '%sum
))))))))
513 (declare-top (unspecial var subl
*last
* sign last-exp
))
515 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
516 ;;; Lambert W function
517 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
521 ;; Corless, R. M., Gonnet, D. E. G., Jeffrey, D. J., Knuth, D. E. (1996).
522 ;; "On the Lambert W function". Advances in Computational Mathematics 5:
525 ;; http://www.apmaths.uwo.ca/~djeffrey/Offprints/W-adv-cm.pdf.
526 ;; or http://www.apmaths.uwo.ca/~rcorless/frames/PAPERS/LambertW/
528 ;; D. J. Jeffrey, D. E. G. Hare, R. M. Corless
529 ;; Unwinding the branches of the Lambert W function
530 ;; The Mathematical Scientist, 21, pp 1-7, (1996)
531 ;; http://www.apmaths.uwo.ca/~djeffrey/Offprints/wbranch.pdf
533 ;; Winitzki, S. Uniform Approximations for Transcendental Functions.
534 ;; In Part 1 of Computational Science and its Applications - ICCSA 2003,
535 ;; Lecture Notes in Computer Science, Vol. 2667, Springer-Verlag,
536 ;; Berlin, 2003, 780-789. DOI 10.1007/3-540-44839-X_82
537 ;; http://homepages.physik.uni-muenchen.de/~Winitzki/papers/
540 ;; Having Fun with Lambert W(x) Function
541 ;; arXiv:1003.1628v1, March 2010, http://arxiv.org/abs/1003.1628
543 ;; See also http://en.wikipedia.org/wiki/Lambert's_W_function
545 (defmfun $lambert_w
(z)
546 (simplify (list '(%lambert_w
) (resimplify z
))))
548 ;;; Set properties to give full support to the parser and display
549 (defprop $lambert_w %lambert_w alias
)
550 (defprop $lambert_w %lambert_w verb
)
551 (defprop %lambert_w $lambert_w reversealias
)
552 (defprop %lambert_w $lambert_w noun
)
554 ;;; lambert_w is a simplifying function
555 (defprop %lambert_w simp-lambertw operators
)
557 ;;; Derivative of lambert_w
561 ((mexpt) $%e
((mtimes ) -
1 ((%lambert_w
) x
)))
562 ((mexpt) ((mplus) 1 ((%lambert_w
) x
)) -
1)))
565 ;;; Integral of lambert_w
566 ;;; integrate(W(x),x) := x*(W(x)^2-W(x)+1)/W(x)
572 ((mexpt) ((%lambert_w
) x
) 2)
573 ((mtimes) -
1 ((%lambert_w
) x
))
575 ((mexpt) ((%lambert_w
) x
) -
1)))
578 (defun simp-lambertw (x yy z
)
579 (declare (ignore yy
))
581 (setq x
(simpcheck (cadr x
) z
))
582 (cond ((equal x
0) 0)
584 ((zerop1 x
) ($bfloat
0)) ;bfloat case
588 ((alike1 x
'((mtimes simp
) ((rat simp
) -
1 2) ((%log simp
) 2)))
589 ;; W(-log(2)/2) = -log(2)
590 '((mtimes simp
) -
1 ((%log simp
) 2)))
591 ((alike1 x
'((mtimes simp
) -
1 ((mexpt simp
) $%e -
1)))
594 ((alike1 x
'((mtimes) ((rat) -
1 2) $%pi
))
595 ;; W(-%pi/2) = %i*%pi/2
596 '((mtimes simp
) ((rat simp
) 1 2) $%i $%pi
))
597 ;; numerical evaluation
598 ((complex-float-numerical-eval-p x
)
599 ;; x may be an integer. eg "lambert_w(1),numer;"
601 (to (bigfloat::lambert-w-k
0 (bigfloat:to
($float x
))))
602 (to (bigfloat::lambert-w-k
0 (bigfloat:to x
)))))
603 ((complex-bigfloat-numerical-eval-p x
)
604 (to (bigfloat::lambert-w-k
0 (bigfloat:to x
))))
605 (t (list '(%lambert_w simp
) x
))))
607 ;; An approximation of the k-branch of generalized Lambert W function
609 ;; z real or complex lisp float
610 ;; Used as initial guess for Halley's iteration.
611 ;; When W(z) is real, ensure that guess is real.
612 (defun init-lambert-w-k (k z
)
613 (let ( ; parameters for k = +/- 1 near branch pont z=-1/%e
615 (branch-point (/ -
1 %e-val
))) ; branch pont z=-1/%e
617 ; For principal branch k=0, use expression by Winitzki
618 ((= k
0) (init-lambert-w-0 z
))
619 ; For k=1 branch, near branch point z=-1/%e with im(z) < 0
622 (< (abs (- branch-point z
)) branch-eps
))
623 (bigfloat::lambert-branch-approx z
))
624 ; For k=-1 branch, z real with -1/%e < z < 0
625 ; W(z) is real in this range
626 ((and (= k -
1) (realp z
) (> z branch-point
) (< z
0))
627 (init-lambert-w-minus1 z
))
628 ; For k=-1 branch, near branch point z=-1/%e with im(z) >= 0
631 (< (abs (- branch-point z
)) branch-eps
))
632 (bigfloat::lambert-branch-approx z
))
633 ; Default to asymptotic expansion Corless et al (4.20)
634 ; W_k(z) = log(z) + 2.pi.i.k - log(log(z)+2.pi.i.k)
635 (t (let ((two-pi-i-k (complex 0.0e0
(* 2 pi k
))))
638 (* -
1 (log (+ (log z
) two-pi-i-k
)))))))))
640 ;; Complex value of the principal branch of Lambert's W function in
641 ;; the entire complex plane with relative error less than 1%, given
642 ;; standard branch cuts for sqrt(z) and log(z).
644 (defun init-lambert-w-0 (z)
645 (let ((a 2.344e0
) (b 0.8842e0
) (c 0.9294e0
) (d 0.5106e0
) (e -
1.213e0
)
646 (y (sqrt (+ (* 2 %e-val z
) 2)) ) ) ; y=sqrt(2*%e*z+2)
647 ; w = (2*log(1+B*y)-log(1+C*log(1+D*y))+E)/(1+1/(2*log(1+B*y)+2*A)
649 (+ (* 2 (log (+ 1 (* b y
))))
650 (* -
1 (log (+ 1 (* c
(log (+ 1 (* d y
)))))))
653 (/ 1 (+ (* 2 (log (+ 1 (* b y
)))) (* 2 a
)))))))
655 ;; Approximate k=-1 branch of Lambert's W function over -1/e < z < 0.
656 ;; W(z) is real, so we ensure the starting guess for Halley iteration
659 (defun init-lambert-w-minus1 (z)
662 (merror "z not real in init-lambert-w-minus1"))
663 ((or (< z
(/ -
1 %e-val
)) (plusp z
))
664 (merror "z outside range of approximation in init-lambert-w-minus1"))
665 ;; In the region where W(z) is real
666 ;; -1/e < z < C, use power series about branch point -1/e ~ -0.36787
667 ;; C = -0.3 seems a reasonable crossover point
669 (bigfloat::lambert-branch-approx z
))
670 ;; otherwise C <= z < 0, use iteration W(z) ~ ln(-z)-ln(-W(z))
671 ;; nine iterations are sufficient over -0.3 <= z < 0
672 (t (let* ((ln-z (log (- z
))) (maxiter 9) (w ln-z
))
673 (dotimes (k maxiter w
)
674 (setq w
(- ln-z
(log (- w
)))))))))
676 (in-package #-gcl
#:bigfloat
#+gcl
"BIGFLOAT")
678 ;; Approximate Lambert W(k,z) for k=1 and k=-1 near branch point z=-1/%e
679 ;; using power series in y=-sqrt(2*%e*z+2)
680 ;; for im(z) < 0, approximates k=1 branch
681 ;; for im(z) >= 0, approximates k=-1 branch
683 ;; Corless et al (1996) (4.22)
686 ;; z is a real or complex bigfloat:
687 (defun lambert-branch-approx (z)
688 (let ((y (- (sqrt (+ (* 2 (%e z
) z
) 2)))) ; y=-sqrt(2*%e*z+2)
689 (b0 -
1) (b1 1) (b2 -
1/3) (b3 11/72))
690 (+ b0
(* y
(+ b1
(* y
(+ b2
(* b3 y
))))))))
692 ;; Algorithm based in part on Corless et al (1996).
694 ;; It is Halley's iteration applied to w*exp(w).
697 ;; w[j] exp(w[j]) - z
698 ;; w[j+1] = w[j] - -------------------------------------------------
699 ;; (w[j]+2)(w[j] exp(w[j]) -z)
700 ;; exp(w[j])(w[j]+1) - ---------------------------
703 ;; The algorithm has cubic convergence. Once convergence begins, the
704 ;; number of digits correct at step k is roughly 3 times the number
705 ;; which were correct at step k-1.
707 ;; Convergence can stall using convergence test abs(w[j+1]-w[j]) < prec,
708 ;; as happens for generalized_lambert_w(-1,z) near branch point z = -1/%e
709 ;; Therefore also stop iterating if abs(w[j]*exp(w[j]) - z) << abs(z)
710 (defun lambert-w-k (k z
&key
(maxiter 50))
711 (let ((w (init-lambert-w-k k z
)) we w1e delta
(prec (* 4 (epsilon z
))))
712 (dotimes (i maxiter
(maxima::merror
"lambert-w-k did not converge"))
713 (setq we
(* w
(exp w
)))
714 (when (<= (abs (- z we
)) (* 4 (epsilon z
) (abs z
))) (return))
715 (setq w1e
(* (1+ w
) (exp w
)))
716 (setq delta
(/ (- we z
)
717 (- w1e
(/ (* (+ w
2) (- we z
)) (+ 2 (* 2 w
))))))
719 (when (<= (abs (/ delta w
)) prec
) (return)))
720 ;; Check iteration converged to correct branch
721 (check-lambert-w-k k w z
)
724 (defmethod init-lambert-w-k ((k integer
) (z number
))
725 (maxima::init-lambert-w-k k z
))
727 (defmethod init-lambert-w-k ((k integer
) (z bigfloat
))
728 (bfloat-init-lambert-w-k k z
))
730 (defmethod init-lambert-w-k ((k integer
) (z complex-bigfloat
))
731 (bfloat-init-lambert-w-k k z
))
733 (defun bfloat-init-lambert-w-k (k z
)
734 "Approximate generalized_lambert_w(k,z) for bigfloat: z as initial guess"
735 (let ((branch-point -
0.36787944117144)) ; branch point -1/%e
737 ;; if k=-1, z very close to -1/%e and imag(z)>=0, use power series
739 (or (zerop (imagpart z
))
740 (plusp (imagpart z
)))
741 (< (abs (- z branch-point
)) 1e-10))
742 (lambert-branch-approx z
))
743 ;; if k=1, z very close to -1/%e and imag(z)<0, use power series
745 (minusp (imagpart z
))
746 (< (abs (- z branch-point
)) 1e-10))
747 (lambert-branch-approx z
))
748 ;; Initialize using float value if z is representable as a float
751 (bigfloat (lambert-w-k k
(cl:complex
(float (realpart z
) 1.0)
752 (float (imagpart z
) 1.0))))
753 (bigfloat (lambert-w-k k
(float z
1.0)))))
754 ;; For large z, use Corless et al (4.20)
755 ;; W_k(z) ~ log(z) + 2.pi.i.k - log(log(z)+2.pi.i.k)
757 (let ((log-z (log z
)))
759 (- log-z
(log log-z
))
760 (let* ((i (make-instance 'complex-bigfloat
:imag
(intofp 1)))
761 (two-pi-i-k (* 2 (%pi z
) i k
)))
762 (- (+ log-z two-pi-i-k
)
763 (log (+ log-z two-pi-i-k
))))))))))
765 ;; Check Lambert W iteration converged to the correct branch
766 ;; W_k(z) + ln W_k(z) = ln z, for k = -1 and z in [-1/e,0)
767 ;; = ln z + 2 pi i k, otherwise
768 ;; See Jeffrey, Hare, Corless (1996), eq (12)
770 ;; z, w bigfloat: numbers
771 (defun check-lambert-w-k (k w z
)
772 (let ((tolerance #-gcl
1.0e-6
773 #+gcl
(cl:float
1/1000000)))
776 ;; k=-1 branch with z and w real.
777 ((and (= k -
1) (realp z
) (minusp z
) (>= z
(/ -
1 (%e z
))))
780 (< (abs (+ w
(log w
) (- (log z
)))) tolerance
))
784 ; i k = (W_k(z) + ln W_k(z) - ln(z)) / 2 pi
786 (setq ik
(/ (+ w
(log w
) (- (log z
))) (* 2 (%pi z
))))
787 (if (and (< (realpart ik
) tolerance
)
788 (< (abs (- k
(imagpart ik
))) tolerance
))
792 (maxima::merror
"Lambert W iteration converged to wrong branch"))))
796 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
797 ;;; Generalized Lambert W function
798 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
800 (defmfun $generalized_lambert_w
(k z
)
801 (simplify (list '(%generalized_lambert_w
) (resimplify k
) (resimplify z
))))
803 ;;; Set properties to give full support to the parser and display
804 (defprop $generalized_lambert_w %generalized_lambert_w alias
)
805 (defprop $generalized_lambert_w %generalized_lambert_w verb
)
806 (defprop %generalized_lambert_w $generalized_lambert_w reversealias
)
807 (defprop %generalized_lambert_w $generalized_lambert_w noun
)
809 ;;; lambert_w is a simplifying function
810 (defprop %generalized_lambert_w simp-generalized-lambertw operators
)
812 ;;; Derivative of lambert_w
813 (defprop %generalized_lambert_w
817 ((mexpt) $%e
((mtimes ) -
1 ((%generalized_lambert_w
) k x
)))
818 ((mexpt) ((mplus) 1 ((%generalized_lambert_w
) k x
)) -
1)))
821 ;;; Integral of lambert_w
822 ;;; integrate(W(k,x),x) := x*(W(k,x)^2-W(k,x)+1)/W(k,x)
823 (defprop %generalized_lambert_w
829 ((mexpt) ((%generalized_lambert_w
) k x
) 2)
830 ((mtimes) -
1 ((%generalized_lambert_w
) k x
))
832 ((mexpt) ((%generalized_lambert_w
) k x
) -
1)))
835 (defun simp-generalized-lambertw (expr ignored z
)
836 (declare (ignore ignored
))
838 (let ((k (simpcheck (cadr expr
) z
))
839 (x (simpcheck (caddr expr
) z
)))
841 ;; Numerical evaluation for real or complex x
842 ((and (integerp k
) (complex-float-numerical-eval-p x
))
843 ;; x may be an integer. eg "generalized_lambert_w(0,1),numer;"
845 (to (bigfloat::lambert-w-k k
(bigfloat:to
($float x
))))
846 (to (bigfloat::lambert-w-k k
(bigfloat:to x
)))))
847 ;; Numerical evaluation for real or complex bigfloat x
848 ((and (integerp k
) (complex-bigfloat-numerical-eval-p x
))
849 (to (bigfloat::lambert-w-k k
(bigfloat:to x
))))
850 (t (list '(%generalized_lambert_w simp
) k x
)))))
852 (in-package "BIGFLOAT")
854 (defvar *debug-li-eval
* nil
)
856 (defun li-using-powers-of-log (n x
)
857 ;; When x is on or near the unit circle the other
858 ;; approaches don't work. Use the expansion in powers of
859 ;; log(z) (from cephes cpolylog)
861 ;; li[s](z) = sum(Z(s-j)*(log(z))^j/j!, j = 0, inf)
863 ;; where Z(j) = zeta(j) for j != 1. For j = 1:
865 ;; Z(1) = -log(-log(z)) + sum(1/k, k, 1, s - 1)
868 ;; This is similar to
869 ;; http://functions.wolfram.com/10.08.06.0024.01, but that
870 ;; identity is clearly undefined if v is a positive
871 ;; integer because zeta(1) is undefined.
875 ;; li[3](z) = Z(3) + Z(2)*log(z) + Z(1)*log(z)^2/2!
876 ;; + Z(0)*log(z)^3/3! + sum(Z(-k)*log(z)^(k+4)/(k+4)!,k,1,inf);
878 ;; But Z(-k) = zeta(-k) is 0 if k is even. So
880 ;; li[3](z) = Z(3) + Z(2)*log(z) + Z(1)*log(z)^2/2!
881 ;; + Z(0)*log(z)^3/3! + sum(Z(-(2*k+1))*log(z)^(2*k+4)/(2*k+4)!,k,0,inf);
884 (let ((sum (- (log (- (log x
))))))
886 (loop for k from
1 below n
889 (to (maxima::$zeta
(maxima::to
(float j
(realpart x
)))))))))
890 (let* ((eps (epsilon x
))
896 (term (* (/ top bot
) (to (zfun (- n k
))))
897 (* (/ top bot
) (to (zfun (- n k
))))))
899 (oddp (- n k
)) ;; even terms are all zero
900 (<= (abs term
) (* (abs sum
) eps
))))
901 ;;(format t "~3d: ~A / ~A = ~A~%" k top bot term)
907 ;; If |x| < series-threshold, the series is used.
908 (let ((series-threshold 0.8))
912 (maxima::$zeta
(maxima::to
(float 3 x
))))
914 ;; li[3](-1) = -(1-2^(1-3))*li[3](1)
919 ;; li[s](-1) = (2^(1-s)-1)*zeta(s)
921 ;; (See http://functions.wolfram.com/10.08.03.0003.01)
922 (* -
3/4 (to (maxima::$zeta
(maxima::to
(float 3 x
))))))
924 ;; For z not in the interval (0, 1) and for integral n, we
925 ;; have the identity:
927 ;; li[n](z) = -log(-z)^n/n! + (-1)^(n-1)*li[n](1/z)
928 ;; + 2 * sum(li[2*r](-1)/(n-2*r)!*log(-z)^(n-2*r), r, 1, floor(n/2))
930 ;; (See http://functions.wolfram.com/ZetaFunctionsandPolylogarithms/PolyLog/17/02/01/01/0008/)
932 ;; In particular for n = 3:
934 ;; li[3](z) = li[3](1/z) - log(-z)/6*(log(-z)^2+%pi^2)
935 (let* ((lg (log (- x
)))
937 (result (- (li3numer (/ x
))
939 (+ (* lg lg
) (* dpi dpi
))))))
942 (li-using-powers-of-log 3 x
))
943 ((> (abs x
) series-threshold
)
944 ;; The series converges too slowly so use the identity:
946 ;; li[3](-x/(1-x)) + li[3](1-x) + li[3](x)
947 ;; = li[3](1) + %pi^2/6*log(1-x) - 1/2*log(x)*(log(1-x))^2 + 1/6*(log(1-x))^3
951 ;; li[3](x) = li[3](1) + %pi^2/6*log(1-x) - 1/2*log(x)*(log(1-x))^2 + 1/6*(log(1-x))^3
952 ;; - li[3](-x/(1-x)) - li[3](1-x)
954 ;; (See http://functions.wolfram.com/10.08.17.0048.01)
959 (decf s
(* 0.5 u u
(log xc
)))
960 (incf s
(/ (* dpi dpi u
) 6))
961 (decf s
(li3numer (- (/ xc x
))))
962 (decf s
(li3numer xc
))
963 (incf s
(li3numer 1))))
965 ;; Sum the power series. threshold determines when the
966 ;; summation has converted.
967 (let* ((threshold (epsilon x
))
970 (incf term
(* 0.125 x x
))
973 (p1 (* p x
) (* p1 x
))
974 (h (/ p1
(* k k k
)) (/ p1
(* k k k
)))
976 ((<= (abs (/ h s
)) threshold
)
980 ;; The series threshold to above sqrt(1/2) because li[2](%i) needs
981 ;; the value of li[2](1/2-%i/2), and the magnitude of the argument
982 ;; is sqrt(1/2) = 0.707. If the threshold is below this, we get
983 ;; into an infinite recursion oscillating between the two args.
984 (let ((series-threshold .75))
988 ;; %pi^2/6. This follows from the series.
989 (/ (expt (%pi z
) 2) 6))
991 ;; -%pi^2/12. From the formula
993 ;; li[s](-1) = (2^(1-s)-1)*zeta(s)
995 ;; (See http://functions.wolfram.com/10.08.03.0003.01)
996 (/ (expt (%pi z
) 2) -
12))
999 ;; li[2](z) = -li[2](1/z) - 1/2*log(-z)^2 - %pi^2/6,
1001 ;; valid for all z not in the intervale (0, 1).
1003 ;; (See http://functions.wolfram.com/10.08.17.0013.01)
1004 (- (+ (li2numer (/ z
))
1005 (* 0.5 (expt (log (- z
)) 2))
1006 (/ (expt (%pi z
) 2) 6))))
1007 ;; this converges faster when close to unit circle
1008 ((> (abs z
) series-threshold
)
1009 (li-using-powers-of-log 2 z
))
1011 ;;(> (abs z) series-threshold)
1012 ;; For 0.5 <= |z|, where the series would not converge very quickly, use
1014 ;; li[2](z) = li[2](1/(1-z)) + 1/2*log(1-z)^2 - log(-z)*log(1-z) - %pi^2/6
1016 ;; (See http://functions.wolfram.com/10.08.17.0016.01)
1017 ;;(let* ((1-z (- 1 z))
1019 ;; (+ (li2numer (/ 1-z))
1021 ;; (- (* (log (- z))
1023 ;; (- (/ (expt (%pi z) 2) 6)))))
1025 ;; Series evaluation:
1027 ;; li[2](z) = sum(z^k/k^2, k, 1, inf);
1028 (let ((eps (epsilon z
)))
1030 (term z
(* term
(/ (* z k k
)
1032 (sum z
(+ term sum
)))
1033 ((<= (abs (/ term sum
)) eps
)
1036 (defun polylog-power-series (s z
)
1037 ;; Series evaluation:
1039 ;; li[s](z) = sum(z^k/k^s, k, 1, inf);
1040 (let ((eps (epsilon z
)))
1042 (term z
(* term z
(expt (/ (- k
1) k
) s
)))
1043 (sum z
(+ term sum
)))
1044 ((<= (abs (/ term sum
)) eps
)
1045 ;; Return the value and the number of terms used, for
1046 ;; debugging and for helping in determining the series
1050 (defun polylog-log-series (s z
)
1051 ;; When x is on or near the unit circle the other
1052 ;; approaches don't work. Use the expansion in powers of
1053 ;; log(z) (from cephes cpolylog)
1055 ;; li[s](z) = sum(Z(s-j)*(log(z))^j/j!, j = 0, inf)
1057 ;; where Z(j) = zeta(j) for j != 1. For j = 1:
1059 ;; Z(1) = -log(-log(z)) + sum(1/k, k, 1, s - 1)
1063 (let ((sum (- (log (- (log z
))))))
1065 (loop for k from
1 below s
1068 (to (maxima::$zeta
(maxima::to
(float j
(realpart z
)))))))))
1069 (let* ((eps (epsilon z
))
1071 (logx^
2 (* logx logx
))
1075 ;; Compute sum(Z(s-j)*log(z)^j/j!, j = 1, s)
1077 (zf (zfun (- s k
)) (zfun (- s k
)))
1078 (term (* (/ top bot
) zf
)
1079 (* (/ top bot
) zf
)))
1081 (when *debug-li-eval
*
1082 (format t
"~3d: ~A / ~A * ~A => ~A~%" k top bot zf term
))
1084 (setf bot
(* bot
(1+ k
)))
1085 (setf top
(* top logx
)))
1087 (when *debug-li-eval
*
1088 (format t
"s = ~A, sum = ~S top, bot = ~S ~S~%"
1090 ;; Compute the sum for j = s+1 and up. But since
1091 ;; zeta(-k) is 0 for k even, we only every other term.
1092 (do* ((k (+ s
1) (+ k
2))
1093 (zf (zfun (- s k
)) (zfun (- s k
)))
1094 (term (* (/ top bot
) zf
)
1095 (* (/ top bot
) zf
)))
1096 ((<= (abs term
) (* (abs sum
) eps
))
1097 ;; Return the result and the number of terms used for
1098 ;; helping in determining the series threshold and the
1099 ;; log-series threshold.
1101 (when *debug-li-eval
*
1102 (format t
"~3d: ~A / ~A = ~A~%" k top bot term
))
1104 (setf bot
(* bot
(+ k
1) (+ k
2)))
1105 (setf top
(* top logx^
2))))))
1107 (defun polylog-inversion-formula (s z
)
1108 ;; For z not in the interval (0, 1) and for integral n, we
1109 ;; have the identity:
1111 ;; li[n](z) = -log(-z)^n/n! + (-1)^(n-1)*li[n](1/z)
1112 ;; + 2 * sum(li[2*r](-1)/(n-2*r)!*log(-z)^(n-2*r), r, 1, floor(n/2))
1114 ;; (See http://functions.wolfram.com/ZetaFunctionsandPolylogarithms/PolyLog/17/02/01/01/0008/)
1118 ;; li[n](z) = -log(-z)^n/n! + (-1)^(n-1)*li[n](1/z)
1119 ;; + 2 * sum(li[2*m-2*r](-1)/(n-2*m+2*r)!*log(-z)^(n-2*m+2*r), r, 0, m - 1)
1121 ;; where m = floor(n/2). Thus, n-2*m = 0 if n is even and 1 if n is odd.
1123 ;; For n = 2*m, we have
1125 ;; li[2*m](z) = -log(-z)^(2*m)/(2*m)! - li[2*m](1/z)
1126 ;; + 2 * sum(li[2*r](-1)/(2*m-2*r)!*log(-z)^(2*m-2*r), r, 1, m)
1127 ;; = -log(-z)^(2*m)/(2*m)! - li[2*m](1/z)
1128 ;; + 2 * sum((li[2*m-2*r](-1)*log(-z)^(2*r+1))/(2*r+1)!,r,0,m-1);
1130 ;; For n = 2*m+1, we have
1132 ;; li[2*m+1](z) = -log(-z)^(2*m+1)/(2*m+1)! + li[2*m+1](1/z)
1133 ;; + 2 * sum(li[2*r](-1)/(2*m-2*r + 1)!*log(-z)^(2*m-2*r + 1), r, 1, m)
1134 ;; = -log(-z)^(2*m+1)/(2*m+1)! + li[2*m+1](1/z)
1135 ;; + 2 * sum((li[2*m-2*r](-1)*log(-z)^(2*r+1))/(2*r+1)!,r,0,m-1);
1138 ;; li[n](z) = -log(-z)^n/n! + (-1)^(n-1)*li[n](1/z)
1139 ;; + 2 * sum((li[2*m-2*r](-1)*log(-z)^(2*r+1))/(2*r+1)!,r,0,floor(n/2)-1);
1140 (let* ((lgz (log (- z
)))
1142 (half-s (floor s
2))
1143 (neg-1 (float -
1 (realpart z
)))
1147 (top (if (oddp s
) lgz
1) (* top lgz^
2))
1148 (bot 1 (* bot
(+ r r -
1) (+ r r
)))
1149 (term (* (li-s-simp (* 2 (- half-s r
)) neg-1
)
1151 (* (li-s-simp (* 2 (- half-s r
)) neg-1
)
1155 (when *debug-li-eval
*
1156 (format t
"r = ~4d: ~A / ~A, ~A; ~A~%" r top bot term sum
)))
1158 (top (if (oddp s
) lgz
1) (* top lgz^
2))
1159 (bot 1 (* bot
(+ r r
) (+ r r
1)))
1160 (term (* (li-s-simp (* 2 (- half-s r
)) neg-1
)
1162 (* (li-s-simp (* 2 (- half-s r
)) neg-1
)
1166 (when *debug-li-eval
*
1167 (format t
"r = ~4d: ~A / ~A, ~A; ~A~%" r top bot term sum
))))
1170 (maxima::take
'(maxima::mfactorial
) s
)))
1171 (* (expt -
1 (- s
1))
1172 (li-s-simp s
(/ z
))))))
1174 (defun li-s-simp (s z
)
1175 (let ((series-threshold 0.5)
1176 (log-series-threshold 2))
1178 (maxima::to
(to 0.0)))
1180 (maxima::$zeta
(maxima::to
(float s z
))))
1182 (- (* (- 1 (expt 2 (- 1 s
)))
1183 (to (li-s-simp s
(- z
))))))
1184 ((<= (abs z
) series-threshold
)
1185 (values (polylog-power-series s z
)))
1186 ((<= (abs z
) log-series-threshold
)
1187 (values (polylog-log-series s z
)))
1189 (polylog-inversion-formula s z
)))))