Skip to content

Commit d949182

Browse files
authored
Merge pull request #682 from Mathics3/remove-duplicate-CatalanNumber-def-in-combinatorica
Remove duplicate Catalan def in Combinatorica...
2 parents 66b1a68 + 26befdd commit d949182

File tree

3 files changed

+104
-40
lines changed

3 files changed

+104
-40
lines changed

mathics/builtin/base.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
import sympy
1111

12-
from mathics.core.exceptions import MessageException
1312
from mathics.core.atoms import Integer, MachineReal, PrecisionReal, String
1413
from mathics.core.attributes import A_NO_ATTRIBUTES, A_PROTECTED, A_READ_PROTECTED
1514
from mathics.core.convert.expression import to_expression, to_numeric_sympy_args
@@ -18,6 +17,7 @@
1817
from mathics.core.convert.sympy import from_sympy
1918
from mathics.core.definitions import Definition
2019
from mathics.core.element import BoxElementMixin
20+
from mathics.core.exceptions import MessageException
2121
from mathics.core.expression import Expression, SymbolDefault
2222
from mathics.core.list import ListExpression
2323
from mathics.core.number import PrecisionValueError, get_precision
@@ -659,7 +659,7 @@ def run_sympy(sympy_fn: Callable, *sympy_args) -> Any:
659659

660660

661661
class SympyFunction(SympyObject):
662-
def apply(self, z, evaluation):
662+
def eval(self, z, evaluation):
663663
# Note: we omit a docstring here, so as not to confuse
664664
# function signature collector ``contribute``.
665665

@@ -675,6 +675,9 @@ def apply(self, z, evaluation):
675675
except:
676676
return
677677

678+
# FIXME: remove after all apply->eval conversions have been done
679+
apply = eval
680+
678681
def get_constant(self, precision, evaluation, have_mpmath=False):
679682
try:
680683
d = get_precision(precision, evaluation)

mathics/builtin/intfns/combinatorial.py

Lines changed: 93 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22
"""
33
Combinatorial Functions
44
5-
<url>:Combinatorics: https://en.wikipedia.org/wiki/Combinatorics</url> is an area of mathematics primarily concerned with counting, both as a means and an end in obtaining results, and certain properties of finite structures.
5+
<url>:Combinatorics: https://en.wikipedia.org/wiki/Combinatorics</url> is an \
6+
area of mathematics primarily concerned with counting, both as a means and an \
7+
end in obtaining results, and certain properties of finite structures.
68
7-
It is closely related to many other areas of Mathematics and has many applications ranging from logic to statistical physics, from evolutionary biology to computer science, etc.
9+
It is closely related to many other areas of Mathematics and has many \
10+
applications ranging from logic to statistical physics, from evolutionary \
11+
biology to computer science, etc.
812
"""
913

1014

15+
from itertools import combinations
16+
1117
from mathics.builtin.arithmetic import _MPMathFunction
1218
from mathics.builtin.base import Builtin, SympyFunction
13-
1419
from mathics.core.atoms import Integer
1520
from mathics.core.attributes import (
1621
A_LISTABLE,
@@ -30,7 +35,6 @@
3035
SymbolTimes,
3136
SymbolTrue,
3237
)
33-
from itertools import combinations
3438

3539
SymbolBinomial = Symbol("Binomial")
3640
SymbolSubsets = Symbol("Subsets")
@@ -62,7 +66,7 @@ def generate():
6266
except _NoBoolVector:
6367
return None
6468

