Skip to content

Commit e7c64d4

Browse files
authored
Merge pull request #718 from Mathics3/gamma-and-elliptic-docs
Make a pass over these special functions
2 parents 3b3bd94 + c7315ec commit e7c64d4

File tree

2 files changed

+107
-36
lines changed

2 files changed

+107
-36
lines changed

mathics/builtin/specialfns/elliptic.py

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
"""
22
Elliptic Integrals
33
4-
In integral calculus, an <url>:elliptic integral: https://en.wikipedia.org/wiki/Elliptic_integral</url> is one of a number of related functions defined as the value of certain integral. Their name originates from their originally arising in connection with the problem of finding the arc length of an ellipse. These functions often are used in cryptography to encode and decode messages.
4+
In integral calculus, an <url>:elliptic integral:
5+
https://en.wikipedia.org/wiki/Elliptic_integral</url> is one of a number of \
6+
related functions defined as the value of certain integral. Their name \
7+
originates from their originally arising in connection with the problem of \
8+
finding the arc length of an ellipse.
59
10+
These functions often are used in cryptography to encode and decode messages.
611
"""
712

813
import sympy
@@ -17,7 +22,12 @@
1722

1823
class EllipticE(SympyFunction):
1924
"""
20-
<url>:WMA link:https://reference.wolfram.com/language/ref/EllipticE.html</url>
25+
<url>
26+
:Elliptic complete elliptic integral of the second kind:
27+
https://en.wikipedia.org/wiki/Elliptic_integral#Complete_elliptic_integral_of_the_second_kind</url> (<url>:SymPy:
28+
https://docs.sympy.org/latest/modules/functions/special.html#sympy.functions.special.elliptic_integrals.elliptic_e</url>, <url>
29+
:WMA:
30+
https://reference.wolfram.com/language/ref/EllipticE.html</url>)
2131
2232
<dl>
2333
<dt>'EllipticE[$m$]'
@@ -46,19 +56,19 @@ class EllipticE(SympyFunction):
4656
summary_text = "elliptic integral of the second kind E(ϕ|m)"
4757
sympy_name = "elliptic_e"
4858

49-
def apply_default(self, args, evaluation):
59+
def eval_default(self, args, evaluation):
5060
"%(name)s[args___]"
5161
evaluation.message("EllipticE", "argt", Integer(len(args.elements)))
5262

53-
def apply_m(self, m, evaluation):
63+
def eval_m(self, m, evaluation):
5464
"%(name)s[m_]"
5565
sympy_arg = numerify(m, evaluation).to_sympy()
5666
try:
5767
return from_sympy(sympy.elliptic_e(sympy_arg))
5868
except:
5969
return
6070

61-
def apply_phi_m(self, phi, m, evaluation):
71+
def eval_phi_m(self, phi, m, evaluation):
6272
"%(name)s[phi_, m_]"
6373
sympy_args = [numerify(a, evaluation).to_sympy() for a in (phi, m)]
6474
try:
@@ -69,7 +79,12 @@ def apply_phi_m(self, phi, m, evaluation):
6979

7080
class EllipticF(SympyFunction):
7181
"""
72-
<url>:WMA link:https://reference.wolfram.com/language/ref/EllipticF.html</url>
82+
<url>
83+
:Complete elliptic integral of the first kind:
84+
https://en.wikipedia.org/wiki/Elliptic_integral#Complete_elliptic_integral_of_the_first_kind</url> (<url>:SymPy:
85+
https://docs.sympy.org/latest/modules/functions/special.html#sympy.functions.special.elliptic_integrals.elliptic_f</url>, <url>
86+
:WMA:
87+
https://reference.wolfram.com/language/ref/EllipticF.html</url>)
7388
7489
<dl>
7590
<dt>'EllipticF[$phi$, $m$]'
@@ -92,11 +107,11 @@ class EllipticF(SympyFunction):
92107
summary_text = "elliptic integral F(ϕ|m)"
93108
sympy_name = "elliptic_f"
94109

