Skip to content

Commit df2f56c

Browse files
authored
Merge pull request #30870 from Rishabh-git10/enh-polyvalnd
ENH: Add N-D evaluation (valnd) to polynomial module
2 parents 71030b8 + 89f6071 commit df2f56c

20 files changed

Lines changed: 515 additions & 6 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Added N-D evaluation functions to the polynomial package
2+
--------------------------------------------------------
3+
New functions ``polyvalnd``, ``chebvalnd``, ``legvalnd``, ``hermvalnd``,
4+
``hermevalnd``, and ``lagvalnd`` have been added to evaluate polynomials
5+
in arbitrary dimensions, analogous to the existing 2D and 3D evaluators.

numpy/polynomial/_polytypes.pyi

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,51 @@ class _FuncVal3D(Protocol):
293293
c: _SeriesLikeCoef_co,
294294
) -> _SupportsCoefOps[Any]: ...
295295

296+
@type_check_only
297+
class _FuncValND(Protocol):
298+
@overload
299+
def __call__(
300+
self,
301+
/,
302+
pts: Sequence[_FloatLike_co],
303+
c: _SeriesLikeFloat_co,
304+
) -> np.floating: ...
305+
@overload
306+
def __call__(
307+
self,
308+
/,
309+
pts: Sequence[_NumberLike_co],
310+
c: _SeriesLikeComplex_co,
311+
) -> np.complexfloating: ...
312+
@overload
313+
def __call__(
314+
self,
315+
/,
316+
pts: Sequence[_ArrayLikeFloat_co],
317+
c: _ArrayLikeFloat_co,
318+
) -> _FloatArray: ...
319+
@overload
320+
def __call__(
321+
self,
322+
/,
323+
pts: Sequence[_ArrayLikeComplex_co],
324+
c: _ArrayLikeComplex_co,
325+
) -> _ComplexArray: ...
326+
@overload
327+
def __call__(
328+
self,
329+
/,
330+
pts: Sequence[_ArrayLikeCoef_co],
331+
c: _ArrayLikeCoef_co,
332+
) -> _ObjectArray: ...
333+
@overload
334+
def __call__(
335+
self,
336+
/,
337+
pts: Sequence[_CoefLike_co],
338+
c: _SeriesLikeCoef_co,
339+
) -> _SupportsCoefOps[Any]: ...
340+
296341
@type_check_only
297342
class _FuncVander(Protocol):
298343
@overload

numpy/polynomial/chebyshev.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
chebval
4545
chebval2d
4646
chebval3d
47+
chebvalnd
4748
chebgrid2d
4849
chebgrid3d
4950
@@ -117,7 +118,7 @@
117118
'chebsub', 'chebmulx', 'chebmul', 'chebdiv', 'chebpow', 'chebval',
118119
'chebder', 'chebint', 'cheb2poly', 'poly2cheb', 'chebfromroots',
119120
'chebvander', 'chebfit', 'chebtrim', 'chebroots', 'chebpts1',
120-
'chebpts2', 'Chebyshev', 'chebval2d', 'chebval3d', 'chebgrid2d',
121+
'chebpts2', 'Chebyshev', 'chebval2d', 'chebval3d', 'chebvalnd', 'chebgrid2d',
121122
'chebgrid3d', 'chebvander2d', 'chebvander3d', 'chebcompanion',
122123
'chebgauss', 'chebweight', 'chebinterpolate']
123124

@@ -1301,6 +1302,57 @@ def chebval3d(x, y, z, c):
13011302
return pu._valnd(chebval, c, x, y, z)
13021303

13031304