65-
def apply(self, u, v, evaluation):
69+
def eval(self, u, v, evaluation):
6670
"%(name)s[u_List, v_List]"
6771
if len(u.elements) != len(v.elements):
6872
return
@@ -85,7 +89,13 @@ class _NoBoolVector(Exception):
8589
class Binomial(_MPMathFunction):
8690
"""
8791
88-
<url>:Binomial Coefficient: https://en.wikipedia.org/wiki/Binomial_coefficient</url> (<url>:SymPy: https://docs.sympy.org/latest/modules/functions/combinatorial.html#binomial</url>, <url>:WMA: https://reference.wolfram.com/language/ref/Binomial.html</url>)
92+
<url>
93+
:Binomial Coefficient:
94+
https://en.wikipedia.org/wiki/Binomial_coefficient</url> (<url>
95+
:SymPy:
96+
https://docs.sympy.org/latest/modules/functions/combinatorial.html#binomial</url>, <url>
97+
:WMA:
98+
https://reference.wolfram.com/language/ref/Binomial.html</url>)
8999
90100
<dl>
91101
<dt>'Binomial[$n$, $k$]'
@@ -120,7 +130,14 @@ class Binomial(_MPMathFunction):
120130

121131
class CatalanNumber(SympyFunction):
122132
"""
123-
<url>:Catalan Number: https://en.wikipedia.org/wiki/Catalan_number</url> (<url>:SymPy: https://docs.sympy.org/latest/modules/functions/combinatorial.html#sympy.functions.combinatorial.numbers.catalan</url>, <url>:WMA: https://reference.wolfram.com/language/ref/CatalanNumber.html</url>)
133+
<url>
134+
:Catalan Number:
135+
https://en.wikipedia.org/wiki/Catalan_number</url> (<url>
136+
:SymPy:
137+
https://docs.sympy.org/latest/modules/functions/combinatorial.html#sympy.functions.combinatorial.numbers.catalan</url>, \
138+
<url>
139+
:WMA:
140+
https://reference.wolfram.com/language/ref/CatalanNumber.html</url>)
124141
125142
<dl>
126143
<dt>'CatalanNumber[$n$]'
@@ -139,19 +156,25 @@ class CatalanNumber(SympyFunction):
139156

140157
# We (and sympy) do not handle fractions or other non-integers
141158
# right now.
142-
def apply_integer(self, n: Integer, evaluation):
159+
def eval_integer(self, n: Integer, evaluation):
143160
"CatalanNumber[n_Integer]"
144-
return self.apply(n, evaluation)
161+
return self.eval(n, evaluation)
145162

146163

