|
5 | 5 |
|
6 | 6 |
|
7 | 7 | import math |
8 | | -from functools import lru_cache |
9 | 8 | from sympy.functions.combinatorial.numbers import stirling |
10 | 9 | from mathics.version import __version__ # noqa used in loading to check consistency. |
11 | 10 |
|
@@ -102,62 +101,6 @@ class Fibonacci(_MPMathFunction): |
102 | 101 | sympy_name = "fibonacci" |
103 | 102 | mpmath_name = "fibonacci" |
104 | 103 |
|
105 | | -# Note: memoizing functions is a big win. For a value of n, more than |
106 | | -# n different values (positive and negative) occur. |
107 | | -# For this function to be effective across top-level calls, |
108 | | -# it needs to be at the module level rather than inside the class. |
109 | | -# Finally, docs say that `maxsize` is best at a power of 2. |
110 | | -# With 1024 we can handle reasonably values of slightly greater than 1024 |
111 | | -# values without trouble: |
112 | | -# PartitionsP[1070] = 366665450770488753893927654278831 |
113 | | -@lru_cache(maxsize=1024) |
114 | | -def number_of_partitions(n: int) -> int: |
115 | | - """Algorithm NumberOfPartitions from Page 67 of Skiena: Implementing |
116 | | - Discrete Mathematics, using Euler's recurrence""" |
117 | | - if n < 0: |
118 | | - return 0 |
119 | | - elif n == 0: |
120 | | - return 1 |
121 | | - sum = 0 |
122 | | - for m in range(math.ceil((1 + math.sqrt(1.0 + 24 * n)) / 6), 0, -1): |
123 | | - mx3 = m * 3 |
124 | | - j = n - m * (mx3 - 1) / 2 |
125 | | - k = n - m * (mx3 + 1) / 2 |
126 | | - # Cut down on memoization by filtering negative numbers here. |
127 | | - # In contrast to the multitude of negative numbers, the n==0 |
128 | | - # case isn't worth saving memoization checking since that is |
129 | | - # one single entry. |
130 | | - part_j = 0 if j < 0 else number_of_partitions(j) |
131 | | - part_k = 0 if k < 0 else number_of_partitions(k) |
132 | | - if m % 2: |
133 | | - sum += part_j + part_k |
134 | | - else: |
135 | | - sum += -part_j - part_k |
136 | | - return sum |
137 | | - |
138 | | -class PartitionsP(Builtin): |
139 | | - """ |
140 | | - <dl> |
141 | | - <dt>'PartitionsP[$n$]' |
142 | | - <dd>return the number p(n) of unrestricted partitions of the integer $n$. |
143 | | - </dl> |
144 | | -
|
145 | | - >> Table[PartitionsP[k], {k, -2, 12}] |
146 | | - = {0, 0, 1, 1, 2, 3, 5, 7, 11, 15, 22, 30, 42, 56, 77} |
147 | | - """ |
148 | | - |
149 | | - attributes = ("Listable", "NumericFunction", "Orderless") |
150 | | - |
151 | | - def apply(self, n, evaluation): |
152 | | - "PartitionsP[n_Integer]" |
153 | | - |
154 | | - return Integer(number_of_partitions(n.get_int_value())) |
155 | | - |
156 | | - # Simpler but inefficient. |
157 | | - # from sympy.utilities.iterables import partitions |
158 | | - # return Integer(len(list(partitions(n.get_int_value())))) |
159 | | - |
160 | | - |
161 | 104 | class _NoBoolVector(Exception): |
162 | 105 | pass |
163 | 106 |
|
|
0 commit comments