95-
def apply_default(self, args, evaluation):
110+
def eval_default(self, args, evaluation):
96111
"%(name)s[args___]"
97112
evaluation.message("EllipticE", "argx", Integer(len(args.elements)))
98113

99-
def apply(self, phi, m, evaluation):
114+
def eval(self, phi, m, evaluation):
100115
"%(name)s[phi_, m_]"
101116
sympy_args = [numerify(a, evaluation).to_sympy() for a in (phi, m)]
102117
try:
@@ -107,7 +122,12 @@ def apply(self, phi, m, evaluation):
107122

108123
class EllipticK(SympyFunction):
109124
"""
110-
<url>:WMA link:https://reference.wolfram.com/language/ref/EllipticK.html</url>
125+
<url>
126+
:Complete elliptic integral of the first kind:
127+
https://en.wikipedia.org/wiki/Elliptic_integral#Complete_elliptic_integral_of_the_first_kind</url> (<url>:SymPy:
128+
https://docs.sympy.org/latest/modules/functions/special.html</url>, <url>
129+
:WMA:
130+
https://reference.wolfram.com/language/ref/EllipticK.html</url>)
111131
112132
<dl>
113133
<dt>'EllipticK[$m$]'
@@ -128,16 +148,16 @@ class EllipticK(SympyFunction):
128148

129149
attributes = A_NUMERIC_FUNCTION | A_LISTABLE | A_PROTECTED
130150
messages = {
131-
"argx": "EllipticE called with `` arguments; 1 argument is expected.",
151+
"argx": "EllipticK called with `` arguments; 1 argument is expected.",
132152
}
133153
summary_text = "elliptic integral of the first kind K(m)"
134154
sympy_name = "elliptic_k"
135155

136-
def apply_default(self, args, evaluation):
156+
def eval_default(self, args, evaluation):
137157
"%(name)s[args___]"
138158
evaluation.message("EllipticK", "argx", Integer(len(args.elements)))
139159

140-
def apply(self, m, evaluation):
160+
def eval(self, m, evaluation):
141161
"%(name)s[m_]"
142162
args = numerify(m, evaluation).get_sequence()
143163
sympy_args = [a.to_sympy() for a in args]
@@ -149,7 +169,12 @@ def apply(self, m, evaluation):
149169

150170
class EllipticPi(SympyFunction):
151171
"""
152-
<url>:WMA link:https://reference.wolfram.com/language/ref/EllipticPi.html</url>
172+
<url>
173+
:Complete elliptic integral of the third kind:
174+
https://en.wikipedia.org/wiki/Elliptic_integral#Incomplete_elliptic_integral_of_the_third_kind</url> (<url>:SymPy:
175+
https://docs.sympy.org/latest/modules/functions/special.html#sympy.functions.special.elliptic_integrals.elliptic_pi</url>, <url>
176+
:WMA:
177+
https://reference.wolfram.com/language/ref/EllipticPi.html</url>)
153178
154179
<dl>
155180
<dt>'EllipticPi[$n$, $m$]'
@@ -172,11 +197,11 @@ class EllipticPi(SympyFunction):
172197
summary_text = "elliptic integral of the third kind P(n|m)"
173198
sympy_name = "elliptic_pi"
174199

175-
def apply_default(self, args, evaluation):
200+
def eval_default(self, args, evaluation):
176201
"%(name)s[args___]"
177202
evaluation.message("EllipticPi", "argt", Integer(len(args.elements)))
178203

179-
def apply_n_m(self, n, m, evaluation):
204+
def eval_n_m(self, n, m, evaluation):
180205
"%(name)s[n_, m_]"
181206
sympy_m = to_numeric_sympy_args(m, evaluation)[0]
182207
sympy_n = to_numeric_sympy_args(n, evaluation)[0]
@@ -185,7 +210,7 @@ def apply_n_m(self, n, m, evaluation):
185210
except:
186211
return
187212

188-
def apply_n_phi_m(self, n, phi, m, evaluation):
213+
def eval_n_phi_m(self, n, phi, m, evaluation):
189214
"%(name)s[n_, phi_, m_]"
190215
sympy_n = to_numeric_sympy_args(n, evaluation)[0]
191216
sympy_phi = to_numeric_sympy_args(m, evaluation)[0]