147164
class DiceDissimilarity(_BooleanDissimilarity):
148165
r"""
149-
<url>:Sørensen–Dice coefficient: https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient</url> (<url>:Sympy: https://docs.scipy.org/doc/scipy/search.html</url>, <url>:DiceDissimilarity: https://reference.wolfram.com/language/ref/DiceDissimilarity.html</url>)
166+
<url>
167+
:Sørensen–Dice coefficient:
168+
https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient</url> (<url>
169+
:Sympy:
170+
https://docs.scipy.org/doc/scipy/search.html</url>, <url>
171+
:DiceDissimilarity:
172+
https://reference.wolfram.com/language/ref/DiceDissimilarity.html</url>)
150173
<dl>
151174
<dt>'DiceDissimilarity[$u$, $v$]'
152-
<dd>returns the Dice dissimilarity between the two boolean 1-D lists $u$ and $v$,
153-
which is defined as (c_tf + c_ft) / (2 * c_tt + c_ft + c_tf), where $n$ is len($u$) and c_ij is
154-
the number of occurrences of $u$[k]=i and $v$[k]=j for $k$ < $n$.
175+
<dd>returns the Dice dissimilarity between the two boolean 1-D lists $u$ and $v$.
176+
This is defined as ($c_tf$ + $c_ft$) / (2 * $c_tt$ + $c_ft$ + c_tf).
177+
$n$ is len($u$) and $c_ij$ is the number of occurrences of $u$[$k$]=$i$ and $v$[$k$]=$j$ for $k$ < $n$.
155178
</dl>
156179
157180
>> DiceDissimilarity[{1, 0, 1, 1, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1}]
@@ -168,10 +191,20 @@ def _compute(self, n, c_ff, c_ft, c_tf, c_tt):
168191

169192
class JaccardDissimilarity(_BooleanDissimilarity):
170193
"""
171-
<url>:Jaccard index: https://en.wikipedia.org/wiki/Jaccard_index</url> (<url>:SciPy: https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jaccard.html</url>, <url>:WMA: https://reference.wolfram.com/language/ref/JaccardDissimilarity.html</url>)
194+
<url>
195+
:Jaccard index:
196+
https://en.wikipedia.org/wiki/Jaccard_index</url> (<url>
197+
:SciPy:
198+
https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jaccard.html</url>, <url>
199+
:WMA:
200+
https://reference.wolfram.com/language/ref/JaccardDissimilarity.html</url>)
172201
<dl>
173202
<dt>'JaccardDissimilarity[$u$, $v$]'
174-
<dd>returns the Jaccard-Needham dissimilarity between the two boolean 1-D lists $u$ and $v$, which is defined as (c_tf + c_ft) / (c_tt + c_ft + c_tf), where $n$ is len($u$) and c_ij is the number of occurrences of $u$[k]=i and $v$[k]=j for $k$ < $n$.
203+
<dd>returns the Jaccard-Needham dissimilarity between the two boolean \
204+
1-D lists $u$ and $v$, which is defined as \
205+
($c_tf$ + $c_ft$) / ($c_tt$ + $c_ft$ + $c_tf$), where $n$ is \
206+
len($u$) and $c_ij$ is the number of occurrences of \
207+
$u$[$k$]=$i$ and $v$[$k$]=$j$ for $k$ < $n$.
175208
</dl>
176209
177210
>> JaccardDissimilarity[{1, 0, 1, 1, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1}]
@@ -193,7 +226,10 @@ class MatchingDissimilarity(_BooleanDissimilarity):
193226
194227
<dl>
195228
<dt>'MatchingDissimilarity[$u$, $v$]'
196-
<dd>returns the Matching dissimilarity between the two boolean 1-D lists $u$ and $v$, which is defined as (c_tf + c_ft) / $n$, where $n$ is len($u$) and c_ij is the number of occurrences of $u$[$k$]=$i$ and $v$[k]=$j$ for $k$ < $n$.
229+
<dd>returns the Matching dissimilarity between the two boolean \
230+
1-D lists $u$ and $v$, which is defined as ($c_tf$ + $c_ft$) / $n$, \
231+
where $n$ is len($u$) and $c_ij$ is the number of occurrences of \
232+
$u$[$k$]=$i$ and $v$[$k$]=$j$ for $k$ < $n$.
197233
</dl>
198234
199235
>> MatchingDissimilarity[{1, 0, 1, 1, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1}]
@@ -208,7 +244,10 @@ def _compute(self, n, c_ff, c_ft, c_tf, c_tt):
208244

209245
class Multinomial(Builtin):
210246
"""
211-
<url>:Multinomial distribution: https://en.wikipedia.org/wiki/Multinomial_distribution</url> (<url>:WMA: https://reference.wolfram.com/language/ref/Multinomial.html</url>)
247+
<url>
248+
:Multinomial distribution:
249+
https://en.wikipedia.org/wiki/Multinomial_distribution</url> (<url>\
250+
:WMA: https://reference.wolfram.com/language/ref/Multinomial.html</url>)
212251
<dl>
213252
<dt>'Multinomial[$n1$, $n2$, ...]'
214253
<dd>gives the multinomial coefficient '($n1$+$n2$+...)!/($n1$!$n2$!...)'.
@@ -229,7 +268,7 @@ class Multinomial(Builtin):
229268
attributes = A_LISTABLE | A_NUMERIC_FUNCTION | A_ORDERLESS | A_PROTECTED
230269
summary_text = "multinomial coefficients"
231270

232-
def apply(self, values, evaluation):
271+
def eval(self, values, evaluation):
233272
"Multinomial[values___]"
234273

235274
values = values.get_sequence()
@@ -245,13 +284,17 @@ def apply(self, values, evaluation):
245284

246285
class RogersTanimotoDissimilarity(_BooleanDissimilarity):
247286
"""
248-
<url>:WMA link:https://reference.wolfram.com/language/ref/RogersTanimotoDissimilarity.html</url>
287+
<url>
288+
:WMA link:
289+
https://reference.wolfram.com/language/ref/RogersTanimotoDissimilarity.html</url>
249290
250291
<dl>
251292
<dt>'RogersTanimotoDissimilarity[$u$, $v$]'
252-
<dd>returns the Rogers-Tanimoto dissimilarity between the two boolean 1-D lists $u$ and $v$,
253-
which is defined as $R$ / (c_tt + c_ff + $R$) where $n$ is len($u$), c_ij is
254-
the number of occurrences of $u$[$k$]=$i$ and $v$[$k]$=$j$ for $k$<n, and $R$ = 2 * (c_tf + c_ft).
293+
<dd>returns the Rogers-Tanimoto dissimilarity between the two boolean \
294+
1-D lists $u$ and $v$, which is defined as \
295+
$R$ / (c_tt + c_ff + $R$) where $n$ is len($u$), c_ij is \
296+
the number of occurrences of $u$[$k$]=$i$ and $v$[$k]$=$j$ for $k$<n, \
297+
and $R$ = 2 * ($c_tf$ + $c_ft$).
255298
</dl>
256299
257300
>> RogersTanimotoDissimilarity[{1, 0, 1, 1, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1}]
@@ -267,13 +310,16 @@ def _compute(self, n, c_ff, c_ft, c_tf, c_tt):
267310