1305+
def chebvalnd(pts, c):
1306+
r"""
1307+
Evaluate an N-D Chebyshev series at points.
1308+
1309+
This function returns the values:
1310+
1311+
.. math::
1312+
p(pts, c) = \sum_{i_1, i_2, \dots, i_n}
1313+
c_{i_1, i_2, \dots, i_n} * T_{i_1}(x_1) * T_{i_2}(x_2) \dots T_{i_n}(x_n)
1314+
1315+
where :math:`x_1, x_2, \dots, x_n = pts`.
1316+
Note that `pts` may also be an `(n, m)` array.
1317+
1318+
The parameters in `pts` are converted to arrays only if they are
1319+
tuples or lists, otherwise they are treated as scalars and
1320+
they must have the same shape after conversion. In either case, either
1321+
the elements of `pts` or their elements must support multiplication and
1322+
addition both with themselves and with the elements of `c`.
1323+
1324+
If `c` has fewer than N dimensions, ones are implicitly appended to its
1325+
shape to make it N-D. The shape of the result will be c.shape[N:] +
1326+
pts[0].shape.
1327+
1328+
Parameters
1329+
----------
1330+
pts : tuple or list of array_like, compatible objects
1331+
The N-dimensional series is evaluated at the points
1332+
``(x_1, x_2, ..., x_n)`` provided in the `pts` iterable, where
1333+
all elements must have the same shape. If any element is a list
1334+
or tuple, it is first converted to an ndarray, otherwise it is
1335+
left unchanged and if it isn't an ndarray it is treated as a scalar.
1336+
c : array_like
1337+
Array of coefficients ordered so that the coefficient of the term of
1338+
multi-degree i,j,k,... is contained in ``c[i,j,k,...]``. If `c` has
1339+
dimension greater than N, the remaining indices enumerate multiple
1340+
sets of coefficients.
1341+
1342+
Returns
1343+
-------
1344+
values : ndarray, compatible object
1345+
The values of the multidimensional Chebyshev series on points formed
1346+
with N-tuples of corresponding values from `pts`.
1347+
1348+
See Also
1349+
--------
1350+
chebval, chebval2d, chebval3d
1351+
1352+
"""
1353+
return pu._valnd(chebval, c, *pts)
1354+
1355+
13041356
def chebgrid3d(x, y, z, c):
13051357
"""
13061358
Evaluate a 3-D Chebyshev series on the Cartesian product of x, y, and z.

numpy/polynomial/chebyshev.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ from ._polytypes import (
2626
_FuncVal,
2727
_FuncVal2D,
2828
_FuncVal3D,
29+
_FuncValND,
2930
_FuncVander,
3031
_FuncVander2D,
3132
_FuncVander3D,
@@ -62,6 +63,7 @@ __all__ = [
6263
"Chebyshev",
6364
"chebval2d",
6465
"chebval3d",
66+
"chebvalnd",
6567
"chebgrid2d",
6668
"chebgrid3d",
6769
"chebvander2d",
@@ -102,6 +104,7 @@ chebint: Final[_FuncInteg] = ...
102104
chebval: Final[_FuncVal] = ...
103105
chebval2d: Final[_FuncVal2D] = ...
104106
chebval3d: Final[_FuncVal3D] = ...
107+
chebvalnd: Final[_FuncValND] = ...
105108
chebgrid2d: Final[_FuncVal2D] = ...
106109
chebgrid3d: Final[_FuncVal3D] = ...
107110
chebvander: Final[_FuncVander] = ...

numpy/polynomial/hermite.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
hermval
4141
hermval2d
4242
hermval3d
43+
hermvalnd
4344
hermgrid2d
4445
hermgrid3d
4546
@@ -85,7 +86,7 @@
8586
'hermsub', 'hermmulx', 'hermmul', 'hermdiv', 'hermpow', 'hermval',
8687
'hermder', 'hermint', 'herm2poly', 'poly2herm', 'hermfromroots',
8788
'hermvander', 'hermfit', 'hermtrim', 'hermroots', 'Hermite',
88-
'hermval2d', 'hermval3d', 'hermgrid2d', 'hermgrid3d', 'hermvander2d',
89+
'hermval2d', 'hermval3d', 'hermvalnd', 'hermgrid2d', 'hermgrid3d', 'hermvander2d',
8990
'hermvander3d', 'hermcompanion', 'hermgauss', 'hermweight']
9091

9192
hermtrim = pu.trimcoef
@@ -1056,6 +1057,57 @@ def hermval3d(x, y, z, c):
10561057
return pu._valnd(hermval, c, x, y, z)
10571058

10581059

1060+
def hermvalnd(pts, c):
1061+
r"""
1062+
Evaluate an N-D Hermite series at points.
1063+
1064+
This function returns the values:
1065+
1066+
.. math::
1067+
p(pts, c) = \sum_{i_1, i_2, \dots, i_n}
1068+
c_{i_1, i_2, \dots, i_n} * H_{i_1}(x_1) * H_{i_2}(x_2) \dots H_{i_n}(x_n)
1069+
1070+
where :math:`x_1, x_2, \dots, x_n = pts`.
1071+
Note that `pts` may also be an `(n, m)` array.
1072+
1073+
The parameters in `pts` are converted to arrays only if they are
1074+
tuples or lists, otherwise they are treated as scalars and
1075+
they must have the same shape after conversion. In either case, either
1076+
the elements of `pts` or their elements must support multiplication and
1077+
addition both with themselves and with the elements of `c`.
1078+
1079+
If `c` has fewer than N dimensions, ones are implicitly appended to its
1080+
shape to make it N-D. The shape of the result will be c.shape[N:] +
1081+
pts[0].shape.
1082+
1083+
Parameters
1084+
----------
1085+
pts : tuple or list of array_like, compatible objects
1086+
The N-dimensional series is evaluated at the points
1087+
``(x_1, x_2, ..., x_n)`` provided in the `pts` iterable, where
1088+
all elements must have the same shape. If any element is a list
1089+
or tuple, it is first converted to an ndarray, otherwise it is
1090+
left unchanged and if it isn't an ndarray it is treated as a scalar.
1091+
c : array_like
1092+
Array of coefficients ordered so that the coefficient of the term of
1093+
multi-degree i,j,k,... is contained in ``c[i,j,k,...]``. If `c` has
1094+
dimension greater than N, the remaining indices enumerate multiple
1095+
sets of coefficients.
1096+
1097+
Returns
1098+
-------
1099+
values : ndarray, compatible object
1100+
The values of the multidimensional polynomial on points formed with
1101+
N-tuples of corresponding values from `pts`.
1102+
1103+
See Also
1104+
--------
1105+
hermval, hermval2d, hermval3d
1106+
1107+
"""
1108+
return pu._valnd(hermval, c, *pts)
1109+
1110+
10591111
def hermgrid3d(x, y, z, c):
10601112
"""
10611113
Evaluate a 3-D Hermite series on the Cartesian product of x, y, and z.