mathics/builtin/specialfns/gamma.py

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@
3333

3434
class Beta(_MPMathMultiFunction):
3535
"""
36-
<url>:WMA link:https://reference.wolfram.com/language/ref/Beta.html</url>
36+
<url>
37+
:Euler beta function:
38+
https://en.wikipedia.org/wiki/Beta_function</url> (<url>:SymPy:
39+
https://docs.sympy.org/latest/modules/functions/special.html#sympy.functions.special.beta_functions.beta</url>, <url>
40+
:WMA:
41+
https://reference.wolfram.com/language/ref/Beta.html</url>)
3742
3843
<dl>
3944
<dt>'Beta[$a$, $b$]'
@@ -75,8 +80,8 @@ def from_sympy(self, sympy_name, elements):
7580
else:
7681
return Expression(Symbol(self.get_name()), *elements)
7782

78-
# sympy does not handles Beta for integer arguments.
79-
def apply_2(self, a, b, evaluation):
83+
# SymPy does not handles Beta for integer arguments.
84+
def eval(self, a, b, evaluation):
8085
"""Beta[a_, b_]"""
8186
if not (a.is_numeric() and b.is_numeric()):
8287
return
@@ -85,7 +90,7 @@ def apply_2(self, a, b, evaluation):
8590
gamma_a_plus_b = Expression(SymbolGamma, a + b)
8691
return gamma_a * gamma_b / gamma_a_plus_b
8792

88-
def apply_3(self, z, a, b, evaluation):
93+
def eval_with_z(self, z, a, b, evaluation):
8994
"""Beta[z_, a_, b_]"""
9095
# Here I needed to do that because the order of the arguments in WL
9196
# is different from the order in mpmath. Most of the code is the same
@@ -215,7 +220,7 @@ class Factorial2(PostfixOperator, _MPMathFunction):
215220
summary_text = "semi-factorial"
216221
options = {"Method": "Automatic"}
217222

218-
def apply(self, number, evaluation, options={}):
223+
def eval(self, number, evaluation, options={}):
219224
"Factorial2[number_?NumberQ, OptionsPattern[%(name)s]]"
220225

221226
try:
@@ -357,10 +362,11 @@ def from_sympy(self, sympy_name, elements):
357362

358363
class LogGamma(_MPMathMultiFunction):
359364
"""
360-
<url>:WMA link:https://reference.wolfram.com/language/ref/LogGamma.html</url>
361-
362-
In number theory the logarithm of the gamma function often appears. For positive real numbers, this can be evaluated as 'Log[Gamma[$z$]]'.
363-
365+
<url>:log-gamma function:
366+
https://en.wikipedia.org/wiki/Gamma_function#The_log-gamma_function</url> (<url>
367+
:SymPy:
368+
https://docs.sympy.org/latest/modules/functions/special.html#sympy.functions.special.gamma_functions.loggamma</url>, <url>
369+
:WMA:https://reference.wolfram.com/language/ref/LogGamma.html</url>)
364370
<dl>
365371
<dt>'LogGamma[$z$]'
366372
<dd>is the logarithm of the gamma function on the complex number $z$.
@@ -402,22 +408,53 @@ def get_sympy_names(self):
402408