268311
class RussellRaoDissimilarity(_BooleanDissimilarity):
269312
"""
270-
<url>:WMA link:https://reference.wolfram.com/language/ref/RusselRaoDissimilarity.html</url>
313+
<url>
314+
:WMA link:
315+
https://reference.wolfram.com/language/ref/RusselRaoDissimilarity.html</url>
271316
272317
<dl>
273318
<dt>'RussellRaoDissimilarity[$u$, $v$]'
274-
<dd>returns the Russell-Rao dissimilarity between the two boolean 1-D lists $u$ and $v$,
275-
which is defined as (n - c_tt) / c_tt where n is len($u$) and c_ij is
276-
the number of occurrences of $u$[k]=i and $v$[k]=j for k<n.
319+
<dd>returns the Russell-Rao dissimilarity between the two boolean \
320+
1-D lists $u$ and $v$, which is defined as ($n$ - $c_tt$) / $c_tt$ \
321+
where $n$ is len($u$) and $c_ij$ is \
322+
the number of occurrences of $u$[k]=i and $v$[$k$]=$j$ for $k$ < $n$.
277323
</dl>
278324
279325
>> RussellRaoDissimilarity[{1, 0, 1, 1, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1}]
@@ -288,12 +334,17 @@ def _compute(self, n, c_ff, c_ft, c_tf, c_tt):
288334

289335
class SokalSneathDissimilarity(_BooleanDissimilarity):
290336
"""
291-
<url>:WMA link:https://reference.wolfram.com/language/ref/SokalSneathDissimilarity.html</url>
337+
<url>
338+
:WMA link:
339+
https://reference.wolfram.com/language/ref/SokalSneathDissimilarity.html</url>
292340
293341
<dl>
294342
<dt>'SokalSneathDissimilarity[$u$, $v$]'
295-
<dd>returns the Sokal-Sneath dissimilarity between the two boolean 1-D lists $u$ and $v$,
296-
which is defined as $R$ / (c_tt + $R$) where $n$ is len($u$), c_ij is the number of occurrences of $u$[$k$]=$i$ and $v$[k]=$j$ for $k$ < $n$, and R = 2 * (c_tf + c_ft).
343+
<dd>returns the Sokal-Sneath dissimilarity between the two boolean \
344+
1-D lists $u$ and $v$, which is defined as $R$ / (c_tt + $R$) where \
345+
$n$ is len($u$), $c_ij$ is the number of occurrences of \
346+
$u$[$k$]=$i$ and $v$[k]=$j$ for $k$ < $n$, \
347+
and $R$ = 2 * ($c_tf$ + $c_ft$).
297348
</dl>
298349
299350
>> SokalSneathDissimilarity[{1, 0, 1, 1, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1}]
@@ -322,7 +373,8 @@ class Subsets(Builtin):
322373
<dd>finds a list of all possible subsets containing exactly $n$ elements.
323374
324375
<dt>'Subsets[$list$, {$min$, $max$}]'
325-
<dd>finds a list of all possible subsets containing between $min$ and $max$ elements.
376+
<dd>finds a list of all possible subsets containing between $min$ and \
377+
$max$ elements.
326378
327379
<dt>'Subsets[$list$, $spec$, $n$]'
328380
<dd>finds a list of the first $n$ possible subsets.
@@ -451,16 +503,16 @@ class Subsets(Builtin):
451503