numpy/polynomial/hermite.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ from ._polytypes import (
2222
_FuncVal,
2323
_FuncVal2D,
2424
_FuncVal3D,
25+
_FuncValND,
2526
_FuncVander,
2627
_FuncVander2D,
2728
_FuncVander3D,
@@ -54,6 +55,7 @@ __all__ = [
5455
"Hermite",
5556
"hermval2d",
5657
"hermval3d",
58+
"hermvalnd",
5759
"hermgrid2d",
5860
"hermgrid3d",
5961
"hermvander2d",
@@ -84,6 +86,7 @@ hermint: Final[_FuncInteg] = ...
8486
hermval: Final[_FuncVal] = ...
8587
hermval2d: Final[_FuncVal2D] = ...
8688
hermval3d: Final[_FuncVal3D] = ...
89+
hermvalnd: Final[_FuncValND] = ...
8790
hermgrid2d: Final[_FuncVal2D] = ...
8891
hermgrid3d: Final[_FuncVal3D] = ...
8992
hermvander: Final[_FuncVander] = ...

numpy/polynomial/hermite_e.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
hermeval
4141
hermeval2d
4242
hermeval3d
43+
hermevalnd
4344
hermegrid2d
4445
hermegrid3d
4546
@@ -85,7 +86,7 @@
8586
'hermeadd', 'hermesub', 'hermemulx', 'hermemul', 'hermediv',
8687
'hermepow', 'hermeval', 'hermeder', 'hermeint', 'herme2poly',
8788
'poly2herme', 'hermefromroots', 'hermevander', 'hermefit', 'hermetrim',
88-
'hermeroots', 'HermiteE', 'hermeval2d', 'hermeval3d', 'hermegrid2d',
89+
'hermeroots', 'HermiteE', 'hermeval2d', 'hermeval3d', 'hermevalnd', 'hermegrid2d',
8990
'hermegrid3d', 'hermevander2d', 'hermevander3d', 'hermecompanion',
9091
'hermegauss', 'hermeweight']
9192

@@ -1020,6 +1021,57 @@ def hermeval3d(x, y, z, c):
10201021
return pu._valnd(hermeval, c, x, y, z)
10211022

10221023

1024+
def hermevalnd(pts, c):
1025+
r"""
1026+
Evaluate an N-D Hermite_e series at points.
1027+
1028+
This function returns the values:
1029+
1030+
.. math::
1031+
p(pts, c) = \sum_{i_1, i_2, \dots, i_n}
1032+
c_{i_1, i_2, \dots, i_n} * He_{i_1}(x_1) * He_{i_2}(x_2) \dots He_{i_n}(x_n)
1033+
1034+
where :math:`x_1, x_2, \dots, x_n = pts`.
1035+
Note that `pts` may also be an `(n, m)` array.
1036+
1037+
The parameters in `pts` are converted to arrays only if they are
1038+
tuples or lists, otherwise they are treated as scalars and
1039+
they must have the same shape after conversion. In either case, either
1040+
the elements of `pts` or their elements must support multiplication and
1041+
addition both with themselves and with the elements of `c`.
1042+
1043+
If `c` has fewer than N dimensions, ones are implicitly appended to its
1044+
shape to make it N-D. The shape of the result will be c.shape[N:] +
1045+
pts[0].shape.
1046+
1047+
Parameters
1048+
----------
1049+
pts : tuple or list of array_like, compatible objects
1050+
The N-dimensional series is evaluated at the points
1051+
``(x_1, x_2, ..., x_n)`` provided in the `pts` iterable, where
1052+
all elements must have the same shape. If any element is a list
1053+
or tuple, it is first converted to an ndarray, otherwise it is
1054+
left unchanged and if it isn't an ndarray it is treated as a scalar.
1055+
c : array_like
1056+
Array of coefficients ordered so that the coefficient of the term of
1057+
multi-degree i,j,k,... is contained in ``c[i,j,k,...]``. If `c` has
1058+
dimension greater than N, the remaining indices enumerate multiple
1059+
sets of coefficients.
1060+
1061+
Returns
1062+
-------
1063+
values : ndarray, compatible object
1064+
The values of the multidimensional polynomial on points formed with
1065+
N-tuples of corresponding values from `pts`.
1066+
1067+
See Also
1068+
--------
1069+
hermeval, hermeval2d, hermeval3d
1070+
1071+
"""
1072+
return pu._valnd(hermeval, c, *pts)
1073+
1074+
10231075
def hermegrid3d(x, y, z, c):
10241076
"""
10251077
Evaluate a 3-D HermiteE series on the Cartesian product of x, y, and z.

numpy/polynomial/hermite_e.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ from ._polytypes import (
2222
_FuncVal,
2323
_FuncVal2D,
2424
_FuncVal3D,
25+
_FuncValND,
2526
_FuncVander,
2627
_FuncVander2D,
2728
_FuncVander3D,
@@ -54,6 +55,7 @@ __all__ = [
5455
"HermiteE",
5556
"hermeval2d",
5657
"hermeval3d",
58+
"hermevalnd",
5759
"hermegrid2d",
5860
"hermegrid3d",
5961
"hermevander2d",
@@ -84,6 +86,7 @@ hermeint: Final[_FuncInteg] = ...
8486
hermeval: Final[_FuncVal] = ...
8587
hermeval2d: Final[_FuncVal2D] = ...
8688
hermeval3d: Final[_FuncVal3D] = ...
89+
hermevalnd: Final[_FuncValND] = ...
8790
hermegrid2d: Final[_FuncVal2D] = ...
8891
hermegrid3d: Final[_FuncVal3D] = ...
8992
hermevander: Final[_FuncVander] = ...

0 commit comments

Comments
 (0)