403409
class Pochhammer(SympyFunction):
404410
"""
405-
<url>:WMA link:https://reference.wolfram.com/language/ref/Pochhammer.html</url>
411+
<url>:Rising factorial:
412+
https://en.wikipedia.org/wiki/Falling_and_rising_factorials</url> (<url>
413+
:SymPy:
414+
https://docs.sympy.org/latest/modules/functions/combinatorial.html#risingfactorial</url>, <url>
415+
:WMA:
416+
https://reference.wolfram.com/language/ref/Pochhammer.html</url>)
417+
418+
The Pochhammer symbol or rising factorial often appears in series \
419+
expansions for hypergeometric functions.
406420
407-
The Pochhammer symbol or rising factorial often appears in series expansions for hypergeometric functions.
408-
The Pochammer symbol has a definie value even when the gamma functions which appear in its definition are infinite.
421+
The Pochammer symbol has a definite value even when the gamma \
422+
functions which appear in its definition are infinite.
409423
<dl>
410424
<dt>'Pochhammer[$a$, $n$]'
411-
<dd>is the Pochhammer symbol (a)_n.
425+
<dd>is the Pochhammer symbol $a_n$.
412426
</dl>
413427
414-
>> Pochhammer[4, 8]
415-
= 6652800
428+
Product of the first 3 numbers:
429+
>> Pochhammer[1, 3]
430+
= 6
431+
432+
'Pochhammer[1, $n$]' is \
433+
the same as Pochhammer[2, $n$-1] since 1 is a multiplicative identity.
434+
435+
>> Pochhammer[1, 3] == Pochhammer[2, 2]
436+
= True
437+
438+
Although sometimes 'Pochhammer[0, $n$]' is taken to be 1, in Mathics it is 0:
439+
>> Pochhammer[0, n]
440+
= 0
441+
442+
Pochhammer uses Gamma for non-Integer values of $n$:
443+
444+
>> Pochhammer[1, 3.001]
445+
= 6.00754
446+
447+
>> Pochhammer[1, 3.001] == Pochhammer[2, 2.001]
448+
= True
449+
450+
>> Pochhammer[1.001, 3] == 1.001 2.001 3.001
451+
= True
416452
"""
417453

418454
attributes = A_LISTABLE | A_NUMERIC_FUNCTION | A_PROTECTED
419455

420456
rules = {
457+
"Pochhammer[0, n_]": "0", # Wikipedia says it should be 1 though.
421458
"Pochhammer[a_, n_]": "Gamma[a + n] / Gamma[a]",
422459
"Derivative[1,0][Pochhammer]": "(Pochhammer[#1, #2]*(-PolyGamma[0, #1] + PolyGamma[0, #1 + #2]))&",
423460
"Derivative[0,1][Pochhammer]": "(Pochhammer[#1, #2]*PolyGamma[0, #1 + #2])&",
@@ -428,7 +465,12 @@ class Pochhammer(SympyFunction):
428465

429466
class PolyGamma(_MPMathMultiFunction):
430467
r"""
431-
<url>:WMA link:https://reference.wolfram.com/language/ref/PolyGamma.html</url>
468+
<url>:Polygamma function:
469+
https://en.wikipedia.org/wiki/Polygamma_function</url> (<url>
470+
:SymPy:
471+
https://docs.sympy.org/latest/modules/functions/special.html#sympy.functions.special.gamma_functions.polygamma</url>, <url>
472+
:WMA:
473+
https://reference.wolfram.com/language/ref/PolyGamma.html</url>)
432474
433475
PolyGamma is a meromorphic function on the complex numbers and is defined as a derivative of the logarithm of the gamma function.
434476
<dl>
@@ -464,13 +506,17 @@ class PolyGamma(_MPMathMultiFunction):
464506

465507

466508
class StieltjesGamma(SympyFunction):
467-
r"""
468-
<url>:WMA link:https://reference.wolfram.com/language/ref/StieltjesGamma.html</url>
509+
"""
510+
<url>:Stieltjes constants:
511+
https://en.wikipedia.org/wiki/Stieltjes_constants</url> (<url>
512+
:SymPy:
513+
https://docs.sympy.org/latest/modules/functions/special.html#sympy.functions.special.zeta_functions.stieltjes</url>, <url>
514+
:WMA:
515+
https://reference.wolfram.com/language/ref/StieltjesGamma.html</url>)
469516
470-
PolyGamma is a meromorphic function on the complex numbers and is defined as a derivative of the logarithm of the gamma function.
471517
<dl>
472518
<dt>'StieltjesGamma[$n$]'
473-
<dd>returns the Stieljs contstant for $n$.
519+
<dd>returns the Stieltjes constant for $n$.
474520
475521
<dt>'StieltjesGamma[$n$, $a$]'
476522
<dd>gives the generalized Stieltjes constant of its parameters

0 commit comments

Comments
 (0)