452504
summary_text = "list all the subsets"
453505

454-
def apply_list(self, list, evaluation):
506+
def eval_list(self, list, evaluation):
455507
"Subsets[list_]"
456508

457509
return (
458510
evaluation.message("Subsets", "normal", Expression(SymbolSubsets, list))
459511
if isinstance(list, Atom)
460-
else self.apply_list_n(list, Integer(len(list.elements)), evaluation)
512+
else self.eval_list_n(list, Integer(len(list.elements)), evaluation)
461513
)
462514

463-
def apply_list_n(self, list, n, evaluation):
515+
def eval_list_n(self, list, n, evaluation):
464516
"Subsets[list_, n_]"
465517

466518
expr = Expression(SymbolSubsets, list, n)
@@ -483,7 +535,7 @@ def apply_list_n(self, list, n, evaluation):
483535

484536
return ListExpression(*nested_list)
485537

486-
def apply_list_pattern(self, list, n, evaluation):
538+
def eval_list_pattern(self, list, n, evaluation):
487539
"Subsets[list_, Pattern[n,_List|All|DirectedInfinity[1]]]"
488540

489541
expr = Expression(SymbolSubsets, list, n)
@@ -493,7 +545,7 @@ def apply_list_pattern(self, list, n, evaluation):
493545
else:
494546
head_t = list.head
495547
if n.get_name() == "System`All" or n.has_form("DirectedInfinity", 1):
496-
return self.apply_list(list, evaluation)
548+
return self.eval_list(list, evaluation)
497549

498550
n_len = len(n.elements)
499551

@@ -557,7 +609,7 @@ def apply_list_pattern(self, list, n, evaluation):
557609

558610
return ListExpression(*nested_list)
559611

560-
def apply_atom_pattern(self, list, n, spec, evaluation):
612+
def eval_atom_pattern(self, list, n, spec, evaluation):
561613
"Subsets[list_?AtomQ, Pattern[n,_List|All|DirectedInfinity[1]], spec_]"
562614

563615
return evaluation.message(
@@ -571,7 +623,11 @@ class YuleDissimilarity(_BooleanDissimilarity):
571623
572624
<dl>
573625
<dt>'YuleDissimilarity[$u$, $v$]'
574-
<dd>returns the Yule dissimilarity between the two boolean 1-D lists $u$ and $v$, which is defined as R / (c_tt * c_ff + R / 2) where n is len($u$), c_ij is the number of occurrences of $u$[k]=i and $v$[k]=j for $k$<$n$, and $R$ = 2 * c_tf * c_ft.
626+
<dd>returns the Yule dissimilarity between the two boolean 1-D lists $u$ \
627+
and $v$, which is defined as $R$ / ($c_tt$ * $c_ff$ + $R$ / 2) \
628+
where $n$ is len($u$), $c_ij$ is the number of occurrences of \
629+
$u$[$k$]=$i$ and $v$[$k$]=$j$ for $k$<$n$, \
630+
and $R$ = 2 * $c_tf$ * $c_ft$.
575631
</dl>
576632
577633
>> YuleDissimilarity[{1, 0, 1, 1, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1}]

mathics/packages/DiscreteMath/CombinatoricaV0.9.m

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1365,7 +1365,12 @@
13651365

13661366
NumberOfTableaux[n_Integer] := Apply[Plus, Map[NumberOfTableaux, Partitions[n]]]
13671367

1368-
CatalanNumber[n_] := Binomial[2n,n]/(n+1) /; (n>=0)
1368+
1369+
(* Mathics now provides CatalanNumber via SymPy. And
1370+
there is something broken with respect to Context that
1371+
would cause this definition to interfere with the Builtin definition.
1372+
*)
1373+
(* CatalanNumber[n_] := Binomial[2n,n]/(n+1) /; (n>=0) *)
13691374

13701375
RandomTableau[shape_List] :=
13711376
Module[{i=j=n=Apply[Plus,shape],done,l,m,h=1,k,y,p=shape},

0 commit comments

Comments
 (0)