|
9 | 9 | import functools
|
10 | 10 | import itertools
|
11 | 11 |
|
12 |
| -def _inv(a: int, prime: int) -> int: |
13 |
| - """ |
14 |
| - Compute multiplicative inverse modulo a prime. |
15 |
| - """ |
16 |
| - return pow(a, prime - 2, prime) |
17 |
| - |
18 | 12 | def interpolate(
|
19 | 13 | points: Union[dict, Sequence[int], Iterable[Sequence[int]]],
|
20 | 14 | modulus: int,
|
21 | 15 | degree: Optional[int] = None
|
22 | 16 | ) -> int:
|
23 | 17 | """
|
24 | 18 | Determine the value at the origin of the domain (*e.g.*, where *x* = 0)
|
25 |
| - given a collection of points. The point information can be represented as |
26 |
| - a collection of two-component coordinates, as a dictionary, or as a sequence |
27 |
| - of values. |
| 19 | + given a collection of points. |
28 | 20 |
|
29 | 21 | :param points: Collection of points to interpolate.
|
30 | 22 | :param modulus: Modulus representing the finite field within which to interpolate.
|
31 | 23 | :param degree: Degree of the target polynomial.
|
32 | 24 |
|
| 25 | + The point information can be represented as a collection of two-component |
| 26 | + coordinates, as a dictionary, or as a sequence of values. |
| 27 | +
|
33 | 28 | >>> interpolate([(1, 15), (2, 9), (3, 3)], 17)
|
34 | 29 | 4
|
35 | 30 | >>> interpolate({1: 15, 2: 9, 3: 3}, 17)
|
@@ -158,6 +153,7 @@ def interpolate(
|
158 | 153 | ValueError: expecting a nonnegative integer degree
|
159 | 154 | """
|
160 | 155 | # pylint: disable=too-many-branches # Allow large number of branches for type checking.
|
| 156 | + # pylint: disable=unnecessary-lambda-assignment # Allow small local functions. |
161 | 157 | values = None # Initially, assume that the supplied point data is not valid.
|
162 | 158 |
|
163 | 159 | if isinstance(points, dict):
|
@@ -224,8 +220,9 @@ def interpolate(
|
224 | 220 | xs = list(values.keys())[:degree + 1]
|
225 | 221 |
|
226 | 222 | # Field arithmetic helper functions.
|
227 |
| - mul = lambda a, b: (a % modulus) * b % modulus # pylint: disable=unnecessary-lambda-assignment |
228 |
| - div = lambda a, b: mul(a, _inv(b, modulus)) # pylint: disable=unnecessary-lambda-assignment |
| 223 | + inv = lambda a, p: pow(a, p - 2, p) |
| 224 | + mul = lambda a, b: ((a % modulus) * b) % modulus |
| 225 | + div = lambda a, b: mul(a, inv(b, modulus)) |
229 | 226 |
|
230 | 227 | # Compute the value of each unique Lagrange basis polynomial at ``0``,
|
231 | 228 | # then sum them all up to get the resulting value at ``0``.
|
|
0 commit comments