Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- lib/python3.12/site-packages/cloudpickle/__init__.py +18 -0
- lib/python3.12/site-packages/cloudpickle/__pycache__/__init__.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/cloudpickle/__pycache__/cloudpickle.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/cloudpickle/__pycache__/cloudpickle_fast.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/cloudpickle/cloudpickle.py +1552 -0
- lib/python3.12/site-packages/cloudpickle/cloudpickle_fast.py +14 -0
- lib/python3.12/site-packages/ninja-1.13.0.dist-info/INSTALLER +1 -0
- lib/python3.12/site-packages/ninja-1.13.0.dist-info/METADATA +102 -0
- lib/python3.12/site-packages/ninja-1.13.0.dist-info/RECORD +18 -0
- lib/python3.12/site-packages/ninja-1.13.0.dist-info/WHEEL +6 -0
- lib/python3.12/site-packages/ninja-1.13.0.dist-info/licenses/AUTHORS.rst +5 -0
- lib/python3.12/site-packages/ninja-1.13.0.dist-info/licenses/LICENSE_Apache_20 +191 -0
- lib/python3.12/site-packages/numpy/__config__.py +162 -0
- lib/python3.12/site-packages/numpy/__init__.cython-30.pxd +1050 -0
- lib/python3.12/site-packages/numpy/__init__.pxd +1015 -0
- lib/python3.12/site-packages/numpy/__init__.py +461 -0
- lib/python3.12/site-packages/numpy/__init__.pyi +0 -0
- lib/python3.12/site-packages/numpy/_distributor_init.py +15 -0
- lib/python3.12/site-packages/numpy/_globals.py +95 -0
- lib/python3.12/site-packages/numpy/_pytesttester.py +207 -0
- lib/python3.12/site-packages/numpy/_pytesttester.pyi +18 -0
- lib/python3.12/site-packages/numpy/conftest.py +138 -0
- lib/python3.12/site-packages/numpy/ctypeslib.py +545 -0
- lib/python3.12/site-packages/numpy/ctypeslib.pyi +251 -0
- lib/python3.12/site-packages/numpy/dtypes.py +77 -0
- lib/python3.12/site-packages/numpy/dtypes.pyi +43 -0
- lib/python3.12/site-packages/numpy/exceptions.py +231 -0
- lib/python3.12/site-packages/numpy/exceptions.pyi +18 -0
- lib/python3.12/site-packages/numpy/matlib.py +378 -0
- lib/python3.12/site-packages/numpy/polynomial/__init__.py +185 -0
- lib/python3.12/site-packages/numpy/polynomial/__init__.pyi +22 -0
- lib/python3.12/site-packages/numpy/polynomial/_polybase.py +1206 -0
- lib/python3.12/site-packages/numpy/polynomial/_polybase.pyi +71 -0
- lib/python3.12/site-packages/numpy/polynomial/chebyshev.py +2082 -0
- lib/python3.12/site-packages/numpy/polynomial/chebyshev.pyi +51 -0
- lib/python3.12/site-packages/numpy/polynomial/hermite.py +1703 -0
- lib/python3.12/site-packages/numpy/polynomial/hermite.pyi +46 -0
- lib/python3.12/site-packages/numpy/polynomial/hermite_e.py +1695 -0
- lib/python3.12/site-packages/numpy/polynomial/hermite_e.pyi +46 -0
- lib/python3.12/site-packages/numpy/polynomial/laguerre.py +1651 -0
- lib/python3.12/site-packages/numpy/polynomial/laguerre.pyi +46 -0
- lib/python3.12/site-packages/numpy/polynomial/legendre.py +1664 -0
- lib/python3.12/site-packages/numpy/polynomial/legendre.pyi +46 -0
- lib/python3.12/site-packages/numpy/polynomial/polynomial.py +1542 -0
- lib/python3.12/site-packages/numpy/polynomial/polynomial.pyi +41 -0
- lib/python3.12/site-packages/numpy/polynomial/polyutils.py +789 -0
- lib/python3.12/site-packages/numpy/polynomial/polyutils.pyi +11 -0
- lib/python3.12/site-packages/numpy/polynomial/setup.py +10 -0
- lib/python3.12/site-packages/numpy/polynomial/tests/__init__.py +0 -0
- lib/python3.12/site-packages/numpy/polynomial/tests/__pycache__/test_classes.cpython-312.pyc +0 -0
lib/python3.12/site-packages/cloudpickle/__init__.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from . import cloudpickle
|
| 2 |
+
from .cloudpickle import * # noqa
|
| 3 |
+
|
| 4 |
+
__doc__ = cloudpickle.__doc__
|
| 5 |
+
|
| 6 |
+
__version__ = "3.1.2"
|
| 7 |
+
|
| 8 |
+
__all__ = [ # noqa
|
| 9 |
+
"__version__",
|
| 10 |
+
"Pickler",
|
| 11 |
+
"CloudPickler",
|
| 12 |
+
"dumps",
|
| 13 |
+
"loads",
|
| 14 |
+
"dump",
|
| 15 |
+
"load",
|
| 16 |
+
"register_pickle_by_value",
|
| 17 |
+
"unregister_pickle_by_value",
|
| 18 |
+
]
|
lib/python3.12/site-packages/cloudpickle/__pycache__/__init__.cpython-312.pyc
ADDED
|
Binary file (454 Bytes). View file
|
|
|
lib/python3.12/site-packages/cloudpickle/__pycache__/cloudpickle.cpython-312.pyc
ADDED
|
Binary file (55.6 kB). View file
|
|
|
lib/python3.12/site-packages/cloudpickle/__pycache__/cloudpickle_fast.cpython-312.pyc
ADDED
|
Binary file (646 Bytes). View file
|
|
|
lib/python3.12/site-packages/cloudpickle/cloudpickle.py
ADDED
|
@@ -0,0 +1,1552 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Pickler class to extend the standard pickle.Pickler functionality
|
| 2 |
+
|
| 3 |
+
The main objective is to make it natural to perform distributed computing on
|
| 4 |
+
clusters (such as PySpark, Dask, Ray...) with interactively defined code
|
| 5 |
+
(functions, classes, ...) written in notebooks or console.
|
| 6 |
+
|
| 7 |
+
In particular this pickler adds the following features:
|
| 8 |
+
- serialize interactively-defined or locally-defined functions, classes,
|
| 9 |
+
enums, typevars, lambdas and nested functions to compiled byte code;
|
| 10 |
+
- deal with some other non-serializable objects in an ad-hoc manner where
|
| 11 |
+
applicable.
|
| 12 |
+
|
| 13 |
+
This pickler is therefore meant to be used for the communication between short
|
| 14 |
+
lived Python processes running the same version of Python and libraries. In
|
| 15 |
+
particular, it is not meant to be used for long term storage of Python objects.
|
| 16 |
+
|
| 17 |
+
It does not include an unpickler, as standard Python unpickling suffices.
|
| 18 |
+
|
| 19 |
+
This module was extracted from the `cloud` package, developed by `PiCloud, Inc.
|
| 20 |
+
<https://web.archive.org/web/20140626004012/http://www.picloud.com/>`_.
|
| 21 |
+
|
| 22 |
+
Copyright (c) 2012-now, CloudPickle developers and contributors.
|
| 23 |
+
Copyright (c) 2012, Regents of the University of California.
|
| 24 |
+
Copyright (c) 2009 `PiCloud, Inc. <https://web.archive.org/web/20140626004012/http://www.picloud.com/>`_.
|
| 25 |
+
All rights reserved.
|
| 26 |
+
|
| 27 |
+
Redistribution and use in source and binary forms, with or without
|
| 28 |
+
modification, are permitted provided that the following conditions
|
| 29 |
+
are met:
|
| 30 |
+
* Redistributions of source code must retain the above copyright
|
| 31 |
+
notice, this list of conditions and the following disclaimer.
|
| 32 |
+
* Redistributions in binary form must reproduce the above copyright
|
| 33 |
+
notice, this list of conditions and the following disclaimer in the
|
| 34 |
+
documentation and/or other materials provided with the distribution.
|
| 35 |
+
* Neither the name of the University of California, Berkeley nor the
|
| 36 |
+
names of its contributors may be used to endorse or promote
|
| 37 |
+
products derived from this software without specific prior written
|
| 38 |
+
permission.
|
| 39 |
+
|
| 40 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 41 |
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| 42 |
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| 43 |
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| 44 |
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| 45 |
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
| 46 |
+
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
| 47 |
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
| 48 |
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
| 49 |
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
| 50 |
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 51 |
+
"""
|
| 52 |
+
|
| 53 |
+
import _collections_abc
|
| 54 |
+
from collections import ChainMap, OrderedDict
|
| 55 |
+
import abc
|
| 56 |
+
import builtins
|
| 57 |
+
import copyreg
|
| 58 |
+
import dataclasses
|
| 59 |
+
import dis
|
| 60 |
+
from enum import Enum
|
| 61 |
+
import io
|
| 62 |
+
import itertools
|
| 63 |
+
import logging
|
| 64 |
+
import opcode
|
| 65 |
+
import pickle
|
| 66 |
+
from pickle import _getattribute as _pickle_getattribute
|
| 67 |
+
import platform
|
| 68 |
+
import struct
|
| 69 |
+
import sys
|
| 70 |
+
import threading
|
| 71 |
+
import types
|
| 72 |
+
import typing
|
| 73 |
+
import uuid
|
| 74 |
+
import warnings
|
| 75 |
+
import weakref
|
| 76 |
+
|
| 77 |
+
# The following import is required to be imported in the cloudpickle
|
| 78 |
+
# namespace to be able to load pickle files generated with older versions of
|
| 79 |
+
# cloudpickle. See: tests/test_backward_compat.py
|
| 80 |
+
from types import CellType # noqa: F401
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
# cloudpickle is meant for inter process communication: we expect all
|
| 84 |
+
# communicating processes to run the same Python version hence we favor
|
| 85 |
+
# communication speed over compatibility:
|
| 86 |
+
DEFAULT_PROTOCOL = pickle.HIGHEST_PROTOCOL
|
| 87 |
+
|
| 88 |
+
# Names of modules whose resources should be treated as dynamic.
|
| 89 |
+
_PICKLE_BY_VALUE_MODULES = set()
|
| 90 |
+
|
| 91 |
+
# Track the provenance of reconstructed dynamic classes to make it possible to
|
| 92 |
+
# reconstruct instances from the matching singleton class definition when
|
| 93 |
+
# appropriate and preserve the usual "isinstance" semantics of Python objects.
|
| 94 |
+
_DYNAMIC_CLASS_TRACKER_BY_CLASS = weakref.WeakKeyDictionary()
|
| 95 |
+
_DYNAMIC_CLASS_TRACKER_BY_ID = weakref.WeakValueDictionary()
|
| 96 |
+
_DYNAMIC_CLASS_TRACKER_LOCK = threading.Lock()
|
| 97 |
+
|
| 98 |
+
PYPY = platform.python_implementation() == "PyPy"
|
| 99 |
+
|
| 100 |
+
builtin_code_type = None
|
| 101 |
+
if PYPY:
|
| 102 |
+
# builtin-code objects only exist in pypy
|
| 103 |
+
builtin_code_type = type(float.__new__.__code__)
|
| 104 |
+
|
| 105 |
+
_extract_code_globals_cache = weakref.WeakKeyDictionary()
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
def _get_or_create_tracker_id(class_def):
|
| 109 |
+
with _DYNAMIC_CLASS_TRACKER_LOCK:
|
| 110 |
+
class_tracker_id = _DYNAMIC_CLASS_TRACKER_BY_CLASS.get(class_def)
|
| 111 |
+
if class_tracker_id is None:
|
| 112 |
+
class_tracker_id = uuid.uuid4().hex
|
| 113 |
+
_DYNAMIC_CLASS_TRACKER_BY_CLASS[class_def] = class_tracker_id
|
| 114 |
+
_DYNAMIC_CLASS_TRACKER_BY_ID[class_tracker_id] = class_def
|
| 115 |
+
return class_tracker_id
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def _lookup_class_or_track(class_tracker_id, class_def):
|
| 119 |
+
if class_tracker_id is not None:
|
| 120 |
+
with _DYNAMIC_CLASS_TRACKER_LOCK:
|
| 121 |
+
class_def = _DYNAMIC_CLASS_TRACKER_BY_ID.setdefault(
|
| 122 |
+
class_tracker_id, class_def
|
| 123 |
+
)
|
| 124 |
+
_DYNAMIC_CLASS_TRACKER_BY_CLASS[class_def] = class_tracker_id
|
| 125 |
+
return class_def
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
def register_pickle_by_value(module):
|
| 129 |
+
"""Register a module to make its functions and classes picklable by value.
|
| 130 |
+
|
| 131 |
+
By default, functions and classes that are attributes of an importable
|
| 132 |
+
module are to be pickled by reference, that is relying on re-importing
|
| 133 |
+
the attribute from the module at load time.
|
| 134 |
+
|
| 135 |
+
If `register_pickle_by_value(module)` is called, all its functions and
|
| 136 |
+
classes are subsequently to be pickled by value, meaning that they can
|
| 137 |
+
be loaded in Python processes where the module is not importable.
|
| 138 |
+
|
| 139 |
+
This is especially useful when developing a module in a distributed
|
| 140 |
+
execution environment: restarting the client Python process with the new
|
| 141 |
+
source code is enough: there is no need to re-install the new version
|
| 142 |
+
of the module on all the worker nodes nor to restart the workers.
|
| 143 |
+
|
| 144 |
+
Note: this feature is considered experimental. See the cloudpickle
|
| 145 |
+
README.md file for more details and limitations.
|
| 146 |
+
"""
|
| 147 |
+
if not isinstance(module, types.ModuleType):
|
| 148 |
+
raise ValueError(f"Input should be a module object, got {str(module)} instead")
|
| 149 |
+
# In the future, cloudpickle may need a way to access any module registered
|
| 150 |
+
# for pickling by value in order to introspect relative imports inside
|
| 151 |
+
# functions pickled by value. (see
|
| 152 |
+
# https://github.com/cloudpipe/cloudpickle/pull/417#issuecomment-873684633).
|
| 153 |
+
# This access can be ensured by checking that module is present in
|
| 154 |
+
# sys.modules at registering time and assuming that it will still be in
|
| 155 |
+
# there when accessed during pickling. Another alternative would be to
|
| 156 |
+
# store a weakref to the module. Even though cloudpickle does not implement
|
| 157 |
+
# this introspection yet, in order to avoid a possible breaking change
|
| 158 |
+
# later, we still enforce the presence of module inside sys.modules.
|
| 159 |
+
if module.__name__ not in sys.modules:
|
| 160 |
+
raise ValueError(
|
| 161 |
+
f"{module} was not imported correctly, have you used an "
|
| 162 |
+
"`import` statement to access it?"
|
| 163 |
+
)
|
| 164 |
+
_PICKLE_BY_VALUE_MODULES.add(module.__name__)
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
def unregister_pickle_by_value(module):
|
| 168 |
+
"""Unregister that the input module should be pickled by value."""
|
| 169 |
+
if not isinstance(module, types.ModuleType):
|
| 170 |
+
raise ValueError(f"Input should be a module object, got {str(module)} instead")
|
| 171 |
+
if module.__name__ not in _PICKLE_BY_VALUE_MODULES:
|
| 172 |
+
raise ValueError(f"{module} is not registered for pickle by value")
|
| 173 |
+
else:
|
| 174 |
+
_PICKLE_BY_VALUE_MODULES.remove(module.__name__)
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
def list_registry_pickle_by_value():
|
| 178 |
+
return _PICKLE_BY_VALUE_MODULES.copy()
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
def _is_registered_pickle_by_value(module):
|
| 182 |
+
module_name = module.__name__
|
| 183 |
+
if module_name in _PICKLE_BY_VALUE_MODULES:
|
| 184 |
+
return True
|
| 185 |
+
while True:
|
| 186 |
+
parent_name = module_name.rsplit(".", 1)[0]
|
| 187 |
+
if parent_name == module_name:
|
| 188 |
+
break
|
| 189 |
+
if parent_name in _PICKLE_BY_VALUE_MODULES:
|
| 190 |
+
return True
|
| 191 |
+
module_name = parent_name
|
| 192 |
+
return False
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
if sys.version_info >= (3, 14):
|
| 196 |
+
def _getattribute(obj, name):
|
| 197 |
+
return _pickle_getattribute(obj, name.split('.'))
|
| 198 |
+
else:
|
| 199 |
+
def _getattribute(obj, name):
|
| 200 |
+
return _pickle_getattribute(obj, name)[0]
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
def _whichmodule(obj, name):
|
| 204 |
+
"""Find the module an object belongs to.
|
| 205 |
+
|
| 206 |
+
This function differs from ``pickle.whichmodule`` in two ways:
|
| 207 |
+
- it does not mangle the cases where obj's module is __main__ and obj was
|
| 208 |
+
not found in any module.
|
| 209 |
+
- Errors arising during module introspection are ignored, as those errors
|
| 210 |
+
are considered unwanted side effects.
|
| 211 |
+
"""
|
| 212 |
+
module_name = getattr(obj, "__module__", None)
|
| 213 |
+
|
| 214 |
+
if module_name is not None:
|
| 215 |
+
return module_name
|
| 216 |
+
# Protect the iteration by using a copy of sys.modules against dynamic
|
| 217 |
+
# modules that trigger imports of other modules upon calls to getattr or
|
| 218 |
+
# other threads importing at the same time.
|
| 219 |
+
for module_name, module in sys.modules.copy().items():
|
| 220 |
+
# Some modules such as coverage can inject non-module objects inside
|
| 221 |
+
# sys.modules
|
| 222 |
+
if (
|
| 223 |
+
module_name == "__main__"
|
| 224 |
+
or module_name == "__mp_main__"
|
| 225 |
+
or module is None
|
| 226 |
+
or not isinstance(module, types.ModuleType)
|
| 227 |
+
):
|
| 228 |
+
continue
|
| 229 |
+
try:
|
| 230 |
+
if _getattribute(module, name) is obj:
|
| 231 |
+
return module_name
|
| 232 |
+
except Exception:
|
| 233 |
+
pass
|
| 234 |
+
return None
|
| 235 |
+
|
| 236 |
+
|
| 237 |
+
def _should_pickle_by_reference(obj, name=None):
|
| 238 |
+
"""Test whether an function or a class should be pickled by reference
|
| 239 |
+
|
| 240 |
+
Pickling by reference means by that the object (typically a function or a
|
| 241 |
+
class) is an attribute of a module that is assumed to be importable in the
|
| 242 |
+
target Python environment. Loading will therefore rely on importing the
|
| 243 |
+
module and then calling `getattr` on it to access the function or class.
|
| 244 |
+
|
| 245 |
+
Pickling by reference is the only option to pickle functions and classes
|
| 246 |
+
in the standard library. In cloudpickle the alternative option is to
|
| 247 |
+
pickle by value (for instance for interactively or locally defined
|
| 248 |
+
functions and classes or for attributes of modules that have been
|
| 249 |
+
explicitly registered to be pickled by value.
|
| 250 |
+
"""
|
| 251 |
+
if isinstance(obj, types.FunctionType) or issubclass(type(obj), type):
|
| 252 |
+
module_and_name = _lookup_module_and_qualname(obj, name=name)
|
| 253 |
+
if module_and_name is None:
|
| 254 |
+
return False
|
| 255 |
+
module, name = module_and_name
|
| 256 |
+
return not _is_registered_pickle_by_value(module)
|
| 257 |
+
|
| 258 |
+
elif isinstance(obj, types.ModuleType):
|
| 259 |
+
# We assume that sys.modules is primarily used as a cache mechanism for
|
| 260 |
+
# the Python import machinery. Checking if a module has been added in
|
| 261 |
+
# is sys.modules therefore a cheap and simple heuristic to tell us
|
| 262 |
+
# whether we can assume that a given module could be imported by name
|
| 263 |
+
# in another Python process.
|
| 264 |
+
if _is_registered_pickle_by_value(obj):
|
| 265 |
+
return False
|
| 266 |
+
return obj.__name__ in sys.modules
|
| 267 |
+
else:
|
| 268 |
+
raise TypeError(
|
| 269 |
+
"cannot check importability of {} instances".format(type(obj).__name__)
|
| 270 |
+
)
|
| 271 |
+
|
| 272 |
+
|
| 273 |
+
def _lookup_module_and_qualname(obj, name=None):
|
| 274 |
+
if name is None:
|
| 275 |
+
name = getattr(obj, "__qualname__", None)
|
| 276 |
+
if name is None: # pragma: no cover
|
| 277 |
+
# This used to be needed for Python 2.7 support but is probably not
|
| 278 |
+
# needed anymore. However we keep the __name__ introspection in case
|
| 279 |
+
# users of cloudpickle rely on this old behavior for unknown reasons.
|
| 280 |
+
name = getattr(obj, "__name__", None)
|
| 281 |
+
|
| 282 |
+
module_name = _whichmodule(obj, name)
|
| 283 |
+
|
| 284 |
+
if module_name is None:
|
| 285 |
+
# In this case, obj.__module__ is None AND obj was not found in any
|
| 286 |
+
# imported module. obj is thus treated as dynamic.
|
| 287 |
+
return None
|
| 288 |
+
|
| 289 |
+
if module_name == "__main__":
|
| 290 |
+
return None
|
| 291 |
+
|
| 292 |
+
# Note: if module_name is in sys.modules, the corresponding module is
|
| 293 |
+
# assumed importable at unpickling time. See #357
|
| 294 |
+
module = sys.modules.get(module_name, None)
|
| 295 |
+
if module is None:
|
| 296 |
+
# The main reason why obj's module would not be imported is that this
|
| 297 |
+
# module has been dynamically created, using for example
|
| 298 |
+
# types.ModuleType. The other possibility is that module was removed
|
| 299 |
+
# from sys.modules after obj was created/imported. But this case is not
|
| 300 |
+
# supported, as the standard pickle does not support it either.
|
| 301 |
+
return None
|
| 302 |
+
|
| 303 |
+
try:
|
| 304 |
+
obj2 = _getattribute(module, name)
|
| 305 |
+
except AttributeError:
|
| 306 |
+
# obj was not found inside the module it points to
|
| 307 |
+
return None
|
| 308 |
+
if obj2 is not obj:
|
| 309 |
+
return None
|
| 310 |
+
return module, name
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
def _extract_code_globals(co):
|
| 314 |
+
"""Find all globals names read or written to by codeblock co."""
|
| 315 |
+
out_names = _extract_code_globals_cache.get(co)
|
| 316 |
+
if out_names is None:
|
| 317 |
+
# We use a dict with None values instead of a set to get a
|
| 318 |
+
# deterministic order and avoid introducing non-deterministic pickle
|
| 319 |
+
# bytes as a results.
|
| 320 |
+
out_names = {name: None for name in _walk_global_ops(co)}
|
| 321 |
+
|
| 322 |
+
# Declaring a function inside another one using the "def ..." syntax
|
| 323 |
+
# generates a constant code object corresponding to the one of the
|
| 324 |
+
# nested function's As the nested function may itself need global
|
| 325 |
+
# variables, we need to introspect its code, extract its globals, (look
|
| 326 |
+
# for code object in it's co_consts attribute..) and add the result to
|
| 327 |
+
# code_globals
|
| 328 |
+
if co.co_consts:
|
| 329 |
+
for const in co.co_consts:
|
| 330 |
+
if isinstance(const, types.CodeType):
|
| 331 |
+
out_names.update(_extract_code_globals(const))
|
| 332 |
+
|
| 333 |
+
_extract_code_globals_cache[co] = out_names
|
| 334 |
+
|
| 335 |
+
return out_names
|
| 336 |
+
|
| 337 |
+
|
| 338 |
+
def _find_imported_submodules(code, top_level_dependencies):
|
| 339 |
+
"""Find currently imported submodules used by a function.
|
| 340 |
+
|
| 341 |
+
Submodules used by a function need to be detected and referenced for the
|
| 342 |
+
function to work correctly at depickling time. Because submodules can be
|
| 343 |
+
referenced as attribute of their parent package (``package.submodule``), we
|
| 344 |
+
need a special introspection technique that does not rely on GLOBAL-related
|
| 345 |
+
opcodes to find references of them in a code object.
|
| 346 |
+
|
| 347 |
+
Example:
|
| 348 |
+
```
|
| 349 |
+
import concurrent.futures
|
| 350 |
+
import cloudpickle
|
| 351 |
+
def func():
|
| 352 |
+
x = concurrent.futures.ThreadPoolExecutor
|
| 353 |
+
if __name__ == '__main__':
|
| 354 |
+
cloudpickle.dumps(func)
|
| 355 |
+
```
|
| 356 |
+
The globals extracted by cloudpickle in the function's state include the
|
| 357 |
+
concurrent package, but not its submodule (here, concurrent.futures), which
|
| 358 |
+
is the module used by func. Find_imported_submodules will detect the usage
|
| 359 |
+
of concurrent.futures. Saving this module alongside with func will ensure
|
| 360 |
+
that calling func once depickled does not fail due to concurrent.futures
|
| 361 |
+
not being imported
|
| 362 |
+
"""
|
| 363 |
+
|
| 364 |
+
subimports = []
|
| 365 |
+
# check if any known dependency is an imported package
|
| 366 |
+
for x in top_level_dependencies:
|
| 367 |
+
if (
|
| 368 |
+
isinstance(x, types.ModuleType)
|
| 369 |
+
and hasattr(x, "__package__")
|
| 370 |
+
and x.__package__
|
| 371 |
+
):
|
| 372 |
+
# check if the package has any currently loaded sub-imports
|
| 373 |
+
prefix = x.__name__ + "."
|
| 374 |
+
# A concurrent thread could mutate sys.modules,
|
| 375 |
+
# make sure we iterate over a copy to avoid exceptions
|
| 376 |
+
for name in list(sys.modules):
|
| 377 |
+
# Older versions of pytest will add a "None" module to
|
| 378 |
+
# sys.modules.
|
| 379 |
+
if name is not None and name.startswith(prefix):
|
| 380 |
+
# check whether the function can address the sub-module
|
| 381 |
+
tokens = set(name[len(prefix) :].split("."))
|
| 382 |
+
if not tokens - set(code.co_names):
|
| 383 |
+
subimports.append(sys.modules[name])
|
| 384 |
+
return subimports
|
| 385 |
+
|
| 386 |
+
|
| 387 |
+
# relevant opcodes
|
| 388 |
+
STORE_GLOBAL = opcode.opmap["STORE_GLOBAL"]
|
| 389 |
+
DELETE_GLOBAL = opcode.opmap["DELETE_GLOBAL"]
|
| 390 |
+
LOAD_GLOBAL = opcode.opmap["LOAD_GLOBAL"]
|
| 391 |
+
GLOBAL_OPS = (STORE_GLOBAL, DELETE_GLOBAL, LOAD_GLOBAL)
|
| 392 |
+
HAVE_ARGUMENT = dis.HAVE_ARGUMENT
|
| 393 |
+
EXTENDED_ARG = dis.EXTENDED_ARG
|
| 394 |
+
|
| 395 |
+
|
| 396 |
+
_BUILTIN_TYPE_NAMES = {}
|
| 397 |
+
for k, v in types.__dict__.items():
|
| 398 |
+
if type(v) is type:
|
| 399 |
+
_BUILTIN_TYPE_NAMES[v] = k
|
| 400 |
+
|
| 401 |
+
|
| 402 |
+
def _builtin_type(name):
|
| 403 |
+
if name == "ClassType": # pragma: no cover
|
| 404 |
+
# Backward compat to load pickle files generated with cloudpickle
|
| 405 |
+
# < 1.3 even if loading pickle files from older versions is not
|
| 406 |
+
# officially supported.
|
| 407 |
+
return type
|
| 408 |
+
return getattr(types, name)
|
| 409 |
+
|
| 410 |
+
|
| 411 |
+
def _walk_global_ops(code):
|
| 412 |
+
"""Yield referenced name for global-referencing instructions in code."""
|
| 413 |
+
for instr in dis.get_instructions(code):
|
| 414 |
+
op = instr.opcode
|
| 415 |
+
if op in GLOBAL_OPS:
|
| 416 |
+
yield instr.argval
|
| 417 |
+
|
| 418 |
+
|
| 419 |
+
def _extract_class_dict(cls):
|
| 420 |
+
"""Retrieve a copy of the dict of a class without the inherited method."""
|
| 421 |
+
# Hack to circumvent non-predictable memoization caused by string interning.
|
| 422 |
+
# See the inline comment in _class_setstate for details.
|
| 423 |
+
clsdict = {"".join(k): cls.__dict__[k] for k in sorted(cls.__dict__)}
|
| 424 |
+
|
| 425 |
+
if len(cls.__bases__) == 1:
|
| 426 |
+
inherited_dict = cls.__bases__[0].__dict__
|
| 427 |
+
else:
|
| 428 |
+
inherited_dict = {}
|
| 429 |
+
for base in reversed(cls.__bases__):
|
| 430 |
+
inherited_dict.update(base.__dict__)
|
| 431 |
+
to_remove = []
|
| 432 |
+
for name, value in clsdict.items():
|
| 433 |
+
try:
|
| 434 |
+
base_value = inherited_dict[name]
|
| 435 |
+
if value is base_value:
|
| 436 |
+
to_remove.append(name)
|
| 437 |
+
except KeyError:
|
| 438 |
+
pass
|
| 439 |
+
for name in to_remove:
|
| 440 |
+
clsdict.pop(name)
|
| 441 |
+
return clsdict
|
| 442 |
+
|
| 443 |
+
|
| 444 |
+
def is_tornado_coroutine(func):
|
| 445 |
+
"""Return whether `func` is a Tornado coroutine function.
|
| 446 |
+
|
| 447 |
+
Running coroutines are not supported.
|
| 448 |
+
"""
|
| 449 |
+
warnings.warn(
|
| 450 |
+
"is_tornado_coroutine is deprecated in cloudpickle 3.0 and will be "
|
| 451 |
+
"removed in cloudpickle 4.0. Use tornado.gen.is_coroutine_function "
|
| 452 |
+
"directly instead.",
|
| 453 |
+
category=DeprecationWarning,
|
| 454 |
+
)
|
| 455 |
+
if "tornado.gen" not in sys.modules:
|
| 456 |
+
return False
|
| 457 |
+
gen = sys.modules["tornado.gen"]
|
| 458 |
+
if not hasattr(gen, "is_coroutine_function"):
|
| 459 |
+
# Tornado version is too old
|
| 460 |
+
return False
|
| 461 |
+
return gen.is_coroutine_function(func)
|
| 462 |
+
|
| 463 |
+
|
| 464 |
+
def subimport(name):
|
| 465 |
+
# We cannot do simply: `return __import__(name)`: Indeed, if ``name`` is
|
| 466 |
+
# the name of a submodule, __import__ will return the top-level root module
|
| 467 |
+
# of this submodule. For instance, __import__('os.path') returns the `os`
|
| 468 |
+
# module.
|
| 469 |
+
__import__(name)
|
| 470 |
+
return sys.modules[name]
|
| 471 |
+
|
| 472 |
+
|
| 473 |
+
def dynamic_subimport(name, vars):
|
| 474 |
+
mod = types.ModuleType(name)
|
| 475 |
+
mod.__dict__.update(vars)
|
| 476 |
+
mod.__dict__["__builtins__"] = builtins.__dict__
|
| 477 |
+
return mod
|
| 478 |
+
|
| 479 |
+
|
| 480 |
+
def _get_cell_contents(cell):
|
| 481 |
+
try:
|
| 482 |
+
return cell.cell_contents
|
| 483 |
+
except ValueError:
|
| 484 |
+
# Handle empty cells explicitly with a sentinel value.
|
| 485 |
+
return _empty_cell_value
|
| 486 |
+
|
| 487 |
+
|
| 488 |
+
def instance(cls):
|
| 489 |
+
"""Create a new instance of a class.
|
| 490 |
+
|
| 491 |
+
Parameters
|
| 492 |
+
----------
|
| 493 |
+
cls : type
|
| 494 |
+
The class to create an instance of.
|
| 495 |
+
|
| 496 |
+
Returns
|
| 497 |
+
-------
|
| 498 |
+
instance : cls
|
| 499 |
+
A new instance of ``cls``.
|
| 500 |
+
"""
|
| 501 |
+
return cls()
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
@instance
|
| 505 |
+
class _empty_cell_value:
|
| 506 |
+
"""Sentinel for empty closures."""
|
| 507 |
+
|
| 508 |
+
@classmethod
|
| 509 |
+
def __reduce__(cls):
|
| 510 |
+
return cls.__name__
|
| 511 |
+
|
| 512 |
+
|
| 513 |
+
def _make_function(code, globals, name, argdefs, closure):
|
| 514 |
+
# Setting __builtins__ in globals is needed for nogil CPython.
|
| 515 |
+
globals["__builtins__"] = __builtins__
|
| 516 |
+
return types.FunctionType(code, globals, name, argdefs, closure)
|
| 517 |
+
|
| 518 |
+
|
| 519 |
+
def _make_empty_cell():
|
| 520 |
+
if False:
|
| 521 |
+
# trick the compiler into creating an empty cell in our lambda
|
| 522 |
+
cell = None
|
| 523 |
+
raise AssertionError("this route should not be executed")
|
| 524 |
+
|
| 525 |
+
return (lambda: cell).__closure__[0]
|
| 526 |
+
|
| 527 |
+
|
| 528 |
+
def _make_cell(value=_empty_cell_value):
|
| 529 |
+
cell = _make_empty_cell()
|
| 530 |
+
if value is not _empty_cell_value:
|
| 531 |
+
cell.cell_contents = value
|
| 532 |
+
return cell
|
| 533 |
+
|
| 534 |
+
|
| 535 |
+
def _make_skeleton_class(
|
| 536 |
+
type_constructor, name, bases, type_kwargs, class_tracker_id, extra
|
| 537 |
+
):
|
| 538 |
+
"""Build dynamic class with an empty __dict__ to be filled once memoized
|
| 539 |
+
|
| 540 |
+
If class_tracker_id is not None, try to lookup an existing class definition
|
| 541 |
+
matching that id. If none is found, track a newly reconstructed class
|
| 542 |
+
definition under that id so that other instances stemming from the same
|
| 543 |
+
class id will also reuse this class definition.
|
| 544 |
+
|
| 545 |
+
The "extra" variable is meant to be a dict (or None) that can be used for
|
| 546 |
+
forward compatibility shall the need arise.
|
| 547 |
+
"""
|
| 548 |
+
# We need to intern the keys of the type_kwargs dict to avoid having
|
| 549 |
+
# different pickles for the same dynamic class depending on whether it was
|
| 550 |
+
# dynamically created or reconstructed from a pickled stream.
|
| 551 |
+
type_kwargs = {sys.intern(k): v for k, v in type_kwargs.items()}
|
| 552 |
+
|
| 553 |
+
skeleton_class = types.new_class(
|
| 554 |
+
name, bases, {"metaclass": type_constructor}, lambda ns: ns.update(type_kwargs)
|
| 555 |
+
)
|
| 556 |
+
|
| 557 |
+
return _lookup_class_or_track(class_tracker_id, skeleton_class)
|
| 558 |
+
|
| 559 |
+
|
| 560 |
+
def _make_skeleton_enum(
|
| 561 |
+
bases, name, qualname, members, module, class_tracker_id, extra
|
| 562 |
+
):
|
| 563 |
+
"""Build dynamic enum with an empty __dict__ to be filled once memoized
|
| 564 |
+
|
| 565 |
+
The creation of the enum class is inspired by the code of
|
| 566 |
+
EnumMeta._create_.
|
| 567 |
+
|
| 568 |
+
If class_tracker_id is not None, try to lookup an existing enum definition
|
| 569 |
+
matching that id. If none is found, track a newly reconstructed enum
|
| 570 |
+
definition under that id so that other instances stemming from the same
|
| 571 |
+
class id will also reuse this enum definition.
|
| 572 |
+
|
| 573 |
+
The "extra" variable is meant to be a dict (or None) that can be used for
|
| 574 |
+
forward compatibility shall the need arise.
|
| 575 |
+
"""
|
| 576 |
+
# enums always inherit from their base Enum class at the last position in
|
| 577 |
+
# the list of base classes:
|
| 578 |
+
enum_base = bases[-1]
|
| 579 |
+
metacls = enum_base.__class__
|
| 580 |
+
classdict = metacls.__prepare__(name, bases)
|
| 581 |
+
|
| 582 |
+
for member_name, member_value in members.items():
|
| 583 |
+
classdict[member_name] = member_value
|
| 584 |
+
enum_class = metacls.__new__(metacls, name, bases, classdict)
|
| 585 |
+
enum_class.__module__ = module
|
| 586 |
+
enum_class.__qualname__ = qualname
|
| 587 |
+
|
| 588 |
+
return _lookup_class_or_track(class_tracker_id, enum_class)
|
| 589 |
+
|
| 590 |
+
|
| 591 |
+
def _make_typevar(name, bound, constraints, covariant, contravariant, class_tracker_id):
|
| 592 |
+
tv = typing.TypeVar(
|
| 593 |
+
name,
|
| 594 |
+
*constraints,
|
| 595 |
+
bound=bound,
|
| 596 |
+
covariant=covariant,
|
| 597 |
+
contravariant=contravariant,
|
| 598 |
+
)
|
| 599 |
+
return _lookup_class_or_track(class_tracker_id, tv)
|
| 600 |
+
|
| 601 |
+
|
| 602 |
+
def _decompose_typevar(obj):
|
| 603 |
+
return (
|
| 604 |
+
obj.__name__,
|
| 605 |
+
obj.__bound__,
|
| 606 |
+
obj.__constraints__,
|
| 607 |
+
obj.__covariant__,
|
| 608 |
+
obj.__contravariant__,
|
| 609 |
+
_get_or_create_tracker_id(obj),
|
| 610 |
+
)
|
| 611 |
+
|
| 612 |
+
|
| 613 |
+
def _typevar_reduce(obj):
|
| 614 |
+
# TypeVar instances require the module information hence why we
|
| 615 |
+
# are not using the _should_pickle_by_reference directly
|
| 616 |
+
module_and_name = _lookup_module_and_qualname(obj, name=obj.__name__)
|
| 617 |
+
|
| 618 |
+
if module_and_name is None:
|
| 619 |
+
return (_make_typevar, _decompose_typevar(obj))
|
| 620 |
+
elif _is_registered_pickle_by_value(module_and_name[0]):
|
| 621 |
+
return (_make_typevar, _decompose_typevar(obj))
|
| 622 |
+
|
| 623 |
+
return (getattr, module_and_name)
|
| 624 |
+
|
| 625 |
+
|
| 626 |
+
def _get_bases(typ):
|
| 627 |
+
if "__orig_bases__" in getattr(typ, "__dict__", {}):
|
| 628 |
+
# For generic types (see PEP 560)
|
| 629 |
+
# Note that simply checking `hasattr(typ, '__orig_bases__')` is not
|
| 630 |
+
# correct. Subclasses of a fully-parameterized generic class does not
|
| 631 |
+
# have `__orig_bases__` defined, but `hasattr(typ, '__orig_bases__')`
|
| 632 |
+
# will return True because it's defined in the base class.
|
| 633 |
+
bases_attr = "__orig_bases__"
|
| 634 |
+
else:
|
| 635 |
+
# For regular class objects
|
| 636 |
+
bases_attr = "__bases__"
|
| 637 |
+
return getattr(typ, bases_attr)
|
| 638 |
+
|
| 639 |
+
|
| 640 |
+
def _make_dict_keys(obj, is_ordered=False):
|
| 641 |
+
if is_ordered:
|
| 642 |
+
return OrderedDict.fromkeys(obj).keys()
|
| 643 |
+
else:
|
| 644 |
+
return dict.fromkeys(obj).keys()
|
| 645 |
+
|
| 646 |
+
|
| 647 |
+
def _make_dict_values(obj, is_ordered=False):
|
| 648 |
+
if is_ordered:
|
| 649 |
+
return OrderedDict((i, _) for i, _ in enumerate(obj)).values()
|
| 650 |
+
else:
|
| 651 |
+
return {i: _ for i, _ in enumerate(obj)}.values()
|
| 652 |
+
|
| 653 |
+
|
| 654 |
+
def _make_dict_items(obj, is_ordered=False):
|
| 655 |
+
if is_ordered:
|
| 656 |
+
return OrderedDict(obj).items()
|
| 657 |
+
else:
|
| 658 |
+
return obj.items()
|
| 659 |
+
|
| 660 |
+
|
| 661 |
+
# COLLECTION OF OBJECTS __getnewargs__-LIKE METHODS
|
| 662 |
+
# -------------------------------------------------
|
| 663 |
+
|
| 664 |
+
|
| 665 |
+
def _class_getnewargs(obj):
|
| 666 |
+
type_kwargs = {}
|
| 667 |
+
if "__module__" in obj.__dict__:
|
| 668 |
+
type_kwargs["__module__"] = obj.__module__
|
| 669 |
+
|
| 670 |
+
__dict__ = obj.__dict__.get("__dict__", None)
|
| 671 |
+
if isinstance(__dict__, property):
|
| 672 |
+
type_kwargs["__dict__"] = __dict__
|
| 673 |
+
|
| 674 |
+
return (
|
| 675 |
+
type(obj),
|
| 676 |
+
obj.__name__,
|
| 677 |
+
_get_bases(obj),
|
| 678 |
+
type_kwargs,
|
| 679 |
+
_get_or_create_tracker_id(obj),
|
| 680 |
+
None,
|
| 681 |
+
)
|
| 682 |
+
|
| 683 |
+
|
| 684 |
+
def _enum_getnewargs(obj):
|
| 685 |
+
members = {e.name: e.value for e in obj}
|
| 686 |
+
return (
|
| 687 |
+
obj.__bases__,
|
| 688 |
+
obj.__name__,
|
| 689 |
+
obj.__qualname__,
|
| 690 |
+
members,
|
| 691 |
+
obj.__module__,
|
| 692 |
+
_get_or_create_tracker_id(obj),
|
| 693 |
+
None,
|
| 694 |
+
)
|
| 695 |
+
|
| 696 |
+
|
| 697 |
+
# COLLECTION OF OBJECTS RECONSTRUCTORS
|
| 698 |
+
# ------------------------------------
|
| 699 |
+
def _file_reconstructor(retval):
|
| 700 |
+
return retval
|
| 701 |
+
|
| 702 |
+
|
| 703 |
+
# COLLECTION OF OBJECTS STATE GETTERS
|
| 704 |
+
# -----------------------------------
|
| 705 |
+
|
| 706 |
+
|
| 707 |
+
def _function_getstate(func):
|
| 708 |
+
# - Put func's dynamic attributes (stored in func.__dict__) in state. These
|
| 709 |
+
# attributes will be restored at unpickling time using
|
| 710 |
+
# f.__dict__.update(state)
|
| 711 |
+
# - Put func's members into slotstate. Such attributes will be restored at
|
| 712 |
+
# unpickling time by iterating over slotstate and calling setattr(func,
|
| 713 |
+
# slotname, slotvalue)
|
| 714 |
+
slotstate = {
|
| 715 |
+
# Hack to circumvent non-predictable memoization caused by string interning.
|
| 716 |
+
# See the inline comment in _class_setstate for details.
|
| 717 |
+
"__name__": "".join(func.__name__),
|
| 718 |
+
"__qualname__": "".join(func.__qualname__),
|
| 719 |
+
"__annotations__": func.__annotations__,
|
| 720 |
+
"__kwdefaults__": func.__kwdefaults__,
|
| 721 |
+
"__defaults__": func.__defaults__,
|
| 722 |
+
"__module__": func.__module__,
|
| 723 |
+
"__doc__": func.__doc__,
|
| 724 |
+
"__closure__": func.__closure__,
|
| 725 |
+
}
|
| 726 |
+
|
| 727 |
+
f_globals_ref = _extract_code_globals(func.__code__)
|
| 728 |
+
f_globals = {k: func.__globals__[k] for k in f_globals_ref if k in func.__globals__}
|
| 729 |
+
|
| 730 |
+
if func.__closure__ is not None:
|
| 731 |
+
closure_values = list(map(_get_cell_contents, func.__closure__))
|
| 732 |
+
else:
|
| 733 |
+
closure_values = ()
|
| 734 |
+
|
| 735 |
+
# Extract currently-imported submodules used by func. Storing these modules
|
| 736 |
+
# in a smoke _cloudpickle_subimports attribute of the object's state will
|
| 737 |
+
# trigger the side effect of importing these modules at unpickling time
|
| 738 |
+
# (which is necessary for func to work correctly once depickled)
|
| 739 |
+
slotstate["_cloudpickle_submodules"] = _find_imported_submodules(
|
| 740 |
+
func.__code__, itertools.chain(f_globals.values(), closure_values)
|
| 741 |
+
)
|
| 742 |
+
slotstate["__globals__"] = f_globals
|
| 743 |
+
|
| 744 |
+
# Hack to circumvent non-predictable memoization caused by string interning.
|
| 745 |
+
# See the inline comment in _class_setstate for details.
|
| 746 |
+
state = {"".join(k): v for k, v in func.__dict__.items()}
|
| 747 |
+
return state, slotstate
|
| 748 |
+
|
| 749 |
+
|
| 750 |
+
def _class_getstate(obj):
|
| 751 |
+
clsdict = _extract_class_dict(obj)
|
| 752 |
+
clsdict.pop("__weakref__", None)
|
| 753 |
+
|
| 754 |
+
if issubclass(type(obj), abc.ABCMeta):
|
| 755 |
+
# If obj is an instance of an ABCMeta subclass, don't pickle the
|
| 756 |
+
# cache/negative caches populated during isinstance/issubclass
|
| 757 |
+
# checks, but pickle the list of registered subclasses of obj.
|
| 758 |
+
clsdict.pop("_abc_cache", None)
|
| 759 |
+
clsdict.pop("_abc_negative_cache", None)
|
| 760 |
+
clsdict.pop("_abc_negative_cache_version", None)
|
| 761 |
+
registry = clsdict.pop("_abc_registry", None)
|
| 762 |
+
if registry is None:
|
| 763 |
+
# The abc caches and registered subclasses of a
|
| 764 |
+
# class are bundled into the single _abc_impl attribute
|
| 765 |
+
clsdict.pop("_abc_impl", None)
|
| 766 |
+
(registry, _, _, _) = abc._get_dump(obj)
|
| 767 |
+
|
| 768 |
+
clsdict["_abc_impl"] = [subclass_weakref() for subclass_weakref in registry]
|
| 769 |
+
else:
|
| 770 |
+
# In the above if clause, registry is a set of weakrefs -- in
|
| 771 |
+
# this case, registry is a WeakSet
|
| 772 |
+
clsdict["_abc_impl"] = [type_ for type_ in registry]
|
| 773 |
+
|
| 774 |
+
if "__slots__" in clsdict:
|
| 775 |
+
# pickle string length optimization: member descriptors of obj are
|
| 776 |
+
# created automatically from obj's __slots__ attribute, no need to
|
| 777 |
+
# save them in obj's state
|
| 778 |
+
if isinstance(obj.__slots__, str):
|
| 779 |
+
clsdict.pop(obj.__slots__)
|
| 780 |
+
else:
|
| 781 |
+
for k in obj.__slots__:
|
| 782 |
+
clsdict.pop(k, None)
|
| 783 |
+
|
| 784 |
+
clsdict.pop("__dict__", None) # unpicklable property object
|
| 785 |
+
|
| 786 |
+
if sys.version_info >= (3, 14):
|
| 787 |
+
# PEP-649/749: __annotate_func__ contains a closure that references the class
|
| 788 |
+
# dict. We need to exclude it from pickling. Python will recreate it when
|
| 789 |
+
# __annotations__ is accessed at unpickling time.
|
| 790 |
+
clsdict.pop("__annotate_func__", None)
|
| 791 |
+
|
| 792 |
+
return (clsdict, {})
|
| 793 |
+
|
| 794 |
+
|
| 795 |
+
def _enum_getstate(obj):
|
| 796 |
+
clsdict, slotstate = _class_getstate(obj)
|
| 797 |
+
|
| 798 |
+
members = {e.name: e.value for e in obj}
|
| 799 |
+
# Cleanup the clsdict that will be passed to _make_skeleton_enum:
|
| 800 |
+
# Those attributes are already handled by the metaclass.
|
| 801 |
+
for attrname in [
|
| 802 |
+
"_generate_next_value_",
|
| 803 |
+
"_member_names_",
|
| 804 |
+
"_member_map_",
|
| 805 |
+
"_member_type_",
|
| 806 |
+
"_value2member_map_",
|
| 807 |
+
]:
|
| 808 |
+
clsdict.pop(attrname, None)
|
| 809 |
+
for member in members:
|
| 810 |
+
clsdict.pop(member)
|
| 811 |
+
# Special handling of Enum subclasses
|
| 812 |
+
return clsdict, slotstate
|
| 813 |
+
|
| 814 |
+
|
| 815 |
+
# COLLECTIONS OF OBJECTS REDUCERS
|
| 816 |
+
# -------------------------------
|
| 817 |
+
# A reducer is a function taking a single argument (obj), and that returns a
|
| 818 |
+
# tuple with all the necessary data to re-construct obj. Apart from a few
|
| 819 |
+
# exceptions (list, dict, bytes, int, etc.), a reducer is necessary to
|
| 820 |
+
# correctly pickle an object.
|
| 821 |
+
# While many built-in objects (Exceptions objects, instances of the "object"
|
| 822 |
+
# class, etc), are shipped with their own built-in reducer (invoked using
|
| 823 |
+
# obj.__reduce__), some do not. The following methods were created to "fill
|
| 824 |
+
# these holes".
|
| 825 |
+
|
| 826 |
+
|
| 827 |
+
def _code_reduce(obj):
|
| 828 |
+
"""code object reducer."""
|
| 829 |
+
# If you are not sure about the order of arguments, take a look at help
|
| 830 |
+
# of the specific type from types, for example:
|
| 831 |
+
# >>> from types import CodeType
|
| 832 |
+
# >>> help(CodeType)
|
| 833 |
+
|
| 834 |
+
# Hack to circumvent non-predictable memoization caused by string interning.
|
| 835 |
+
# See the inline comment in _class_setstate for details.
|
| 836 |
+
co_name = "".join(obj.co_name)
|
| 837 |
+
|
| 838 |
+
# Create shallow copies of these tuple to make cloudpickle payload deterministic.
|
| 839 |
+
# When creating a code object during load, copies of these four tuples are
|
| 840 |
+
# created, while in the main process, these tuples can be shared.
|
| 841 |
+
# By always creating copies, we make sure the resulting payload is deterministic.
|
| 842 |
+
co_names = tuple(name for name in obj.co_names)
|
| 843 |
+
co_varnames = tuple(name for name in obj.co_varnames)
|
| 844 |
+
co_freevars = tuple(name for name in obj.co_freevars)
|
| 845 |
+
co_cellvars = tuple(name for name in obj.co_cellvars)
|
| 846 |
+
if hasattr(obj, "co_exceptiontable"):
|
| 847 |
+
# Python 3.11 and later: there are some new attributes
|
| 848 |
+
# related to the enhanced exceptions.
|
| 849 |
+
args = (
|
| 850 |
+
obj.co_argcount,
|
| 851 |
+
obj.co_posonlyargcount,
|
| 852 |
+
obj.co_kwonlyargcount,
|
| 853 |
+
obj.co_nlocals,
|
| 854 |
+
obj.co_stacksize,
|
| 855 |
+
obj.co_flags,
|
| 856 |
+
obj.co_code,
|
| 857 |
+
obj.co_consts,
|
| 858 |
+
co_names,
|
| 859 |
+
co_varnames,
|
| 860 |
+
obj.co_filename,
|
| 861 |
+
co_name,
|
| 862 |
+
obj.co_qualname,
|
| 863 |
+
obj.co_firstlineno,
|
| 864 |
+
obj.co_linetable,
|
| 865 |
+
obj.co_exceptiontable,
|
| 866 |
+
co_freevars,
|
| 867 |
+
co_cellvars,
|
| 868 |
+
)
|
| 869 |
+
elif hasattr(obj, "co_linetable"):
|
| 870 |
+
# Python 3.10 and later: obj.co_lnotab is deprecated and constructor
|
| 871 |
+
# expects obj.co_linetable instead.
|
| 872 |
+
args = (
|
| 873 |
+
obj.co_argcount,
|
| 874 |
+
obj.co_posonlyargcount,
|
| 875 |
+
obj.co_kwonlyargcount,
|
| 876 |
+
obj.co_nlocals,
|
| 877 |
+
obj.co_stacksize,
|
| 878 |
+
obj.co_flags,
|
| 879 |
+
obj.co_code,
|
| 880 |
+
obj.co_consts,
|
| 881 |
+
co_names,
|
| 882 |
+
co_varnames,
|
| 883 |
+
obj.co_filename,
|
| 884 |
+
co_name,
|
| 885 |
+
obj.co_firstlineno,
|
| 886 |
+
obj.co_linetable,
|
| 887 |
+
co_freevars,
|
| 888 |
+
co_cellvars,
|
| 889 |
+
)
|
| 890 |
+
elif hasattr(obj, "co_nmeta"): # pragma: no cover
|
| 891 |
+
# "nogil" Python: modified attributes from 3.9
|
| 892 |
+
args = (
|
| 893 |
+
obj.co_argcount,
|
| 894 |
+
obj.co_posonlyargcount,
|
| 895 |
+
obj.co_kwonlyargcount,
|
| 896 |
+
obj.co_nlocals,
|
| 897 |
+
obj.co_framesize,
|
| 898 |
+
obj.co_ndefaultargs,
|
| 899 |
+
obj.co_nmeta,
|
| 900 |
+
obj.co_flags,
|
| 901 |
+
obj.co_code,
|
| 902 |
+
obj.co_consts,
|
| 903 |
+
co_varnames,
|
| 904 |
+
obj.co_filename,
|
| 905 |
+
co_name,
|
| 906 |
+
obj.co_firstlineno,
|
| 907 |
+
obj.co_lnotab,
|
| 908 |
+
obj.co_exc_handlers,
|
| 909 |
+
obj.co_jump_table,
|
| 910 |
+
co_freevars,
|
| 911 |
+
co_cellvars,
|
| 912 |
+
obj.co_free2reg,
|
| 913 |
+
obj.co_cell2reg,
|
| 914 |
+
)
|
| 915 |
+
else:
|
| 916 |
+
# Backward compat for 3.8 and 3.9
|
| 917 |
+
args = (
|
| 918 |
+
obj.co_argcount,
|
| 919 |
+
obj.co_posonlyargcount,
|
| 920 |
+
obj.co_kwonlyargcount,
|
| 921 |
+
obj.co_nlocals,
|
| 922 |
+
obj.co_stacksize,
|
| 923 |
+
obj.co_flags,
|
| 924 |
+
obj.co_code,
|
| 925 |
+
obj.co_consts,
|
| 926 |
+
co_names,
|
| 927 |
+
co_varnames,
|
| 928 |
+
obj.co_filename,
|
| 929 |
+
co_name,
|
| 930 |
+
obj.co_firstlineno,
|
| 931 |
+
obj.co_lnotab,
|
| 932 |
+
co_freevars,
|
| 933 |
+
co_cellvars,
|
| 934 |
+
)
|
| 935 |
+
return types.CodeType, args
|
| 936 |
+
|
| 937 |
+
|
| 938 |
+
def _cell_reduce(obj):
|
| 939 |
+
"""Cell (containing values of a function's free variables) reducer."""
|
| 940 |
+
try:
|
| 941 |
+
obj.cell_contents
|
| 942 |
+
except ValueError: # cell is empty
|
| 943 |
+
return _make_empty_cell, ()
|
| 944 |
+
else:
|
| 945 |
+
return _make_cell, (obj.cell_contents,)
|
| 946 |
+
|
| 947 |
+
|
| 948 |
+
def _classmethod_reduce(obj):
|
| 949 |
+
orig_func = obj.__func__
|
| 950 |
+
return type(obj), (orig_func,)
|
| 951 |
+
|
| 952 |
+
|
| 953 |
+
def _file_reduce(obj):
|
| 954 |
+
"""Save a file."""
|
| 955 |
+
import io
|
| 956 |
+
|
| 957 |
+
if not hasattr(obj, "name") or not hasattr(obj, "mode"):
|
| 958 |
+
raise pickle.PicklingError(
|
| 959 |
+
"Cannot pickle files that do not map to an actual file"
|
| 960 |
+
)
|
| 961 |
+
if obj is sys.stdout:
|
| 962 |
+
return getattr, (sys, "stdout")
|
| 963 |
+
if obj is sys.stderr:
|
| 964 |
+
return getattr, (sys, "stderr")
|
| 965 |
+
if obj is sys.stdin:
|
| 966 |
+
raise pickle.PicklingError("Cannot pickle standard input")
|
| 967 |
+
if obj.closed:
|
| 968 |
+
raise pickle.PicklingError("Cannot pickle closed files")
|
| 969 |
+
if hasattr(obj, "isatty") and obj.isatty():
|
| 970 |
+
raise pickle.PicklingError("Cannot pickle files that map to tty objects")
|
| 971 |
+
if "r" not in obj.mode and "+" not in obj.mode:
|
| 972 |
+
raise pickle.PicklingError(
|
| 973 |
+
"Cannot pickle files that are not opened for reading: %s" % obj.mode
|
| 974 |
+
)
|
| 975 |
+
|
| 976 |
+
name = obj.name
|
| 977 |
+
|
| 978 |
+
retval = io.StringIO()
|
| 979 |
+
|
| 980 |
+
try:
|
| 981 |
+
# Read the whole file
|
| 982 |
+
curloc = obj.tell()
|
| 983 |
+
obj.seek(0)
|
| 984 |
+
contents = obj.read()
|
| 985 |
+
obj.seek(curloc)
|
| 986 |
+
except OSError as e:
|
| 987 |
+
raise pickle.PicklingError(
|
| 988 |
+
"Cannot pickle file %s as it cannot be read" % name
|
| 989 |
+
) from e
|
| 990 |
+
retval.write(contents)
|
| 991 |
+
retval.seek(curloc)
|
| 992 |
+
|
| 993 |
+
retval.name = name
|
| 994 |
+
return _file_reconstructor, (retval,)
|
| 995 |
+
|
| 996 |
+
|
| 997 |
+
def _getset_descriptor_reduce(obj):
|
| 998 |
+
return getattr, (obj.__objclass__, obj.__name__)
|
| 999 |
+
|
| 1000 |
+
|
| 1001 |
+
def _mappingproxy_reduce(obj):
|
| 1002 |
+
return types.MappingProxyType, (dict(obj),)
|
| 1003 |
+
|
| 1004 |
+
|
| 1005 |
+
def _memoryview_reduce(obj):
|
| 1006 |
+
return bytes, (obj.tobytes(),)
|
| 1007 |
+
|
| 1008 |
+
|
| 1009 |
+
def _module_reduce(obj):
|
| 1010 |
+
if _should_pickle_by_reference(obj):
|
| 1011 |
+
return subimport, (obj.__name__,)
|
| 1012 |
+
else:
|
| 1013 |
+
# Some external libraries can populate the "__builtins__" entry of a
|
| 1014 |
+
# module's `__dict__` with unpicklable objects (see #316). For that
|
| 1015 |
+
# reason, we do not attempt to pickle the "__builtins__" entry, and
|
| 1016 |
+
# restore a default value for it at unpickling time.
|
| 1017 |
+
state = obj.__dict__.copy()
|
| 1018 |
+
state.pop("__builtins__", None)
|
| 1019 |
+
return dynamic_subimport, (obj.__name__, state)
|
| 1020 |
+
|
| 1021 |
+
|
| 1022 |
+
def _method_reduce(obj):
|
| 1023 |
+
return (types.MethodType, (obj.__func__, obj.__self__))
|
| 1024 |
+
|
| 1025 |
+
|
| 1026 |
+
def _logger_reduce(obj):
|
| 1027 |
+
return logging.getLogger, (obj.name,)
|
| 1028 |
+
|
| 1029 |
+
|
| 1030 |
+
def _root_logger_reduce(obj):
|
| 1031 |
+
return logging.getLogger, ()
|
| 1032 |
+
|
| 1033 |
+
|
| 1034 |
+
def _property_reduce(obj):
|
| 1035 |
+
return property, (obj.fget, obj.fset, obj.fdel, obj.__doc__)
|
| 1036 |
+
|
| 1037 |
+
|
| 1038 |
+
def _weakset_reduce(obj):
|
| 1039 |
+
return weakref.WeakSet, (list(obj),)
|
| 1040 |
+
|
| 1041 |
+
|
| 1042 |
+
def _dynamic_class_reduce(obj):
|
| 1043 |
+
"""Save a class that can't be referenced as a module attribute.
|
| 1044 |
+
|
| 1045 |
+
This method is used to serialize classes that are defined inside
|
| 1046 |
+
functions, or that otherwise can't be serialized as attribute lookups
|
| 1047 |
+
from importable modules.
|
| 1048 |
+
"""
|
| 1049 |
+
if Enum is not None and issubclass(obj, Enum):
|
| 1050 |
+
return (
|
| 1051 |
+
_make_skeleton_enum,
|
| 1052 |
+
_enum_getnewargs(obj),
|
| 1053 |
+
_enum_getstate(obj),
|
| 1054 |
+
None,
|
| 1055 |
+
None,
|
| 1056 |
+
_class_setstate,
|
| 1057 |
+
)
|
| 1058 |
+
else:
|
| 1059 |
+
return (
|
| 1060 |
+
_make_skeleton_class,
|
| 1061 |
+
_class_getnewargs(obj),
|
| 1062 |
+
_class_getstate(obj),
|
| 1063 |
+
None,
|
| 1064 |
+
None,
|
| 1065 |
+
_class_setstate,
|
| 1066 |
+
)
|
| 1067 |
+
|
| 1068 |
+
|
| 1069 |
+
def _class_reduce(obj):
|
| 1070 |
+
"""Select the reducer depending on the dynamic nature of the class obj."""
|
| 1071 |
+
if obj is type(None): # noqa
|
| 1072 |
+
return type, (None,)
|
| 1073 |
+
elif obj is type(Ellipsis):
|
| 1074 |
+
return type, (Ellipsis,)
|
| 1075 |
+
elif obj is type(NotImplemented):
|
| 1076 |
+
return type, (NotImplemented,)
|
| 1077 |
+
elif obj in _BUILTIN_TYPE_NAMES:
|
| 1078 |
+
return _builtin_type, (_BUILTIN_TYPE_NAMES[obj],)
|
| 1079 |
+
elif not _should_pickle_by_reference(obj):
|
| 1080 |
+
return _dynamic_class_reduce(obj)
|
| 1081 |
+
return NotImplemented
|
| 1082 |
+
|
| 1083 |
+
|
| 1084 |
+
def _dict_keys_reduce(obj):
|
| 1085 |
+
# Safer not to ship the full dict as sending the rest might
|
| 1086 |
+
# be unintended and could potentially cause leaking of
|
| 1087 |
+
# sensitive information
|
| 1088 |
+
return _make_dict_keys, (list(obj),)
|
| 1089 |
+
|
| 1090 |
+
|
| 1091 |
+
def _dict_values_reduce(obj):
|
| 1092 |
+
# Safer not to ship the full dict as sending the rest might
|
| 1093 |
+
# be unintended and could potentially cause leaking of
|
| 1094 |
+
# sensitive information
|
| 1095 |
+
return _make_dict_values, (list(obj),)
|
| 1096 |
+
|
| 1097 |
+
|
| 1098 |
+
def _dict_items_reduce(obj):
|
| 1099 |
+
return _make_dict_items, (dict(obj),)
|
| 1100 |
+
|
| 1101 |
+
|
| 1102 |
+
def _odict_keys_reduce(obj):
|
| 1103 |
+
# Safer not to ship the full dict as sending the rest might
|
| 1104 |
+
# be unintended and could potentially cause leaking of
|
| 1105 |
+
# sensitive information
|
| 1106 |
+
return _make_dict_keys, (list(obj), True)
|
| 1107 |
+
|
| 1108 |
+
|
| 1109 |
+
def _odict_values_reduce(obj):
|
| 1110 |
+
# Safer not to ship the full dict as sending the rest might
|
| 1111 |
+
# be unintended and could potentially cause leaking of
|
| 1112 |
+
# sensitive information
|
| 1113 |
+
return _make_dict_values, (list(obj), True)
|
| 1114 |
+
|
| 1115 |
+
|
| 1116 |
+
def _odict_items_reduce(obj):
|
| 1117 |
+
return _make_dict_items, (dict(obj), True)
|
| 1118 |
+
|
| 1119 |
+
|
| 1120 |
+
def _dataclass_field_base_reduce(obj):
|
| 1121 |
+
return _get_dataclass_field_type_sentinel, (obj.name,)
|
| 1122 |
+
|
| 1123 |
+
|
| 1124 |
+
# COLLECTIONS OF OBJECTS STATE SETTERS
|
| 1125 |
+
# ------------------------------------
|
| 1126 |
+
# state setters are called at unpickling time, once the object is created and
|
| 1127 |
+
# it has to be updated to how it was at unpickling time.
|
| 1128 |
+
|
| 1129 |
+
|
| 1130 |
+
def _function_setstate(obj, state):
|
| 1131 |
+
"""Update the state of a dynamic function.
|
| 1132 |
+
|
| 1133 |
+
As __closure__ and __globals__ are readonly attributes of a function, we
|
| 1134 |
+
cannot rely on the native setstate routine of pickle.load_build, that calls
|
| 1135 |
+
setattr on items of the slotstate. Instead, we have to modify them inplace.
|
| 1136 |
+
"""
|
| 1137 |
+
state, slotstate = state
|
| 1138 |
+
obj.__dict__.update(state)
|
| 1139 |
+
|
| 1140 |
+
obj_globals = slotstate.pop("__globals__")
|
| 1141 |
+
obj_closure = slotstate.pop("__closure__")
|
| 1142 |
+
# _cloudpickle_subimports is a set of submodules that must be loaded for
|
| 1143 |
+
# the pickled function to work correctly at unpickling time. Now that these
|
| 1144 |
+
# submodules are depickled (hence imported), they can be removed from the
|
| 1145 |
+
# object's state (the object state only served as a reference holder to
|
| 1146 |
+
# these submodules)
|
| 1147 |
+
slotstate.pop("_cloudpickle_submodules")
|
| 1148 |
+
|
| 1149 |
+
obj.__globals__.update(obj_globals)
|
| 1150 |
+
obj.__globals__["__builtins__"] = __builtins__
|
| 1151 |
+
|
| 1152 |
+
if obj_closure is not None:
|
| 1153 |
+
for i, cell in enumerate(obj_closure):
|
| 1154 |
+
try:
|
| 1155 |
+
value = cell.cell_contents
|
| 1156 |
+
except ValueError: # cell is empty
|
| 1157 |
+
continue
|
| 1158 |
+
obj.__closure__[i].cell_contents = value
|
| 1159 |
+
|
| 1160 |
+
for k, v in slotstate.items():
|
| 1161 |
+
setattr(obj, k, v)
|
| 1162 |
+
|
| 1163 |
+
|
| 1164 |
+
def _class_setstate(obj, state):
|
| 1165 |
+
state, slotstate = state
|
| 1166 |
+
registry = None
|
| 1167 |
+
for attrname, attr in state.items():
|
| 1168 |
+
if attrname == "_abc_impl":
|
| 1169 |
+
registry = attr
|
| 1170 |
+
else:
|
| 1171 |
+
# Note: setting attribute names on a class automatically triggers their
|
| 1172 |
+
# interning in CPython:
|
| 1173 |
+
# https://github.com/python/cpython/blob/v3.12.0/Objects/object.c#L957
|
| 1174 |
+
#
|
| 1175 |
+
# This means that to get deterministic pickling for a dynamic class that
|
| 1176 |
+
# was initially defined in a different Python process, the pickler
|
| 1177 |
+
# needs to ensure that dynamic class and function attribute names are
|
| 1178 |
+
# systematically copied into a non-interned version to avoid
|
| 1179 |
+
# unpredictable pickle payloads.
|
| 1180 |
+
#
|
| 1181 |
+
# Indeed the Pickler's memoizer relies on physical object identity to break
|
| 1182 |
+
# cycles in the reference graph of the object being serialized.
|
| 1183 |
+
setattr(obj, attrname, attr)
|
| 1184 |
+
|
| 1185 |
+
if sys.version_info >= (3, 13) and "__firstlineno__" in state:
|
| 1186 |
+
# Set the Python 3.13+ only __firstlineno__ attribute one more time, as it
|
| 1187 |
+
# will be automatically deleted by the `setattr(obj, attrname, attr)` call
|
| 1188 |
+
# above when `attrname` is "__firstlineno__". We assume that preserving this
|
| 1189 |
+
# information might be important for some users and that it not stale in the
|
| 1190 |
+
# context of cloudpickle usage, hence legitimate to propagate. Furthermore it
|
| 1191 |
+
# is necessary to do so to keep deterministic chained pickling as tested in
|
| 1192 |
+
# test_deterministic_str_interning_for_chained_dynamic_class_pickling.
|
| 1193 |
+
obj.__firstlineno__ = state["__firstlineno__"]
|
| 1194 |
+
|
| 1195 |
+
if registry is not None:
|
| 1196 |
+
for subclass in registry:
|
| 1197 |
+
obj.register(subclass)
|
| 1198 |
+
|
| 1199 |
+
# PEP-649/749: During pickling, we excluded the __annotate_func__ attribute but it
|
| 1200 |
+
# will be created by Python. Subsequently, annotations will be recreated when
|
| 1201 |
+
# __annotations__ is accessed.
|
| 1202 |
+
|
| 1203 |
+
return obj
|
| 1204 |
+
|
| 1205 |
+
|
| 1206 |
+
# COLLECTION OF DATACLASS UTILITIES
|
| 1207 |
+
# ---------------------------------
|
| 1208 |
+
# There are some internal sentinel values whose identity must be preserved when
|
| 1209 |
+
# unpickling dataclass fields. Each sentinel value has a unique name that we can
|
| 1210 |
+
# use to retrieve its identity at unpickling time.
|
| 1211 |
+
|
| 1212 |
+
|
| 1213 |
+
_DATACLASSE_FIELD_TYPE_SENTINELS = {
|
| 1214 |
+
dataclasses._FIELD.name: dataclasses._FIELD,
|
| 1215 |
+
dataclasses._FIELD_CLASSVAR.name: dataclasses._FIELD_CLASSVAR,
|
| 1216 |
+
dataclasses._FIELD_INITVAR.name: dataclasses._FIELD_INITVAR,
|
| 1217 |
+
}
|
| 1218 |
+
|
| 1219 |
+
|
| 1220 |
+
def _get_dataclass_field_type_sentinel(name):
|
| 1221 |
+
return _DATACLASSE_FIELD_TYPE_SENTINELS[name]
|
| 1222 |
+
|
| 1223 |
+
|
| 1224 |
+
class Pickler(pickle.Pickler):
|
| 1225 |
+
# set of reducers defined and used by cloudpickle (private)
|
| 1226 |
+
_dispatch_table = {}
|
| 1227 |
+
_dispatch_table[classmethod] = _classmethod_reduce
|
| 1228 |
+
_dispatch_table[io.TextIOWrapper] = _file_reduce
|
| 1229 |
+
_dispatch_table[logging.Logger] = _logger_reduce
|
| 1230 |
+
_dispatch_table[logging.RootLogger] = _root_logger_reduce
|
| 1231 |
+
_dispatch_table[memoryview] = _memoryview_reduce
|
| 1232 |
+
_dispatch_table[property] = _property_reduce
|
| 1233 |
+
_dispatch_table[staticmethod] = _classmethod_reduce
|
| 1234 |
+
_dispatch_table[CellType] = _cell_reduce
|
| 1235 |
+
_dispatch_table[types.CodeType] = _code_reduce
|
| 1236 |
+
_dispatch_table[types.GetSetDescriptorType] = _getset_descriptor_reduce
|
| 1237 |
+
_dispatch_table[types.ModuleType] = _module_reduce
|
| 1238 |
+
_dispatch_table[types.MethodType] = _method_reduce
|
| 1239 |
+
_dispatch_table[types.MappingProxyType] = _mappingproxy_reduce
|
| 1240 |
+
_dispatch_table[weakref.WeakSet] = _weakset_reduce
|
| 1241 |
+
_dispatch_table[typing.TypeVar] = _typevar_reduce
|
| 1242 |
+
_dispatch_table[_collections_abc.dict_keys] = _dict_keys_reduce
|
| 1243 |
+
_dispatch_table[_collections_abc.dict_values] = _dict_values_reduce
|
| 1244 |
+
_dispatch_table[_collections_abc.dict_items] = _dict_items_reduce
|
| 1245 |
+
_dispatch_table[type(OrderedDict().keys())] = _odict_keys_reduce
|
| 1246 |
+
_dispatch_table[type(OrderedDict().values())] = _odict_values_reduce
|
| 1247 |
+
_dispatch_table[type(OrderedDict().items())] = _odict_items_reduce
|
| 1248 |
+
_dispatch_table[abc.abstractmethod] = _classmethod_reduce
|
| 1249 |
+
_dispatch_table[abc.abstractclassmethod] = _classmethod_reduce
|
| 1250 |
+
_dispatch_table[abc.abstractstaticmethod] = _classmethod_reduce
|
| 1251 |
+
_dispatch_table[abc.abstractproperty] = _property_reduce
|
| 1252 |
+
_dispatch_table[dataclasses._FIELD_BASE] = _dataclass_field_base_reduce
|
| 1253 |
+
|
| 1254 |
+
dispatch_table = ChainMap(_dispatch_table, copyreg.dispatch_table)
|
| 1255 |
+
|
| 1256 |
+
# function reducers are defined as instance methods of cloudpickle.Pickler
|
| 1257 |
+
# objects, as they rely on a cloudpickle.Pickler attribute (globals_ref)
|
| 1258 |
+
def _dynamic_function_reduce(self, func):
|
| 1259 |
+
"""Reduce a function that is not pickleable via attribute lookup."""
|
| 1260 |
+
newargs = self._function_getnewargs(func)
|
| 1261 |
+
state = _function_getstate(func)
|
| 1262 |
+
return (_make_function, newargs, state, None, None, _function_setstate)
|
| 1263 |
+
|
| 1264 |
+
def _function_reduce(self, obj):
|
| 1265 |
+
"""Reducer for function objects.
|
| 1266 |
+
|
| 1267 |
+
If obj is a top-level attribute of a file-backed module, this reducer
|
| 1268 |
+
returns NotImplemented, making the cloudpickle.Pickler fall back to
|
| 1269 |
+
traditional pickle.Pickler routines to save obj. Otherwise, it reduces
|
| 1270 |
+
obj using a custom cloudpickle reducer designed specifically to handle
|
| 1271 |
+
dynamic functions.
|
| 1272 |
+
"""
|
| 1273 |
+
if _should_pickle_by_reference(obj):
|
| 1274 |
+
return NotImplemented
|
| 1275 |
+
else:
|
| 1276 |
+
return self._dynamic_function_reduce(obj)
|
| 1277 |
+
|
| 1278 |
+
def _function_getnewargs(self, func):
|
| 1279 |
+
code = func.__code__
|
| 1280 |
+
|
| 1281 |
+
# base_globals represents the future global namespace of func at
|
| 1282 |
+
# unpickling time. Looking it up and storing it in
|
| 1283 |
+
# cloudpickle.Pickler.globals_ref allow functions sharing the same
|
| 1284 |
+
# globals at pickling time to also share them once unpickled, at one
|
| 1285 |
+
# condition: since globals_ref is an attribute of a cloudpickle.Pickler
|
| 1286 |
+
# instance, and that a new cloudpickle.Pickler is created each time
|
| 1287 |
+
# cloudpickle.dump or cloudpickle.dumps is called, functions also need
|
| 1288 |
+
# to be saved within the same invocation of
|
| 1289 |
+
# cloudpickle.dump/cloudpickle.dumps (for example:
|
| 1290 |
+
# cloudpickle.dumps([f1, f2])). There is no such limitation when using
|
| 1291 |
+
# cloudpickle.Pickler.dump, as long as the multiple invocations are
|
| 1292 |
+
# bound to the same cloudpickle.Pickler instance.
|
| 1293 |
+
base_globals = self.globals_ref.setdefault(id(func.__globals__), {})
|
| 1294 |
+
|
| 1295 |
+
if base_globals == {}:
|
| 1296 |
+
# Add module attributes used to resolve relative imports
|
| 1297 |
+
# instructions inside func.
|
| 1298 |
+
for k in ["__package__", "__name__", "__path__", "__file__"]:
|
| 1299 |
+
if k in func.__globals__:
|
| 1300 |
+
base_globals[k] = func.__globals__[k]
|
| 1301 |
+
|
| 1302 |
+
# Do not bind the free variables before the function is created to
|
| 1303 |
+
# avoid infinite recursion.
|
| 1304 |
+
if func.__closure__ is None:
|
| 1305 |
+
closure = None
|
| 1306 |
+
else:
|
| 1307 |
+
closure = tuple(_make_empty_cell() for _ in range(len(code.co_freevars)))
|
| 1308 |
+
|
| 1309 |
+
return code, base_globals, None, None, closure
|
| 1310 |
+
|
| 1311 |
+
def dump(self, obj):
|
| 1312 |
+
try:
|
| 1313 |
+
return super().dump(obj)
|
| 1314 |
+
except RecursionError as e:
|
| 1315 |
+
msg = "Could not pickle object as excessively deep recursion required."
|
| 1316 |
+
raise pickle.PicklingError(msg) from e
|
| 1317 |
+
|
| 1318 |
+
def __init__(self, file, protocol=None, buffer_callback=None):
|
| 1319 |
+
if protocol is None:
|
| 1320 |
+
protocol = DEFAULT_PROTOCOL
|
| 1321 |
+
super().__init__(file, protocol=protocol, buffer_callback=buffer_callback)
|
| 1322 |
+
# map functions __globals__ attribute ids, to ensure that functions
|
| 1323 |
+
# sharing the same global namespace at pickling time also share
|
| 1324 |
+
# their global namespace at unpickling time.
|
| 1325 |
+
self.globals_ref = {}
|
| 1326 |
+
self.proto = int(protocol)
|
| 1327 |
+
|
| 1328 |
+
if not PYPY:
|
| 1329 |
+
# pickle.Pickler is the C implementation of the CPython pickler and
|
| 1330 |
+
# therefore we rely on reduce_override method to customize the pickler
|
| 1331 |
+
# behavior.
|
| 1332 |
+
|
| 1333 |
+
# `cloudpickle.Pickler.dispatch` is only left for backward
|
| 1334 |
+
# compatibility - note that when using protocol 5,
|
| 1335 |
+
# `cloudpickle.Pickler.dispatch` is not an extension of
|
| 1336 |
+
# `pickle._Pickler.dispatch` dictionary, because `cloudpickle.Pickler`
|
| 1337 |
+
# subclasses the C-implemented `pickle.Pickler`, which does not expose
|
| 1338 |
+
# a `dispatch` attribute. Earlier versions of `cloudpickle.Pickler`
|
| 1339 |
+
# used `cloudpickle.Pickler.dispatch` as a class-level attribute
|
| 1340 |
+
# storing all reducers implemented by cloudpickle, but the attribute
|
| 1341 |
+
# name was not a great choice given because it would collide with a
|
| 1342 |
+
# similarly named attribute in the pure-Python `pickle._Pickler`
|
| 1343 |
+
# implementation in the standard library.
|
| 1344 |
+
dispatch = dispatch_table
|
| 1345 |
+
|
| 1346 |
+
# Implementation of the reducer_override callback, in order to
|
| 1347 |
+
# efficiently serialize dynamic functions and classes by subclassing
|
| 1348 |
+
# the C-implemented `pickle.Pickler`.
|
| 1349 |
+
# TODO: decorrelate reducer_override (which is tied to CPython's
|
| 1350 |
+
# implementation - would it make sense to backport it to pypy? - and
|
| 1351 |
+
# pickle's protocol 5 which is implementation agnostic. Currently, the
|
| 1352 |
+
# availability of both notions coincide on CPython's pickle, but it may
|
| 1353 |
+
# not be the case anymore when pypy implements protocol 5.
|
| 1354 |
+
|
| 1355 |
+
def reducer_override(self, obj):
|
| 1356 |
+
"""Type-agnostic reducing callback for function and classes.
|
| 1357 |
+
|
| 1358 |
+
For performance reasons, subclasses of the C `pickle.Pickler` class
|
| 1359 |
+
cannot register custom reducers for functions and classes in the
|
| 1360 |
+
dispatch_table attribute. Reducers for such types must instead
|
| 1361 |
+
implemented via the special `reducer_override` method.
|
| 1362 |
+
|
| 1363 |
+
Note that this method will be called for any object except a few
|
| 1364 |
+
builtin-types (int, lists, dicts etc.), which differs from reducers
|
| 1365 |
+
in the Pickler's dispatch_table, each of them being invoked for
|
| 1366 |
+
objects of a specific type only.
|
| 1367 |
+
|
| 1368 |
+
This property comes in handy for classes: although most classes are
|
| 1369 |
+
instances of the ``type`` metaclass, some of them can be instances
|
| 1370 |
+
of other custom metaclasses (such as enum.EnumMeta for example). In
|
| 1371 |
+
particular, the metaclass will likely not be known in advance, and
|
| 1372 |
+
thus cannot be special-cased using an entry in the dispatch_table.
|
| 1373 |
+
reducer_override, among other things, allows us to register a
|
| 1374 |
+
reducer that will be called for any class, independently of its
|
| 1375 |
+
type.
|
| 1376 |
+
|
| 1377 |
+
Notes:
|
| 1378 |
+
|
| 1379 |
+
* reducer_override has the priority over dispatch_table-registered
|
| 1380 |
+
reducers.
|
| 1381 |
+
* reducer_override can be used to fix other limitations of
|
| 1382 |
+
cloudpickle for other types that suffered from type-specific
|
| 1383 |
+
reducers, such as Exceptions. See
|
| 1384 |
+
https://github.com/cloudpipe/cloudpickle/issues/248
|
| 1385 |
+
"""
|
| 1386 |
+
t = type(obj)
|
| 1387 |
+
try:
|
| 1388 |
+
is_anyclass = issubclass(t, type)
|
| 1389 |
+
except TypeError: # t is not a class (old Boost; see SF #502085)
|
| 1390 |
+
is_anyclass = False
|
| 1391 |
+
|
| 1392 |
+
if is_anyclass:
|
| 1393 |
+
return _class_reduce(obj)
|
| 1394 |
+
elif isinstance(obj, types.FunctionType):
|
| 1395 |
+
return self._function_reduce(obj)
|
| 1396 |
+
else:
|
| 1397 |
+
# fallback to save_global, including the Pickler's
|
| 1398 |
+
# dispatch_table
|
| 1399 |
+
return NotImplemented
|
| 1400 |
+
|
| 1401 |
+
else:
|
| 1402 |
+
# When reducer_override is not available, hack the pure-Python
|
| 1403 |
+
# Pickler's types.FunctionType and type savers. Note: the type saver
|
| 1404 |
+
# must override Pickler.save_global, because pickle.py contains a
|
| 1405 |
+
# hard-coded call to save_global when pickling meta-classes.
|
| 1406 |
+
dispatch = pickle.Pickler.dispatch.copy()
|
| 1407 |
+
|
| 1408 |
+
def _save_reduce_pickle5(
|
| 1409 |
+
self,
|
| 1410 |
+
func,
|
| 1411 |
+
args,
|
| 1412 |
+
state=None,
|
| 1413 |
+
listitems=None,
|
| 1414 |
+
dictitems=None,
|
| 1415 |
+
state_setter=None,
|
| 1416 |
+
obj=None,
|
| 1417 |
+
):
|
| 1418 |
+
save = self.save
|
| 1419 |
+
write = self.write
|
| 1420 |
+
self.save_reduce(
|
| 1421 |
+
func,
|
| 1422 |
+
args,
|
| 1423 |
+
state=None,
|
| 1424 |
+
listitems=listitems,
|
| 1425 |
+
dictitems=dictitems,
|
| 1426 |
+
obj=obj,
|
| 1427 |
+
)
|
| 1428 |
+
# backport of the Python 3.8 state_setter pickle operations
|
| 1429 |
+
save(state_setter)
|
| 1430 |
+
save(obj) # simple BINGET opcode as obj is already memoized.
|
| 1431 |
+
save(state)
|
| 1432 |
+
write(pickle.TUPLE2)
|
| 1433 |
+
# Trigger a state_setter(obj, state) function call.
|
| 1434 |
+
write(pickle.REDUCE)
|
| 1435 |
+
# The purpose of state_setter is to carry-out an
|
| 1436 |
+
# inplace modification of obj. We do not care about what the
|
| 1437 |
+
# method might return, so its output is eventually removed from
|
| 1438 |
+
# the stack.
|
| 1439 |
+
write(pickle.POP)
|
| 1440 |
+
|
| 1441 |
+
def save_global(self, obj, name=None, pack=struct.pack):
|
| 1442 |
+
"""Main dispatch method.
|
| 1443 |
+
|
| 1444 |
+
The name of this method is somewhat misleading: all types get
|
| 1445 |
+
dispatched here.
|
| 1446 |
+
"""
|
| 1447 |
+
if obj is type(None): # noqa
|
| 1448 |
+
return self.save_reduce(type, (None,), obj=obj)
|
| 1449 |
+
elif obj is type(Ellipsis):
|
| 1450 |
+
return self.save_reduce(type, (Ellipsis,), obj=obj)
|
| 1451 |
+
elif obj is type(NotImplemented):
|
| 1452 |
+
return self.save_reduce(type, (NotImplemented,), obj=obj)
|
| 1453 |
+
elif obj in _BUILTIN_TYPE_NAMES:
|
| 1454 |
+
return self.save_reduce(
|
| 1455 |
+
_builtin_type, (_BUILTIN_TYPE_NAMES[obj],), obj=obj
|
| 1456 |
+
)
|
| 1457 |
+
|
| 1458 |
+
if name is not None:
|
| 1459 |
+
super().save_global(obj, name=name)
|
| 1460 |
+
elif not _should_pickle_by_reference(obj, name=name):
|
| 1461 |
+
self._save_reduce_pickle5(*_dynamic_class_reduce(obj), obj=obj)
|
| 1462 |
+
else:
|
| 1463 |
+
super().save_global(obj, name=name)
|
| 1464 |
+
|
| 1465 |
+
dispatch[type] = save_global
|
| 1466 |
+
|
| 1467 |
+
def save_function(self, obj, name=None):
|
| 1468 |
+
"""Registered with the dispatch to handle all function types.
|
| 1469 |
+
|
| 1470 |
+
Determines what kind of function obj is (e.g. lambda, defined at
|
| 1471 |
+
interactive prompt, etc) and handles the pickling appropriately.
|
| 1472 |
+
"""
|
| 1473 |
+
if _should_pickle_by_reference(obj, name=name):
|
| 1474 |
+
return super().save_global(obj, name=name)
|
| 1475 |
+
elif PYPY and isinstance(obj.__code__, builtin_code_type):
|
| 1476 |
+
return self.save_pypy_builtin_func(obj)
|
| 1477 |
+
else:
|
| 1478 |
+
return self._save_reduce_pickle5(
|
| 1479 |
+
*self._dynamic_function_reduce(obj), obj=obj
|
| 1480 |
+
)
|
| 1481 |
+
|
| 1482 |
+
def save_pypy_builtin_func(self, obj):
|
| 1483 |
+
"""Save pypy equivalent of builtin functions.
|
| 1484 |
+
|
| 1485 |
+
PyPy does not have the concept of builtin-functions. Instead,
|
| 1486 |
+
builtin-functions are simple function instances, but with a
|
| 1487 |
+
builtin-code attribute.
|
| 1488 |
+
Most of the time, builtin functions should be pickled by attribute.
|
| 1489 |
+
But PyPy has flaky support for __qualname__, so some builtin
|
| 1490 |
+
functions such as float.__new__ will be classified as dynamic. For
|
| 1491 |
+
this reason only, we created this special routine. Because
|
| 1492 |
+
builtin-functions are not expected to have closure or globals,
|
| 1493 |
+
there is no additional hack (compared the one already implemented
|
| 1494 |
+
in pickle) to protect ourselves from reference cycles. A simple
|
| 1495 |
+
(reconstructor, newargs, obj.__dict__) tuple is save_reduced. Note
|
| 1496 |
+
also that PyPy improved their support for __qualname__ in v3.6, so
|
| 1497 |
+
this routing should be removed when cloudpickle supports only PyPy
|
| 1498 |
+
3.6 and later.
|
| 1499 |
+
"""
|
| 1500 |
+
rv = (
|
| 1501 |
+
types.FunctionType,
|
| 1502 |
+
(obj.__code__, {}, obj.__name__, obj.__defaults__, obj.__closure__),
|
| 1503 |
+
obj.__dict__,
|
| 1504 |
+
)
|
| 1505 |
+
self.save_reduce(*rv, obj=obj)
|
| 1506 |
+
|
| 1507 |
+
dispatch[types.FunctionType] = save_function
|
| 1508 |
+
|
| 1509 |
+
|
| 1510 |
+
# Shorthands similar to pickle.dump/pickle.dumps
|
| 1511 |
+
|
| 1512 |
+
|
| 1513 |
+
def dump(obj, file, protocol=None, buffer_callback=None):
|
| 1514 |
+
"""Serialize obj as bytes streamed into file
|
| 1515 |
+
|
| 1516 |
+
protocol defaults to cloudpickle.DEFAULT_PROTOCOL which is an alias to
|
| 1517 |
+
pickle.HIGHEST_PROTOCOL. This setting favors maximum communication
|
| 1518 |
+
speed between processes running the same Python version.
|
| 1519 |
+
|
| 1520 |
+
Set protocol=pickle.DEFAULT_PROTOCOL instead if you need to ensure
|
| 1521 |
+
compatibility with older versions of Python (although this is not always
|
| 1522 |
+
guaranteed to work because cloudpickle relies on some internal
|
| 1523 |
+
implementation details that can change from one Python version to the
|
| 1524 |
+
next).
|
| 1525 |
+
"""
|
| 1526 |
+
Pickler(file, protocol=protocol, buffer_callback=buffer_callback).dump(obj)
|
| 1527 |
+
|
| 1528 |
+
|
| 1529 |
+
def dumps(obj, protocol=None, buffer_callback=None):
|
| 1530 |
+
"""Serialize obj as a string of bytes allocated in memory
|
| 1531 |
+
|
| 1532 |
+
protocol defaults to cloudpickle.DEFAULT_PROTOCOL which is an alias to
|
| 1533 |
+
pickle.HIGHEST_PROTOCOL. This setting favors maximum communication
|
| 1534 |
+
speed between processes running the same Python version.
|
| 1535 |
+
|
| 1536 |
+
Set protocol=pickle.DEFAULT_PROTOCOL instead if you need to ensure
|
| 1537 |
+
compatibility with older versions of Python (although this is not always
|
| 1538 |
+
guaranteed to work because cloudpickle relies on some internal
|
| 1539 |
+
implementation details that can change from one Python version to the
|
| 1540 |
+
next).
|
| 1541 |
+
"""
|
| 1542 |
+
with io.BytesIO() as file:
|
| 1543 |
+
cp = Pickler(file, protocol=protocol, buffer_callback=buffer_callback)
|
| 1544 |
+
cp.dump(obj)
|
| 1545 |
+
return file.getvalue()
|
| 1546 |
+
|
| 1547 |
+
|
| 1548 |
+
# Include pickles unloading functions in this namespace for convenience.
|
| 1549 |
+
load, loads = pickle.load, pickle.loads
|
| 1550 |
+
|
| 1551 |
+
# Backward compat alias.
|
| 1552 |
+
CloudPickler = Pickler
|
lib/python3.12/site-packages/cloudpickle/cloudpickle_fast.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Compatibility module.
|
| 2 |
+
|
| 3 |
+
It can be necessary to load files generated by previous versions of cloudpickle
|
| 4 |
+
that rely on symbols being defined under the `cloudpickle.cloudpickle_fast`
|
| 5 |
+
namespace.
|
| 6 |
+
|
| 7 |
+
See: tests/test_backward_compat.py
|
| 8 |
+
"""
|
| 9 |
+
|
| 10 |
+
from . import cloudpickle
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def __getattr__(name):
|
| 14 |
+
return getattr(cloudpickle, name)
|
lib/python3.12/site-packages/ninja-1.13.0.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
lib/python3.12/site-packages/ninja-1.13.0.dist-info/METADATA
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.1
|
| 2 |
+
Name: ninja
|
| 3 |
+
Version: 1.13.0
|
| 4 |
+
Summary: Ninja is a small build system with a focus on speed
|
| 5 |
+
Keywords: build,c++,cross-compilation,cross-platform,fortran,ninja
|
| 6 |
+
Author-Email: Jean-Christophe Fillion-Robin <scikit-build@googlegroups.com>, Henry Schreiner <henryfs@princeton.edu>
|
| 7 |
+
Classifier: Development Status :: 5 - Production/Stable
|
| 8 |
+
Classifier: Intended Audience :: Developers
|
| 9 |
+
Classifier: License :: OSI Approved :: Apache Software License
|
| 10 |
+
Classifier: License :: OSI Approved :: BSD License
|
| 11 |
+
Classifier: Operating System :: OS Independent
|
| 12 |
+
Classifier: Programming Language :: C
|
| 13 |
+
Classifier: Programming Language :: C++
|
| 14 |
+
Classifier: Programming Language :: Fortran
|
| 15 |
+
Classifier: Programming Language :: Python
|
| 16 |
+
Classifier: Topic :: Software Development :: Build Tools
|
| 17 |
+
Classifier: Typing :: Typed
|
| 18 |
+
Project-URL: Bug Tracker, https://github.com/scikit-build/ninja-python-distributions/issues
|
| 19 |
+
Project-URL: Documentation, https://github.com/scikit-build/ninja-python-distributions#readme
|
| 20 |
+
Project-URL: Download, https://github.com/ninja-build/ninja/releases
|
| 21 |
+
Project-URL: Homepage, http://ninja-build.org/
|
| 22 |
+
Project-URL: Mailing list, https://groups.google.com/forum/#!forum/scikit-build
|
| 23 |
+
Project-URL: Source Code, https://github.com/scikit-build/ninja-python-distributions
|
| 24 |
+
Requires-Python: >=3.8
|
| 25 |
+
Description-Content-Type: text/x-rst
|
| 26 |
+
|
| 27 |
+
==========================
|
| 28 |
+
Ninja Python Distributions
|
| 29 |
+
==========================
|
| 30 |
+
|
| 31 |
+
`Ninja <http://www.ninja-build.org>`_ is a small build system with a focus on speed.
|
| 32 |
+
|
| 33 |
+
The latest Ninja python wheels provide `ninja 1.13.0.gd74ef.kitware.jobserver-pipe-1 <https://ninja-build.org/manual.html>`_ executable
|
| 34 |
+
and `ninja_syntax.py` for generating `.ninja` files.
|
| 35 |
+
|
| 36 |
+
.. image:: https://raw.githubusercontent.com/scikit-build/ninja-python-distributions/master/ninja-python-distributions-logo.png
|
| 37 |
+
|
| 38 |
+
Latest Release
|
| 39 |
+
--------------
|
| 40 |
+
|
| 41 |
+
.. table::
|
| 42 |
+
|
| 43 |
+
+----------------------------------------------------------------------+---------------------------------------------------------------------------+
|
| 44 |
+
| Versions | Downloads |
|
| 45 |
+
+======================================================================+===========================================================================+
|
| 46 |
+
| .. image:: https://img.shields.io/pypi/v/ninja.svg | .. image:: https://img.shields.io/badge/downloads-2535k%20total-green.svg |
|
| 47 |
+
| :target: https://pypi.python.org/pypi/ninja | :target: https://pypi.python.org/pypi/ninja |
|
| 48 |
+
+----------------------------------------------------------------------+---------------------------------------------------------------------------+
|
| 49 |
+
|
| 50 |
+
Build Status
|
| 51 |
+
------------
|
| 52 |
+
|
| 53 |
+
.. table::
|
| 54 |
+
|
| 55 |
+
+---------------+-------------------------------------------------------------------------------------------------------------+
|
| 56 |
+
| | GitHub Actions (Windows, macOS, Linux) |
|
| 57 |
+
+===============+=============================================================================================================+
|
| 58 |
+
| PyPI | .. image:: https://github.com/scikit-build/ninja-python-distributions/actions/workflows/build.yml/badge.svg |
|
| 59 |
+
| | :target: https://github.com/scikit-build/ninja-python-distributions/actions/workflows/build.yml |
|
| 60 |
+
+---------------+-------------------------------------------------------------------------------------------------------------+
|
| 61 |
+
|
| 62 |
+
Maintainers
|
| 63 |
+
-----------
|
| 64 |
+
|
| 65 |
+
* `How to update ninja version ? <https://github.com/scikit-build/ninja-python-distributions/blob/master/docs/update_ninja_version.rst>`_
|
| 66 |
+
|
| 67 |
+
* `How to make a release ? <https://github.com/scikit-build/ninja-python-distributions/blob/master/docs/make_a_release.rst>`_
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
Miscellaneous
|
| 71 |
+
-------------
|
| 72 |
+
|
| 73 |
+
* Documentation: https://github.com/scikit-build/ninja-python-distributions#readme
|
| 74 |
+
* Source code: https://github.com/scikit-build/ninja-python-distributions
|
| 75 |
+
* Mailing list: https://groups.google.com/forum/#!forum/scikit-build
|
| 76 |
+
|
| 77 |
+
Python Version Support
|
| 78 |
+
----------------------
|
| 79 |
+
|
| 80 |
+
Versions after 1.11.1.1 no longer support Python 2-3.6, and require manylinux2010+ on linux.
|
| 81 |
+
Versions after 1.13 no longer support Python 3.7, and require manylinux2014+/musllinux_1_2+ on linux.
|
| 82 |
+
|
| 83 |
+
License
|
| 84 |
+
-------
|
| 85 |
+
|
| 86 |
+
This project is maintained by Jean-Christophe Fillion-Robin from Kitware Inc.
|
| 87 |
+
It is covered by the `Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>`_.
|
| 88 |
+
|
| 89 |
+
Ninja is also distributed under the `Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>`_.
|
| 90 |
+
For more information about Ninja, visit https://ninja-build.org
|
| 91 |
+
|
| 92 |
+
Logo was originally created by Libby Rose from Kitware Inc.
|
| 93 |
+
It is covered by `CC BY 4.0 <https://creativecommons.org/licenses/by/4.0/>`_.
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
History
|
| 97 |
+
-------
|
| 98 |
+
|
| 99 |
+
ninja-python-distributions was initially developed in November 2016 by
|
| 100 |
+
Jean-Christophe Fillion-Robin to facilitate the distribution of project using
|
| 101 |
+
`scikit-build <http://scikit-build.readthedocs.io/>`_ and depending on CMake
|
| 102 |
+
and Ninja.
|
lib/python3.12/site-packages/ninja-1.13.0.dist-info/RECORD
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
../../../bin/ninja,sha256=aW-WKKednOUDFM-VVtfNGh0exSuP1Sgo9vnbFxlWW2c,372384
|
| 2 |
+
ninja-1.13.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 3 |
+
ninja-1.13.0.dist-info/METADATA,sha256=jXb8Tjgs7c0ivK6qdIrzmz-nkxtyRCOW0VyxgWWdCk4,5148
|
| 4 |
+
ninja-1.13.0.dist-info/RECORD,,
|
| 5 |
+
ninja-1.13.0.dist-info/WHEEL,sha256=zzOwTeuxXsHOT9QV_vcZk1hX9KJAUdqJD7e-2jGJxLA,150
|
| 6 |
+
ninja-1.13.0.dist-info/licenses/AUTHORS.rst,sha256=bGE1t_Lhm2ir8S7n_jbLDohP84fpJ5sNCuxvDVsKNQg,142
|
| 7 |
+
ninja-1.13.0.dist-info/licenses/LICENSE_Apache_20,sha256=c7p036pSC0mkAbXSFFmoUjoUbzt1GKgz7qXvqFEwv2g,10273
|
| 8 |
+
ninja/__init__.py,sha256=taDHI20kpmjxOT72PiSyE42Pvz3KLXlwMfTZvvnRMKM,1533
|
| 9 |
+
ninja/__main__.py,sha256=6iPLwHHAc2TMbojFVcUzERrzN0RvIsywuZc4KpJCg_4,100
|
| 10 |
+
ninja/__pycache__/__init__.cpython-312.pyc,,
|
| 11 |
+
ninja/__pycache__/__main__.cpython-312.pyc,,
|
| 12 |
+
ninja/__pycache__/_version.cpython-312.pyc,,
|
| 13 |
+
ninja/__pycache__/ninja_syntax.cpython-312.pyc,,
|
| 14 |
+
ninja/_version.py,sha256=M85oP8JJdZ4yZHcp9qfGYLKUYvnN3kTyQosVcYPCPow,19
|
| 15 |
+
ninja/_version.pyi,sha256=j5kbzfm6lOn8BzASXWjGIA1yT0OlHTWqlbyZ8Si_o0E,118
|
| 16 |
+
ninja/ninja_syntax.py,sha256=RCXZ6Roda3lwnbhtQw6I6bJcpE98mXUZ9jocnvC4IQY,8148
|
| 17 |
+
ninja/ninja_syntax.pyi,sha256=5IHH7N9CTKnMDDetFKHOsPK0SOSK_7Q4YtgzhIMNLE0,1576
|
| 18 |
+
ninja/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
lib/python3.12/site-packages/ninja-1.13.0.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: scikit-build-core 0.11.5
|
| 3 |
+
Root-Is-Purelib: false
|
| 4 |
+
Tag: py3-none-manylinux_2_17_x86_64
|
| 5 |
+
Tag: py3-none-manylinux2014_x86_64
|
| 6 |
+
|
lib/python3.12/site-packages/ninja-1.13.0.dist-info/licenses/AUTHORS.rst
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
=======
|
| 2 |
+
Credits
|
| 3 |
+
=======
|
| 4 |
+
|
| 5 |
+
Please see the GitHub project page at https://github.com/scikit-build/ninja-python-distributions/graphs/contributors
|
lib/python3.12/site-packages/ninja-1.13.0.dist-info/licenses/LICENSE_Apache_20
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Apache License
|
| 2 |
+
Version 2.0, January 2004
|
| 3 |
+
http://www.apache.org/licenses/
|
| 4 |
+
|
| 5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 6 |
+
|
| 7 |
+
1. Definitions.
|
| 8 |
+
|
| 9 |
+
"License" shall mean the terms and conditions for use, reproduction, and
|
| 10 |
+
distribution as defined by Sections 1 through 9 of this document.
|
| 11 |
+
|
| 12 |
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
| 13 |
+
owner that is granting the License.
|
| 14 |
+
|
| 15 |
+
"Legal Entity" shall mean the union of the acting entity and all other entities
|
| 16 |
+
that control, are controlled by, or are under common control with that entity.
|
| 17 |
+
For the purposes of this definition, "control" means (i) the power, direct or
|
| 18 |
+
indirect, to cause the direction or management of such entity, whether by
|
| 19 |
+
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 20 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 21 |
+
|
| 22 |
+
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
| 23 |
+
permissions granted by this License.
|
| 24 |
+
|
| 25 |
+
"Source" form shall mean the preferred form for making modifications, including
|
| 26 |
+
but not limited to software source code, documentation source, and configuration
|
| 27 |
+
files.
|
| 28 |
+
|
| 29 |
+
"Object" form shall mean any form resulting from mechanical transformation or
|
| 30 |
+
translation of a Source form, including but not limited to compiled object code,
|
| 31 |
+
generated documentation, and conversions to other media types.
|
| 32 |
+
|
| 33 |
+
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
| 34 |
+
available under the License, as indicated by a copyright notice that is included
|
| 35 |
+
in or attached to the work (an example is provided in the Appendix below).
|
| 36 |
+
|
| 37 |
+
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
| 38 |
+
is based on (or derived from) the Work and for which the editorial revisions,
|
| 39 |
+
annotations, elaborations, or other modifications represent, as a whole, an
|
| 40 |
+
original work of authorship. For the purposes of this License, Derivative Works
|
| 41 |
+
shall not include works that remain separable from, or merely link (or bind by
|
| 42 |
+
name) to the interfaces of, the Work and Derivative Works thereof.
|
| 43 |
+
|
| 44 |
+
"Contribution" shall mean any work of authorship, including the original version
|
| 45 |
+
of the Work and any modifications or additions to that Work or Derivative Works
|
| 46 |
+
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
| 47 |
+
by the copyright owner or by an individual or Legal Entity authorized to submit
|
| 48 |
+
on behalf of the copyright owner. For the purposes of this definition,
|
| 49 |
+
"submitted" means any form of electronic, verbal, or written communication sent
|
| 50 |
+
to the Licensor or its representatives, including but not limited to
|
| 51 |
+
communication on electronic mailing lists, source code control systems, and
|
| 52 |
+
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
| 53 |
+
the purpose of discussing and improving the Work, but excluding communication
|
| 54 |
+
that is conspicuously marked or otherwise designated in writing by the copyright
|
| 55 |
+
owner as "Not a Contribution."
|
| 56 |
+
|
| 57 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
| 58 |
+
of whom a Contribution has been received by Licensor and subsequently
|
| 59 |
+
incorporated within the Work.
|
| 60 |
+
|
| 61 |
+
2. Grant of Copyright License.
|
| 62 |
+
|
| 63 |
+
Subject to the terms and conditions of this License, each Contributor hereby
|
| 64 |
+
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
| 65 |
+
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
| 66 |
+
publicly display, publicly perform, sublicense, and distribute the Work and such
|
| 67 |
+
Derivative Works in Source or Object form.
|
| 68 |
+
|
| 69 |
+
3. Grant of Patent License.
|
| 70 |
+
|
| 71 |
+
Subject to the terms and conditions of this License, each Contributor hereby
|
| 72 |
+
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
| 73 |
+
irrevocable (except as stated in this section) patent license to make, have
|
| 74 |
+
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
| 75 |
+
such license applies only to those patent claims licensable by such Contributor
|
| 76 |
+
that are necessarily infringed by their Contribution(s) alone or by combination
|
| 77 |
+
of their Contribution(s) with the Work to which such Contribution(s) was
|
| 78 |
+
submitted. If You institute patent litigation against any entity (including a
|
| 79 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
| 80 |
+
Contribution incorporated within the Work constitutes direct or contributory
|
| 81 |
+
patent infringement, then any patent licenses granted to You under this License
|
| 82 |
+
for that Work shall terminate as of the date such litigation is filed.
|
| 83 |
+
|
| 84 |
+
4. Redistribution.
|
| 85 |
+
|
| 86 |
+
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
| 87 |
+
in any medium, with or without modifications, and in Source or Object form,
|
| 88 |
+
provided that You meet the following conditions:
|
| 89 |
+
|
| 90 |
+
You must give any other recipients of the Work or Derivative Works a copy of
|
| 91 |
+
this License; and
|
| 92 |
+
You must cause any modified files to carry prominent notices stating that You
|
| 93 |
+
changed the files; and
|
| 94 |
+
You must retain, in the Source form of any Derivative Works that You distribute,
|
| 95 |
+
all copyright, patent, trademark, and attribution notices from the Source form
|
| 96 |
+
of the Work, excluding those notices that do not pertain to any part of the
|
| 97 |
+
Derivative Works; and
|
| 98 |
+
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
| 99 |
+
Derivative Works that You distribute must include a readable copy of the
|
| 100 |
+
attribution notices contained within such NOTICE file, excluding those notices
|
| 101 |
+
that do not pertain to any part of the Derivative Works, in at least one of the
|
| 102 |
+
following places: within a NOTICE text file distributed as part of the
|
| 103 |
+
Derivative Works; within the Source form or documentation, if provided along
|
| 104 |
+
with the Derivative Works; or, within a display generated by the Derivative
|
| 105 |
+
Works, if and wherever such third-party notices normally appear. The contents of
|
| 106 |
+
the NOTICE file are for informational purposes only and do not modify the
|
| 107 |
+
License. You may add Your own attribution notices within Derivative Works that
|
| 108 |
+
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
| 109 |
+
provided that such additional attribution notices cannot be construed as
|
| 110 |
+
modifying the License.
|
| 111 |
+
You may add Your own copyright statement to Your modifications and may provide
|
| 112 |
+
additional or different license terms and conditions for use, reproduction, or
|
| 113 |
+
distribution of Your modifications, or for any such Derivative Works as a whole,
|
| 114 |
+
provided Your use, reproduction, and distribution of the Work otherwise complies
|
| 115 |
+
with the conditions stated in this License.
|
| 116 |
+
|
| 117 |
+
5. Submission of Contributions.
|
| 118 |
+
|
| 119 |
+
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
| 120 |
+
for inclusion in the Work by You to the Licensor shall be under the terms and
|
| 121 |
+
conditions of this License, without any additional terms or conditions.
|
| 122 |
+
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
| 123 |
+
any separate license agreement you may have executed with Licensor regarding
|
| 124 |
+
such Contributions.
|
| 125 |
+
|
| 126 |
+
6. Trademarks.
|
| 127 |
+
|
| 128 |
+
This License does not grant permission to use the trade names, trademarks,
|
| 129 |
+
service marks, or product names of the Licensor, except as required for
|
| 130 |
+
reasonable and customary use in describing the origin of the Work and
|
| 131 |
+
reproducing the content of the NOTICE file.
|
| 132 |
+
|
| 133 |
+
7. Disclaimer of Warranty.
|
| 134 |
+
|
| 135 |
+
Unless required by applicable law or agreed to in writing, Licensor provides the
|
| 136 |
+
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 137 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
| 138 |
+
including, without limitation, any warranties or conditions of TITLE,
|
| 139 |
+
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
| 140 |
+
solely responsible for determining the appropriateness of using or
|
| 141 |
+
redistributing the Work and assume any risks associated with Your exercise of
|
| 142 |
+
permissions under this License.
|
| 143 |
+
|
| 144 |
+
8. Limitation of Liability.
|
| 145 |
+
|
| 146 |
+
In no event and under no legal theory, whether in tort (including negligence),
|
| 147 |
+
contract, or otherwise, unless required by applicable law (such as deliberate
|
| 148 |
+
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
| 149 |
+
liable to You for damages, including any direct, indirect, special, incidental,
|
| 150 |
+
or consequential damages of any character arising as a result of this License or
|
| 151 |
+
out of the use or inability to use the Work (including but not limited to
|
| 152 |
+
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
| 153 |
+
any and all other commercial damages or losses), even if such Contributor has
|
| 154 |
+
been advised of the possibility of such damages.
|
| 155 |
+
|
| 156 |
+
9. Accepting Warranty or Additional Liability.
|
| 157 |
+
|
| 158 |
+
While redistributing the Work or Derivative Works thereof, You may choose to
|
| 159 |
+
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
| 160 |
+
other liability obligations and/or rights consistent with this License. However,
|
| 161 |
+
in accepting such obligations, You may act only on Your own behalf and on Your
|
| 162 |
+
sole responsibility, not on behalf of any other Contributor, and only if You
|
| 163 |
+
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
| 164 |
+
incurred by, or claims asserted against, such Contributor by reason of your
|
| 165 |
+
accepting any such warranty or additional liability.
|
| 166 |
+
|
| 167 |
+
END OF TERMS AND CONDITIONS
|
| 168 |
+
|
| 169 |
+
APPENDIX: How to apply the Apache License to your work
|
| 170 |
+
|
| 171 |
+
To apply the Apache License to your work, attach the following boilerplate
|
| 172 |
+
notice, with the fields enclosed by brackets "[]" replaced with your own
|
| 173 |
+
identifying information. (Don't include the brackets!) The text should be
|
| 174 |
+
enclosed in the appropriate comment syntax for the file format. We also
|
| 175 |
+
recommend that a file or class name and description of purpose be included on
|
| 176 |
+
the same "printed page" as the copyright notice for easier identification within
|
| 177 |
+
third-party archives.
|
| 178 |
+
|
| 179 |
+
Copyright [yyyy] [name of copyright owner]
|
| 180 |
+
|
| 181 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 182 |
+
you may not use this file except in compliance with the License.
|
| 183 |
+
You may obtain a copy of the License at
|
| 184 |
+
|
| 185 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 186 |
+
|
| 187 |
+
Unless required by applicable law or agreed to in writing, software
|
| 188 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 189 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 190 |
+
See the License for the specific language governing permissions and
|
| 191 |
+
limitations under the License.
|
lib/python3.12/site-packages/numpy/__config__.py
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This file is generated by numpy's build process
|
| 2 |
+
# It contains system_info results at the time of building this package.
|
| 3 |
+
from enum import Enum
|
| 4 |
+
from numpy.core._multiarray_umath import (
|
| 5 |
+
__cpu_features__,
|
| 6 |
+
__cpu_baseline__,
|
| 7 |
+
__cpu_dispatch__,
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
__all__ = ["show"]
|
| 11 |
+
_built_with_meson = True
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class DisplayModes(Enum):
|
| 15 |
+
stdout = "stdout"
|
| 16 |
+
dicts = "dicts"
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def _cleanup(d):
|
| 20 |
+
"""
|
| 21 |
+
Removes empty values in a `dict` recursively
|
| 22 |
+
This ensures we remove values that Meson could not provide to CONFIG
|
| 23 |
+
"""
|
| 24 |
+
if isinstance(d, dict):
|
| 25 |
+
return {k: _cleanup(v) for k, v in d.items() if v and _cleanup(v)}
|
| 26 |
+
else:
|
| 27 |
+
return d
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
CONFIG = _cleanup(
|
| 31 |
+
{
|
| 32 |
+
"Compilers": {
|
| 33 |
+
"c": {
|
| 34 |
+
"name": "gcc",
|
| 35 |
+
"linker": r"ld.bfd",
|
| 36 |
+
"version": "10.2.1",
|
| 37 |
+
"commands": r"cc",
|
| 38 |
+
"args": r"-fno-strict-aliasing",
|
| 39 |
+
"linker args": r"-Wl,--strip-debug, -fno-strict-aliasing",
|
| 40 |
+
},
|
| 41 |
+
"cython": {
|
| 42 |
+
"name": "cython",
|
| 43 |
+
"linker": r"cython",
|
| 44 |
+
"version": "3.0.8",
|
| 45 |
+
"commands": r"cython",
|
| 46 |
+
"args": r"",
|
| 47 |
+
"linker args": r"",
|
| 48 |
+
},
|
| 49 |
+
"c++": {
|
| 50 |
+
"name": "gcc",
|
| 51 |
+
"linker": r"ld.bfd",
|
| 52 |
+
"version": "10.2.1",
|
| 53 |
+
"commands": r"c++",
|
| 54 |
+
"args": r"",
|
| 55 |
+
"linker args": r"-Wl,--strip-debug",
|
| 56 |
+
},
|
| 57 |
+
},
|
| 58 |
+
"Machine Information": {
|
| 59 |
+
"host": {
|
| 60 |
+
"cpu": "x86_64",
|
| 61 |
+
"family": "x86_64",
|
| 62 |
+
"endian": "little",
|
| 63 |
+
"system": "linux",
|
| 64 |
+
},
|
| 65 |
+
"build": {
|
| 66 |
+
"cpu": "x86_64",
|
| 67 |
+
"family": "x86_64",
|
| 68 |
+
"endian": "little",
|
| 69 |
+
"system": "linux",
|
| 70 |
+
},
|
| 71 |
+
"cross-compiled": bool("False".lower().replace("false", "")),
|
| 72 |
+
},
|
| 73 |
+
"Build Dependencies": {
|
| 74 |
+
"blas": {
|
| 75 |
+
"name": "openblas64",
|
| 76 |
+
"found": bool("True".lower().replace("false", "")),
|
| 77 |
+
"version": "0.3.23.dev",
|
| 78 |
+
"detection method": "pkgconfig",
|
| 79 |
+
"include directory": r"/usr/local/include",
|
| 80 |
+
"lib directory": r"/usr/local/lib",
|
| 81 |
+
"openblas configuration": r"USE_64BITINT=1 DYNAMIC_ARCH=1 DYNAMIC_OLDER= NO_CBLAS= NO_LAPACK= NO_LAPACKE= NO_AFFINITY=1 USE_OPENMP= HASWELL MAX_THREADS=2",
|
| 82 |
+
"pc file directory": r"/usr/local/lib/pkgconfig",
|
| 83 |
+
},
|
| 84 |
+
"lapack": {
|
| 85 |
+
"name": "dep140551260102944",
|
| 86 |
+
"found": bool("True".lower().replace("false", "")),
|
| 87 |
+
"version": "1.26.4",
|
| 88 |
+
"detection method": "internal",
|
| 89 |
+
"include directory": r"unknown",
|
| 90 |
+
"lib directory": r"unknown",
|
| 91 |
+
"openblas configuration": r"unknown",
|
| 92 |
+
"pc file directory": r"unknown",
|
| 93 |
+
},
|
| 94 |
+
},
|
| 95 |
+
"Python Information": {
|
| 96 |
+
"path": r"/opt/python/cp312-cp312/bin/python",
|
| 97 |
+
"version": "3.12",
|
| 98 |
+
},
|
| 99 |
+
"SIMD Extensions": {
|
| 100 |
+
"baseline": __cpu_baseline__,
|
| 101 |
+
"found": [
|
| 102 |
+
feature for feature in __cpu_dispatch__ if __cpu_features__[feature]
|
| 103 |
+
],
|
| 104 |
+
"not found": [
|
| 105 |
+
feature for feature in __cpu_dispatch__ if not __cpu_features__[feature]
|
| 106 |
+
],
|
| 107 |
+
},
|
| 108 |
+
}
|
| 109 |
+
)
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
def _check_pyyaml():
|
| 113 |
+
import yaml
|
| 114 |
+
|
| 115 |
+
return yaml
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def show(mode=DisplayModes.stdout.value):
|
| 119 |
+
"""
|
| 120 |
+
Show libraries and system information on which NumPy was built
|
| 121 |
+
and is being used
|
| 122 |
+
|
| 123 |
+
Parameters
|
| 124 |
+
----------
|
| 125 |
+
mode : {`'stdout'`, `'dicts'`}, optional.
|
| 126 |
+
Indicates how to display the config information.
|
| 127 |
+
`'stdout'` prints to console, `'dicts'` returns a dictionary
|
| 128 |
+
of the configuration.
|
| 129 |
+
|
| 130 |
+
Returns
|
| 131 |
+
-------
|
| 132 |
+
out : {`dict`, `None`}
|
| 133 |
+
If mode is `'dicts'`, a dict is returned, else None
|
| 134 |
+
|
| 135 |
+
See Also
|
| 136 |
+
--------
|
| 137 |
+
get_include : Returns the directory containing NumPy C
|
| 138 |
+
header files.
|
| 139 |
+
|
| 140 |
+
Notes
|
| 141 |
+
-----
|
| 142 |
+
1. The `'stdout'` mode will give more readable
|
| 143 |
+
output if ``pyyaml`` is installed
|
| 144 |
+
|
| 145 |
+
"""
|
| 146 |
+
if mode == DisplayModes.stdout.value:
|
| 147 |
+
try: # Non-standard library, check import
|
| 148 |
+
yaml = _check_pyyaml()
|
| 149 |
+
|
| 150 |
+
print(yaml.dump(CONFIG))
|
| 151 |
+
except ModuleNotFoundError:
|
| 152 |
+
import warnings
|
| 153 |
+
import json
|
| 154 |
+
|
| 155 |
+
warnings.warn("Install `pyyaml` for better output", stacklevel=1)
|
| 156 |
+
print(json.dumps(CONFIG, indent=2))
|
| 157 |
+
elif mode == DisplayModes.dicts.value:
|
| 158 |
+
return CONFIG
|
| 159 |
+
else:
|
| 160 |
+
raise AttributeError(
|
| 161 |
+
f"Invalid `mode`, use one of: {', '.join([e.value for e in DisplayModes])}"
|
| 162 |
+
)
|
lib/python3.12/site-packages/numpy/__init__.cython-30.pxd
ADDED
|
@@ -0,0 +1,1050 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# NumPy static imports for Cython >= 3.0
|
| 2 |
+
#
|
| 3 |
+
# If any of the PyArray_* functions are called, import_array must be
|
| 4 |
+
# called first. This is done automatically by Cython 3.0+ if a call
|
| 5 |
+
# is not detected inside of the module.
|
| 6 |
+
#
|
| 7 |
+
# Author: Dag Sverre Seljebotn
|
| 8 |
+
#
|
| 9 |
+
|
| 10 |
+
from cpython.ref cimport Py_INCREF
|
| 11 |
+
from cpython.object cimport PyObject, PyTypeObject, PyObject_TypeCheck
|
| 12 |
+
cimport libc.stdio as stdio
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
cdef extern from *:
|
| 16 |
+
# Leave a marker that the NumPy declarations came from NumPy itself and not from Cython.
|
| 17 |
+
# See https://github.com/cython/cython/issues/3573
|
| 18 |
+
"""
|
| 19 |
+
/* Using NumPy API declarations from "numpy/__init__.cython-30.pxd" */
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
cdef extern from "Python.h":
|
| 24 |
+
ctypedef int Py_intptr_t
|
| 25 |
+
|
| 26 |
+
cdef extern from "numpy/arrayobject.h":
|
| 27 |
+
ctypedef Py_intptr_t npy_intp
|
| 28 |
+
ctypedef size_t npy_uintp
|
| 29 |
+
|
| 30 |
+
cdef enum NPY_TYPES:
|
| 31 |
+
NPY_BOOL
|
| 32 |
+
NPY_BYTE
|
| 33 |
+
NPY_UBYTE
|
| 34 |
+
NPY_SHORT
|
| 35 |
+
NPY_USHORT
|
| 36 |
+
NPY_INT
|
| 37 |
+
NPY_UINT
|
| 38 |
+
NPY_LONG
|
| 39 |
+
NPY_ULONG
|
| 40 |
+
NPY_LONGLONG
|
| 41 |
+
NPY_ULONGLONG
|
| 42 |
+
NPY_FLOAT
|
| 43 |
+
NPY_DOUBLE
|
| 44 |
+
NPY_LONGDOUBLE
|
| 45 |
+
NPY_CFLOAT
|
| 46 |
+
NPY_CDOUBLE
|
| 47 |
+
NPY_CLONGDOUBLE
|
| 48 |
+
NPY_OBJECT
|
| 49 |
+
NPY_STRING
|
| 50 |
+
NPY_UNICODE
|
| 51 |
+
NPY_VOID
|
| 52 |
+
NPY_DATETIME
|
| 53 |
+
NPY_TIMEDELTA
|
| 54 |
+
NPY_NTYPES
|
| 55 |
+
NPY_NOTYPE
|
| 56 |
+
|
| 57 |
+
NPY_INT8
|
| 58 |
+
NPY_INT16
|
| 59 |
+
NPY_INT32
|
| 60 |
+
NPY_INT64
|
| 61 |
+
NPY_INT128
|
| 62 |
+
NPY_INT256
|
| 63 |
+
NPY_UINT8
|
| 64 |
+
NPY_UINT16
|
| 65 |
+
NPY_UINT32
|
| 66 |
+
NPY_UINT64
|
| 67 |
+
NPY_UINT128
|
| 68 |
+
NPY_UINT256
|
| 69 |
+
NPY_FLOAT16
|
| 70 |
+
NPY_FLOAT32
|
| 71 |
+
NPY_FLOAT64
|
| 72 |
+
NPY_FLOAT80
|
| 73 |
+
NPY_FLOAT96
|
| 74 |
+
NPY_FLOAT128
|
| 75 |
+
NPY_FLOAT256
|
| 76 |
+
NPY_COMPLEX32
|
| 77 |
+
NPY_COMPLEX64
|
| 78 |
+
NPY_COMPLEX128
|
| 79 |
+
NPY_COMPLEX160
|
| 80 |
+
NPY_COMPLEX192
|
| 81 |
+
NPY_COMPLEX256
|
| 82 |
+
NPY_COMPLEX512
|
| 83 |
+
|
| 84 |
+
NPY_INTP
|
| 85 |
+
|
| 86 |
+
ctypedef enum NPY_ORDER:
|
| 87 |
+
NPY_ANYORDER
|
| 88 |
+
NPY_CORDER
|
| 89 |
+
NPY_FORTRANORDER
|
| 90 |
+
NPY_KEEPORDER
|
| 91 |
+
|
| 92 |
+
ctypedef enum NPY_CASTING:
|
| 93 |
+
NPY_NO_CASTING
|
| 94 |
+
NPY_EQUIV_CASTING
|
| 95 |
+
NPY_SAFE_CASTING
|
| 96 |
+
NPY_SAME_KIND_CASTING
|
| 97 |
+
NPY_UNSAFE_CASTING
|
| 98 |
+
|
| 99 |
+
ctypedef enum NPY_CLIPMODE:
|
| 100 |
+
NPY_CLIP
|
| 101 |
+
NPY_WRAP
|
| 102 |
+
NPY_RAISE
|
| 103 |
+
|
| 104 |
+
ctypedef enum NPY_SCALARKIND:
|
| 105 |
+
NPY_NOSCALAR,
|
| 106 |
+
NPY_BOOL_SCALAR,
|
| 107 |
+
NPY_INTPOS_SCALAR,
|
| 108 |
+
NPY_INTNEG_SCALAR,
|
| 109 |
+
NPY_FLOAT_SCALAR,
|
| 110 |
+
NPY_COMPLEX_SCALAR,
|
| 111 |
+
NPY_OBJECT_SCALAR
|
| 112 |
+
|
| 113 |
+
ctypedef enum NPY_SORTKIND:
|
| 114 |
+
NPY_QUICKSORT
|
| 115 |
+
NPY_HEAPSORT
|
| 116 |
+
NPY_MERGESORT
|
| 117 |
+
|
| 118 |
+
ctypedef enum NPY_SEARCHSIDE:
|
| 119 |
+
NPY_SEARCHLEFT
|
| 120 |
+
NPY_SEARCHRIGHT
|
| 121 |
+
|
| 122 |
+
enum:
|
| 123 |
+
# DEPRECATED since NumPy 1.7 ! Do not use in new code!
|
| 124 |
+
NPY_C_CONTIGUOUS
|
| 125 |
+
NPY_F_CONTIGUOUS
|
| 126 |
+
NPY_CONTIGUOUS
|
| 127 |
+
NPY_FORTRAN
|
| 128 |
+
NPY_OWNDATA
|
| 129 |
+
NPY_FORCECAST
|
| 130 |
+
NPY_ENSURECOPY
|
| 131 |
+
NPY_ENSUREARRAY
|
| 132 |
+
NPY_ELEMENTSTRIDES
|
| 133 |
+
NPY_ALIGNED
|
| 134 |
+
NPY_NOTSWAPPED
|
| 135 |
+
NPY_WRITEABLE
|
| 136 |
+
NPY_ARR_HAS_DESCR
|
| 137 |
+
|
| 138 |
+
NPY_BEHAVED
|
| 139 |
+
NPY_BEHAVED_NS
|
| 140 |
+
NPY_CARRAY
|
| 141 |
+
NPY_CARRAY_RO
|
| 142 |
+
NPY_FARRAY
|
| 143 |
+
NPY_FARRAY_RO
|
| 144 |
+
NPY_DEFAULT
|
| 145 |
+
|
| 146 |
+
NPY_IN_ARRAY
|
| 147 |
+
NPY_OUT_ARRAY
|
| 148 |
+
NPY_INOUT_ARRAY
|
| 149 |
+
NPY_IN_FARRAY
|
| 150 |
+
NPY_OUT_FARRAY
|
| 151 |
+
NPY_INOUT_FARRAY
|
| 152 |
+
|
| 153 |
+
NPY_UPDATE_ALL
|
| 154 |
+
|
| 155 |
+
enum:
|
| 156 |
+
# Added in NumPy 1.7 to replace the deprecated enums above.
|
| 157 |
+
NPY_ARRAY_C_CONTIGUOUS
|
| 158 |
+
NPY_ARRAY_F_CONTIGUOUS
|
| 159 |
+
NPY_ARRAY_OWNDATA
|
| 160 |
+
NPY_ARRAY_FORCECAST
|
| 161 |
+
NPY_ARRAY_ENSURECOPY
|
| 162 |
+
NPY_ARRAY_ENSUREARRAY
|
| 163 |
+
NPY_ARRAY_ELEMENTSTRIDES
|
| 164 |
+
NPY_ARRAY_ALIGNED
|
| 165 |
+
NPY_ARRAY_NOTSWAPPED
|
| 166 |
+
NPY_ARRAY_WRITEABLE
|
| 167 |
+
NPY_ARRAY_WRITEBACKIFCOPY
|
| 168 |
+
|
| 169 |
+
NPY_ARRAY_BEHAVED
|
| 170 |
+
NPY_ARRAY_BEHAVED_NS
|
| 171 |
+
NPY_ARRAY_CARRAY
|
| 172 |
+
NPY_ARRAY_CARRAY_RO
|
| 173 |
+
NPY_ARRAY_FARRAY
|
| 174 |
+
NPY_ARRAY_FARRAY_RO
|
| 175 |
+
NPY_ARRAY_DEFAULT
|
| 176 |
+
|
| 177 |
+
NPY_ARRAY_IN_ARRAY
|
| 178 |
+
NPY_ARRAY_OUT_ARRAY
|
| 179 |
+
NPY_ARRAY_INOUT_ARRAY
|
| 180 |
+
NPY_ARRAY_IN_FARRAY
|
| 181 |
+
NPY_ARRAY_OUT_FARRAY
|
| 182 |
+
NPY_ARRAY_INOUT_FARRAY
|
| 183 |
+
|
| 184 |
+
NPY_ARRAY_UPDATE_ALL
|
| 185 |
+
|
| 186 |
+
cdef enum:
|
| 187 |
+
NPY_MAXDIMS
|
| 188 |
+
|
| 189 |
+
npy_intp NPY_MAX_ELSIZE
|
| 190 |
+
|
| 191 |
+
ctypedef void (*PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *, void *)
|
| 192 |
+
|
| 193 |
+
ctypedef struct PyArray_ArrayDescr:
|
| 194 |
+
# shape is a tuple, but Cython doesn't support "tuple shape"
|
| 195 |
+
# inside a non-PyObject declaration, so we have to declare it
|
| 196 |
+
# as just a PyObject*.
|
| 197 |
+
PyObject* shape
|
| 198 |
+
|
| 199 |
+
ctypedef struct PyArray_Descr:
|
| 200 |
+
pass
|
| 201 |
+
|
| 202 |
+
ctypedef class numpy.dtype [object PyArray_Descr, check_size ignore]:
|
| 203 |
+
# Use PyDataType_* macros when possible, however there are no macros
|
| 204 |
+
# for accessing some of the fields, so some are defined.
|
| 205 |
+
cdef PyTypeObject* typeobj
|
| 206 |
+
cdef char kind
|
| 207 |
+
cdef char type
|
| 208 |
+
# Numpy sometimes mutates this without warning (e.g. it'll
|
| 209 |
+
# sometimes change "|" to "<" in shared dtype objects on
|
| 210 |
+
# little-endian machines). If this matters to you, use
|
| 211 |
+
# PyArray_IsNativeByteOrder(dtype.byteorder) instead of
|
| 212 |
+
# directly accessing this field.
|
| 213 |
+
cdef char byteorder
|
| 214 |
+
cdef char flags
|
| 215 |
+
cdef int type_num
|
| 216 |
+
cdef int itemsize "elsize"
|
| 217 |
+
cdef int alignment
|
| 218 |
+
cdef object fields
|
| 219 |
+
cdef tuple names
|
| 220 |
+
# Use PyDataType_HASSUBARRAY to test whether this field is
|
| 221 |
+
# valid (the pointer can be NULL). Most users should access
|
| 222 |
+
# this field via the inline helper method PyDataType_SHAPE.
|
| 223 |
+
cdef PyArray_ArrayDescr* subarray
|
| 224 |
+
|
| 225 |
+
ctypedef class numpy.flatiter [object PyArrayIterObject, check_size ignore]:
|
| 226 |
+
# Use through macros
|
| 227 |
+
pass
|
| 228 |
+
|
| 229 |
+
ctypedef class numpy.broadcast [object PyArrayMultiIterObject, check_size ignore]:
|
| 230 |
+
# Use through macros
|
| 231 |
+
pass
|
| 232 |
+
|
| 233 |
+
ctypedef struct PyArrayObject:
|
| 234 |
+
# For use in situations where ndarray can't replace PyArrayObject*,
|
| 235 |
+
# like PyArrayObject**.
|
| 236 |
+
pass
|
| 237 |
+
|
| 238 |
+
ctypedef class numpy.ndarray [object PyArrayObject, check_size ignore]:
|
| 239 |
+
cdef __cythonbufferdefaults__ = {"mode": "strided"}
|
| 240 |
+
|
| 241 |
+
# NOTE: no field declarations since direct access is deprecated since NumPy 1.7
|
| 242 |
+
# Instead, we use properties that map to the corresponding C-API functions.
|
| 243 |
+
|
| 244 |
+
@property
|
| 245 |
+
cdef inline PyObject* base(self) nogil:
|
| 246 |
+
"""Returns a borrowed reference to the object owning the data/memory.
|
| 247 |
+
"""
|
| 248 |
+
return PyArray_BASE(self)
|
| 249 |
+
|
| 250 |
+
@property
|
| 251 |
+
cdef inline dtype descr(self):
|
| 252 |
+
"""Returns an owned reference to the dtype of the array.
|
| 253 |
+
"""
|
| 254 |
+
return <dtype>PyArray_DESCR(self)
|
| 255 |
+
|
| 256 |
+
@property
|
| 257 |
+
cdef inline int ndim(self) nogil:
|
| 258 |
+
"""Returns the number of dimensions in the array.
|
| 259 |
+
"""
|
| 260 |
+
return PyArray_NDIM(self)
|
| 261 |
+
|
| 262 |
+
@property
|
| 263 |
+
cdef inline npy_intp *shape(self) nogil:
|
| 264 |
+
"""Returns a pointer to the dimensions/shape of the array.
|
| 265 |
+
The number of elements matches the number of dimensions of the array (ndim).
|
| 266 |
+
Can return NULL for 0-dimensional arrays.
|
| 267 |
+
"""
|
| 268 |
+
return PyArray_DIMS(self)
|
| 269 |
+
|
| 270 |
+
@property
|
| 271 |
+
cdef inline npy_intp *strides(self) nogil:
|
| 272 |
+
"""Returns a pointer to the strides of the array.
|
| 273 |
+
The number of elements matches the number of dimensions of the array (ndim).
|
| 274 |
+
"""
|
| 275 |
+
return PyArray_STRIDES(self)
|
| 276 |
+
|
| 277 |
+
@property
|
| 278 |
+
cdef inline npy_intp size(self) nogil:
|
| 279 |
+
"""Returns the total size (in number of elements) of the array.
|
| 280 |
+
"""
|
| 281 |
+
return PyArray_SIZE(self)
|
| 282 |
+
|
| 283 |
+
@property
|
| 284 |
+
cdef inline char* data(self) nogil:
|
| 285 |
+
"""The pointer to the data buffer as a char*.
|
| 286 |
+
This is provided for legacy reasons to avoid direct struct field access.
|
| 287 |
+
For new code that needs this access, you probably want to cast the result
|
| 288 |
+
of `PyArray_DATA()` instead, which returns a 'void*'.
|
| 289 |
+
"""
|
| 290 |
+
return PyArray_BYTES(self)
|
| 291 |
+
|
| 292 |
+
ctypedef unsigned char npy_bool
|
| 293 |
+
|
| 294 |
+
ctypedef signed char npy_byte
|
| 295 |
+
ctypedef signed short npy_short
|
| 296 |
+
ctypedef signed int npy_int
|
| 297 |
+
ctypedef signed long npy_long
|
| 298 |
+
ctypedef signed long long npy_longlong
|
| 299 |
+
|
| 300 |
+
ctypedef unsigned char npy_ubyte
|
| 301 |
+
ctypedef unsigned short npy_ushort
|
| 302 |
+
ctypedef unsigned int npy_uint
|
| 303 |
+
ctypedef unsigned long npy_ulong
|
| 304 |
+
ctypedef unsigned long long npy_ulonglong
|
| 305 |
+
|
| 306 |
+
ctypedef float npy_float
|
| 307 |
+
ctypedef double npy_double
|
| 308 |
+
ctypedef long double npy_longdouble
|
| 309 |
+
|
| 310 |
+
ctypedef signed char npy_int8
|
| 311 |
+
ctypedef signed short npy_int16
|
| 312 |
+
ctypedef signed int npy_int32
|
| 313 |
+
ctypedef signed long long npy_int64
|
| 314 |
+
ctypedef signed long long npy_int96
|
| 315 |
+
ctypedef signed long long npy_int128
|
| 316 |
+
|
| 317 |
+
ctypedef unsigned char npy_uint8
|
| 318 |
+
ctypedef unsigned short npy_uint16
|
| 319 |
+
ctypedef unsigned int npy_uint32
|
| 320 |
+
ctypedef unsigned long long npy_uint64
|
| 321 |
+
ctypedef unsigned long long npy_uint96
|
| 322 |
+
ctypedef unsigned long long npy_uint128
|
| 323 |
+
|
| 324 |
+
ctypedef float npy_float32
|
| 325 |
+
ctypedef double npy_float64
|
| 326 |
+
ctypedef long double npy_float80
|
| 327 |
+
ctypedef long double npy_float96
|
| 328 |
+
ctypedef long double npy_float128
|
| 329 |
+
|
| 330 |
+
ctypedef struct npy_cfloat:
|
| 331 |
+
float real
|
| 332 |
+
float imag
|
| 333 |
+
|
| 334 |
+
ctypedef struct npy_cdouble:
|
| 335 |
+
double real
|
| 336 |
+
double imag
|
| 337 |
+
|
| 338 |
+
ctypedef struct npy_clongdouble:
|
| 339 |
+
long double real
|
| 340 |
+
long double imag
|
| 341 |
+
|
| 342 |
+
ctypedef struct npy_complex64:
|
| 343 |
+
float real
|
| 344 |
+
float imag
|
| 345 |
+
|
| 346 |
+
ctypedef struct npy_complex128:
|
| 347 |
+
double real
|
| 348 |
+
double imag
|
| 349 |
+
|
| 350 |
+
ctypedef struct npy_complex160:
|
| 351 |
+
long double real
|
| 352 |
+
long double imag
|
| 353 |
+
|
| 354 |
+
ctypedef struct npy_complex192:
|
| 355 |
+
long double real
|
| 356 |
+
long double imag
|
| 357 |
+
|
| 358 |
+
ctypedef struct npy_complex256:
|
| 359 |
+
long double real
|
| 360 |
+
long double imag
|
| 361 |
+
|
| 362 |
+
ctypedef struct PyArray_Dims:
|
| 363 |
+
npy_intp *ptr
|
| 364 |
+
int len
|
| 365 |
+
|
| 366 |
+
int _import_array() except -1
|
| 367 |
+
# A second definition so _import_array isn't marked as used when we use it here.
|
| 368 |
+
# Do not use - subject to change any time.
|
| 369 |
+
int __pyx_import_array "_import_array"() except -1
|
| 370 |
+
|
| 371 |
+
#
|
| 372 |
+
# Macros from ndarrayobject.h
|
| 373 |
+
#
|
| 374 |
+
bint PyArray_CHKFLAGS(ndarray m, int flags) nogil
|
| 375 |
+
bint PyArray_IS_C_CONTIGUOUS(ndarray arr) nogil
|
| 376 |
+
bint PyArray_IS_F_CONTIGUOUS(ndarray arr) nogil
|
| 377 |
+
bint PyArray_ISCONTIGUOUS(ndarray m) nogil
|
| 378 |
+
bint PyArray_ISWRITEABLE(ndarray m) nogil
|
| 379 |
+
bint PyArray_ISALIGNED(ndarray m) nogil
|
| 380 |
+
|
| 381 |
+
int PyArray_NDIM(ndarray) nogil
|
| 382 |
+
bint PyArray_ISONESEGMENT(ndarray) nogil
|
| 383 |
+
bint PyArray_ISFORTRAN(ndarray) nogil
|
| 384 |
+
int PyArray_FORTRANIF(ndarray) nogil
|
| 385 |
+
|
| 386 |
+
void* PyArray_DATA(ndarray) nogil
|
| 387 |
+
char* PyArray_BYTES(ndarray) nogil
|
| 388 |
+
|
| 389 |
+
npy_intp* PyArray_DIMS(ndarray) nogil
|
| 390 |
+
npy_intp* PyArray_STRIDES(ndarray) nogil
|
| 391 |
+
npy_intp PyArray_DIM(ndarray, size_t) nogil
|
| 392 |
+
npy_intp PyArray_STRIDE(ndarray, size_t) nogil
|
| 393 |
+
|
| 394 |
+
PyObject *PyArray_BASE(ndarray) nogil # returns borrowed reference!
|
| 395 |
+
PyArray_Descr *PyArray_DESCR(ndarray) nogil # returns borrowed reference to dtype!
|
| 396 |
+
PyArray_Descr *PyArray_DTYPE(ndarray) nogil # returns borrowed reference to dtype! NP 1.7+ alias for descr.
|
| 397 |
+
int PyArray_FLAGS(ndarray) nogil
|
| 398 |
+
void PyArray_CLEARFLAGS(ndarray, int flags) nogil # Added in NumPy 1.7
|
| 399 |
+
void PyArray_ENABLEFLAGS(ndarray, int flags) nogil # Added in NumPy 1.7
|
| 400 |
+
npy_intp PyArray_ITEMSIZE(ndarray) nogil
|
| 401 |
+
int PyArray_TYPE(ndarray arr) nogil
|
| 402 |
+
|
| 403 |
+
object PyArray_GETITEM(ndarray arr, void *itemptr)
|
| 404 |
+
int PyArray_SETITEM(ndarray arr, void *itemptr, object obj) except -1
|
| 405 |
+
|
| 406 |
+
bint PyTypeNum_ISBOOL(int) nogil
|
| 407 |
+
bint PyTypeNum_ISUNSIGNED(int) nogil
|
| 408 |
+
bint PyTypeNum_ISSIGNED(int) nogil
|
| 409 |
+
bint PyTypeNum_ISINTEGER(int) nogil
|
| 410 |
+
bint PyTypeNum_ISFLOAT(int) nogil
|
| 411 |
+
bint PyTypeNum_ISNUMBER(int) nogil
|
| 412 |
+
bint PyTypeNum_ISSTRING(int) nogil
|
| 413 |
+
bint PyTypeNum_ISCOMPLEX(int) nogil
|
| 414 |
+
bint PyTypeNum_ISPYTHON(int) nogil
|
| 415 |
+
bint PyTypeNum_ISFLEXIBLE(int) nogil
|
| 416 |
+
bint PyTypeNum_ISUSERDEF(int) nogil
|
| 417 |
+
bint PyTypeNum_ISEXTENDED(int) nogil
|
| 418 |
+
bint PyTypeNum_ISOBJECT(int) nogil
|
| 419 |
+
|
| 420 |
+
bint PyDataType_ISBOOL(dtype) nogil
|
| 421 |
+
bint PyDataType_ISUNSIGNED(dtype) nogil
|
| 422 |
+
bint PyDataType_ISSIGNED(dtype) nogil
|
| 423 |
+
bint PyDataType_ISINTEGER(dtype) nogil
|
| 424 |
+
bint PyDataType_ISFLOAT(dtype) nogil
|
| 425 |
+
bint PyDataType_ISNUMBER(dtype) nogil
|
| 426 |
+
bint PyDataType_ISSTRING(dtype) nogil
|
| 427 |
+
bint PyDataType_ISCOMPLEX(dtype) nogil
|
| 428 |
+
bint PyDataType_ISPYTHON(dtype) nogil
|
| 429 |
+
bint PyDataType_ISFLEXIBLE(dtype) nogil
|
| 430 |
+
bint PyDataType_ISUSERDEF(dtype) nogil
|
| 431 |
+
bint PyDataType_ISEXTENDED(dtype) nogil
|
| 432 |
+
bint PyDataType_ISOBJECT(dtype) nogil
|
| 433 |
+
bint PyDataType_HASFIELDS(dtype) nogil
|
| 434 |
+
bint PyDataType_HASSUBARRAY(dtype) nogil
|
| 435 |
+
|
| 436 |
+
bint PyArray_ISBOOL(ndarray) nogil
|
| 437 |
+
bint PyArray_ISUNSIGNED(ndarray) nogil
|
| 438 |
+
bint PyArray_ISSIGNED(ndarray) nogil
|
| 439 |
+
bint PyArray_ISINTEGER(ndarray) nogil
|
| 440 |
+
bint PyArray_ISFLOAT(ndarray) nogil
|
| 441 |
+
bint PyArray_ISNUMBER(ndarray) nogil
|
| 442 |
+
bint PyArray_ISSTRING(ndarray) nogil
|
| 443 |
+
bint PyArray_ISCOMPLEX(ndarray) nogil
|
| 444 |
+
bint PyArray_ISPYTHON(ndarray) nogil
|
| 445 |
+
bint PyArray_ISFLEXIBLE(ndarray) nogil
|
| 446 |
+
bint PyArray_ISUSERDEF(ndarray) nogil
|
| 447 |
+
bint PyArray_ISEXTENDED(ndarray) nogil
|
| 448 |
+
bint PyArray_ISOBJECT(ndarray) nogil
|
| 449 |
+
bint PyArray_HASFIELDS(ndarray) nogil
|
| 450 |
+
|
| 451 |
+
bint PyArray_ISVARIABLE(ndarray) nogil
|
| 452 |
+
|
| 453 |
+
bint PyArray_SAFEALIGNEDCOPY(ndarray) nogil
|
| 454 |
+
bint PyArray_ISNBO(char) nogil # works on ndarray.byteorder
|
| 455 |
+
bint PyArray_IsNativeByteOrder(char) nogil # works on ndarray.byteorder
|
| 456 |
+
bint PyArray_ISNOTSWAPPED(ndarray) nogil
|
| 457 |
+
bint PyArray_ISBYTESWAPPED(ndarray) nogil
|
| 458 |
+
|
| 459 |
+
bint PyArray_FLAGSWAP(ndarray, int) nogil
|
| 460 |
+
|
| 461 |
+
bint PyArray_ISCARRAY(ndarray) nogil
|
| 462 |
+
bint PyArray_ISCARRAY_RO(ndarray) nogil
|
| 463 |
+
bint PyArray_ISFARRAY(ndarray) nogil
|
| 464 |
+
bint PyArray_ISFARRAY_RO(ndarray) nogil
|
| 465 |
+
bint PyArray_ISBEHAVED(ndarray) nogil
|
| 466 |
+
bint PyArray_ISBEHAVED_RO(ndarray) nogil
|
| 467 |
+
|
| 468 |
+
|
| 469 |
+
bint PyDataType_ISNOTSWAPPED(dtype) nogil
|
| 470 |
+
bint PyDataType_ISBYTESWAPPED(dtype) nogil
|
| 471 |
+
|
| 472 |
+
bint PyArray_DescrCheck(object)
|
| 473 |
+
|
| 474 |
+
bint PyArray_Check(object)
|
| 475 |
+
bint PyArray_CheckExact(object)
|
| 476 |
+
|
| 477 |
+
# Cannot be supported due to out arg:
|
| 478 |
+
# bint PyArray_HasArrayInterfaceType(object, dtype, object, object&)
|
| 479 |
+
# bint PyArray_HasArrayInterface(op, out)
|
| 480 |
+
|
| 481 |
+
|
| 482 |
+
bint PyArray_IsZeroDim(object)
|
| 483 |
+
# Cannot be supported due to ## ## in macro:
|
| 484 |
+
# bint PyArray_IsScalar(object, verbatim work)
|
| 485 |
+
bint PyArray_CheckScalar(object)
|
| 486 |
+
bint PyArray_IsPythonNumber(object)
|
| 487 |
+
bint PyArray_IsPythonScalar(object)
|
| 488 |
+
bint PyArray_IsAnyScalar(object)
|
| 489 |
+
bint PyArray_CheckAnyScalar(object)
|
| 490 |
+
|
| 491 |
+
ndarray PyArray_GETCONTIGUOUS(ndarray)
|
| 492 |
+
bint PyArray_SAMESHAPE(ndarray, ndarray) nogil
|
| 493 |
+
npy_intp PyArray_SIZE(ndarray) nogil
|
| 494 |
+
npy_intp PyArray_NBYTES(ndarray) nogil
|
| 495 |
+
|
| 496 |
+
object PyArray_FROM_O(object)
|
| 497 |
+
object PyArray_FROM_OF(object m, int flags)
|
| 498 |
+
object PyArray_FROM_OT(object m, int type)
|
| 499 |
+
object PyArray_FROM_OTF(object m, int type, int flags)
|
| 500 |
+
object PyArray_FROMANY(object m, int type, int min, int max, int flags)
|
| 501 |
+
object PyArray_ZEROS(int nd, npy_intp* dims, int type, int fortran)
|
| 502 |
+
object PyArray_EMPTY(int nd, npy_intp* dims, int type, int fortran)
|
| 503 |
+
void PyArray_FILLWBYTE(object, int val)
|
| 504 |
+
npy_intp PyArray_REFCOUNT(object)
|
| 505 |
+
object PyArray_ContiguousFromAny(op, int, int min_depth, int max_depth)
|
| 506 |
+
unsigned char PyArray_EquivArrTypes(ndarray a1, ndarray a2)
|
| 507 |
+
bint PyArray_EquivByteorders(int b1, int b2) nogil
|
| 508 |
+
object PyArray_SimpleNew(int nd, npy_intp* dims, int typenum)
|
| 509 |
+
object PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data)
|
| 510 |
+
#object PyArray_SimpleNewFromDescr(int nd, npy_intp* dims, dtype descr)
|
| 511 |
+
object PyArray_ToScalar(void* data, ndarray arr)
|
| 512 |
+
|
| 513 |
+
void* PyArray_GETPTR1(ndarray m, npy_intp i) nogil
|
| 514 |
+
void* PyArray_GETPTR2(ndarray m, npy_intp i, npy_intp j) nogil
|
| 515 |
+
void* PyArray_GETPTR3(ndarray m, npy_intp i, npy_intp j, npy_intp k) nogil
|
| 516 |
+
void* PyArray_GETPTR4(ndarray m, npy_intp i, npy_intp j, npy_intp k, npy_intp l) nogil
|
| 517 |
+
|
| 518 |
+
# Cannot be supported due to out arg
|
| 519 |
+
# void PyArray_DESCR_REPLACE(descr)
|
| 520 |
+
|
| 521 |
+
|
| 522 |
+
object PyArray_Copy(ndarray)
|
| 523 |
+
object PyArray_FromObject(object op, int type, int min_depth, int max_depth)
|
| 524 |
+
object PyArray_ContiguousFromObject(object op, int type, int min_depth, int max_depth)
|
| 525 |
+
object PyArray_CopyFromObject(object op, int type, int min_depth, int max_depth)
|
| 526 |
+
|
| 527 |
+
object PyArray_Cast(ndarray mp, int type_num)
|
| 528 |
+
object PyArray_Take(ndarray ap, object items, int axis)
|
| 529 |
+
object PyArray_Put(ndarray ap, object items, object values)
|
| 530 |
+
|
| 531 |
+
void PyArray_ITER_RESET(flatiter it) nogil
|
| 532 |
+
void PyArray_ITER_NEXT(flatiter it) nogil
|
| 533 |
+
void PyArray_ITER_GOTO(flatiter it, npy_intp* destination) nogil
|
| 534 |
+
void PyArray_ITER_GOTO1D(flatiter it, npy_intp ind) nogil
|
| 535 |
+
void* PyArray_ITER_DATA(flatiter it) nogil
|
| 536 |
+
bint PyArray_ITER_NOTDONE(flatiter it) nogil
|
| 537 |
+
|
| 538 |
+
void PyArray_MultiIter_RESET(broadcast multi) nogil
|
| 539 |
+
void PyArray_MultiIter_NEXT(broadcast multi) nogil
|
| 540 |
+
void PyArray_MultiIter_GOTO(broadcast multi, npy_intp dest) nogil
|
| 541 |
+
void PyArray_MultiIter_GOTO1D(broadcast multi, npy_intp ind) nogil
|
| 542 |
+
void* PyArray_MultiIter_DATA(broadcast multi, npy_intp i) nogil
|
| 543 |
+
void PyArray_MultiIter_NEXTi(broadcast multi, npy_intp i) nogil
|
| 544 |
+
bint PyArray_MultiIter_NOTDONE(broadcast multi) nogil
|
| 545 |
+
|
| 546 |
+
# Functions from __multiarray_api.h
|
| 547 |
+
|
| 548 |
+
# Functions taking dtype and returning object/ndarray are disabled
|
| 549 |
+
# for now as they steal dtype references. I'm conservative and disable
|
| 550 |
+
# more than is probably needed until it can be checked further.
|
| 551 |
+
int PyArray_SetNumericOps (object) except -1
|
| 552 |
+
object PyArray_GetNumericOps ()
|
| 553 |
+
int PyArray_INCREF (ndarray) except * # uses PyArray_Item_INCREF...
|
| 554 |
+
int PyArray_XDECREF (ndarray) except * # uses PyArray_Item_DECREF...
|
| 555 |
+
void PyArray_SetStringFunction (object, int)
|
| 556 |
+
dtype PyArray_DescrFromType (int)
|
| 557 |
+
object PyArray_TypeObjectFromType (int)
|
| 558 |
+
char * PyArray_Zero (ndarray)
|
| 559 |
+
char * PyArray_One (ndarray)
|
| 560 |
+
#object PyArray_CastToType (ndarray, dtype, int)
|
| 561 |
+
int PyArray_CastTo (ndarray, ndarray) except -1
|
| 562 |
+
int PyArray_CastAnyTo (ndarray, ndarray) except -1
|
| 563 |
+
int PyArray_CanCastSafely (int, int) # writes errors
|
| 564 |
+
npy_bool PyArray_CanCastTo (dtype, dtype) # writes errors
|
| 565 |
+
int PyArray_ObjectType (object, int) except 0
|
| 566 |
+
dtype PyArray_DescrFromObject (object, dtype)
|
| 567 |
+
#ndarray* PyArray_ConvertToCommonType (object, int *)
|
| 568 |
+
dtype PyArray_DescrFromScalar (object)
|
| 569 |
+
dtype PyArray_DescrFromTypeObject (object)
|
| 570 |
+
npy_intp PyArray_Size (object)
|
| 571 |
+
#object PyArray_Scalar (void *, dtype, object)
|
| 572 |
+
#object PyArray_FromScalar (object, dtype)
|
| 573 |
+
void PyArray_ScalarAsCtype (object, void *)
|
| 574 |
+
#int PyArray_CastScalarToCtype (object, void *, dtype)
|
| 575 |
+
#int PyArray_CastScalarDirect (object, dtype, void *, int)
|
| 576 |
+
object PyArray_ScalarFromObject (object)
|
| 577 |
+
#PyArray_VectorUnaryFunc * PyArray_GetCastFunc (dtype, int)
|
| 578 |
+
object PyArray_FromDims (int, int *, int)
|
| 579 |
+
#object PyArray_FromDimsAndDataAndDescr (int, int *, dtype, char *)
|
| 580 |
+
#object PyArray_FromAny (object, dtype, int, int, int, object)
|
| 581 |
+
object PyArray_EnsureArray (object)
|
| 582 |
+
object PyArray_EnsureAnyArray (object)
|
| 583 |
+
#object PyArray_FromFile (stdio.FILE *, dtype, npy_intp, char *)
|
| 584 |
+
#object PyArray_FromString (char *, npy_intp, dtype, npy_intp, char *)
|
| 585 |
+
#object PyArray_FromBuffer (object, dtype, npy_intp, npy_intp)
|
| 586 |
+
#object PyArray_FromIter (object, dtype, npy_intp)
|
| 587 |
+
object PyArray_Return (ndarray)
|
| 588 |
+
#object PyArray_GetField (ndarray, dtype, int)
|
| 589 |
+
#int PyArray_SetField (ndarray, dtype, int, object) except -1
|
| 590 |
+
object PyArray_Byteswap (ndarray, npy_bool)
|
| 591 |
+
object PyArray_Resize (ndarray, PyArray_Dims *, int, NPY_ORDER)
|
| 592 |
+
int PyArray_MoveInto (ndarray, ndarray) except -1
|
| 593 |
+
int PyArray_CopyInto (ndarray, ndarray) except -1
|
| 594 |
+
int PyArray_CopyAnyInto (ndarray, ndarray) except -1
|
| 595 |
+
int PyArray_CopyObject (ndarray, object) except -1
|
| 596 |
+
object PyArray_NewCopy (ndarray, NPY_ORDER)
|
| 597 |
+
object PyArray_ToList (ndarray)
|
| 598 |
+
object PyArray_ToString (ndarray, NPY_ORDER)
|
| 599 |
+
int PyArray_ToFile (ndarray, stdio.FILE *, char *, char *) except -1
|
| 600 |
+
int PyArray_Dump (object, object, int) except -1
|
| 601 |
+
object PyArray_Dumps (object, int)
|
| 602 |
+
int PyArray_ValidType (int) # Cannot error
|
| 603 |
+
void PyArray_UpdateFlags (ndarray, int)
|
| 604 |
+
object PyArray_New (type, int, npy_intp *, int, npy_intp *, void *, int, int, object)
|
| 605 |
+
#object PyArray_NewFromDescr (type, dtype, int, npy_intp *, npy_intp *, void *, int, object)
|
| 606 |
+
#dtype PyArray_DescrNew (dtype)
|
| 607 |
+
dtype PyArray_DescrNewFromType (int)
|
| 608 |
+
double PyArray_GetPriority (object, double) # clears errors as of 1.25
|
| 609 |
+
object PyArray_IterNew (object)
|
| 610 |
+
object PyArray_MultiIterNew (int, ...)
|
| 611 |
+
|
| 612 |
+
int PyArray_PyIntAsInt (object) except? -1
|
| 613 |
+
npy_intp PyArray_PyIntAsIntp (object)
|
| 614 |
+
int PyArray_Broadcast (broadcast) except -1
|
| 615 |
+
void PyArray_FillObjectArray (ndarray, object) except *
|
| 616 |
+
int PyArray_FillWithScalar (ndarray, object) except -1
|
| 617 |
+
npy_bool PyArray_CheckStrides (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)
|
| 618 |
+
dtype PyArray_DescrNewByteorder (dtype, char)
|
| 619 |
+
object PyArray_IterAllButAxis (object, int *)
|
| 620 |
+
#object PyArray_CheckFromAny (object, dtype, int, int, int, object)
|
| 621 |
+
#object PyArray_FromArray (ndarray, dtype, int)
|
| 622 |
+
object PyArray_FromInterface (object)
|
| 623 |
+
object PyArray_FromStructInterface (object)
|
| 624 |
+
#object PyArray_FromArrayAttr (object, dtype, object)
|
| 625 |
+
#NPY_SCALARKIND PyArray_ScalarKind (int, ndarray*)
|
| 626 |
+
int PyArray_CanCoerceScalar (int, int, NPY_SCALARKIND)
|
| 627 |
+
object PyArray_NewFlagsObject (object)
|
| 628 |
+
npy_bool PyArray_CanCastScalar (type, type)
|
| 629 |
+
#int PyArray_CompareUCS4 (npy_ucs4 *, npy_ucs4 *, register size_t)
|
| 630 |
+
int PyArray_RemoveSmallest (broadcast) except -1
|
| 631 |
+
int PyArray_ElementStrides (object)
|
| 632 |
+
void PyArray_Item_INCREF (char *, dtype) except *
|
| 633 |
+
void PyArray_Item_XDECREF (char *, dtype) except *
|
| 634 |
+
object PyArray_FieldNames (object)
|
| 635 |
+
object PyArray_Transpose (ndarray, PyArray_Dims *)
|
| 636 |
+
object PyArray_TakeFrom (ndarray, object, int, ndarray, NPY_CLIPMODE)
|
| 637 |
+
object PyArray_PutTo (ndarray, object, object, NPY_CLIPMODE)
|
| 638 |
+
object PyArray_PutMask (ndarray, object, object)
|
| 639 |
+
object PyArray_Repeat (ndarray, object, int)
|
| 640 |
+
object PyArray_Choose (ndarray, object, ndarray, NPY_CLIPMODE)
|
| 641 |
+
int PyArray_Sort (ndarray, int, NPY_SORTKIND) except -1
|
| 642 |
+
object PyArray_ArgSort (ndarray, int, NPY_SORTKIND)
|
| 643 |
+
object PyArray_SearchSorted (ndarray, object, NPY_SEARCHSIDE, PyObject *)
|
| 644 |
+
object PyArray_ArgMax (ndarray, int, ndarray)
|
| 645 |
+
object PyArray_ArgMin (ndarray, int, ndarray)
|
| 646 |
+
object PyArray_Reshape (ndarray, object)
|
| 647 |
+
object PyArray_Newshape (ndarray, PyArray_Dims *, NPY_ORDER)
|
| 648 |
+
object PyArray_Squeeze (ndarray)
|
| 649 |
+
#object PyArray_View (ndarray, dtype, type)
|
| 650 |
+
object PyArray_SwapAxes (ndarray, int, int)
|
| 651 |
+
object PyArray_Max (ndarray, int, ndarray)
|
| 652 |
+
object PyArray_Min (ndarray, int, ndarray)
|
| 653 |
+
object PyArray_Ptp (ndarray, int, ndarray)
|
| 654 |
+
object PyArray_Mean (ndarray, int, int, ndarray)
|
| 655 |
+
object PyArray_Trace (ndarray, int, int, int, int, ndarray)
|
| 656 |
+
object PyArray_Diagonal (ndarray, int, int, int)
|
| 657 |
+
object PyArray_Clip (ndarray, object, object, ndarray)
|
| 658 |
+
object PyArray_Conjugate (ndarray, ndarray)
|
| 659 |
+
object PyArray_Nonzero (ndarray)
|
| 660 |
+
object PyArray_Std (ndarray, int, int, ndarray, int)
|
| 661 |
+
object PyArray_Sum (ndarray, int, int, ndarray)
|
| 662 |
+
object PyArray_CumSum (ndarray, int, int, ndarray)
|
| 663 |
+
object PyArray_Prod (ndarray, int, int, ndarray)
|
| 664 |
+
object PyArray_CumProd (ndarray, int, int, ndarray)
|
| 665 |
+
object PyArray_All (ndarray, int, ndarray)
|
| 666 |
+
object PyArray_Any (ndarray, int, ndarray)
|
| 667 |
+
object PyArray_Compress (ndarray, object, int, ndarray)
|
| 668 |
+
object PyArray_Flatten (ndarray, NPY_ORDER)
|
| 669 |
+
object PyArray_Ravel (ndarray, NPY_ORDER)
|
| 670 |
+
npy_intp PyArray_MultiplyList (npy_intp *, int)
|
| 671 |
+
int PyArray_MultiplyIntList (int *, int)
|
| 672 |
+
void * PyArray_GetPtr (ndarray, npy_intp*)
|
| 673 |
+
int PyArray_CompareLists (npy_intp *, npy_intp *, int)
|
| 674 |
+
#int PyArray_AsCArray (object*, void *, npy_intp *, int, dtype)
|
| 675 |
+
#int PyArray_As1D (object*, char **, int *, int)
|
| 676 |
+
#int PyArray_As2D (object*, char ***, int *, int *, int)
|
| 677 |
+
int PyArray_Free (object, void *)
|
| 678 |
+
#int PyArray_Converter (object, object*)
|
| 679 |
+
int PyArray_IntpFromSequence (object, npy_intp *, int) except -1
|
| 680 |
+
object PyArray_Concatenate (object, int)
|
| 681 |
+
object PyArray_InnerProduct (object, object)
|
| 682 |
+
object PyArray_MatrixProduct (object, object)
|
| 683 |
+
object PyArray_CopyAndTranspose (object)
|
| 684 |
+
object PyArray_Correlate (object, object, int)
|
| 685 |
+
int PyArray_TypestrConvert (int, int)
|
| 686 |
+
#int PyArray_DescrConverter (object, dtype*) except 0
|
| 687 |
+
#int PyArray_DescrConverter2 (object, dtype*) except 0
|
| 688 |
+
int PyArray_IntpConverter (object, PyArray_Dims *) except 0
|
| 689 |
+
#int PyArray_BufferConverter (object, chunk) except 0
|
| 690 |
+
int PyArray_AxisConverter (object, int *) except 0
|
| 691 |
+
int PyArray_BoolConverter (object, npy_bool *) except 0
|
| 692 |
+
int PyArray_ByteorderConverter (object, char *) except 0
|
| 693 |
+
int PyArray_OrderConverter (object, NPY_ORDER *) except 0
|
| 694 |
+
unsigned char PyArray_EquivTypes (dtype, dtype) # clears errors
|
| 695 |
+
#object PyArray_Zeros (int, npy_intp *, dtype, int)
|
| 696 |
+
#object PyArray_Empty (int, npy_intp *, dtype, int)
|
| 697 |
+
object PyArray_Where (object, object, object)
|
| 698 |
+
object PyArray_Arange (double, double, double, int)
|
| 699 |
+
#object PyArray_ArangeObj (object, object, object, dtype)
|
| 700 |
+
int PyArray_SortkindConverter (object, NPY_SORTKIND *) except 0
|
| 701 |
+
object PyArray_LexSort (object, int)
|
| 702 |
+
object PyArray_Round (ndarray, int, ndarray)
|
| 703 |
+
unsigned char PyArray_EquivTypenums (int, int)
|
| 704 |
+
int PyArray_RegisterDataType (dtype) except -1
|
| 705 |
+
int PyArray_RegisterCastFunc (dtype, int, PyArray_VectorUnaryFunc *) except -1
|
| 706 |
+
int PyArray_RegisterCanCast (dtype, int, NPY_SCALARKIND) except -1
|
| 707 |
+
#void PyArray_InitArrFuncs (PyArray_ArrFuncs *)
|
| 708 |
+
object PyArray_IntTupleFromIntp (int, npy_intp *)
|
| 709 |
+
int PyArray_TypeNumFromName (char *)
|
| 710 |
+
int PyArray_ClipmodeConverter (object, NPY_CLIPMODE *) except 0
|
| 711 |
+
#int PyArray_OutputConverter (object, ndarray*) except 0
|
| 712 |
+
object PyArray_BroadcastToShape (object, npy_intp *, int)
|
| 713 |
+
void _PyArray_SigintHandler (int)
|
| 714 |
+
void* _PyArray_GetSigintBuf ()
|
| 715 |
+
#int PyArray_DescrAlignConverter (object, dtype*) except 0
|
| 716 |
+
#int PyArray_DescrAlignConverter2 (object, dtype*) except 0
|
| 717 |
+
int PyArray_SearchsideConverter (object, void *) except 0
|
| 718 |
+
object PyArray_CheckAxis (ndarray, int *, int)
|
| 719 |
+
npy_intp PyArray_OverflowMultiplyList (npy_intp *, int)
|
| 720 |
+
int PyArray_CompareString (char *, char *, size_t)
|
| 721 |
+
int PyArray_SetBaseObject(ndarray, base) except -1 # NOTE: steals a reference to base! Use "set_array_base()" instead.
|
| 722 |
+
|
| 723 |
+
|
| 724 |
+
# Typedefs that matches the runtime dtype objects in
|
| 725 |
+
# the numpy module.
|
| 726 |
+
|
| 727 |
+
# The ones that are commented out needs an IFDEF function
|
| 728 |
+
# in Cython to enable them only on the right systems.
|
| 729 |
+
|
| 730 |
+
ctypedef npy_int8 int8_t
|
| 731 |
+
ctypedef npy_int16 int16_t
|
| 732 |
+
ctypedef npy_int32 int32_t
|
| 733 |
+
ctypedef npy_int64 int64_t
|
| 734 |
+
#ctypedef npy_int96 int96_t
|
| 735 |
+
#ctypedef npy_int128 int128_t
|
| 736 |
+
|
| 737 |
+
ctypedef npy_uint8 uint8_t
|
| 738 |
+
ctypedef npy_uint16 uint16_t
|
| 739 |
+
ctypedef npy_uint32 uint32_t
|
| 740 |
+
ctypedef npy_uint64 uint64_t
|
| 741 |
+
#ctypedef npy_uint96 uint96_t
|
| 742 |
+
#ctypedef npy_uint128 uint128_t
|
| 743 |
+
|
| 744 |
+
ctypedef npy_float32 float32_t
|
| 745 |
+
ctypedef npy_float64 float64_t
|
| 746 |
+
#ctypedef npy_float80 float80_t
|
| 747 |
+
#ctypedef npy_float128 float128_t
|
| 748 |
+
|
| 749 |
+
ctypedef float complex complex64_t
|
| 750 |
+
ctypedef double complex complex128_t
|
| 751 |
+
|
| 752 |
+
# The int types are mapped a bit surprising --
|
| 753 |
+
# numpy.int corresponds to 'l' and numpy.long to 'q'
|
| 754 |
+
ctypedef npy_long int_t
|
| 755 |
+
ctypedef npy_longlong longlong_t
|
| 756 |
+
|
| 757 |
+
ctypedef npy_ulong uint_t
|
| 758 |
+
ctypedef npy_ulonglong ulonglong_t
|
| 759 |
+
|
| 760 |
+
ctypedef npy_intp intp_t
|
| 761 |
+
ctypedef npy_uintp uintp_t
|
| 762 |
+
|
| 763 |
+
ctypedef npy_double float_t
|
| 764 |
+
ctypedef npy_double double_t
|
| 765 |
+
ctypedef npy_longdouble longdouble_t
|
| 766 |
+
|
| 767 |
+
ctypedef npy_cfloat cfloat_t
|
| 768 |
+
ctypedef npy_cdouble cdouble_t
|
| 769 |
+
ctypedef npy_clongdouble clongdouble_t
|
| 770 |
+
|
| 771 |
+
ctypedef npy_cdouble complex_t
|
| 772 |
+
|
| 773 |
+
cdef inline object PyArray_MultiIterNew1(a):
|
| 774 |
+
return PyArray_MultiIterNew(1, <void*>a)
|
| 775 |
+
|
| 776 |
+
cdef inline object PyArray_MultiIterNew2(a, b):
|
| 777 |
+
return PyArray_MultiIterNew(2, <void*>a, <void*>b)
|
| 778 |
+
|
| 779 |
+
cdef inline object PyArray_MultiIterNew3(a, b, c):
|
| 780 |
+
return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
|
| 781 |
+
|
| 782 |
+
cdef inline object PyArray_MultiIterNew4(a, b, c, d):
|
| 783 |
+
return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
|
| 784 |
+
|
| 785 |
+
cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
|
| 786 |
+
return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
|
| 787 |
+
|
| 788 |
+
cdef inline tuple PyDataType_SHAPE(dtype d):
|
| 789 |
+
if PyDataType_HASSUBARRAY(d):
|
| 790 |
+
return <tuple>d.subarray.shape
|
| 791 |
+
else:
|
| 792 |
+
return ()
|
| 793 |
+
|
| 794 |
+
|
| 795 |
+
cdef extern from "numpy/ndarrayobject.h":
|
| 796 |
+
PyTypeObject PyTimedeltaArrType_Type
|
| 797 |
+
PyTypeObject PyDatetimeArrType_Type
|
| 798 |
+
ctypedef int64_t npy_timedelta
|
| 799 |
+
ctypedef int64_t npy_datetime
|
| 800 |
+
|
| 801 |
+
cdef extern from "numpy/ndarraytypes.h":
|
| 802 |
+
ctypedef struct PyArray_DatetimeMetaData:
|
| 803 |
+
NPY_DATETIMEUNIT base
|
| 804 |
+
int64_t num
|
| 805 |
+
|
| 806 |
+
cdef extern from "numpy/arrayscalars.h":
|
| 807 |
+
|
| 808 |
+
# abstract types
|
| 809 |
+
ctypedef class numpy.generic [object PyObject]:
|
| 810 |
+
pass
|
| 811 |
+
ctypedef class numpy.number [object PyObject]:
|
| 812 |
+
pass
|
| 813 |
+
ctypedef class numpy.integer [object PyObject]:
|
| 814 |
+
pass
|
| 815 |
+
ctypedef class numpy.signedinteger [object PyObject]:
|
| 816 |
+
pass
|
| 817 |
+
ctypedef class numpy.unsignedinteger [object PyObject]:
|
| 818 |
+
pass
|
| 819 |
+
ctypedef class numpy.inexact [object PyObject]:
|
| 820 |
+
pass
|
| 821 |
+
ctypedef class numpy.floating [object PyObject]:
|
| 822 |
+
pass
|
| 823 |
+
ctypedef class numpy.complexfloating [object PyObject]:
|
| 824 |
+
pass
|
| 825 |
+
ctypedef class numpy.flexible [object PyObject]:
|
| 826 |
+
pass
|
| 827 |
+
ctypedef class numpy.character [object PyObject]:
|
| 828 |
+
pass
|
| 829 |
+
|
| 830 |
+
ctypedef struct PyDatetimeScalarObject:
|
| 831 |
+
# PyObject_HEAD
|
| 832 |
+
npy_datetime obval
|
| 833 |
+
PyArray_DatetimeMetaData obmeta
|
| 834 |
+
|
| 835 |
+
ctypedef struct PyTimedeltaScalarObject:
|
| 836 |
+
# PyObject_HEAD
|
| 837 |
+
npy_timedelta obval
|
| 838 |
+
PyArray_DatetimeMetaData obmeta
|
| 839 |
+
|
| 840 |
+
ctypedef enum NPY_DATETIMEUNIT:
|
| 841 |
+
NPY_FR_Y
|
| 842 |
+
NPY_FR_M
|
| 843 |
+
NPY_FR_W
|
| 844 |
+
NPY_FR_D
|
| 845 |
+
NPY_FR_B
|
| 846 |
+
NPY_FR_h
|
| 847 |
+
NPY_FR_m
|
| 848 |
+
NPY_FR_s
|
| 849 |
+
NPY_FR_ms
|
| 850 |
+
NPY_FR_us
|
| 851 |
+
NPY_FR_ns
|
| 852 |
+
NPY_FR_ps
|
| 853 |
+
NPY_FR_fs
|
| 854 |
+
NPY_FR_as
|
| 855 |
+
NPY_FR_GENERIC
|
| 856 |
+
|
| 857 |
+
|
| 858 |
+
#
|
| 859 |
+
# ufunc API
|
| 860 |
+
#
|
| 861 |
+
|
| 862 |
+
cdef extern from "numpy/ufuncobject.h":
|
| 863 |
+
|
| 864 |
+
ctypedef void (*PyUFuncGenericFunction) (char **, npy_intp *, npy_intp *, void *)
|
| 865 |
+
|
| 866 |
+
ctypedef class numpy.ufunc [object PyUFuncObject, check_size ignore]:
|
| 867 |
+
cdef:
|
| 868 |
+
int nin, nout, nargs
|
| 869 |
+
int identity
|
| 870 |
+
PyUFuncGenericFunction *functions
|
| 871 |
+
void **data
|
| 872 |
+
int ntypes
|
| 873 |
+
int check_return
|
| 874 |
+
char *name
|
| 875 |
+
char *types
|
| 876 |
+
char *doc
|
| 877 |
+
void *ptr
|
| 878 |
+
PyObject *obj
|
| 879 |
+
PyObject *userloops
|
| 880 |
+
|
| 881 |
+
cdef enum:
|
| 882 |
+
PyUFunc_Zero
|
| 883 |
+
PyUFunc_One
|
| 884 |
+
PyUFunc_None
|
| 885 |
+
UFUNC_ERR_IGNORE
|
| 886 |
+
UFUNC_ERR_WARN
|
| 887 |
+
UFUNC_ERR_RAISE
|
| 888 |
+
UFUNC_ERR_CALL
|
| 889 |
+
UFUNC_ERR_PRINT
|
| 890 |
+
UFUNC_ERR_LOG
|
| 891 |
+
UFUNC_MASK_DIVIDEBYZERO
|
| 892 |
+
UFUNC_MASK_OVERFLOW
|
| 893 |
+
UFUNC_MASK_UNDERFLOW
|
| 894 |
+
UFUNC_MASK_INVALID
|
| 895 |
+
UFUNC_SHIFT_DIVIDEBYZERO
|
| 896 |
+
UFUNC_SHIFT_OVERFLOW
|
| 897 |
+
UFUNC_SHIFT_UNDERFLOW
|
| 898 |
+
UFUNC_SHIFT_INVALID
|
| 899 |
+
UFUNC_FPE_DIVIDEBYZERO
|
| 900 |
+
UFUNC_FPE_OVERFLOW
|
| 901 |
+
UFUNC_FPE_UNDERFLOW
|
| 902 |
+
UFUNC_FPE_INVALID
|
| 903 |
+
UFUNC_ERR_DEFAULT
|
| 904 |
+
UFUNC_ERR_DEFAULT2
|
| 905 |
+
|
| 906 |
+
object PyUFunc_FromFuncAndData(PyUFuncGenericFunction *,
|
| 907 |
+
void **, char *, int, int, int, int, char *, char *, int)
|
| 908 |
+
int PyUFunc_RegisterLoopForType(ufunc, int,
|
| 909 |
+
PyUFuncGenericFunction, int *, void *) except -1
|
| 910 |
+
void PyUFunc_f_f_As_d_d \
|
| 911 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 912 |
+
void PyUFunc_d_d \
|
| 913 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 914 |
+
void PyUFunc_f_f \
|
| 915 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 916 |
+
void PyUFunc_g_g \
|
| 917 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 918 |
+
void PyUFunc_F_F_As_D_D \
|
| 919 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 920 |
+
void PyUFunc_F_F \
|
| 921 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 922 |
+
void PyUFunc_D_D \
|
| 923 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 924 |
+
void PyUFunc_G_G \
|
| 925 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 926 |
+
void PyUFunc_O_O \
|
| 927 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 928 |
+
void PyUFunc_ff_f_As_dd_d \
|
| 929 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 930 |
+
void PyUFunc_ff_f \
|
| 931 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 932 |
+
void PyUFunc_dd_d \
|
| 933 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 934 |
+
void PyUFunc_gg_g \
|
| 935 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 936 |
+
void PyUFunc_FF_F_As_DD_D \
|
| 937 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 938 |
+
void PyUFunc_DD_D \
|
| 939 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 940 |
+
void PyUFunc_FF_F \
|
| 941 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 942 |
+
void PyUFunc_GG_G \
|
| 943 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 944 |
+
void PyUFunc_OO_O \
|
| 945 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 946 |
+
void PyUFunc_O_O_method \
|
| 947 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 948 |
+
void PyUFunc_OO_O_method \
|
| 949 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 950 |
+
void PyUFunc_On_Om \
|
| 951 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 952 |
+
int PyUFunc_GetPyValues \
|
| 953 |
+
(char *, int *, int *, PyObject **)
|
| 954 |
+
int PyUFunc_checkfperr \
|
| 955 |
+
(int, PyObject *, int *)
|
| 956 |
+
void PyUFunc_clearfperr()
|
| 957 |
+
int PyUFunc_getfperr()
|
| 958 |
+
int PyUFunc_handlefperr \
|
| 959 |
+
(int, PyObject *, int, int *) except -1
|
| 960 |
+
int PyUFunc_ReplaceLoopBySignature \
|
| 961 |
+
(ufunc, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *)
|
| 962 |
+
object PyUFunc_FromFuncAndDataAndSignature \
|
| 963 |
+
(PyUFuncGenericFunction *, void **, char *, int, int, int,
|
| 964 |
+
int, char *, char *, int, char *)
|
| 965 |
+
|
| 966 |
+
int _import_umath() except -1
|
| 967 |
+
|
| 968 |
+
cdef inline void set_array_base(ndarray arr, object base):
|
| 969 |
+
Py_INCREF(base) # important to do this before stealing the reference below!
|
| 970 |
+
PyArray_SetBaseObject(arr, base)
|
| 971 |
+
|
| 972 |
+
cdef inline object get_array_base(ndarray arr):
|
| 973 |
+
base = PyArray_BASE(arr)
|
| 974 |
+
if base is NULL:
|
| 975 |
+
return None
|
| 976 |
+
return <object>base
|
| 977 |
+
|
| 978 |
+
# Versions of the import_* functions which are more suitable for
|
| 979 |
+
# Cython code.
|
| 980 |
+
cdef inline int import_array() except -1:
|
| 981 |
+
try:
|
| 982 |
+
__pyx_import_array()
|
| 983 |
+
except Exception:
|
| 984 |
+
raise ImportError("numpy.core.multiarray failed to import")
|
| 985 |
+
|
| 986 |
+
cdef inline int import_umath() except -1:
|
| 987 |
+
try:
|
| 988 |
+
_import_umath()
|
| 989 |
+
except Exception:
|
| 990 |
+
raise ImportError("numpy.core.umath failed to import")
|
| 991 |
+
|
| 992 |
+
cdef inline int import_ufunc() except -1:
|
| 993 |
+
try:
|
| 994 |
+
_import_umath()
|
| 995 |
+
except Exception:
|
| 996 |
+
raise ImportError("numpy.core.umath failed to import")
|
| 997 |
+
|
| 998 |
+
|
| 999 |
+
cdef inline bint is_timedelta64_object(object obj):
|
| 1000 |
+
"""
|
| 1001 |
+
Cython equivalent of `isinstance(obj, np.timedelta64)`
|
| 1002 |
+
|
| 1003 |
+
Parameters
|
| 1004 |
+
----------
|
| 1005 |
+
obj : object
|
| 1006 |
+
|
| 1007 |
+
Returns
|
| 1008 |
+
-------
|
| 1009 |
+
bool
|
| 1010 |
+
"""
|
| 1011 |
+
return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type)
|
| 1012 |
+
|
| 1013 |
+
|
| 1014 |
+
cdef inline bint is_datetime64_object(object obj):
|
| 1015 |
+
"""
|
| 1016 |
+
Cython equivalent of `isinstance(obj, np.datetime64)`
|
| 1017 |
+
|
| 1018 |
+
Parameters
|
| 1019 |
+
----------
|
| 1020 |
+
obj : object
|
| 1021 |
+
|
| 1022 |
+
Returns
|
| 1023 |
+
-------
|
| 1024 |
+
bool
|
| 1025 |
+
"""
|
| 1026 |
+
return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type)
|
| 1027 |
+
|
| 1028 |
+
|
| 1029 |
+
cdef inline npy_datetime get_datetime64_value(object obj) nogil:
|
| 1030 |
+
"""
|
| 1031 |
+
returns the int64 value underlying scalar numpy datetime64 object
|
| 1032 |
+
|
| 1033 |
+
Note that to interpret this as a datetime, the corresponding unit is
|
| 1034 |
+
also needed. That can be found using `get_datetime64_unit`.
|
| 1035 |
+
"""
|
| 1036 |
+
return (<PyDatetimeScalarObject*>obj).obval
|
| 1037 |
+
|
| 1038 |
+
|
| 1039 |
+
cdef inline npy_timedelta get_timedelta64_value(object obj) nogil:
|
| 1040 |
+
"""
|
| 1041 |
+
returns the int64 value underlying scalar numpy timedelta64 object
|
| 1042 |
+
"""
|
| 1043 |
+
return (<PyTimedeltaScalarObject*>obj).obval
|
| 1044 |
+
|
| 1045 |
+
|
| 1046 |
+
cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil:
|
| 1047 |
+
"""
|
| 1048 |
+
returns the unit part of the dtype for a numpy datetime64 object.
|
| 1049 |
+
"""
|
| 1050 |
+
return <NPY_DATETIMEUNIT>(<PyDatetimeScalarObject*>obj).obmeta.base
|
lib/python3.12/site-packages/numpy/__init__.pxd
ADDED
|
@@ -0,0 +1,1015 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# NumPy static imports for Cython < 3.0
|
| 2 |
+
#
|
| 3 |
+
# If any of the PyArray_* functions are called, import_array must be
|
| 4 |
+
# called first.
|
| 5 |
+
#
|
| 6 |
+
# Author: Dag Sverre Seljebotn
|
| 7 |
+
#
|
| 8 |
+
|
| 9 |
+
DEF _buffer_format_string_len = 255
|
| 10 |
+
|
| 11 |
+
cimport cpython.buffer as pybuf
|
| 12 |
+
from cpython.ref cimport Py_INCREF
|
| 13 |
+
from cpython.mem cimport PyObject_Malloc, PyObject_Free
|
| 14 |
+
from cpython.object cimport PyObject, PyTypeObject
|
| 15 |
+
from cpython.buffer cimport PyObject_GetBuffer
|
| 16 |
+
from cpython.type cimport type
|
| 17 |
+
cimport libc.stdio as stdio
|
| 18 |
+
|
| 19 |
+
cdef extern from "Python.h":
|
| 20 |
+
ctypedef int Py_intptr_t
|
| 21 |
+
bint PyObject_TypeCheck(object obj, PyTypeObject* type)
|
| 22 |
+
|
| 23 |
+
cdef extern from "numpy/arrayobject.h":
|
| 24 |
+
ctypedef Py_intptr_t npy_intp
|
| 25 |
+
ctypedef size_t npy_uintp
|
| 26 |
+
|
| 27 |
+
cdef enum NPY_TYPES:
|
| 28 |
+
NPY_BOOL
|
| 29 |
+
NPY_BYTE
|
| 30 |
+
NPY_UBYTE
|
| 31 |
+
NPY_SHORT
|
| 32 |
+
NPY_USHORT
|
| 33 |
+
NPY_INT
|
| 34 |
+
NPY_UINT
|
| 35 |
+
NPY_LONG
|
| 36 |
+
NPY_ULONG
|
| 37 |
+
NPY_LONGLONG
|
| 38 |
+
NPY_ULONGLONG
|
| 39 |
+
NPY_FLOAT
|
| 40 |
+
NPY_DOUBLE
|
| 41 |
+
NPY_LONGDOUBLE
|
| 42 |
+
NPY_CFLOAT
|
| 43 |
+
NPY_CDOUBLE
|
| 44 |
+
NPY_CLONGDOUBLE
|
| 45 |
+
NPY_OBJECT
|
| 46 |
+
NPY_STRING
|
| 47 |
+
NPY_UNICODE
|
| 48 |
+
NPY_VOID
|
| 49 |
+
NPY_DATETIME
|
| 50 |
+
NPY_TIMEDELTA
|
| 51 |
+
NPY_NTYPES
|
| 52 |
+
NPY_NOTYPE
|
| 53 |
+
|
| 54 |
+
NPY_INT8
|
| 55 |
+
NPY_INT16
|
| 56 |
+
NPY_INT32
|
| 57 |
+
NPY_INT64
|
| 58 |
+
NPY_INT128
|
| 59 |
+
NPY_INT256
|
| 60 |
+
NPY_UINT8
|
| 61 |
+
NPY_UINT16
|
| 62 |
+
NPY_UINT32
|
| 63 |
+
NPY_UINT64
|
| 64 |
+
NPY_UINT128
|
| 65 |
+
NPY_UINT256
|
| 66 |
+
NPY_FLOAT16
|
| 67 |
+
NPY_FLOAT32
|
| 68 |
+
NPY_FLOAT64
|
| 69 |
+
NPY_FLOAT80
|
| 70 |
+
NPY_FLOAT96
|
| 71 |
+
NPY_FLOAT128
|
| 72 |
+
NPY_FLOAT256
|
| 73 |
+
NPY_COMPLEX32
|
| 74 |
+
NPY_COMPLEX64
|
| 75 |
+
NPY_COMPLEX128
|
| 76 |
+
NPY_COMPLEX160
|
| 77 |
+
NPY_COMPLEX192
|
| 78 |
+
NPY_COMPLEX256
|
| 79 |
+
NPY_COMPLEX512
|
| 80 |
+
|
| 81 |
+
NPY_INTP
|
| 82 |
+
|
| 83 |
+
ctypedef enum NPY_ORDER:
|
| 84 |
+
NPY_ANYORDER
|
| 85 |
+
NPY_CORDER
|
| 86 |
+
NPY_FORTRANORDER
|
| 87 |
+
NPY_KEEPORDER
|
| 88 |
+
|
| 89 |
+
ctypedef enum NPY_CASTING:
|
| 90 |
+
NPY_NO_CASTING
|
| 91 |
+
NPY_EQUIV_CASTING
|
| 92 |
+
NPY_SAFE_CASTING
|
| 93 |
+
NPY_SAME_KIND_CASTING
|
| 94 |
+
NPY_UNSAFE_CASTING
|
| 95 |
+
|
| 96 |
+
ctypedef enum NPY_CLIPMODE:
|
| 97 |
+
NPY_CLIP
|
| 98 |
+
NPY_WRAP
|
| 99 |
+
NPY_RAISE
|
| 100 |
+
|
| 101 |
+
ctypedef enum NPY_SCALARKIND:
|
| 102 |
+
NPY_NOSCALAR,
|
| 103 |
+
NPY_BOOL_SCALAR,
|
| 104 |
+
NPY_INTPOS_SCALAR,
|
| 105 |
+
NPY_INTNEG_SCALAR,
|
| 106 |
+
NPY_FLOAT_SCALAR,
|
| 107 |
+
NPY_COMPLEX_SCALAR,
|
| 108 |
+
NPY_OBJECT_SCALAR
|
| 109 |
+
|
| 110 |
+
ctypedef enum NPY_SORTKIND:
|
| 111 |
+
NPY_QUICKSORT
|
| 112 |
+
NPY_HEAPSORT
|
| 113 |
+
NPY_MERGESORT
|
| 114 |
+
|
| 115 |
+
ctypedef enum NPY_SEARCHSIDE:
|
| 116 |
+
NPY_SEARCHLEFT
|
| 117 |
+
NPY_SEARCHRIGHT
|
| 118 |
+
|
| 119 |
+
enum:
|
| 120 |
+
# DEPRECATED since NumPy 1.7 ! Do not use in new code!
|
| 121 |
+
NPY_C_CONTIGUOUS
|
| 122 |
+
NPY_F_CONTIGUOUS
|
| 123 |
+
NPY_CONTIGUOUS
|
| 124 |
+
NPY_FORTRAN
|
| 125 |
+
NPY_OWNDATA
|
| 126 |
+
NPY_FORCECAST
|
| 127 |
+
NPY_ENSURECOPY
|
| 128 |
+
NPY_ENSUREARRAY
|
| 129 |
+
NPY_ELEMENTSTRIDES
|
| 130 |
+
NPY_ALIGNED
|
| 131 |
+
NPY_NOTSWAPPED
|
| 132 |
+
NPY_WRITEABLE
|
| 133 |
+
NPY_ARR_HAS_DESCR
|
| 134 |
+
|
| 135 |
+
NPY_BEHAVED
|
| 136 |
+
NPY_BEHAVED_NS
|
| 137 |
+
NPY_CARRAY
|
| 138 |
+
NPY_CARRAY_RO
|
| 139 |
+
NPY_FARRAY
|
| 140 |
+
NPY_FARRAY_RO
|
| 141 |
+
NPY_DEFAULT
|
| 142 |
+
|
| 143 |
+
NPY_IN_ARRAY
|
| 144 |
+
NPY_OUT_ARRAY
|
| 145 |
+
NPY_INOUT_ARRAY
|
| 146 |
+
NPY_IN_FARRAY
|
| 147 |
+
NPY_OUT_FARRAY
|
| 148 |
+
NPY_INOUT_FARRAY
|
| 149 |
+
|
| 150 |
+
NPY_UPDATE_ALL
|
| 151 |
+
|
| 152 |
+
enum:
|
| 153 |
+
# Added in NumPy 1.7 to replace the deprecated enums above.
|
| 154 |
+
NPY_ARRAY_C_CONTIGUOUS
|
| 155 |
+
NPY_ARRAY_F_CONTIGUOUS
|
| 156 |
+
NPY_ARRAY_OWNDATA
|
| 157 |
+
NPY_ARRAY_FORCECAST
|
| 158 |
+
NPY_ARRAY_ENSURECOPY
|
| 159 |
+
NPY_ARRAY_ENSUREARRAY
|
| 160 |
+
NPY_ARRAY_ELEMENTSTRIDES
|
| 161 |
+
NPY_ARRAY_ALIGNED
|
| 162 |
+
NPY_ARRAY_NOTSWAPPED
|
| 163 |
+
NPY_ARRAY_WRITEABLE
|
| 164 |
+
NPY_ARRAY_WRITEBACKIFCOPY
|
| 165 |
+
|
| 166 |
+
NPY_ARRAY_BEHAVED
|
| 167 |
+
NPY_ARRAY_BEHAVED_NS
|
| 168 |
+
NPY_ARRAY_CARRAY
|
| 169 |
+
NPY_ARRAY_CARRAY_RO
|
| 170 |
+
NPY_ARRAY_FARRAY
|
| 171 |
+
NPY_ARRAY_FARRAY_RO
|
| 172 |
+
NPY_ARRAY_DEFAULT
|
| 173 |
+
|
| 174 |
+
NPY_ARRAY_IN_ARRAY
|
| 175 |
+
NPY_ARRAY_OUT_ARRAY
|
| 176 |
+
NPY_ARRAY_INOUT_ARRAY
|
| 177 |
+
NPY_ARRAY_IN_FARRAY
|
| 178 |
+
NPY_ARRAY_OUT_FARRAY
|
| 179 |
+
NPY_ARRAY_INOUT_FARRAY
|
| 180 |
+
|
| 181 |
+
NPY_ARRAY_UPDATE_ALL
|
| 182 |
+
|
| 183 |
+
cdef enum:
|
| 184 |
+
NPY_MAXDIMS
|
| 185 |
+
|
| 186 |
+
npy_intp NPY_MAX_ELSIZE
|
| 187 |
+
|
| 188 |
+
ctypedef void (*PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *, void *)
|
| 189 |
+
|
| 190 |
+
ctypedef struct PyArray_ArrayDescr:
|
| 191 |
+
# shape is a tuple, but Cython doesn't support "tuple shape"
|
| 192 |
+
# inside a non-PyObject declaration, so we have to declare it
|
| 193 |
+
# as just a PyObject*.
|
| 194 |
+
PyObject* shape
|
| 195 |
+
|
| 196 |
+
ctypedef struct PyArray_Descr:
|
| 197 |
+
pass
|
| 198 |
+
|
| 199 |
+
ctypedef class numpy.dtype [object PyArray_Descr, check_size ignore]:
|
| 200 |
+
# Use PyDataType_* macros when possible, however there are no macros
|
| 201 |
+
# for accessing some of the fields, so some are defined.
|
| 202 |
+
cdef PyTypeObject* typeobj
|
| 203 |
+
cdef char kind
|
| 204 |
+
cdef char type
|
| 205 |
+
# Numpy sometimes mutates this without warning (e.g. it'll
|
| 206 |
+
# sometimes change "|" to "<" in shared dtype objects on
|
| 207 |
+
# little-endian machines). If this matters to you, use
|
| 208 |
+
# PyArray_IsNativeByteOrder(dtype.byteorder) instead of
|
| 209 |
+
# directly accessing this field.
|
| 210 |
+
cdef char byteorder
|
| 211 |
+
cdef char flags
|
| 212 |
+
cdef int type_num
|
| 213 |
+
cdef int itemsize "elsize"
|
| 214 |
+
cdef int alignment
|
| 215 |
+
cdef object fields
|
| 216 |
+
cdef tuple names
|
| 217 |
+
# Use PyDataType_HASSUBARRAY to test whether this field is
|
| 218 |
+
# valid (the pointer can be NULL). Most users should access
|
| 219 |
+
# this field via the inline helper method PyDataType_SHAPE.
|
| 220 |
+
cdef PyArray_ArrayDescr* subarray
|
| 221 |
+
|
| 222 |
+
ctypedef class numpy.flatiter [object PyArrayIterObject, check_size ignore]:
|
| 223 |
+
# Use through macros
|
| 224 |
+
pass
|
| 225 |
+
|
| 226 |
+
ctypedef class numpy.broadcast [object PyArrayMultiIterObject, check_size ignore]:
|
| 227 |
+
cdef int numiter
|
| 228 |
+
cdef npy_intp size, index
|
| 229 |
+
cdef int nd
|
| 230 |
+
cdef npy_intp *dimensions
|
| 231 |
+
cdef void **iters
|
| 232 |
+
|
| 233 |
+
ctypedef struct PyArrayObject:
|
| 234 |
+
# For use in situations where ndarray can't replace PyArrayObject*,
|
| 235 |
+
# like PyArrayObject**.
|
| 236 |
+
pass
|
| 237 |
+
|
| 238 |
+
ctypedef class numpy.ndarray [object PyArrayObject, check_size ignore]:
|
| 239 |
+
cdef __cythonbufferdefaults__ = {"mode": "strided"}
|
| 240 |
+
|
| 241 |
+
cdef:
|
| 242 |
+
# Only taking a few of the most commonly used and stable fields.
|
| 243 |
+
# One should use PyArray_* macros instead to access the C fields.
|
| 244 |
+
char *data
|
| 245 |
+
int ndim "nd"
|
| 246 |
+
npy_intp *shape "dimensions"
|
| 247 |
+
npy_intp *strides
|
| 248 |
+
dtype descr # deprecated since NumPy 1.7 !
|
| 249 |
+
PyObject* base # NOT PUBLIC, DO NOT USE !
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
ctypedef unsigned char npy_bool
|
| 254 |
+
|
| 255 |
+
ctypedef signed char npy_byte
|
| 256 |
+
ctypedef signed short npy_short
|
| 257 |
+
ctypedef signed int npy_int
|
| 258 |
+
ctypedef signed long npy_long
|
| 259 |
+
ctypedef signed long long npy_longlong
|
| 260 |
+
|
| 261 |
+
ctypedef unsigned char npy_ubyte
|
| 262 |
+
ctypedef unsigned short npy_ushort
|
| 263 |
+
ctypedef unsigned int npy_uint
|
| 264 |
+
ctypedef unsigned long npy_ulong
|
| 265 |
+
ctypedef unsigned long long npy_ulonglong
|
| 266 |
+
|
| 267 |
+
ctypedef float npy_float
|
| 268 |
+
ctypedef double npy_double
|
| 269 |
+
ctypedef long double npy_longdouble
|
| 270 |
+
|
| 271 |
+
ctypedef signed char npy_int8
|
| 272 |
+
ctypedef signed short npy_int16
|
| 273 |
+
ctypedef signed int npy_int32
|
| 274 |
+
ctypedef signed long long npy_int64
|
| 275 |
+
ctypedef signed long long npy_int96
|
| 276 |
+
ctypedef signed long long npy_int128
|
| 277 |
+
|
| 278 |
+
ctypedef unsigned char npy_uint8
|
| 279 |
+
ctypedef unsigned short npy_uint16
|
| 280 |
+
ctypedef unsigned int npy_uint32
|
| 281 |
+
ctypedef unsigned long long npy_uint64
|
| 282 |
+
ctypedef unsigned long long npy_uint96
|
| 283 |
+
ctypedef unsigned long long npy_uint128
|
| 284 |
+
|
| 285 |
+
ctypedef float npy_float32
|
| 286 |
+
ctypedef double npy_float64
|
| 287 |
+
ctypedef long double npy_float80
|
| 288 |
+
ctypedef long double npy_float96
|
| 289 |
+
ctypedef long double npy_float128
|
| 290 |
+
|
| 291 |
+
ctypedef struct npy_cfloat:
|
| 292 |
+
float real
|
| 293 |
+
float imag
|
| 294 |
+
|
| 295 |
+
ctypedef struct npy_cdouble:
|
| 296 |
+
double real
|
| 297 |
+
double imag
|
| 298 |
+
|
| 299 |
+
ctypedef struct npy_clongdouble:
|
| 300 |
+
long double real
|
| 301 |
+
long double imag
|
| 302 |
+
|
| 303 |
+
ctypedef struct npy_complex64:
|
| 304 |
+
float real
|
| 305 |
+
float imag
|
| 306 |
+
|
| 307 |
+
ctypedef struct npy_complex128:
|
| 308 |
+
double real
|
| 309 |
+
double imag
|
| 310 |
+
|
| 311 |
+
ctypedef struct npy_complex160:
|
| 312 |
+
long double real
|
| 313 |
+
long double imag
|
| 314 |
+
|
| 315 |
+
ctypedef struct npy_complex192:
|
| 316 |
+
long double real
|
| 317 |
+
long double imag
|
| 318 |
+
|
| 319 |
+
ctypedef struct npy_complex256:
|
| 320 |
+
long double real
|
| 321 |
+
long double imag
|
| 322 |
+
|
| 323 |
+
ctypedef struct PyArray_Dims:
|
| 324 |
+
npy_intp *ptr
|
| 325 |
+
int len
|
| 326 |
+
|
| 327 |
+
int _import_array() except -1
|
| 328 |
+
# A second definition so _import_array isn't marked as used when we use it here.
|
| 329 |
+
# Do not use - subject to change any time.
|
| 330 |
+
int __pyx_import_array "_import_array"() except -1
|
| 331 |
+
|
| 332 |
+
#
|
| 333 |
+
# Macros from ndarrayobject.h
|
| 334 |
+
#
|
| 335 |
+
bint PyArray_CHKFLAGS(ndarray m, int flags) nogil
|
| 336 |
+
bint PyArray_IS_C_CONTIGUOUS(ndarray arr) nogil
|
| 337 |
+
bint PyArray_IS_F_CONTIGUOUS(ndarray arr) nogil
|
| 338 |
+
bint PyArray_ISCONTIGUOUS(ndarray m) nogil
|
| 339 |
+
bint PyArray_ISWRITEABLE(ndarray m) nogil
|
| 340 |
+
bint PyArray_ISALIGNED(ndarray m) nogil
|
| 341 |
+
|
| 342 |
+
int PyArray_NDIM(ndarray) nogil
|
| 343 |
+
bint PyArray_ISONESEGMENT(ndarray) nogil
|
| 344 |
+
bint PyArray_ISFORTRAN(ndarray) nogil
|
| 345 |
+
int PyArray_FORTRANIF(ndarray) nogil
|
| 346 |
+
|
| 347 |
+
void* PyArray_DATA(ndarray) nogil
|
| 348 |
+
char* PyArray_BYTES(ndarray) nogil
|
| 349 |
+
|
| 350 |
+
npy_intp* PyArray_DIMS(ndarray) nogil
|
| 351 |
+
npy_intp* PyArray_STRIDES(ndarray) nogil
|
| 352 |
+
npy_intp PyArray_DIM(ndarray, size_t) nogil
|
| 353 |
+
npy_intp PyArray_STRIDE(ndarray, size_t) nogil
|
| 354 |
+
|
| 355 |
+
PyObject *PyArray_BASE(ndarray) nogil # returns borrowed reference!
|
| 356 |
+
PyArray_Descr *PyArray_DESCR(ndarray) nogil # returns borrowed reference to dtype!
|
| 357 |
+
int PyArray_FLAGS(ndarray) nogil
|
| 358 |
+
npy_intp PyArray_ITEMSIZE(ndarray) nogil
|
| 359 |
+
int PyArray_TYPE(ndarray arr) nogil
|
| 360 |
+
|
| 361 |
+
object PyArray_GETITEM(ndarray arr, void *itemptr)
|
| 362 |
+
int PyArray_SETITEM(ndarray arr, void *itemptr, object obj) except -1
|
| 363 |
+
|
| 364 |
+
bint PyTypeNum_ISBOOL(int) nogil
|
| 365 |
+
bint PyTypeNum_ISUNSIGNED(int) nogil
|
| 366 |
+
bint PyTypeNum_ISSIGNED(int) nogil
|
| 367 |
+
bint PyTypeNum_ISINTEGER(int) nogil
|
| 368 |
+
bint PyTypeNum_ISFLOAT(int) nogil
|
| 369 |
+
bint PyTypeNum_ISNUMBER(int) nogil
|
| 370 |
+
bint PyTypeNum_ISSTRING(int) nogil
|
| 371 |
+
bint PyTypeNum_ISCOMPLEX(int) nogil
|
| 372 |
+
bint PyTypeNum_ISPYTHON(int) nogil
|
| 373 |
+
bint PyTypeNum_ISFLEXIBLE(int) nogil
|
| 374 |
+
bint PyTypeNum_ISUSERDEF(int) nogil
|
| 375 |
+
bint PyTypeNum_ISEXTENDED(int) nogil
|
| 376 |
+
bint PyTypeNum_ISOBJECT(int) nogil
|
| 377 |
+
|
| 378 |
+
bint PyDataType_ISBOOL(dtype) nogil
|
| 379 |
+
bint PyDataType_ISUNSIGNED(dtype) nogil
|
| 380 |
+
bint PyDataType_ISSIGNED(dtype) nogil
|
| 381 |
+
bint PyDataType_ISINTEGER(dtype) nogil
|
| 382 |
+
bint PyDataType_ISFLOAT(dtype) nogil
|
| 383 |
+
bint PyDataType_ISNUMBER(dtype) nogil
|
| 384 |
+
bint PyDataType_ISSTRING(dtype) nogil
|
| 385 |
+
bint PyDataType_ISCOMPLEX(dtype) nogil
|
| 386 |
+
bint PyDataType_ISPYTHON(dtype) nogil
|
| 387 |
+
bint PyDataType_ISFLEXIBLE(dtype) nogil
|
| 388 |
+
bint PyDataType_ISUSERDEF(dtype) nogil
|
| 389 |
+
bint PyDataType_ISEXTENDED(dtype) nogil
|
| 390 |
+
bint PyDataType_ISOBJECT(dtype) nogil
|
| 391 |
+
bint PyDataType_HASFIELDS(dtype) nogil
|
| 392 |
+
bint PyDataType_HASSUBARRAY(dtype) nogil
|
| 393 |
+
|
| 394 |
+
bint PyArray_ISBOOL(ndarray) nogil
|
| 395 |
+
bint PyArray_ISUNSIGNED(ndarray) nogil
|
| 396 |
+
bint PyArray_ISSIGNED(ndarray) nogil
|
| 397 |
+
bint PyArray_ISINTEGER(ndarray) nogil
|
| 398 |
+
bint PyArray_ISFLOAT(ndarray) nogil
|
| 399 |
+
bint PyArray_ISNUMBER(ndarray) nogil
|
| 400 |
+
bint PyArray_ISSTRING(ndarray) nogil
|
| 401 |
+
bint PyArray_ISCOMPLEX(ndarray) nogil
|
| 402 |
+
bint PyArray_ISPYTHON(ndarray) nogil
|
| 403 |
+
bint PyArray_ISFLEXIBLE(ndarray) nogil
|
| 404 |
+
bint PyArray_ISUSERDEF(ndarray) nogil
|
| 405 |
+
bint PyArray_ISEXTENDED(ndarray) nogil
|
| 406 |
+
bint PyArray_ISOBJECT(ndarray) nogil
|
| 407 |
+
bint PyArray_HASFIELDS(ndarray) nogil
|
| 408 |
+
|
| 409 |
+
bint PyArray_ISVARIABLE(ndarray) nogil
|
| 410 |
+
|
| 411 |
+
bint PyArray_SAFEALIGNEDCOPY(ndarray) nogil
|
| 412 |
+
bint PyArray_ISNBO(char) nogil # works on ndarray.byteorder
|
| 413 |
+
bint PyArray_IsNativeByteOrder(char) nogil # works on ndarray.byteorder
|
| 414 |
+
bint PyArray_ISNOTSWAPPED(ndarray) nogil
|
| 415 |
+
bint PyArray_ISBYTESWAPPED(ndarray) nogil
|
| 416 |
+
|
| 417 |
+
bint PyArray_FLAGSWAP(ndarray, int) nogil
|
| 418 |
+
|
| 419 |
+
bint PyArray_ISCARRAY(ndarray) nogil
|
| 420 |
+
bint PyArray_ISCARRAY_RO(ndarray) nogil
|
| 421 |
+
bint PyArray_ISFARRAY(ndarray) nogil
|
| 422 |
+
bint PyArray_ISFARRAY_RO(ndarray) nogil
|
| 423 |
+
bint PyArray_ISBEHAVED(ndarray) nogil
|
| 424 |
+
bint PyArray_ISBEHAVED_RO(ndarray) nogil
|
| 425 |
+
|
| 426 |
+
|
| 427 |
+
bint PyDataType_ISNOTSWAPPED(dtype) nogil
|
| 428 |
+
bint PyDataType_ISBYTESWAPPED(dtype) nogil
|
| 429 |
+
|
| 430 |
+
bint PyArray_DescrCheck(object)
|
| 431 |
+
|
| 432 |
+
bint PyArray_Check(object)
|
| 433 |
+
bint PyArray_CheckExact(object)
|
| 434 |
+
|
| 435 |
+
# Cannot be supported due to out arg:
|
| 436 |
+
# bint PyArray_HasArrayInterfaceType(object, dtype, object, object&)
|
| 437 |
+
# bint PyArray_HasArrayInterface(op, out)
|
| 438 |
+
|
| 439 |
+
|
| 440 |
+
bint PyArray_IsZeroDim(object)
|
| 441 |
+
# Cannot be supported due to ## ## in macro:
|
| 442 |
+
# bint PyArray_IsScalar(object, verbatim work)
|
| 443 |
+
bint PyArray_CheckScalar(object)
|
| 444 |
+
bint PyArray_IsPythonNumber(object)
|
| 445 |
+
bint PyArray_IsPythonScalar(object)
|
| 446 |
+
bint PyArray_IsAnyScalar(object)
|
| 447 |
+
bint PyArray_CheckAnyScalar(object)
|
| 448 |
+
|
| 449 |
+
ndarray PyArray_GETCONTIGUOUS(ndarray)
|
| 450 |
+
bint PyArray_SAMESHAPE(ndarray, ndarray) nogil
|
| 451 |
+
npy_intp PyArray_SIZE(ndarray) nogil
|
| 452 |
+
npy_intp PyArray_NBYTES(ndarray) nogil
|
| 453 |
+
|
| 454 |
+
object PyArray_FROM_O(object)
|
| 455 |
+
object PyArray_FROM_OF(object m, int flags)
|
| 456 |
+
object PyArray_FROM_OT(object m, int type)
|
| 457 |
+
object PyArray_FROM_OTF(object m, int type, int flags)
|
| 458 |
+
object PyArray_FROMANY(object m, int type, int min, int max, int flags)
|
| 459 |
+
object PyArray_ZEROS(int nd, npy_intp* dims, int type, int fortran)
|
| 460 |
+
object PyArray_EMPTY(int nd, npy_intp* dims, int type, int fortran)
|
| 461 |
+
void PyArray_FILLWBYTE(object, int val)
|
| 462 |
+
npy_intp PyArray_REFCOUNT(object)
|
| 463 |
+
object PyArray_ContiguousFromAny(op, int, int min_depth, int max_depth)
|
| 464 |
+
unsigned char PyArray_EquivArrTypes(ndarray a1, ndarray a2)
|
| 465 |
+
bint PyArray_EquivByteorders(int b1, int b2) nogil
|
| 466 |
+
object PyArray_SimpleNew(int nd, npy_intp* dims, int typenum)
|
| 467 |
+
object PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data)
|
| 468 |
+
#object PyArray_SimpleNewFromDescr(int nd, npy_intp* dims, dtype descr)
|
| 469 |
+
object PyArray_ToScalar(void* data, ndarray arr)
|
| 470 |
+
|
| 471 |
+
void* PyArray_GETPTR1(ndarray m, npy_intp i) nogil
|
| 472 |
+
void* PyArray_GETPTR2(ndarray m, npy_intp i, npy_intp j) nogil
|
| 473 |
+
void* PyArray_GETPTR3(ndarray m, npy_intp i, npy_intp j, npy_intp k) nogil
|
| 474 |
+
void* PyArray_GETPTR4(ndarray m, npy_intp i, npy_intp j, npy_intp k, npy_intp l) nogil
|
| 475 |
+
|
| 476 |
+
# Cannot be supported due to out arg
|
| 477 |
+
# void PyArray_DESCR_REPLACE(descr)
|
| 478 |
+
|
| 479 |
+
|
| 480 |
+
object PyArray_Copy(ndarray)
|
| 481 |
+
object PyArray_FromObject(object op, int type, int min_depth, int max_depth)
|
| 482 |
+
object PyArray_ContiguousFromObject(object op, int type, int min_depth, int max_depth)
|
| 483 |
+
object PyArray_CopyFromObject(object op, int type, int min_depth, int max_depth)
|
| 484 |
+
|
| 485 |
+
object PyArray_Cast(ndarray mp, int type_num)
|
| 486 |
+
object PyArray_Take(ndarray ap, object items, int axis)
|
| 487 |
+
object PyArray_Put(ndarray ap, object items, object values)
|
| 488 |
+
|
| 489 |
+
void PyArray_ITER_RESET(flatiter it) nogil
|
| 490 |
+
void PyArray_ITER_NEXT(flatiter it) nogil
|
| 491 |
+
void PyArray_ITER_GOTO(flatiter it, npy_intp* destination) nogil
|
| 492 |
+
void PyArray_ITER_GOTO1D(flatiter it, npy_intp ind) nogil
|
| 493 |
+
void* PyArray_ITER_DATA(flatiter it) nogil
|
| 494 |
+
bint PyArray_ITER_NOTDONE(flatiter it) nogil
|
| 495 |
+
|
| 496 |
+
void PyArray_MultiIter_RESET(broadcast multi) nogil
|
| 497 |
+
void PyArray_MultiIter_NEXT(broadcast multi) nogil
|
| 498 |
+
void PyArray_MultiIter_GOTO(broadcast multi, npy_intp dest) nogil
|
| 499 |
+
void PyArray_MultiIter_GOTO1D(broadcast multi, npy_intp ind) nogil
|
| 500 |
+
void* PyArray_MultiIter_DATA(broadcast multi, npy_intp i) nogil
|
| 501 |
+
void PyArray_MultiIter_NEXTi(broadcast multi, npy_intp i) nogil
|
| 502 |
+
bint PyArray_MultiIter_NOTDONE(broadcast multi) nogil
|
| 503 |
+
|
| 504 |
+
# Functions from __multiarray_api.h
|
| 505 |
+
|
| 506 |
+
# Functions taking dtype and returning object/ndarray are disabled
|
| 507 |
+
# for now as they steal dtype references. I'm conservative and disable
|
| 508 |
+
# more than is probably needed until it can be checked further.
|
| 509 |
+
int PyArray_SetNumericOps (object) except -1
|
| 510 |
+
object PyArray_GetNumericOps ()
|
| 511 |
+
int PyArray_INCREF (ndarray) except * # uses PyArray_Item_INCREF...
|
| 512 |
+
int PyArray_XDECREF (ndarray) except * # uses PyArray_Item_DECREF...
|
| 513 |
+
void PyArray_SetStringFunction (object, int)
|
| 514 |
+
dtype PyArray_DescrFromType (int)
|
| 515 |
+
object PyArray_TypeObjectFromType (int)
|
| 516 |
+
char * PyArray_Zero (ndarray)
|
| 517 |
+
char * PyArray_One (ndarray)
|
| 518 |
+
#object PyArray_CastToType (ndarray, dtype, int)
|
| 519 |
+
int PyArray_CastTo (ndarray, ndarray) except -1
|
| 520 |
+
int PyArray_CastAnyTo (ndarray, ndarray) except -1
|
| 521 |
+
int PyArray_CanCastSafely (int, int) # writes errors
|
| 522 |
+
npy_bool PyArray_CanCastTo (dtype, dtype) # writes errors
|
| 523 |
+
int PyArray_ObjectType (object, int) except 0
|
| 524 |
+
dtype PyArray_DescrFromObject (object, dtype)
|
| 525 |
+
#ndarray* PyArray_ConvertToCommonType (object, int *)
|
| 526 |
+
dtype PyArray_DescrFromScalar (object)
|
| 527 |
+
dtype PyArray_DescrFromTypeObject (object)
|
| 528 |
+
npy_intp PyArray_Size (object)
|
| 529 |
+
#object PyArray_Scalar (void *, dtype, object)
|
| 530 |
+
#object PyArray_FromScalar (object, dtype)
|
| 531 |
+
void PyArray_ScalarAsCtype (object, void *)
|
| 532 |
+
#int PyArray_CastScalarToCtype (object, void *, dtype)
|
| 533 |
+
#int PyArray_CastScalarDirect (object, dtype, void *, int)
|
| 534 |
+
object PyArray_ScalarFromObject (object)
|
| 535 |
+
#PyArray_VectorUnaryFunc * PyArray_GetCastFunc (dtype, int)
|
| 536 |
+
object PyArray_FromDims (int, int *, int)
|
| 537 |
+
#object PyArray_FromDimsAndDataAndDescr (int, int *, dtype, char *)
|
| 538 |
+
#object PyArray_FromAny (object, dtype, int, int, int, object)
|
| 539 |
+
object PyArray_EnsureArray (object)
|
| 540 |
+
object PyArray_EnsureAnyArray (object)
|
| 541 |
+
#object PyArray_FromFile (stdio.FILE *, dtype, npy_intp, char *)
|
| 542 |
+
#object PyArray_FromString (char *, npy_intp, dtype, npy_intp, char *)
|
| 543 |
+
#object PyArray_FromBuffer (object, dtype, npy_intp, npy_intp)
|
| 544 |
+
#object PyArray_FromIter (object, dtype, npy_intp)
|
| 545 |
+
object PyArray_Return (ndarray)
|
| 546 |
+
#object PyArray_GetField (ndarray, dtype, int)
|
| 547 |
+
#int PyArray_SetField (ndarray, dtype, int, object) except -1
|
| 548 |
+
object PyArray_Byteswap (ndarray, npy_bool)
|
| 549 |
+
object PyArray_Resize (ndarray, PyArray_Dims *, int, NPY_ORDER)
|
| 550 |
+
int PyArray_MoveInto (ndarray, ndarray) except -1
|
| 551 |
+
int PyArray_CopyInto (ndarray, ndarray) except -1
|
| 552 |
+
int PyArray_CopyAnyInto (ndarray, ndarray) except -1
|
| 553 |
+
int PyArray_CopyObject (ndarray, object) except -1
|
| 554 |
+
object PyArray_NewCopy (ndarray, NPY_ORDER)
|
| 555 |
+
object PyArray_ToList (ndarray)
|
| 556 |
+
object PyArray_ToString (ndarray, NPY_ORDER)
|
| 557 |
+
int PyArray_ToFile (ndarray, stdio.FILE *, char *, char *) except -1
|
| 558 |
+
int PyArray_Dump (object, object, int) except -1
|
| 559 |
+
object PyArray_Dumps (object, int)
|
| 560 |
+
int PyArray_ValidType (int) # Cannot error
|
| 561 |
+
void PyArray_UpdateFlags (ndarray, int)
|
| 562 |
+
object PyArray_New (type, int, npy_intp *, int, npy_intp *, void *, int, int, object)
|
| 563 |
+
#object PyArray_NewFromDescr (type, dtype, int, npy_intp *, npy_intp *, void *, int, object)
|
| 564 |
+
#dtype PyArray_DescrNew (dtype)
|
| 565 |
+
dtype PyArray_DescrNewFromType (int)
|
| 566 |
+
double PyArray_GetPriority (object, double) # clears errors as of 1.25
|
| 567 |
+
object PyArray_IterNew (object)
|
| 568 |
+
object PyArray_MultiIterNew (int, ...)
|
| 569 |
+
|
| 570 |
+
int PyArray_PyIntAsInt (object) except? -1
|
| 571 |
+
npy_intp PyArray_PyIntAsIntp (object)
|
| 572 |
+
int PyArray_Broadcast (broadcast) except -1
|
| 573 |
+
void PyArray_FillObjectArray (ndarray, object) except *
|
| 574 |
+
int PyArray_FillWithScalar (ndarray, object) except -1
|
| 575 |
+
npy_bool PyArray_CheckStrides (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)
|
| 576 |
+
dtype PyArray_DescrNewByteorder (dtype, char)
|
| 577 |
+
object PyArray_IterAllButAxis (object, int *)
|
| 578 |
+
#object PyArray_CheckFromAny (object, dtype, int, int, int, object)
|
| 579 |
+
#object PyArray_FromArray (ndarray, dtype, int)
|
| 580 |
+
object PyArray_FromInterface (object)
|
| 581 |
+
object PyArray_FromStructInterface (object)
|
| 582 |
+
#object PyArray_FromArrayAttr (object, dtype, object)
|
| 583 |
+
#NPY_SCALARKIND PyArray_ScalarKind (int, ndarray*)
|
| 584 |
+
int PyArray_CanCoerceScalar (int, int, NPY_SCALARKIND)
|
| 585 |
+
object PyArray_NewFlagsObject (object)
|
| 586 |
+
npy_bool PyArray_CanCastScalar (type, type)
|
| 587 |
+
#int PyArray_CompareUCS4 (npy_ucs4 *, npy_ucs4 *, register size_t)
|
| 588 |
+
int PyArray_RemoveSmallest (broadcast) except -1
|
| 589 |
+
int PyArray_ElementStrides (object)
|
| 590 |
+
void PyArray_Item_INCREF (char *, dtype) except *
|
| 591 |
+
void PyArray_Item_XDECREF (char *, dtype) except *
|
| 592 |
+
object PyArray_FieldNames (object)
|
| 593 |
+
object PyArray_Transpose (ndarray, PyArray_Dims *)
|
| 594 |
+
object PyArray_TakeFrom (ndarray, object, int, ndarray, NPY_CLIPMODE)
|
| 595 |
+
object PyArray_PutTo (ndarray, object, object, NPY_CLIPMODE)
|
| 596 |
+
object PyArray_PutMask (ndarray, object, object)
|
| 597 |
+
object PyArray_Repeat (ndarray, object, int)
|
| 598 |
+
object PyArray_Choose (ndarray, object, ndarray, NPY_CLIPMODE)
|
| 599 |
+
int PyArray_Sort (ndarray, int, NPY_SORTKIND) except -1
|
| 600 |
+
object PyArray_ArgSort (ndarray, int, NPY_SORTKIND)
|
| 601 |
+
object PyArray_SearchSorted (ndarray, object, NPY_SEARCHSIDE, PyObject *)
|
| 602 |
+
object PyArray_ArgMax (ndarray, int, ndarray)
|
| 603 |
+
object PyArray_ArgMin (ndarray, int, ndarray)
|
| 604 |
+
object PyArray_Reshape (ndarray, object)
|
| 605 |
+
object PyArray_Newshape (ndarray, PyArray_Dims *, NPY_ORDER)
|
| 606 |
+
object PyArray_Squeeze (ndarray)
|
| 607 |
+
#object PyArray_View (ndarray, dtype, type)
|
| 608 |
+
object PyArray_SwapAxes (ndarray, int, int)
|
| 609 |
+
object PyArray_Max (ndarray, int, ndarray)
|
| 610 |
+
object PyArray_Min (ndarray, int, ndarray)
|
| 611 |
+
object PyArray_Ptp (ndarray, int, ndarray)
|
| 612 |
+
object PyArray_Mean (ndarray, int, int, ndarray)
|
| 613 |
+
object PyArray_Trace (ndarray, int, int, int, int, ndarray)
|
| 614 |
+
object PyArray_Diagonal (ndarray, int, int, int)
|
| 615 |
+
object PyArray_Clip (ndarray, object, object, ndarray)
|
| 616 |
+
object PyArray_Conjugate (ndarray, ndarray)
|
| 617 |
+
object PyArray_Nonzero (ndarray)
|
| 618 |
+
object PyArray_Std (ndarray, int, int, ndarray, int)
|
| 619 |
+
object PyArray_Sum (ndarray, int, int, ndarray)
|
| 620 |
+
object PyArray_CumSum (ndarray, int, int, ndarray)
|
| 621 |
+
object PyArray_Prod (ndarray, int, int, ndarray)
|
| 622 |
+
object PyArray_CumProd (ndarray, int, int, ndarray)
|
| 623 |
+
object PyArray_All (ndarray, int, ndarray)
|
| 624 |
+
object PyArray_Any (ndarray, int, ndarray)
|
| 625 |
+
object PyArray_Compress (ndarray, object, int, ndarray)
|
| 626 |
+
object PyArray_Flatten (ndarray, NPY_ORDER)
|
| 627 |
+
object PyArray_Ravel (ndarray, NPY_ORDER)
|
| 628 |
+
npy_intp PyArray_MultiplyList (npy_intp *, int)
|
| 629 |
+
int PyArray_MultiplyIntList (int *, int)
|
| 630 |
+
void * PyArray_GetPtr (ndarray, npy_intp*)
|
| 631 |
+
int PyArray_CompareLists (npy_intp *, npy_intp *, int)
|
| 632 |
+
#int PyArray_AsCArray (object*, void *, npy_intp *, int, dtype)
|
| 633 |
+
#int PyArray_As1D (object*, char **, int *, int)
|
| 634 |
+
#int PyArray_As2D (object*, char ***, int *, int *, int)
|
| 635 |
+
int PyArray_Free (object, void *)
|
| 636 |
+
#int PyArray_Converter (object, object*)
|
| 637 |
+
int PyArray_IntpFromSequence (object, npy_intp *, int) except -1
|
| 638 |
+
object PyArray_Concatenate (object, int)
|
| 639 |
+
object PyArray_InnerProduct (object, object)
|
| 640 |
+
object PyArray_MatrixProduct (object, object)
|
| 641 |
+
object PyArray_CopyAndTranspose (object)
|
| 642 |
+
object PyArray_Correlate (object, object, int)
|
| 643 |
+
int PyArray_TypestrConvert (int, int)
|
| 644 |
+
#int PyArray_DescrConverter (object, dtype*) except 0
|
| 645 |
+
#int PyArray_DescrConverter2 (object, dtype*) except 0
|
| 646 |
+
int PyArray_IntpConverter (object, PyArray_Dims *) except 0
|
| 647 |
+
#int PyArray_BufferConverter (object, chunk) except 0
|
| 648 |
+
int PyArray_AxisConverter (object, int *) except 0
|
| 649 |
+
int PyArray_BoolConverter (object, npy_bool *) except 0
|
| 650 |
+
int PyArray_ByteorderConverter (object, char *) except 0
|
| 651 |
+
int PyArray_OrderConverter (object, NPY_ORDER *) except 0
|
| 652 |
+
unsigned char PyArray_EquivTypes (dtype, dtype) # clears errors
|
| 653 |
+
#object PyArray_Zeros (int, npy_intp *, dtype, int)
|
| 654 |
+
#object PyArray_Empty (int, npy_intp *, dtype, int)
|
| 655 |
+
object PyArray_Where (object, object, object)
|
| 656 |
+
object PyArray_Arange (double, double, double, int)
|
| 657 |
+
#object PyArray_ArangeObj (object, object, object, dtype)
|
| 658 |
+
int PyArray_SortkindConverter (object, NPY_SORTKIND *) except 0
|
| 659 |
+
object PyArray_LexSort (object, int)
|
| 660 |
+
object PyArray_Round (ndarray, int, ndarray)
|
| 661 |
+
unsigned char PyArray_EquivTypenums (int, int)
|
| 662 |
+
int PyArray_RegisterDataType (dtype) except -1
|
| 663 |
+
int PyArray_RegisterCastFunc (dtype, int, PyArray_VectorUnaryFunc *) except -1
|
| 664 |
+
int PyArray_RegisterCanCast (dtype, int, NPY_SCALARKIND) except -1
|
| 665 |
+
#void PyArray_InitArrFuncs (PyArray_ArrFuncs *)
|
| 666 |
+
object PyArray_IntTupleFromIntp (int, npy_intp *)
|
| 667 |
+
int PyArray_TypeNumFromName (char *)
|
| 668 |
+
int PyArray_ClipmodeConverter (object, NPY_CLIPMODE *) except 0
|
| 669 |
+
#int PyArray_OutputConverter (object, ndarray*) except 0
|
| 670 |
+
object PyArray_BroadcastToShape (object, npy_intp *, int)
|
| 671 |
+
void _PyArray_SigintHandler (int)
|
| 672 |
+
void* _PyArray_GetSigintBuf ()
|
| 673 |
+
#int PyArray_DescrAlignConverter (object, dtype*) except 0
|
| 674 |
+
#int PyArray_DescrAlignConverter2 (object, dtype*) except 0
|
| 675 |
+
int PyArray_SearchsideConverter (object, void *) except 0
|
| 676 |
+
object PyArray_CheckAxis (ndarray, int *, int)
|
| 677 |
+
npy_intp PyArray_OverflowMultiplyList (npy_intp *, int)
|
| 678 |
+
int PyArray_CompareString (char *, char *, size_t)
|
| 679 |
+
int PyArray_SetBaseObject(ndarray, base) except -1 # NOTE: steals a reference to base! Use "set_array_base()" instead.
|
| 680 |
+
|
| 681 |
+
|
| 682 |
+
# Typedefs that matches the runtime dtype objects in
|
| 683 |
+
# the numpy module.
|
| 684 |
+
|
| 685 |
+
# The ones that are commented out needs an IFDEF function
|
| 686 |
+
# in Cython to enable them only on the right systems.
|
| 687 |
+
|
| 688 |
+
ctypedef npy_int8 int8_t
|
| 689 |
+
ctypedef npy_int16 int16_t
|
| 690 |
+
ctypedef npy_int32 int32_t
|
| 691 |
+
ctypedef npy_int64 int64_t
|
| 692 |
+
#ctypedef npy_int96 int96_t
|
| 693 |
+
#ctypedef npy_int128 int128_t
|
| 694 |
+
|
| 695 |
+
ctypedef npy_uint8 uint8_t
|
| 696 |
+
ctypedef npy_uint16 uint16_t
|
| 697 |
+
ctypedef npy_uint32 uint32_t
|
| 698 |
+
ctypedef npy_uint64 uint64_t
|
| 699 |
+
#ctypedef npy_uint96 uint96_t
|
| 700 |
+
#ctypedef npy_uint128 uint128_t
|
| 701 |
+
|
| 702 |
+
ctypedef npy_float32 float32_t
|
| 703 |
+
ctypedef npy_float64 float64_t
|
| 704 |
+
#ctypedef npy_float80 float80_t
|
| 705 |
+
#ctypedef npy_float128 float128_t
|
| 706 |
+
|
| 707 |
+
ctypedef float complex complex64_t
|
| 708 |
+
ctypedef double complex complex128_t
|
| 709 |
+
|
| 710 |
+
# The int types are mapped a bit surprising --
|
| 711 |
+
# numpy.int corresponds to 'l' and numpy.long to 'q'
|
| 712 |
+
ctypedef npy_long int_t
|
| 713 |
+
ctypedef npy_longlong longlong_t
|
| 714 |
+
|
| 715 |
+
ctypedef npy_ulong uint_t
|
| 716 |
+
ctypedef npy_ulonglong ulonglong_t
|
| 717 |
+
|
| 718 |
+
ctypedef npy_intp intp_t
|
| 719 |
+
ctypedef npy_uintp uintp_t
|
| 720 |
+
|
| 721 |
+
ctypedef npy_double float_t
|
| 722 |
+
ctypedef npy_double double_t
|
| 723 |
+
ctypedef npy_longdouble longdouble_t
|
| 724 |
+
|
| 725 |
+
ctypedef npy_cfloat cfloat_t
|
| 726 |
+
ctypedef npy_cdouble cdouble_t
|
| 727 |
+
ctypedef npy_clongdouble clongdouble_t
|
| 728 |
+
|
| 729 |
+
ctypedef npy_cdouble complex_t
|
| 730 |
+
|
| 731 |
+
cdef inline object PyArray_MultiIterNew1(a):
|
| 732 |
+
return PyArray_MultiIterNew(1, <void*>a)
|
| 733 |
+
|
| 734 |
+
cdef inline object PyArray_MultiIterNew2(a, b):
|
| 735 |
+
return PyArray_MultiIterNew(2, <void*>a, <void*>b)
|
| 736 |
+
|
| 737 |
+
cdef inline object PyArray_MultiIterNew3(a, b, c):
|
| 738 |
+
return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
|
| 739 |
+
|
| 740 |
+
cdef inline object PyArray_MultiIterNew4(a, b, c, d):
|
| 741 |
+
return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
|
| 742 |
+
|
| 743 |
+
cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
|
| 744 |
+
return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
|
| 745 |
+
|
| 746 |
+
cdef inline tuple PyDataType_SHAPE(dtype d):
|
| 747 |
+
if PyDataType_HASSUBARRAY(d):
|
| 748 |
+
return <tuple>d.subarray.shape
|
| 749 |
+
else:
|
| 750 |
+
return ()
|
| 751 |
+
|
| 752 |
+
|
| 753 |
+
cdef extern from "numpy/ndarrayobject.h":
|
| 754 |
+
PyTypeObject PyTimedeltaArrType_Type
|
| 755 |
+
PyTypeObject PyDatetimeArrType_Type
|
| 756 |
+
ctypedef int64_t npy_timedelta
|
| 757 |
+
ctypedef int64_t npy_datetime
|
| 758 |
+
|
| 759 |
+
cdef extern from "numpy/ndarraytypes.h":
|
| 760 |
+
ctypedef struct PyArray_DatetimeMetaData:
|
| 761 |
+
NPY_DATETIMEUNIT base
|
| 762 |
+
int64_t num
|
| 763 |
+
|
| 764 |
+
cdef extern from "numpy/arrayscalars.h":
|
| 765 |
+
|
| 766 |
+
# abstract types
|
| 767 |
+
ctypedef class numpy.generic [object PyObject]:
|
| 768 |
+
pass
|
| 769 |
+
ctypedef class numpy.number [object PyObject]:
|
| 770 |
+
pass
|
| 771 |
+
ctypedef class numpy.integer [object PyObject]:
|
| 772 |
+
pass
|
| 773 |
+
ctypedef class numpy.signedinteger [object PyObject]:
|
| 774 |
+
pass
|
| 775 |
+
ctypedef class numpy.unsignedinteger [object PyObject]:
|
| 776 |
+
pass
|
| 777 |
+
ctypedef class numpy.inexact [object PyObject]:
|
| 778 |
+
pass
|
| 779 |
+
ctypedef class numpy.floating [object PyObject]:
|
| 780 |
+
pass
|
| 781 |
+
ctypedef class numpy.complexfloating [object PyObject]:
|
| 782 |
+
pass
|
| 783 |
+
ctypedef class numpy.flexible [object PyObject]:
|
| 784 |
+
pass
|
| 785 |
+
ctypedef class numpy.character [object PyObject]:
|
| 786 |
+
pass
|
| 787 |
+
|
| 788 |
+
ctypedef struct PyDatetimeScalarObject:
|
| 789 |
+
# PyObject_HEAD
|
| 790 |
+
npy_datetime obval
|
| 791 |
+
PyArray_DatetimeMetaData obmeta
|
| 792 |
+
|
| 793 |
+
ctypedef struct PyTimedeltaScalarObject:
|
| 794 |
+
# PyObject_HEAD
|
| 795 |
+
npy_timedelta obval
|
| 796 |
+
PyArray_DatetimeMetaData obmeta
|
| 797 |
+
|
| 798 |
+
ctypedef enum NPY_DATETIMEUNIT:
|
| 799 |
+
NPY_FR_Y
|
| 800 |
+
NPY_FR_M
|
| 801 |
+
NPY_FR_W
|
| 802 |
+
NPY_FR_D
|
| 803 |
+
NPY_FR_B
|
| 804 |
+
NPY_FR_h
|
| 805 |
+
NPY_FR_m
|
| 806 |
+
NPY_FR_s
|
| 807 |
+
NPY_FR_ms
|
| 808 |
+
NPY_FR_us
|
| 809 |
+
NPY_FR_ns
|
| 810 |
+
NPY_FR_ps
|
| 811 |
+
NPY_FR_fs
|
| 812 |
+
NPY_FR_as
|
| 813 |
+
NPY_FR_GENERIC
|
| 814 |
+
|
| 815 |
+
|
| 816 |
+
#
|
| 817 |
+
# ufunc API
|
| 818 |
+
#
|
| 819 |
+
|
| 820 |
+
cdef extern from "numpy/ufuncobject.h":
|
| 821 |
+
|
| 822 |
+
ctypedef void (*PyUFuncGenericFunction) (char **, npy_intp *, npy_intp *, void *)
|
| 823 |
+
|
| 824 |
+
ctypedef class numpy.ufunc [object PyUFuncObject, check_size ignore]:
|
| 825 |
+
cdef:
|
| 826 |
+
int nin, nout, nargs
|
| 827 |
+
int identity
|
| 828 |
+
PyUFuncGenericFunction *functions
|
| 829 |
+
void **data
|
| 830 |
+
int ntypes
|
| 831 |
+
int check_return
|
| 832 |
+
char *name
|
| 833 |
+
char *types
|
| 834 |
+
char *doc
|
| 835 |
+
void *ptr
|
| 836 |
+
PyObject *obj
|
| 837 |
+
PyObject *userloops
|
| 838 |
+
|
| 839 |
+
cdef enum:
|
| 840 |
+
PyUFunc_Zero
|
| 841 |
+
PyUFunc_One
|
| 842 |
+
PyUFunc_None
|
| 843 |
+
UFUNC_ERR_IGNORE
|
| 844 |
+
UFUNC_ERR_WARN
|
| 845 |
+
UFUNC_ERR_RAISE
|
| 846 |
+
UFUNC_ERR_CALL
|
| 847 |
+
UFUNC_ERR_PRINT
|
| 848 |
+
UFUNC_ERR_LOG
|
| 849 |
+
UFUNC_MASK_DIVIDEBYZERO
|
| 850 |
+
UFUNC_MASK_OVERFLOW
|
| 851 |
+
UFUNC_MASK_UNDERFLOW
|
| 852 |
+
UFUNC_MASK_INVALID
|
| 853 |
+
UFUNC_SHIFT_DIVIDEBYZERO
|
| 854 |
+
UFUNC_SHIFT_OVERFLOW
|
| 855 |
+
UFUNC_SHIFT_UNDERFLOW
|
| 856 |
+
UFUNC_SHIFT_INVALID
|
| 857 |
+
UFUNC_FPE_DIVIDEBYZERO
|
| 858 |
+
UFUNC_FPE_OVERFLOW
|
| 859 |
+
UFUNC_FPE_UNDERFLOW
|
| 860 |
+
UFUNC_FPE_INVALID
|
| 861 |
+
UFUNC_ERR_DEFAULT
|
| 862 |
+
UFUNC_ERR_DEFAULT2
|
| 863 |
+
|
| 864 |
+
object PyUFunc_FromFuncAndData(PyUFuncGenericFunction *,
|
| 865 |
+
void **, char *, int, int, int, int, char *, char *, int)
|
| 866 |
+
int PyUFunc_RegisterLoopForType(ufunc, int,
|
| 867 |
+
PyUFuncGenericFunction, int *, void *) except -1
|
| 868 |
+
void PyUFunc_f_f_As_d_d \
|
| 869 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 870 |
+
void PyUFunc_d_d \
|
| 871 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 872 |
+
void PyUFunc_f_f \
|
| 873 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 874 |
+
void PyUFunc_g_g \
|
| 875 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 876 |
+
void PyUFunc_F_F_As_D_D \
|
| 877 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 878 |
+
void PyUFunc_F_F \
|
| 879 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 880 |
+
void PyUFunc_D_D \
|
| 881 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 882 |
+
void PyUFunc_G_G \
|
| 883 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 884 |
+
void PyUFunc_O_O \
|
| 885 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 886 |
+
void PyUFunc_ff_f_As_dd_d \
|
| 887 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 888 |
+
void PyUFunc_ff_f \
|
| 889 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 890 |
+
void PyUFunc_dd_d \
|
| 891 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 892 |
+
void PyUFunc_gg_g \
|
| 893 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 894 |
+
void PyUFunc_FF_F_As_DD_D \
|
| 895 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 896 |
+
void PyUFunc_DD_D \
|
| 897 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 898 |
+
void PyUFunc_FF_F \
|
| 899 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 900 |
+
void PyUFunc_GG_G \
|
| 901 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 902 |
+
void PyUFunc_OO_O \
|
| 903 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 904 |
+
void PyUFunc_O_O_method \
|
| 905 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 906 |
+
void PyUFunc_OO_O_method \
|
| 907 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 908 |
+
void PyUFunc_On_Om \
|
| 909 |
+
(char **, npy_intp *, npy_intp *, void *)
|
| 910 |
+
int PyUFunc_GetPyValues \
|
| 911 |
+
(char *, int *, int *, PyObject **)
|
| 912 |
+
int PyUFunc_checkfperr \
|
| 913 |
+
(int, PyObject *, int *)
|
| 914 |
+
void PyUFunc_clearfperr()
|
| 915 |
+
int PyUFunc_getfperr()
|
| 916 |
+
int PyUFunc_handlefperr \
|
| 917 |
+
(int, PyObject *, int, int *) except -1
|
| 918 |
+
int PyUFunc_ReplaceLoopBySignature \
|
| 919 |
+
(ufunc, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *)
|
| 920 |
+
object PyUFunc_FromFuncAndDataAndSignature \
|
| 921 |
+
(PyUFuncGenericFunction *, void **, char *, int, int, int,
|
| 922 |
+
int, char *, char *, int, char *)
|
| 923 |
+
|
| 924 |
+
int _import_umath() except -1
|
| 925 |
+
|
| 926 |
+
cdef inline void set_array_base(ndarray arr, object base):
|
| 927 |
+
Py_INCREF(base) # important to do this before stealing the reference below!
|
| 928 |
+
PyArray_SetBaseObject(arr, base)
|
| 929 |
+
|
| 930 |
+
cdef inline object get_array_base(ndarray arr):
|
| 931 |
+
base = PyArray_BASE(arr)
|
| 932 |
+
if base is NULL:
|
| 933 |
+
return None
|
| 934 |
+
return <object>base
|
| 935 |
+
|
| 936 |
+
# Versions of the import_* functions which are more suitable for
|
| 937 |
+
# Cython code.
|
| 938 |
+
cdef inline int import_array() except -1:
|
| 939 |
+
try:
|
| 940 |
+
__pyx_import_array()
|
| 941 |
+
except Exception:
|
| 942 |
+
raise ImportError("numpy.core.multiarray failed to import")
|
| 943 |
+
|
| 944 |
+
cdef inline int import_umath() except -1:
|
| 945 |
+
try:
|
| 946 |
+
_import_umath()
|
| 947 |
+
except Exception:
|
| 948 |
+
raise ImportError("numpy.core.umath failed to import")
|
| 949 |
+
|
| 950 |
+
cdef inline int import_ufunc() except -1:
|
| 951 |
+
try:
|
| 952 |
+
_import_umath()
|
| 953 |
+
except Exception:
|
| 954 |
+
raise ImportError("numpy.core.umath failed to import")
|
| 955 |
+
|
| 956 |
+
cdef extern from *:
|
| 957 |
+
# Leave a marker that the NumPy declarations came from this file
|
| 958 |
+
# See https://github.com/cython/cython/issues/3573
|
| 959 |
+
"""
|
| 960 |
+
/* NumPy API declarations from "numpy/__init__.pxd" */
|
| 961 |
+
"""
|
| 962 |
+
|
| 963 |
+
|
| 964 |
+
cdef inline bint is_timedelta64_object(object obj):
|
| 965 |
+
"""
|
| 966 |
+
Cython equivalent of `isinstance(obj, np.timedelta64)`
|
| 967 |
+
|
| 968 |
+
Parameters
|
| 969 |
+
----------
|
| 970 |
+
obj : object
|
| 971 |
+
|
| 972 |
+
Returns
|
| 973 |
+
-------
|
| 974 |
+
bool
|
| 975 |
+
"""
|
| 976 |
+
return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type)
|
| 977 |
+
|
| 978 |
+
|
| 979 |
+
cdef inline bint is_datetime64_object(object obj):
|
| 980 |
+
"""
|
| 981 |
+
Cython equivalent of `isinstance(obj, np.datetime64)`
|
| 982 |
+
|
| 983 |
+
Parameters
|
| 984 |
+
----------
|
| 985 |
+
obj : object
|
| 986 |
+
|
| 987 |
+
Returns
|
| 988 |
+
-------
|
| 989 |
+
bool
|
| 990 |
+
"""
|
| 991 |
+
return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type)
|
| 992 |
+
|
| 993 |
+
|
| 994 |
+
cdef inline npy_datetime get_datetime64_value(object obj) nogil:
|
| 995 |
+
"""
|
| 996 |
+
returns the int64 value underlying scalar numpy datetime64 object
|
| 997 |
+
|
| 998 |
+
Note that to interpret this as a datetime, the corresponding unit is
|
| 999 |
+
also needed. That can be found using `get_datetime64_unit`.
|
| 1000 |
+
"""
|
| 1001 |
+
return (<PyDatetimeScalarObject*>obj).obval
|
| 1002 |
+
|
| 1003 |
+
|
| 1004 |
+
cdef inline npy_timedelta get_timedelta64_value(object obj) nogil:
|
| 1005 |
+
"""
|
| 1006 |
+
returns the int64 value underlying scalar numpy timedelta64 object
|
| 1007 |
+
"""
|
| 1008 |
+
return (<PyTimedeltaScalarObject*>obj).obval
|
| 1009 |
+
|
| 1010 |
+
|
| 1011 |
+
cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil:
|
| 1012 |
+
"""
|
| 1013 |
+
returns the unit part of the dtype for a numpy datetime64 object.
|
| 1014 |
+
"""
|
| 1015 |
+
return <NPY_DATETIMEUNIT>(<PyDatetimeScalarObject*>obj).obmeta.base
|
lib/python3.12/site-packages/numpy/__init__.py
ADDED
|
@@ -0,0 +1,461 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
NumPy
|
| 3 |
+
=====
|
| 4 |
+
|
| 5 |
+
Provides
|
| 6 |
+
1. An array object of arbitrary homogeneous items
|
| 7 |
+
2. Fast mathematical operations over arrays
|
| 8 |
+
3. Linear Algebra, Fourier Transforms, Random Number Generation
|
| 9 |
+
|
| 10 |
+
How to use the documentation
|
| 11 |
+
----------------------------
|
| 12 |
+
Documentation is available in two forms: docstrings provided
|
| 13 |
+
with the code, and a loose standing reference guide, available from
|
| 14 |
+
`the NumPy homepage <https://numpy.org>`_.
|
| 15 |
+
|
| 16 |
+
We recommend exploring the docstrings using
|
| 17 |
+
`IPython <https://ipython.org>`_, an advanced Python shell with
|
| 18 |
+
TAB-completion and introspection capabilities. See below for further
|
| 19 |
+
instructions.
|
| 20 |
+
|
| 21 |
+
The docstring examples assume that `numpy` has been imported as ``np``::
|
| 22 |
+
|
| 23 |
+
>>> import numpy as np
|
| 24 |
+
|
| 25 |
+
Code snippets are indicated by three greater-than signs::
|
| 26 |
+
|
| 27 |
+
>>> x = 42
|
| 28 |
+
>>> x = x + 1
|
| 29 |
+
|
| 30 |
+
Use the built-in ``help`` function to view a function's docstring::
|
| 31 |
+
|
| 32 |
+
>>> help(np.sort)
|
| 33 |
+
... # doctest: +SKIP
|
| 34 |
+
|
| 35 |
+
For some objects, ``np.info(obj)`` may provide additional help. This is
|
| 36 |
+
particularly true if you see the line "Help on ufunc object:" at the top
|
| 37 |
+
of the help() page. Ufuncs are implemented in C, not Python, for speed.
|
| 38 |
+
The native Python help() does not know how to view their help, but our
|
| 39 |
+
np.info() function does.
|
| 40 |
+
|
| 41 |
+
To search for documents containing a keyword, do::
|
| 42 |
+
|
| 43 |
+
>>> np.lookfor('keyword')
|
| 44 |
+
... # doctest: +SKIP
|
| 45 |
+
|
| 46 |
+
General-purpose documents like a glossary and help on the basic concepts
|
| 47 |
+
of numpy are available under the ``doc`` sub-module::
|
| 48 |
+
|
| 49 |
+
>>> from numpy import doc
|
| 50 |
+
>>> help(doc)
|
| 51 |
+
... # doctest: +SKIP
|
| 52 |
+
|
| 53 |
+
Available subpackages
|
| 54 |
+
---------------------
|
| 55 |
+
lib
|
| 56 |
+
Basic functions used by several sub-packages.
|
| 57 |
+
random
|
| 58 |
+
Core Random Tools
|
| 59 |
+
linalg
|
| 60 |
+
Core Linear Algebra Tools
|
| 61 |
+
fft
|
| 62 |
+
Core FFT routines
|
| 63 |
+
polynomial
|
| 64 |
+
Polynomial tools
|
| 65 |
+
testing
|
| 66 |
+
NumPy testing tools
|
| 67 |
+
distutils
|
| 68 |
+
Enhancements to distutils with support for
|
| 69 |
+
Fortran compilers support and more (for Python <= 3.11).
|
| 70 |
+
|
| 71 |
+
Utilities
|
| 72 |
+
---------
|
| 73 |
+
test
|
| 74 |
+
Run numpy unittests
|
| 75 |
+
show_config
|
| 76 |
+
Show numpy build configuration
|
| 77 |
+
matlib
|
| 78 |
+
Make everything matrices.
|
| 79 |
+
__version__
|
| 80 |
+
NumPy version string
|
| 81 |
+
|
| 82 |
+
Viewing documentation using IPython
|
| 83 |
+
-----------------------------------
|
| 84 |
+
|
| 85 |
+
Start IPython and import `numpy` usually under the alias ``np``: `import
|
| 86 |
+
numpy as np`. Then, directly past or use the ``%cpaste`` magic to paste
|
| 87 |
+
examples into the shell. To see which functions are available in `numpy`,
|
| 88 |
+
type ``np.<TAB>`` (where ``<TAB>`` refers to the TAB key), or use
|
| 89 |
+
``np.*cos*?<ENTER>`` (where ``<ENTER>`` refers to the ENTER key) to narrow
|
| 90 |
+
down the list. To view the docstring for a function, use
|
| 91 |
+
``np.cos?<ENTER>`` (to view the docstring) and ``np.cos??<ENTER>`` (to view
|
| 92 |
+
the source code).
|
| 93 |
+
|
| 94 |
+
Copies vs. in-place operation
|
| 95 |
+
-----------------------------
|
| 96 |
+
Most of the functions in `numpy` return a copy of the array argument
|
| 97 |
+
(e.g., `np.sort`). In-place versions of these functions are often
|
| 98 |
+
available as array methods, i.e. ``x = np.array([1,2,3]); x.sort()``.
|
| 99 |
+
Exceptions to this rule are documented.
|
| 100 |
+
|
| 101 |
+
"""
|
| 102 |
+
import sys
|
| 103 |
+
import warnings
|
| 104 |
+
|
| 105 |
+
from ._globals import _NoValue, _CopyMode
|
| 106 |
+
# These exceptions were moved in 1.25 and are hidden from __dir__()
|
| 107 |
+
from .exceptions import (
|
| 108 |
+
ComplexWarning, ModuleDeprecationWarning, VisibleDeprecationWarning,
|
| 109 |
+
TooHardError, AxisError)
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
# If a version with git hash was stored, use that instead
|
| 113 |
+
from . import version
|
| 114 |
+
from .version import __version__
|
| 115 |
+
|
| 116 |
+
# We first need to detect if we're being called as part of the numpy setup
|
| 117 |
+
# procedure itself in a reliable manner.
|
| 118 |
+
try:
|
| 119 |
+
__NUMPY_SETUP__
|
| 120 |
+
except NameError:
|
| 121 |
+
__NUMPY_SETUP__ = False
|
| 122 |
+
|
| 123 |
+
if __NUMPY_SETUP__:
|
| 124 |
+
sys.stderr.write('Running from numpy source directory.\n')
|
| 125 |
+
else:
|
| 126 |
+
# Allow distributors to run custom init code before importing numpy.core
|
| 127 |
+
from . import _distributor_init
|
| 128 |
+
|
| 129 |
+
try:
|
| 130 |
+
from numpy.__config__ import show as show_config
|
| 131 |
+
except ImportError as e:
|
| 132 |
+
msg = """Error importing numpy: you should not try to import numpy from
|
| 133 |
+
its source directory; please exit the numpy source tree, and relaunch
|
| 134 |
+
your python interpreter from there."""
|
| 135 |
+
raise ImportError(msg) from e
|
| 136 |
+
|
| 137 |
+
__all__ = [
|
| 138 |
+
'exceptions', 'ModuleDeprecationWarning', 'VisibleDeprecationWarning',
|
| 139 |
+
'ComplexWarning', 'TooHardError', 'AxisError']
|
| 140 |
+
|
| 141 |
+
# mapping of {name: (value, deprecation_msg)}
|
| 142 |
+
__deprecated_attrs__ = {}
|
| 143 |
+
|
| 144 |
+
from . import core
|
| 145 |
+
from .core import *
|
| 146 |
+
from . import compat
|
| 147 |
+
from . import exceptions
|
| 148 |
+
from . import dtypes
|
| 149 |
+
from . import lib
|
| 150 |
+
# NOTE: to be revisited following future namespace cleanup.
|
| 151 |
+
# See gh-14454 and gh-15672 for discussion.
|
| 152 |
+
from .lib import *
|
| 153 |
+
|
| 154 |
+
from . import linalg
|
| 155 |
+
from . import fft
|
| 156 |
+
from . import polynomial
|
| 157 |
+
from . import random
|
| 158 |
+
from . import ctypeslib
|
| 159 |
+
from . import ma
|
| 160 |
+
from . import matrixlib as _mat
|
| 161 |
+
from .matrixlib import *
|
| 162 |
+
|
| 163 |
+
# Deprecations introduced in NumPy 1.20.0, 2020-06-06
|
| 164 |
+
import builtins as _builtins
|
| 165 |
+
|
| 166 |
+
_msg = (
|
| 167 |
+
"module 'numpy' has no attribute '{n}'.\n"
|
| 168 |
+
"`np.{n}` was a deprecated alias for the builtin `{n}`. "
|
| 169 |
+
"To avoid this error in existing code, use `{n}` by itself. "
|
| 170 |
+
"Doing this will not modify any behavior and is safe. {extended_msg}\n"
|
| 171 |
+
"The aliases was originally deprecated in NumPy 1.20; for more "
|
| 172 |
+
"details and guidance see the original release note at:\n"
|
| 173 |
+
" https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations")
|
| 174 |
+
|
| 175 |
+
_specific_msg = (
|
| 176 |
+
"If you specifically wanted the numpy scalar type, use `np.{}` here.")
|
| 177 |
+
|
| 178 |
+
_int_extended_msg = (
|
| 179 |
+
"When replacing `np.{}`, you may wish to use e.g. `np.int64` "
|
| 180 |
+
"or `np.int32` to specify the precision. If you wish to review "
|
| 181 |
+
"your current use, check the release note link for "
|
| 182 |
+
"additional information.")
|
| 183 |
+
|
| 184 |
+
_type_info = [
|
| 185 |
+
("object", ""), # The NumPy scalar only exists by name.
|
| 186 |
+
("bool", _specific_msg.format("bool_")),
|
| 187 |
+
("float", _specific_msg.format("float64")),
|
| 188 |
+
("complex", _specific_msg.format("complex128")),
|
| 189 |
+
("str", _specific_msg.format("str_")),
|
| 190 |
+
("int", _int_extended_msg.format("int"))]
|
| 191 |
+
|
| 192 |
+
__former_attrs__ = {
|
| 193 |
+
n: _msg.format(n=n, extended_msg=extended_msg)
|
| 194 |
+
for n, extended_msg in _type_info
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
# Future warning introduced in NumPy 1.24.0, 2022-11-17
|
| 198 |
+
_msg = (
|
| 199 |
+
"`np.{n}` is a deprecated alias for `{an}`. (Deprecated NumPy 1.24)")
|
| 200 |
+
|
| 201 |
+
# Some of these are awkward (since `np.str` may be preferable in the long
|
| 202 |
+
# term), but overall the names ending in 0 seem undesirable
|
| 203 |
+
_type_info = [
|
| 204 |
+
("bool8", bool_, "np.bool_"),
|
| 205 |
+
("int0", intp, "np.intp"),
|
| 206 |
+
("uint0", uintp, "np.uintp"),
|
| 207 |
+
("str0", str_, "np.str_"),
|
| 208 |
+
("bytes0", bytes_, "np.bytes_"),
|
| 209 |
+
("void0", void, "np.void"),
|
| 210 |
+
("object0", object_,
|
| 211 |
+
"`np.object0` is a deprecated alias for `np.object_`. "
|
| 212 |
+
"`object` can be used instead. (Deprecated NumPy 1.24)")]
|
| 213 |
+
|
| 214 |
+
# Some of these could be defined right away, but most were aliases to
|
| 215 |
+
# the Python objects and only removed in NumPy 1.24. Defining them should
|
| 216 |
+
# probably wait for NumPy 1.26 or 2.0.
|
| 217 |
+
# When defined, these should possibly not be added to `__all__` to avoid
|
| 218 |
+
# import with `from numpy import *`.
|
| 219 |
+
__future_scalars__ = {"bool", "long", "ulong", "str", "bytes", "object"}
|
| 220 |
+
|
| 221 |
+
__deprecated_attrs__.update({
|
| 222 |
+
n: (alias, _msg.format(n=n, an=an)) for n, alias, an in _type_info})
|
| 223 |
+
|
| 224 |
+
import math
|
| 225 |
+
|
| 226 |
+
__deprecated_attrs__['math'] = (math,
|
| 227 |
+
"`np.math` is a deprecated alias for the standard library `math` "
|
| 228 |
+
"module (Deprecated Numpy 1.25). Replace usages of `np.math` with "
|
| 229 |
+
"`math`")
|
| 230 |
+
|
| 231 |
+
del math, _msg, _type_info
|
| 232 |
+
|
| 233 |
+
from .core import abs
|
| 234 |
+
# now that numpy modules are imported, can initialize limits
|
| 235 |
+
core.getlimits._register_known_types()
|
| 236 |
+
|
| 237 |
+
__all__.extend(['__version__', 'show_config'])
|
| 238 |
+
__all__.extend(core.__all__)
|
| 239 |
+
__all__.extend(_mat.__all__)
|
| 240 |
+
__all__.extend(lib.__all__)
|
| 241 |
+
__all__.extend(['linalg', 'fft', 'random', 'ctypeslib', 'ma'])
|
| 242 |
+
|
| 243 |
+
# Remove min and max from __all__ to avoid `from numpy import *` override
|
| 244 |
+
# the builtins min/max. Temporary fix for 1.25.x/1.26.x, see gh-24229.
|
| 245 |
+
__all__.remove('min')
|
| 246 |
+
__all__.remove('max')
|
| 247 |
+
__all__.remove('round')
|
| 248 |
+
|
| 249 |
+
# Remove one of the two occurrences of `issubdtype`, which is exposed as
|
| 250 |
+
# both `numpy.core.issubdtype` and `numpy.lib.issubdtype`.
|
| 251 |
+
__all__.remove('issubdtype')
|
| 252 |
+
|
| 253 |
+
# These are exported by np.core, but are replaced by the builtins below
|
| 254 |
+
# remove them to ensure that we don't end up with `np.long == np.int_`,
|
| 255 |
+
# which would be a breaking change.
|
| 256 |
+
del long, unicode
|
| 257 |
+
__all__.remove('long')
|
| 258 |
+
__all__.remove('unicode')
|
| 259 |
+
|
| 260 |
+
# Remove things that are in the numpy.lib but not in the numpy namespace
|
| 261 |
+
# Note that there is a test (numpy/tests/test_public_api.py:test_numpy_namespace)
|
| 262 |
+
# that prevents adding more things to the main namespace by accident.
|
| 263 |
+
# The list below will grow until the `from .lib import *` fixme above is
|
| 264 |
+
# taken care of
|
| 265 |
+
__all__.remove('Arrayterator')
|
| 266 |
+
del Arrayterator
|
| 267 |
+
|
| 268 |
+
# These names were removed in NumPy 1.20. For at least one release,
|
| 269 |
+
# attempts to access these names in the numpy namespace will trigger
|
| 270 |
+
# a warning, and calling the function will raise an exception.
|
| 271 |
+
_financial_names = ['fv', 'ipmt', 'irr', 'mirr', 'nper', 'npv', 'pmt',
|
| 272 |
+
'ppmt', 'pv', 'rate']
|
| 273 |
+
__expired_functions__ = {
|
| 274 |
+
name: (f'In accordance with NEP 32, the function {name} was removed '
|
| 275 |
+
'from NumPy version 1.20. A replacement for this function '
|
| 276 |
+
'is available in the numpy_financial library: '
|
| 277 |
+
'https://pypi.org/project/numpy-financial')
|
| 278 |
+
for name in _financial_names}
|
| 279 |
+
|
| 280 |
+
# Filter out Cython harmless warnings
|
| 281 |
+
warnings.filterwarnings("ignore", message="numpy.dtype size changed")
|
| 282 |
+
warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
|
| 283 |
+
warnings.filterwarnings("ignore", message="numpy.ndarray size changed")
|
| 284 |
+
|
| 285 |
+
# oldnumeric and numarray were removed in 1.9. In case some packages import
|
| 286 |
+
# but do not use them, we define them here for backward compatibility.
|
| 287 |
+
oldnumeric = 'removed'
|
| 288 |
+
numarray = 'removed'
|
| 289 |
+
|
| 290 |
+
def __getattr__(attr):
|
| 291 |
+
# Warn for expired attributes, and return a dummy function
|
| 292 |
+
# that always raises an exception.
|
| 293 |
+
import warnings
|
| 294 |
+
import math
|
| 295 |
+
try:
|
| 296 |
+
msg = __expired_functions__[attr]
|
| 297 |
+
except KeyError:
|
| 298 |
+
pass
|
| 299 |
+
else:
|
| 300 |
+
warnings.warn(msg, DeprecationWarning, stacklevel=2)
|
| 301 |
+
|
| 302 |
+
def _expired(*args, **kwds):
|
| 303 |
+
raise RuntimeError(msg)
|
| 304 |
+
|
| 305 |
+
return _expired
|
| 306 |
+
|
| 307 |
+
# Emit warnings for deprecated attributes
|
| 308 |
+
try:
|
| 309 |
+
val, msg = __deprecated_attrs__[attr]
|
| 310 |
+
except KeyError:
|
| 311 |
+
pass
|
| 312 |
+
else:
|
| 313 |
+
warnings.warn(msg, DeprecationWarning, stacklevel=2)
|
| 314 |
+
return val
|
| 315 |
+
|
| 316 |
+
if attr in __future_scalars__:
|
| 317 |
+
# And future warnings for those that will change, but also give
|
| 318 |
+
# the AttributeError
|
| 319 |
+
warnings.warn(
|
| 320 |
+
f"In the future `np.{attr}` will be defined as the "
|
| 321 |
+
"corresponding NumPy scalar.", FutureWarning, stacklevel=2)
|
| 322 |
+
|
| 323 |
+
if attr in __former_attrs__:
|
| 324 |
+
raise AttributeError(__former_attrs__[attr])
|
| 325 |
+
|
| 326 |
+
if attr == 'testing':
|
| 327 |
+
import numpy.testing as testing
|
| 328 |
+
return testing
|
| 329 |
+
elif attr == 'Tester':
|
| 330 |
+
"Removed in NumPy 1.25.0"
|
| 331 |
+
raise RuntimeError("Tester was removed in NumPy 1.25.")
|
| 332 |
+
|
| 333 |
+
raise AttributeError("module {!r} has no attribute "
|
| 334 |
+
"{!r}".format(__name__, attr))
|
| 335 |
+
|
| 336 |
+
def __dir__():
|
| 337 |
+
public_symbols = globals().keys() | {'testing'}
|
| 338 |
+
public_symbols -= {
|
| 339 |
+
"core", "matrixlib",
|
| 340 |
+
# These were moved in 1.25 and may be deprecated eventually:
|
| 341 |
+
"ModuleDeprecationWarning", "VisibleDeprecationWarning",
|
| 342 |
+
"ComplexWarning", "TooHardError", "AxisError"
|
| 343 |
+
}
|
| 344 |
+
return list(public_symbols)
|
| 345 |
+
|
| 346 |
+
# Pytest testing
|
| 347 |
+
from numpy._pytesttester import PytestTester
|
| 348 |
+
test = PytestTester(__name__)
|
| 349 |
+
del PytestTester
|
| 350 |
+
|
| 351 |
+
def _sanity_check():
|
| 352 |
+
"""
|
| 353 |
+
Quick sanity checks for common bugs caused by environment.
|
| 354 |
+
There are some cases e.g. with wrong BLAS ABI that cause wrong
|
| 355 |
+
results under specific runtime conditions that are not necessarily
|
| 356 |
+
achieved during test suite runs, and it is useful to catch those early.
|
| 357 |
+
|
| 358 |
+
See https://github.com/numpy/numpy/issues/8577 and other
|
| 359 |
+
similar bug reports.
|
| 360 |
+
|
| 361 |
+
"""
|
| 362 |
+
try:
|
| 363 |
+
x = ones(2, dtype=float32)
|
| 364 |
+
if not abs(x.dot(x) - float32(2.0)) < 1e-5:
|
| 365 |
+
raise AssertionError()
|
| 366 |
+
except AssertionError:
|
| 367 |
+
msg = ("The current Numpy installation ({!r}) fails to "
|
| 368 |
+
"pass simple sanity checks. This can be caused for example "
|
| 369 |
+
"by incorrect BLAS library being linked in, or by mixing "
|
| 370 |
+
"package managers (pip, conda, apt, ...). Search closed "
|
| 371 |
+
"numpy issues for similar problems.")
|
| 372 |
+
raise RuntimeError(msg.format(__file__)) from None
|
| 373 |
+
|
| 374 |
+
_sanity_check()
|
| 375 |
+
del _sanity_check
|
| 376 |
+
|
| 377 |
+
def _mac_os_check():
|
| 378 |
+
"""
|
| 379 |
+
Quick Sanity check for Mac OS look for accelerate build bugs.
|
| 380 |
+
Testing numpy polyfit calls init_dgelsd(LAPACK)
|
| 381 |
+
"""
|
| 382 |
+
try:
|
| 383 |
+
c = array([3., 2., 1.])
|
| 384 |
+
x = linspace(0, 2, 5)
|
| 385 |
+
y = polyval(c, x)
|
| 386 |
+
_ = polyfit(x, y, 2, cov=True)
|
| 387 |
+
except ValueError:
|
| 388 |
+
pass
|
| 389 |
+
|
| 390 |
+
if sys.platform == "darwin":
|
| 391 |
+
from . import exceptions
|
| 392 |
+
with warnings.catch_warnings(record=True) as w:
|
| 393 |
+
_mac_os_check()
|
| 394 |
+
# Throw runtime error, if the test failed Check for warning and error_message
|
| 395 |
+
if len(w) > 0:
|
| 396 |
+
for _wn in w:
|
| 397 |
+
if _wn.category is exceptions.RankWarning:
|
| 398 |
+
# Ignore other warnings, they may not be relevant (see gh-25433).
|
| 399 |
+
error_message = f"{_wn.category.__name__}: {str(_wn.message)}"
|
| 400 |
+
msg = (
|
| 401 |
+
"Polyfit sanity test emitted a warning, most likely due "
|
| 402 |
+
"to using a buggy Accelerate backend."
|
| 403 |
+
"\nIf you compiled yourself, more information is available at:"
|
| 404 |
+
"\nhttps://numpy.org/devdocs/building/index.html"
|
| 405 |
+
"\nOtherwise report this to the vendor "
|
| 406 |
+
"that provided NumPy.\n\n{}\n".format(error_message))
|
| 407 |
+
raise RuntimeError(msg)
|
| 408 |
+
del _wn
|
| 409 |
+
del w
|
| 410 |
+
del _mac_os_check
|
| 411 |
+
|
| 412 |
+
# We usually use madvise hugepages support, but on some old kernels it
|
| 413 |
+
# is slow and thus better avoided.
|
| 414 |
+
# Specifically kernel version 4.6 had a bug fix which probably fixed this:
|
| 415 |
+
# https://github.com/torvalds/linux/commit/7cf91a98e607c2f935dbcc177d70011e95b8faff
|
| 416 |
+
import os
|
| 417 |
+
use_hugepage = os.environ.get("NUMPY_MADVISE_HUGEPAGE", None)
|
| 418 |
+
if sys.platform == "linux" and use_hugepage is None:
|
| 419 |
+
# If there is an issue with parsing the kernel version,
|
| 420 |
+
# set use_hugepages to 0. Usage of LooseVersion will handle
|
| 421 |
+
# the kernel version parsing better, but avoided since it
|
| 422 |
+
# will increase the import time. See: #16679 for related discussion.
|
| 423 |
+
try:
|
| 424 |
+
use_hugepage = 1
|
| 425 |
+
kernel_version = os.uname().release.split(".")[:2]
|
| 426 |
+
kernel_version = tuple(int(v) for v in kernel_version)
|
| 427 |
+
if kernel_version < (4, 6):
|
| 428 |
+
use_hugepage = 0
|
| 429 |
+
except ValueError:
|
| 430 |
+
use_hugepages = 0
|
| 431 |
+
elif use_hugepage is None:
|
| 432 |
+
# This is not Linux, so it should not matter, just enable anyway
|
| 433 |
+
use_hugepage = 1
|
| 434 |
+
else:
|
| 435 |
+
use_hugepage = int(use_hugepage)
|
| 436 |
+
|
| 437 |
+
# Note that this will currently only make a difference on Linux
|
| 438 |
+
core.multiarray._set_madvise_hugepage(use_hugepage)
|
| 439 |
+
del use_hugepage
|
| 440 |
+
|
| 441 |
+
# Give a warning if NumPy is reloaded or imported on a sub-interpreter
|
| 442 |
+
# We do this from python, since the C-module may not be reloaded and
|
| 443 |
+
# it is tidier organized.
|
| 444 |
+
core.multiarray._multiarray_umath._reload_guard()
|
| 445 |
+
|
| 446 |
+
# default to "weak" promotion for "NumPy 2".
|
| 447 |
+
core._set_promotion_state(
|
| 448 |
+
os.environ.get("NPY_PROMOTION_STATE",
|
| 449 |
+
"weak" if _using_numpy2_behavior() else "legacy"))
|
| 450 |
+
|
| 451 |
+
# Tell PyInstaller where to find hook-numpy.py
|
| 452 |
+
def _pyinstaller_hooks_dir():
|
| 453 |
+
from pathlib import Path
|
| 454 |
+
return [str(Path(__file__).with_name("_pyinstaller").resolve())]
|
| 455 |
+
|
| 456 |
+
# Remove symbols imported for internal use
|
| 457 |
+
del os
|
| 458 |
+
|
| 459 |
+
|
| 460 |
+
# Remove symbols imported for internal use
|
| 461 |
+
del sys, warnings
|
lib/python3.12/site-packages/numpy/__init__.pyi
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
lib/python3.12/site-packages/numpy/_distributor_init.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
""" Distributor init file
|
| 2 |
+
|
| 3 |
+
Distributors: you can add custom code here to support particular distributions
|
| 4 |
+
of numpy.
|
| 5 |
+
|
| 6 |
+
For example, this is a good place to put any BLAS/LAPACK initialization code.
|
| 7 |
+
|
| 8 |
+
The numpy standard source distribution will not put code in this file, so you
|
| 9 |
+
can safely replace this file with your own version.
|
| 10 |
+
"""
|
| 11 |
+
|
| 12 |
+
try:
|
| 13 |
+
from . import _distributor_init_local
|
| 14 |
+
except ImportError:
|
| 15 |
+
pass
|
lib/python3.12/site-packages/numpy/_globals.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Module defining global singleton classes.
|
| 3 |
+
|
| 4 |
+
This module raises a RuntimeError if an attempt to reload it is made. In that
|
| 5 |
+
way the identities of the classes defined here are fixed and will remain so
|
| 6 |
+
even if numpy itself is reloaded. In particular, a function like the following
|
| 7 |
+
will still work correctly after numpy is reloaded::
|
| 8 |
+
|
| 9 |
+
def foo(arg=np._NoValue):
|
| 10 |
+
if arg is np._NoValue:
|
| 11 |
+
...
|
| 12 |
+
|
| 13 |
+
That was not the case when the singleton classes were defined in the numpy
|
| 14 |
+
``__init__.py`` file. See gh-7844 for a discussion of the reload problem that
|
| 15 |
+
motivated this module.
|
| 16 |
+
|
| 17 |
+
"""
|
| 18 |
+
import enum
|
| 19 |
+
|
| 20 |
+
from ._utils import set_module as _set_module
|
| 21 |
+
|
| 22 |
+
__all__ = ['_NoValue', '_CopyMode']
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
# Disallow reloading this module so as to preserve the identities of the
|
| 26 |
+
# classes defined here.
|
| 27 |
+
if '_is_loaded' in globals():
|
| 28 |
+
raise RuntimeError('Reloading numpy._globals is not allowed')
|
| 29 |
+
_is_loaded = True
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class _NoValueType:
|
| 33 |
+
"""Special keyword value.
|
| 34 |
+
|
| 35 |
+
The instance of this class may be used as the default value assigned to a
|
| 36 |
+
keyword if no other obvious default (e.g., `None`) is suitable,
|
| 37 |
+
|
| 38 |
+
Common reasons for using this keyword are:
|
| 39 |
+
|
| 40 |
+
- A new keyword is added to a function, and that function forwards its
|
| 41 |
+
inputs to another function or method which can be defined outside of
|
| 42 |
+
NumPy. For example, ``np.std(x)`` calls ``x.std``, so when a ``keepdims``
|
| 43 |
+
keyword was added that could only be forwarded if the user explicitly
|
| 44 |
+
specified ``keepdims``; downstream array libraries may not have added
|
| 45 |
+
the same keyword, so adding ``x.std(..., keepdims=keepdims)``
|
| 46 |
+
unconditionally could have broken previously working code.
|
| 47 |
+
- A keyword is being deprecated, and a deprecation warning must only be
|
| 48 |
+
emitted when the keyword is used.
|
| 49 |
+
|
| 50 |
+
"""
|
| 51 |
+
__instance = None
|
| 52 |
+
def __new__(cls):
|
| 53 |
+
# ensure that only one instance exists
|
| 54 |
+
if not cls.__instance:
|
| 55 |
+
cls.__instance = super().__new__(cls)
|
| 56 |
+
return cls.__instance
|
| 57 |
+
|
| 58 |
+
def __repr__(self):
|
| 59 |
+
return "<no value>"
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
_NoValue = _NoValueType()
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
@_set_module("numpy")
|
| 66 |
+
class _CopyMode(enum.Enum):
|
| 67 |
+
"""
|
| 68 |
+
An enumeration for the copy modes supported
|
| 69 |
+
by numpy.copy() and numpy.array(). The following three modes are supported,
|
| 70 |
+
|
| 71 |
+
- ALWAYS: This means that a deep copy of the input
|
| 72 |
+
array will always be taken.
|
| 73 |
+
- IF_NEEDED: This means that a deep copy of the input
|
| 74 |
+
array will be taken only if necessary.
|
| 75 |
+
- NEVER: This means that the deep copy will never be taken.
|
| 76 |
+
If a copy cannot be avoided then a `ValueError` will be
|
| 77 |
+
raised.
|
| 78 |
+
|
| 79 |
+
Note that the buffer-protocol could in theory do copies. NumPy currently
|
| 80 |
+
assumes an object exporting the buffer protocol will never do this.
|
| 81 |
+
"""
|
| 82 |
+
|
| 83 |
+
ALWAYS = True
|
| 84 |
+
IF_NEEDED = False
|
| 85 |
+
NEVER = 2
|
| 86 |
+
|
| 87 |
+
def __bool__(self):
|
| 88 |
+
# For backwards compatibility
|
| 89 |
+
if self == _CopyMode.ALWAYS:
|
| 90 |
+
return True
|
| 91 |
+
|
| 92 |
+
if self == _CopyMode.IF_NEEDED:
|
| 93 |
+
return False
|
| 94 |
+
|
| 95 |
+
raise ValueError(f"{self} is neither True nor False.")
|
lib/python3.12/site-packages/numpy/_pytesttester.py
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Pytest test running.
|
| 3 |
+
|
| 4 |
+
This module implements the ``test()`` function for NumPy modules. The usual
|
| 5 |
+
boiler plate for doing that is to put the following in the module
|
| 6 |
+
``__init__.py`` file::
|
| 7 |
+
|
| 8 |
+
from numpy._pytesttester import PytestTester
|
| 9 |
+
test = PytestTester(__name__)
|
| 10 |
+
del PytestTester
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
Warnings filtering and other runtime settings should be dealt with in the
|
| 14 |
+
``pytest.ini`` file in the numpy repo root. The behavior of the test depends on
|
| 15 |
+
whether or not that file is found as follows:
|
| 16 |
+
|
| 17 |
+
* ``pytest.ini`` is present (develop mode)
|
| 18 |
+
All warnings except those explicitly filtered out are raised as error.
|
| 19 |
+
* ``pytest.ini`` is absent (release mode)
|
| 20 |
+
DeprecationWarnings and PendingDeprecationWarnings are ignored, other
|
| 21 |
+
warnings are passed through.
|
| 22 |
+
|
| 23 |
+
In practice, tests run from the numpy repo are run in develop mode. That
|
| 24 |
+
includes the standard ``python runtests.py`` invocation.
|
| 25 |
+
|
| 26 |
+
This module is imported by every numpy subpackage, so lies at the top level to
|
| 27 |
+
simplify circular import issues. For the same reason, it contains no numpy
|
| 28 |
+
imports at module scope, instead importing numpy within function calls.
|
| 29 |
+
"""
|
| 30 |
+
import sys
|
| 31 |
+
import os
|
| 32 |
+
|
| 33 |
+
__all__ = ['PytestTester']
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def _show_numpy_info():
|
| 37 |
+
import numpy as np
|
| 38 |
+
|
| 39 |
+
print("NumPy version %s" % np.__version__)
|
| 40 |
+
relaxed_strides = np.ones((10, 1), order="C").flags.f_contiguous
|
| 41 |
+
print("NumPy relaxed strides checking option:", relaxed_strides)
|
| 42 |
+
info = np.lib.utils._opt_info()
|
| 43 |
+
print("NumPy CPU features: ", (info if info else 'nothing enabled'))
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
class PytestTester:
|
| 47 |
+
"""
|
| 48 |
+
Pytest test runner.
|
| 49 |
+
|
| 50 |
+
A test function is typically added to a package's __init__.py like so::
|
| 51 |
+
|
| 52 |
+
from numpy._pytesttester import PytestTester
|
| 53 |
+
test = PytestTester(__name__).test
|
| 54 |
+
del PytestTester
|
| 55 |
+
|
| 56 |
+
Calling this test function finds and runs all tests associated with the
|
| 57 |
+
module and all its sub-modules.
|
| 58 |
+
|
| 59 |
+
Attributes
|
| 60 |
+
----------
|
| 61 |
+
module_name : str
|
| 62 |
+
Full path to the package to test.
|
| 63 |
+
|
| 64 |
+
Parameters
|
| 65 |
+
----------
|
| 66 |
+
module_name : module name
|
| 67 |
+
The name of the module to test.
|
| 68 |
+
|
| 69 |
+
Notes
|
| 70 |
+
-----
|
| 71 |
+
Unlike the previous ``nose``-based implementation, this class is not
|
| 72 |
+
publicly exposed as it performs some ``numpy``-specific warning
|
| 73 |
+
suppression.
|
| 74 |
+
|
| 75 |
+
"""
|
| 76 |
+
def __init__(self, module_name):
|
| 77 |
+
self.module_name = module_name
|
| 78 |
+
|
| 79 |
+
def __call__(self, label='fast', verbose=1, extra_argv=None,
|
| 80 |
+
doctests=False, coverage=False, durations=-1, tests=None):
|
| 81 |
+
"""
|
| 82 |
+
Run tests for module using pytest.
|
| 83 |
+
|
| 84 |
+
Parameters
|
| 85 |
+
----------
|
| 86 |
+
label : {'fast', 'full'}, optional
|
| 87 |
+
Identifies the tests to run. When set to 'fast', tests decorated
|
| 88 |
+
with `pytest.mark.slow` are skipped, when 'full', the slow marker
|
| 89 |
+
is ignored.
|
| 90 |
+
verbose : int, optional
|
| 91 |
+
Verbosity value for test outputs, in the range 1-3. Default is 1.
|
| 92 |
+
extra_argv : list, optional
|
| 93 |
+
List with any extra arguments to pass to pytests.
|
| 94 |
+
doctests : bool, optional
|
| 95 |
+
.. note:: Not supported
|
| 96 |
+
coverage : bool, optional
|
| 97 |
+
If True, report coverage of NumPy code. Default is False.
|
| 98 |
+
Requires installation of (pip) pytest-cov.
|
| 99 |
+
durations : int, optional
|
| 100 |
+
If < 0, do nothing, If 0, report time of all tests, if > 0,
|
| 101 |
+
report the time of the slowest `timer` tests. Default is -1.
|
| 102 |
+
tests : test or list of tests
|
| 103 |
+
Tests to be executed with pytest '--pyargs'
|
| 104 |
+
|
| 105 |
+
Returns
|
| 106 |
+
-------
|
| 107 |
+
result : bool
|
| 108 |
+
Return True on success, false otherwise.
|
| 109 |
+
|
| 110 |
+
Notes
|
| 111 |
+
-----
|
| 112 |
+
Each NumPy module exposes `test` in its namespace to run all tests for
|
| 113 |
+
it. For example, to run all tests for numpy.lib:
|
| 114 |
+
|
| 115 |
+
>>> np.lib.test() #doctest: +SKIP
|
| 116 |
+
|
| 117 |
+
Examples
|
| 118 |
+
--------
|
| 119 |
+
>>> result = np.lib.test() #doctest: +SKIP
|
| 120 |
+
...
|
| 121 |
+
1023 passed, 2 skipped, 6 deselected, 1 xfailed in 10.39 seconds
|
| 122 |
+
>>> result
|
| 123 |
+
True
|
| 124 |
+
|
| 125 |
+
"""
|
| 126 |
+
import pytest
|
| 127 |
+
import warnings
|
| 128 |
+
|
| 129 |
+
module = sys.modules[self.module_name]
|
| 130 |
+
module_path = os.path.abspath(module.__path__[0])
|
| 131 |
+
|
| 132 |
+
# setup the pytest arguments
|
| 133 |
+
pytest_args = ["-l"]
|
| 134 |
+
|
| 135 |
+
# offset verbosity. The "-q" cancels a "-v".
|
| 136 |
+
pytest_args += ["-q"]
|
| 137 |
+
|
| 138 |
+
if sys.version_info < (3, 12):
|
| 139 |
+
with warnings.catch_warnings():
|
| 140 |
+
warnings.simplefilter("always")
|
| 141 |
+
# Filter out distutils cpu warnings (could be localized to
|
| 142 |
+
# distutils tests). ASV has problems with top level import,
|
| 143 |
+
# so fetch module for suppression here.
|
| 144 |
+
from numpy.distutils import cpuinfo
|
| 145 |
+
|
| 146 |
+
with warnings.catch_warnings(record=True):
|
| 147 |
+
# Ignore the warning from importing the array_api submodule. This
|
| 148 |
+
# warning is done on import, so it would break pytest collection,
|
| 149 |
+
# but importing it early here prevents the warning from being
|
| 150 |
+
# issued when it imported again.
|
| 151 |
+
import numpy.array_api
|
| 152 |
+
|
| 153 |
+
# Filter out annoying import messages. Want these in both develop and
|
| 154 |
+
# release mode.
|
| 155 |
+
pytest_args += [
|
| 156 |
+
"-W ignore:Not importing directory",
|
| 157 |
+
"-W ignore:numpy.dtype size changed",
|
| 158 |
+
"-W ignore:numpy.ufunc size changed",
|
| 159 |
+
"-W ignore::UserWarning:cpuinfo",
|
| 160 |
+
]
|
| 161 |
+
|
| 162 |
+
# When testing matrices, ignore their PendingDeprecationWarnings
|
| 163 |
+
pytest_args += [
|
| 164 |
+
"-W ignore:the matrix subclass is not",
|
| 165 |
+
"-W ignore:Importing from numpy.matlib is",
|
| 166 |
+
]
|
| 167 |
+
|
| 168 |
+
if doctests:
|
| 169 |
+
pytest_args += ["--doctest-modules"]
|
| 170 |
+
|
| 171 |
+
if extra_argv:
|
| 172 |
+
pytest_args += list(extra_argv)
|
| 173 |
+
|
| 174 |
+
if verbose > 1:
|
| 175 |
+
pytest_args += ["-" + "v"*(verbose - 1)]
|
| 176 |
+
|
| 177 |
+
if coverage:
|
| 178 |
+
pytest_args += ["--cov=" + module_path]
|
| 179 |
+
|
| 180 |
+
if label == "fast":
|
| 181 |
+
# not importing at the top level to avoid circular import of module
|
| 182 |
+
from numpy.testing import IS_PYPY
|
| 183 |
+
if IS_PYPY:
|
| 184 |
+
pytest_args += ["-m", "not slow and not slow_pypy"]
|
| 185 |
+
else:
|
| 186 |
+
pytest_args += ["-m", "not slow"]
|
| 187 |
+
|
| 188 |
+
elif label != "full":
|
| 189 |
+
pytest_args += ["-m", label]
|
| 190 |
+
|
| 191 |
+
if durations >= 0:
|
| 192 |
+
pytest_args += ["--durations=%s" % durations]
|
| 193 |
+
|
| 194 |
+
if tests is None:
|
| 195 |
+
tests = [self.module_name]
|
| 196 |
+
|
| 197 |
+
pytest_args += ["--pyargs"] + list(tests)
|
| 198 |
+
|
| 199 |
+
# run tests.
|
| 200 |
+
_show_numpy_info()
|
| 201 |
+
|
| 202 |
+
try:
|
| 203 |
+
code = pytest.main(pytest_args)
|
| 204 |
+
except SystemExit as exc:
|
| 205 |
+
code = exc.code
|
| 206 |
+
|
| 207 |
+
return code == 0
|
lib/python3.12/site-packages/numpy/_pytesttester.pyi
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from collections.abc import Iterable
|
| 2 |
+
from typing import Literal as L
|
| 3 |
+
|
| 4 |
+
__all__: list[str]
|
| 5 |
+
|
| 6 |
+
class PytestTester:
|
| 7 |
+
module_name: str
|
| 8 |
+
def __init__(self, module_name: str) -> None: ...
|
| 9 |
+
def __call__(
|
| 10 |
+
self,
|
| 11 |
+
label: L["fast", "full"] = ...,
|
| 12 |
+
verbose: int = ...,
|
| 13 |
+
extra_argv: None | Iterable[str] = ...,
|
| 14 |
+
doctests: L[False] = ...,
|
| 15 |
+
coverage: bool = ...,
|
| 16 |
+
durations: int = ...,
|
| 17 |
+
tests: None | Iterable[str] = ...,
|
| 18 |
+
) -> bool: ...
|
lib/python3.12/site-packages/numpy/conftest.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Pytest configuration and fixtures for the Numpy test suite.
|
| 3 |
+
"""
|
| 4 |
+
import os
|
| 5 |
+
import tempfile
|
| 6 |
+
|
| 7 |
+
import hypothesis
|
| 8 |
+
import pytest
|
| 9 |
+
import numpy
|
| 10 |
+
|
| 11 |
+
from numpy.core._multiarray_tests import get_fpu_mode
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
_old_fpu_mode = None
|
| 15 |
+
_collect_results = {}
|
| 16 |
+
|
| 17 |
+
# Use a known and persistent tmpdir for hypothesis' caches, which
|
| 18 |
+
# can be automatically cleared by the OS or user.
|
| 19 |
+
hypothesis.configuration.set_hypothesis_home_dir(
|
| 20 |
+
os.path.join(tempfile.gettempdir(), ".hypothesis")
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
# We register two custom profiles for Numpy - for details see
|
| 24 |
+
# https://hypothesis.readthedocs.io/en/latest/settings.html
|
| 25 |
+
# The first is designed for our own CI runs; the latter also
|
| 26 |
+
# forces determinism and is designed for use via np.test()
|
| 27 |
+
hypothesis.settings.register_profile(
|
| 28 |
+
name="numpy-profile", deadline=None, print_blob=True,
|
| 29 |
+
)
|
| 30 |
+
hypothesis.settings.register_profile(
|
| 31 |
+
name="np.test() profile",
|
| 32 |
+
deadline=None, print_blob=True, database=None, derandomize=True,
|
| 33 |
+
suppress_health_check=list(hypothesis.HealthCheck),
|
| 34 |
+
)
|
| 35 |
+
# Note that the default profile is chosen based on the presence
|
| 36 |
+
# of pytest.ini, but can be overridden by passing the
|
| 37 |
+
# --hypothesis-profile=NAME argument to pytest.
|
| 38 |
+
_pytest_ini = os.path.join(os.path.dirname(__file__), "..", "pytest.ini")
|
| 39 |
+
hypothesis.settings.load_profile(
|
| 40 |
+
"numpy-profile" if os.path.isfile(_pytest_ini) else "np.test() profile"
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
# The experimentalAPI is used in _umath_tests
|
| 44 |
+
os.environ["NUMPY_EXPERIMENTAL_DTYPE_API"] = "1"
|
| 45 |
+
|
| 46 |
+
def pytest_configure(config):
|
| 47 |
+
config.addinivalue_line("markers",
|
| 48 |
+
"valgrind_error: Tests that are known to error under valgrind.")
|
| 49 |
+
config.addinivalue_line("markers",
|
| 50 |
+
"leaks_references: Tests that are known to leak references.")
|
| 51 |
+
config.addinivalue_line("markers",
|
| 52 |
+
"slow: Tests that are very slow.")
|
| 53 |
+
config.addinivalue_line("markers",
|
| 54 |
+
"slow_pypy: Tests that are very slow on pypy.")
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
def pytest_addoption(parser):
|
| 58 |
+
parser.addoption("--available-memory", action="store", default=None,
|
| 59 |
+
help=("Set amount of memory available for running the "
|
| 60 |
+
"test suite. This can result to tests requiring "
|
| 61 |
+
"especially large amounts of memory to be skipped. "
|
| 62 |
+
"Equivalent to setting environment variable "
|
| 63 |
+
"NPY_AVAILABLE_MEM. Default: determined"
|
| 64 |
+
"automatically."))
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def pytest_sessionstart(session):
|
| 68 |
+
available_mem = session.config.getoption('available_memory')
|
| 69 |
+
if available_mem is not None:
|
| 70 |
+
os.environ['NPY_AVAILABLE_MEM'] = available_mem
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
#FIXME when yield tests are gone.
|
| 74 |
+
@pytest.hookimpl()
|
| 75 |
+
def pytest_itemcollected(item):
|
| 76 |
+
"""
|
| 77 |
+
Check FPU precision mode was not changed during test collection.
|
| 78 |
+
|
| 79 |
+
The clumsy way we do it here is mainly necessary because numpy
|
| 80 |
+
still uses yield tests, which can execute code at test collection
|
| 81 |
+
time.
|
| 82 |
+
"""
|
| 83 |
+
global _old_fpu_mode
|
| 84 |
+
|
| 85 |
+
mode = get_fpu_mode()
|
| 86 |
+
|
| 87 |
+
if _old_fpu_mode is None:
|
| 88 |
+
_old_fpu_mode = mode
|
| 89 |
+
elif mode != _old_fpu_mode:
|
| 90 |
+
_collect_results[item] = (_old_fpu_mode, mode)
|
| 91 |
+
_old_fpu_mode = mode
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
@pytest.fixture(scope="function", autouse=True)
|
| 95 |
+
def check_fpu_mode(request):
|
| 96 |
+
"""
|
| 97 |
+
Check FPU precision mode was not changed during the test.
|
| 98 |
+
"""
|
| 99 |
+
old_mode = get_fpu_mode()
|
| 100 |
+
yield
|
| 101 |
+
new_mode = get_fpu_mode()
|
| 102 |
+
|
| 103 |
+
if old_mode != new_mode:
|
| 104 |
+
raise AssertionError("FPU precision mode changed from {0:#x} to {1:#x}"
|
| 105 |
+
" during the test".format(old_mode, new_mode))
|
| 106 |
+
|
| 107 |
+
collect_result = _collect_results.get(request.node)
|
| 108 |
+
if collect_result is not None:
|
| 109 |
+
old_mode, new_mode = collect_result
|
| 110 |
+
raise AssertionError("FPU precision mode changed from {0:#x} to {1:#x}"
|
| 111 |
+
" when collecting the test".format(old_mode,
|
| 112 |
+
new_mode))
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
@pytest.fixture(autouse=True)
|
| 116 |
+
def add_np(doctest_namespace):
|
| 117 |
+
doctest_namespace['np'] = numpy
|
| 118 |
+
|
| 119 |
+
@pytest.fixture(autouse=True)
|
| 120 |
+
def env_setup(monkeypatch):
|
| 121 |
+
monkeypatch.setenv('PYTHONHASHSEED', '0')
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
@pytest.fixture(params=[True, False])
|
| 125 |
+
def weak_promotion(request):
|
| 126 |
+
"""
|
| 127 |
+
Fixture to ensure "legacy" promotion state or change it to use the new
|
| 128 |
+
weak promotion (plus warning). `old_promotion` should be used as a
|
| 129 |
+
parameter in the function.
|
| 130 |
+
"""
|
| 131 |
+
state = numpy._get_promotion_state()
|
| 132 |
+
if request.param:
|
| 133 |
+
numpy._set_promotion_state("weak_and_warn")
|
| 134 |
+
else:
|
| 135 |
+
numpy._set_promotion_state("legacy")
|
| 136 |
+
|
| 137 |
+
yield request.param
|
| 138 |
+
numpy._set_promotion_state(state)
|
lib/python3.12/site-packages/numpy/ctypeslib.py
ADDED
|
@@ -0,0 +1,545 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
============================
|
| 3 |
+
``ctypes`` Utility Functions
|
| 4 |
+
============================
|
| 5 |
+
|
| 6 |
+
See Also
|
| 7 |
+
--------
|
| 8 |
+
load_library : Load a C library.
|
| 9 |
+
ndpointer : Array restype/argtype with verification.
|
| 10 |
+
as_ctypes : Create a ctypes array from an ndarray.
|
| 11 |
+
as_array : Create an ndarray from a ctypes array.
|
| 12 |
+
|
| 13 |
+
References
|
| 14 |
+
----------
|
| 15 |
+
.. [1] "SciPy Cookbook: ctypes", https://scipy-cookbook.readthedocs.io/items/Ctypes.html
|
| 16 |
+
|
| 17 |
+
Examples
|
| 18 |
+
--------
|
| 19 |
+
Load the C library:
|
| 20 |
+
|
| 21 |
+
>>> _lib = np.ctypeslib.load_library('libmystuff', '.') #doctest: +SKIP
|
| 22 |
+
|
| 23 |
+
Our result type, an ndarray that must be of type double, be 1-dimensional
|
| 24 |
+
and is C-contiguous in memory:
|
| 25 |
+
|
| 26 |
+
>>> array_1d_double = np.ctypeslib.ndpointer(
|
| 27 |
+
... dtype=np.double,
|
| 28 |
+
... ndim=1, flags='CONTIGUOUS') #doctest: +SKIP
|
| 29 |
+
|
| 30 |
+
Our C-function typically takes an array and updates its values
|
| 31 |
+
in-place. For example::
|
| 32 |
+
|
| 33 |
+
void foo_func(double* x, int length)
|
| 34 |
+
{
|
| 35 |
+
int i;
|
| 36 |
+
for (i = 0; i < length; i++) {
|
| 37 |
+
x[i] = i*i;
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
We wrap it using:
|
| 42 |
+
|
| 43 |
+
>>> _lib.foo_func.restype = None #doctest: +SKIP
|
| 44 |
+
>>> _lib.foo_func.argtypes = [array_1d_double, c_int] #doctest: +SKIP
|
| 45 |
+
|
| 46 |
+
Then, we're ready to call ``foo_func``:
|
| 47 |
+
|
| 48 |
+
>>> out = np.empty(15, dtype=np.double)
|
| 49 |
+
>>> _lib.foo_func(out, len(out)) #doctest: +SKIP
|
| 50 |
+
|
| 51 |
+
"""
|
| 52 |
+
__all__ = ['load_library', 'ndpointer', 'c_intp', 'as_ctypes', 'as_array',
|
| 53 |
+
'as_ctypes_type']
|
| 54 |
+
|
| 55 |
+
import os
|
| 56 |
+
from numpy import (
|
| 57 |
+
integer, ndarray, dtype as _dtype, asarray, frombuffer
|
| 58 |
+
)
|
| 59 |
+
from numpy.core.multiarray import _flagdict, flagsobj
|
| 60 |
+
|
| 61 |
+
try:
|
| 62 |
+
import ctypes
|
| 63 |
+
except ImportError:
|
| 64 |
+
ctypes = None
|
| 65 |
+
|
| 66 |
+
if ctypes is None:
|
| 67 |
+
def _dummy(*args, **kwds):
|
| 68 |
+
"""
|
| 69 |
+
Dummy object that raises an ImportError if ctypes is not available.
|
| 70 |
+
|
| 71 |
+
Raises
|
| 72 |
+
------
|
| 73 |
+
ImportError
|
| 74 |
+
If ctypes is not available.
|
| 75 |
+
|
| 76 |
+
"""
|
| 77 |
+
raise ImportError("ctypes is not available.")
|
| 78 |
+
load_library = _dummy
|
| 79 |
+
as_ctypes = _dummy
|
| 80 |
+
as_array = _dummy
|
| 81 |
+
from numpy import intp as c_intp
|
| 82 |
+
_ndptr_base = object
|
| 83 |
+
else:
|
| 84 |
+
import numpy.core._internal as nic
|
| 85 |
+
c_intp = nic._getintp_ctype()
|
| 86 |
+
del nic
|
| 87 |
+
_ndptr_base = ctypes.c_void_p
|
| 88 |
+
|
| 89 |
+
# Adapted from Albert Strasheim
|
| 90 |
+
def load_library(libname, loader_path):
|
| 91 |
+
"""
|
| 92 |
+
It is possible to load a library using
|
| 93 |
+
|
| 94 |
+
>>> lib = ctypes.cdll[<full_path_name>] # doctest: +SKIP
|
| 95 |
+
|
| 96 |
+
But there are cross-platform considerations, such as library file extensions,
|
| 97 |
+
plus the fact Windows will just load the first library it finds with that name.
|
| 98 |
+
NumPy supplies the load_library function as a convenience.
|
| 99 |
+
|
| 100 |
+
.. versionchanged:: 1.20.0
|
| 101 |
+
Allow libname and loader_path to take any
|
| 102 |
+
:term:`python:path-like object`.
|
| 103 |
+
|
| 104 |
+
Parameters
|
| 105 |
+
----------
|
| 106 |
+
libname : path-like
|
| 107 |
+
Name of the library, which can have 'lib' as a prefix,
|
| 108 |
+
but without an extension.
|
| 109 |
+
loader_path : path-like
|
| 110 |
+
Where the library can be found.
|
| 111 |
+
|
| 112 |
+
Returns
|
| 113 |
+
-------
|
| 114 |
+
ctypes.cdll[libpath] : library object
|
| 115 |
+
A ctypes library object
|
| 116 |
+
|
| 117 |
+
Raises
|
| 118 |
+
------
|
| 119 |
+
OSError
|
| 120 |
+
If there is no library with the expected extension, or the
|
| 121 |
+
library is defective and cannot be loaded.
|
| 122 |
+
"""
|
| 123 |
+
# Convert path-like objects into strings
|
| 124 |
+
libname = os.fsdecode(libname)
|
| 125 |
+
loader_path = os.fsdecode(loader_path)
|
| 126 |
+
|
| 127 |
+
ext = os.path.splitext(libname)[1]
|
| 128 |
+
if not ext:
|
| 129 |
+
import sys
|
| 130 |
+
import sysconfig
|
| 131 |
+
# Try to load library with platform-specific name, otherwise
|
| 132 |
+
# default to libname.[so|dll|dylib]. Sometimes, these files are
|
| 133 |
+
# built erroneously on non-linux platforms.
|
| 134 |
+
base_ext = ".so"
|
| 135 |
+
if sys.platform.startswith("darwin"):
|
| 136 |
+
base_ext = ".dylib"
|
| 137 |
+
elif sys.platform.startswith("win"):
|
| 138 |
+
base_ext = ".dll"
|
| 139 |
+
libname_ext = [libname + base_ext]
|
| 140 |
+
so_ext = sysconfig.get_config_var("EXT_SUFFIX")
|
| 141 |
+
if not so_ext == base_ext:
|
| 142 |
+
libname_ext.insert(0, libname + so_ext)
|
| 143 |
+
else:
|
| 144 |
+
libname_ext = [libname]
|
| 145 |
+
|
| 146 |
+
loader_path = os.path.abspath(loader_path)
|
| 147 |
+
if not os.path.isdir(loader_path):
|
| 148 |
+
libdir = os.path.dirname(loader_path)
|
| 149 |
+
else:
|
| 150 |
+
libdir = loader_path
|
| 151 |
+
|
| 152 |
+
for ln in libname_ext:
|
| 153 |
+
libpath = os.path.join(libdir, ln)
|
| 154 |
+
if os.path.exists(libpath):
|
| 155 |
+
try:
|
| 156 |
+
return ctypes.cdll[libpath]
|
| 157 |
+
except OSError:
|
| 158 |
+
## defective lib file
|
| 159 |
+
raise
|
| 160 |
+
## if no successful return in the libname_ext loop:
|
| 161 |
+
raise OSError("no file with expected extension")
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
def _num_fromflags(flaglist):
|
| 165 |
+
num = 0
|
| 166 |
+
for val in flaglist:
|
| 167 |
+
num += _flagdict[val]
|
| 168 |
+
return num
|
| 169 |
+
|
| 170 |
+
_flagnames = ['C_CONTIGUOUS', 'F_CONTIGUOUS', 'ALIGNED', 'WRITEABLE',
|
| 171 |
+
'OWNDATA', 'WRITEBACKIFCOPY']
|
| 172 |
+
def _flags_fromnum(num):
|
| 173 |
+
res = []
|
| 174 |
+
for key in _flagnames:
|
| 175 |
+
value = _flagdict[key]
|
| 176 |
+
if (num & value):
|
| 177 |
+
res.append(key)
|
| 178 |
+
return res
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
class _ndptr(_ndptr_base):
|
| 182 |
+
@classmethod
|
| 183 |
+
def from_param(cls, obj):
|
| 184 |
+
if not isinstance(obj, ndarray):
|
| 185 |
+
raise TypeError("argument must be an ndarray")
|
| 186 |
+
if cls._dtype_ is not None \
|
| 187 |
+
and obj.dtype != cls._dtype_:
|
| 188 |
+
raise TypeError("array must have data type %s" % cls._dtype_)
|
| 189 |
+
if cls._ndim_ is not None \
|
| 190 |
+
and obj.ndim != cls._ndim_:
|
| 191 |
+
raise TypeError("array must have %d dimension(s)" % cls._ndim_)
|
| 192 |
+
if cls._shape_ is not None \
|
| 193 |
+
and obj.shape != cls._shape_:
|
| 194 |
+
raise TypeError("array must have shape %s" % str(cls._shape_))
|
| 195 |
+
if cls._flags_ is not None \
|
| 196 |
+
and ((obj.flags.num & cls._flags_) != cls._flags_):
|
| 197 |
+
raise TypeError("array must have flags %s" %
|
| 198 |
+
_flags_fromnum(cls._flags_))
|
| 199 |
+
return obj.ctypes
|
| 200 |
+
|
| 201 |
+
|
| 202 |
+
class _concrete_ndptr(_ndptr):
|
| 203 |
+
"""
|
| 204 |
+
Like _ndptr, but with `_shape_` and `_dtype_` specified.
|
| 205 |
+
|
| 206 |
+
Notably, this means the pointer has enough information to reconstruct
|
| 207 |
+
the array, which is not generally true.
|
| 208 |
+
"""
|
| 209 |
+
def _check_retval_(self):
|
| 210 |
+
"""
|
| 211 |
+
This method is called when this class is used as the .restype
|
| 212 |
+
attribute for a shared-library function, to automatically wrap the
|
| 213 |
+
pointer into an array.
|
| 214 |
+
"""
|
| 215 |
+
return self.contents
|
| 216 |
+
|
| 217 |
+
@property
|
| 218 |
+
def contents(self):
|
| 219 |
+
"""
|
| 220 |
+
Get an ndarray viewing the data pointed to by this pointer.
|
| 221 |
+
|
| 222 |
+
This mirrors the `contents` attribute of a normal ctypes pointer
|
| 223 |
+
"""
|
| 224 |
+
full_dtype = _dtype((self._dtype_, self._shape_))
|
| 225 |
+
full_ctype = ctypes.c_char * full_dtype.itemsize
|
| 226 |
+
buffer = ctypes.cast(self, ctypes.POINTER(full_ctype)).contents
|
| 227 |
+
return frombuffer(buffer, dtype=full_dtype).squeeze(axis=0)
|
| 228 |
+
|
| 229 |
+
|
| 230 |
+
# Factory for an array-checking class with from_param defined for
|
| 231 |
+
# use with ctypes argtypes mechanism
|
| 232 |
+
_pointer_type_cache = {}
|
| 233 |
+
def ndpointer(dtype=None, ndim=None, shape=None, flags=None):
|
| 234 |
+
"""
|
| 235 |
+
Array-checking restype/argtypes.
|
| 236 |
+
|
| 237 |
+
An ndpointer instance is used to describe an ndarray in restypes
|
| 238 |
+
and argtypes specifications. This approach is more flexible than
|
| 239 |
+
using, for example, ``POINTER(c_double)``, since several restrictions
|
| 240 |
+
can be specified, which are verified upon calling the ctypes function.
|
| 241 |
+
These include data type, number of dimensions, shape and flags. If a
|
| 242 |
+
given array does not satisfy the specified restrictions,
|
| 243 |
+
a ``TypeError`` is raised.
|
| 244 |
+
|
| 245 |
+
Parameters
|
| 246 |
+
----------
|
| 247 |
+
dtype : data-type, optional
|
| 248 |
+
Array data-type.
|
| 249 |
+
ndim : int, optional
|
| 250 |
+
Number of array dimensions.
|
| 251 |
+
shape : tuple of ints, optional
|
| 252 |
+
Array shape.
|
| 253 |
+
flags : str or tuple of str
|
| 254 |
+
Array flags; may be one or more of:
|
| 255 |
+
|
| 256 |
+
- C_CONTIGUOUS / C / CONTIGUOUS
|
| 257 |
+
- F_CONTIGUOUS / F / FORTRAN
|
| 258 |
+
- OWNDATA / O
|
| 259 |
+
- WRITEABLE / W
|
| 260 |
+
- ALIGNED / A
|
| 261 |
+
- WRITEBACKIFCOPY / X
|
| 262 |
+
|
| 263 |
+
Returns
|
| 264 |
+
-------
|
| 265 |
+
klass : ndpointer type object
|
| 266 |
+
A type object, which is an ``_ndtpr`` instance containing
|
| 267 |
+
dtype, ndim, shape and flags information.
|
| 268 |
+
|
| 269 |
+
Raises
|
| 270 |
+
------
|
| 271 |
+
TypeError
|
| 272 |
+
If a given array does not satisfy the specified restrictions.
|
| 273 |
+
|
| 274 |
+
Examples
|
| 275 |
+
--------
|
| 276 |
+
>>> clib.somefunc.argtypes = [np.ctypeslib.ndpointer(dtype=np.float64,
|
| 277 |
+
... ndim=1,
|
| 278 |
+
... flags='C_CONTIGUOUS')]
|
| 279 |
+
... #doctest: +SKIP
|
| 280 |
+
>>> clib.somefunc(np.array([1, 2, 3], dtype=np.float64))
|
| 281 |
+
... #doctest: +SKIP
|
| 282 |
+
|
| 283 |
+
"""
|
| 284 |
+
|
| 285 |
+
# normalize dtype to an Optional[dtype]
|
| 286 |
+
if dtype is not None:
|
| 287 |
+
dtype = _dtype(dtype)
|
| 288 |
+
|
| 289 |
+
# normalize flags to an Optional[int]
|
| 290 |
+
num = None
|
| 291 |
+
if flags is not None:
|
| 292 |
+
if isinstance(flags, str):
|
| 293 |
+
flags = flags.split(',')
|
| 294 |
+
elif isinstance(flags, (int, integer)):
|
| 295 |
+
num = flags
|
| 296 |
+
flags = _flags_fromnum(num)
|
| 297 |
+
elif isinstance(flags, flagsobj):
|
| 298 |
+
num = flags.num
|
| 299 |
+
flags = _flags_fromnum(num)
|
| 300 |
+
if num is None:
|
| 301 |
+
try:
|
| 302 |
+
flags = [x.strip().upper() for x in flags]
|
| 303 |
+
except Exception as e:
|
| 304 |
+
raise TypeError("invalid flags specification") from e
|
| 305 |
+
num = _num_fromflags(flags)
|
| 306 |
+
|
| 307 |
+
# normalize shape to an Optional[tuple]
|
| 308 |
+
if shape is not None:
|
| 309 |
+
try:
|
| 310 |
+
shape = tuple(shape)
|
| 311 |
+
except TypeError:
|
| 312 |
+
# single integer -> 1-tuple
|
| 313 |
+
shape = (shape,)
|
| 314 |
+
|
| 315 |
+
cache_key = (dtype, ndim, shape, num)
|
| 316 |
+
|
| 317 |
+
try:
|
| 318 |
+
return _pointer_type_cache[cache_key]
|
| 319 |
+
except KeyError:
|
| 320 |
+
pass
|
| 321 |
+
|
| 322 |
+
# produce a name for the new type
|
| 323 |
+
if dtype is None:
|
| 324 |
+
name = 'any'
|
| 325 |
+
elif dtype.names is not None:
|
| 326 |
+
name = str(id(dtype))
|
| 327 |
+
else:
|
| 328 |
+
name = dtype.str
|
| 329 |
+
if ndim is not None:
|
| 330 |
+
name += "_%dd" % ndim
|
| 331 |
+
if shape is not None:
|
| 332 |
+
name += "_"+"x".join(str(x) for x in shape)
|
| 333 |
+
if flags is not None:
|
| 334 |
+
name += "_"+"_".join(flags)
|
| 335 |
+
|
| 336 |
+
if dtype is not None and shape is not None:
|
| 337 |
+
base = _concrete_ndptr
|
| 338 |
+
else:
|
| 339 |
+
base = _ndptr
|
| 340 |
+
|
| 341 |
+
klass = type("ndpointer_%s"%name, (base,),
|
| 342 |
+
{"_dtype_": dtype,
|
| 343 |
+
"_shape_" : shape,
|
| 344 |
+
"_ndim_" : ndim,
|
| 345 |
+
"_flags_" : num})
|
| 346 |
+
_pointer_type_cache[cache_key] = klass
|
| 347 |
+
return klass
|
| 348 |
+
|
| 349 |
+
|
| 350 |
+
if ctypes is not None:
|
| 351 |
+
def _ctype_ndarray(element_type, shape):
|
| 352 |
+
""" Create an ndarray of the given element type and shape """
|
| 353 |
+
for dim in shape[::-1]:
|
| 354 |
+
element_type = dim * element_type
|
| 355 |
+
# prevent the type name include np.ctypeslib
|
| 356 |
+
element_type.__module__ = None
|
| 357 |
+
return element_type
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
def _get_scalar_type_map():
|
| 361 |
+
"""
|
| 362 |
+
Return a dictionary mapping native endian scalar dtype to ctypes types
|
| 363 |
+
"""
|
| 364 |
+
ct = ctypes
|
| 365 |
+
simple_types = [
|
| 366 |
+
ct.c_byte, ct.c_short, ct.c_int, ct.c_long, ct.c_longlong,
|
| 367 |
+
ct.c_ubyte, ct.c_ushort, ct.c_uint, ct.c_ulong, ct.c_ulonglong,
|
| 368 |
+
ct.c_float, ct.c_double,
|
| 369 |
+
ct.c_bool,
|
| 370 |
+
]
|
| 371 |
+
return {_dtype(ctype): ctype for ctype in simple_types}
|
| 372 |
+
|
| 373 |
+
|
| 374 |
+
_scalar_type_map = _get_scalar_type_map()
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
def _ctype_from_dtype_scalar(dtype):
|
| 378 |
+
# swapping twice ensure that `=` is promoted to <, >, or |
|
| 379 |
+
dtype_with_endian = dtype.newbyteorder('S').newbyteorder('S')
|
| 380 |
+
dtype_native = dtype.newbyteorder('=')
|
| 381 |
+
try:
|
| 382 |
+
ctype = _scalar_type_map[dtype_native]
|
| 383 |
+
except KeyError as e:
|
| 384 |
+
raise NotImplementedError(
|
| 385 |
+
"Converting {!r} to a ctypes type".format(dtype)
|
| 386 |
+
) from None
|
| 387 |
+
|
| 388 |
+
if dtype_with_endian.byteorder == '>':
|
| 389 |
+
ctype = ctype.__ctype_be__
|
| 390 |
+
elif dtype_with_endian.byteorder == '<':
|
| 391 |
+
ctype = ctype.__ctype_le__
|
| 392 |
+
|
| 393 |
+
return ctype
|
| 394 |
+
|
| 395 |
+
|
| 396 |
+
def _ctype_from_dtype_subarray(dtype):
|
| 397 |
+
element_dtype, shape = dtype.subdtype
|
| 398 |
+
ctype = _ctype_from_dtype(element_dtype)
|
| 399 |
+
return _ctype_ndarray(ctype, shape)
|
| 400 |
+
|
| 401 |
+
|
| 402 |
+
def _ctype_from_dtype_structured(dtype):
|
| 403 |
+
# extract offsets of each field
|
| 404 |
+
field_data = []
|
| 405 |
+
for name in dtype.names:
|
| 406 |
+
field_dtype, offset = dtype.fields[name][:2]
|
| 407 |
+
field_data.append((offset, name, _ctype_from_dtype(field_dtype)))
|
| 408 |
+
|
| 409 |
+
# ctypes doesn't care about field order
|
| 410 |
+
field_data = sorted(field_data, key=lambda f: f[0])
|
| 411 |
+
|
| 412 |
+
if len(field_data) > 1 and all(offset == 0 for offset, name, ctype in field_data):
|
| 413 |
+
# union, if multiple fields all at address 0
|
| 414 |
+
size = 0
|
| 415 |
+
_fields_ = []
|
| 416 |
+
for offset, name, ctype in field_data:
|
| 417 |
+
_fields_.append((name, ctype))
|
| 418 |
+
size = max(size, ctypes.sizeof(ctype))
|
| 419 |
+
|
| 420 |
+
# pad to the right size
|
| 421 |
+
if dtype.itemsize != size:
|
| 422 |
+
_fields_.append(('', ctypes.c_char * dtype.itemsize))
|
| 423 |
+
|
| 424 |
+
# we inserted manual padding, so always `_pack_`
|
| 425 |
+
return type('union', (ctypes.Union,), dict(
|
| 426 |
+
_fields_=_fields_,
|
| 427 |
+
_pack_=1,
|
| 428 |
+
__module__=None,
|
| 429 |
+
))
|
| 430 |
+
else:
|
| 431 |
+
last_offset = 0
|
| 432 |
+
_fields_ = []
|
| 433 |
+
for offset, name, ctype in field_data:
|
| 434 |
+
padding = offset - last_offset
|
| 435 |
+
if padding < 0:
|
| 436 |
+
raise NotImplementedError("Overlapping fields")
|
| 437 |
+
if padding > 0:
|
| 438 |
+
_fields_.append(('', ctypes.c_char * padding))
|
| 439 |
+
|
| 440 |
+
_fields_.append((name, ctype))
|
| 441 |
+
last_offset = offset + ctypes.sizeof(ctype)
|
| 442 |
+
|
| 443 |
+
|
| 444 |
+
padding = dtype.itemsize - last_offset
|
| 445 |
+
if padding > 0:
|
| 446 |
+
_fields_.append(('', ctypes.c_char * padding))
|
| 447 |
+
|
| 448 |
+
# we inserted manual padding, so always `_pack_`
|
| 449 |
+
return type('struct', (ctypes.Structure,), dict(
|
| 450 |
+
_fields_=_fields_,
|
| 451 |
+
_pack_=1,
|
| 452 |
+
__module__=None,
|
| 453 |
+
))
|
| 454 |
+
|
| 455 |
+
|
| 456 |
+
def _ctype_from_dtype(dtype):
|
| 457 |
+
if dtype.fields is not None:
|
| 458 |
+
return _ctype_from_dtype_structured(dtype)
|
| 459 |
+
elif dtype.subdtype is not None:
|
| 460 |
+
return _ctype_from_dtype_subarray(dtype)
|
| 461 |
+
else:
|
| 462 |
+
return _ctype_from_dtype_scalar(dtype)
|
| 463 |
+
|
| 464 |
+
|
| 465 |
+
def as_ctypes_type(dtype):
|
| 466 |
+
r"""
|
| 467 |
+
Convert a dtype into a ctypes type.
|
| 468 |
+
|
| 469 |
+
Parameters
|
| 470 |
+
----------
|
| 471 |
+
dtype : dtype
|
| 472 |
+
The dtype to convert
|
| 473 |
+
|
| 474 |
+
Returns
|
| 475 |
+
-------
|
| 476 |
+
ctype
|
| 477 |
+
A ctype scalar, union, array, or struct
|
| 478 |
+
|
| 479 |
+
Raises
|
| 480 |
+
------
|
| 481 |
+
NotImplementedError
|
| 482 |
+
If the conversion is not possible
|
| 483 |
+
|
| 484 |
+
Notes
|
| 485 |
+
-----
|
| 486 |
+
This function does not losslessly round-trip in either direction.
|
| 487 |
+
|
| 488 |
+
``np.dtype(as_ctypes_type(dt))`` will:
|
| 489 |
+
|
| 490 |
+
- insert padding fields
|
| 491 |
+
- reorder fields to be sorted by offset
|
| 492 |
+
- discard field titles
|
| 493 |
+
|
| 494 |
+
``as_ctypes_type(np.dtype(ctype))`` will:
|
| 495 |
+
|
| 496 |
+
- discard the class names of `ctypes.Structure`\ s and
|
| 497 |
+
`ctypes.Union`\ s
|
| 498 |
+
- convert single-element `ctypes.Union`\ s into single-element
|
| 499 |
+
`ctypes.Structure`\ s
|
| 500 |
+
- insert padding fields
|
| 501 |
+
|
| 502 |
+
"""
|
| 503 |
+
return _ctype_from_dtype(_dtype(dtype))
|
| 504 |
+
|
| 505 |
+
|
| 506 |
+
def as_array(obj, shape=None):
|
| 507 |
+
"""
|
| 508 |
+
Create a numpy array from a ctypes array or POINTER.
|
| 509 |
+
|
| 510 |
+
The numpy array shares the memory with the ctypes object.
|
| 511 |
+
|
| 512 |
+
The shape parameter must be given if converting from a ctypes POINTER.
|
| 513 |
+
The shape parameter is ignored if converting from a ctypes array
|
| 514 |
+
"""
|
| 515 |
+
if isinstance(obj, ctypes._Pointer):
|
| 516 |
+
# convert pointers to an array of the desired shape
|
| 517 |
+
if shape is None:
|
| 518 |
+
raise TypeError(
|
| 519 |
+
'as_array() requires a shape argument when called on a '
|
| 520 |
+
'pointer')
|
| 521 |
+
p_arr_type = ctypes.POINTER(_ctype_ndarray(obj._type_, shape))
|
| 522 |
+
obj = ctypes.cast(obj, p_arr_type).contents
|
| 523 |
+
|
| 524 |
+
return asarray(obj)
|
| 525 |
+
|
| 526 |
+
|
| 527 |
+
def as_ctypes(obj):
|
| 528 |
+
"""Create and return a ctypes object from a numpy array. Actually
|
| 529 |
+
anything that exposes the __array_interface__ is accepted."""
|
| 530 |
+
ai = obj.__array_interface__
|
| 531 |
+
if ai["strides"]:
|
| 532 |
+
raise TypeError("strided arrays not supported")
|
| 533 |
+
if ai["version"] != 3:
|
| 534 |
+
raise TypeError("only __array_interface__ version 3 supported")
|
| 535 |
+
addr, readonly = ai["data"]
|
| 536 |
+
if readonly:
|
| 537 |
+
raise TypeError("readonly arrays unsupported")
|
| 538 |
+
|
| 539 |
+
# can't use `_dtype((ai["typestr"], ai["shape"]))` here, as it overflows
|
| 540 |
+
# dtype.itemsize (gh-14214)
|
| 541 |
+
ctype_scalar = as_ctypes_type(ai["typestr"])
|
| 542 |
+
result_type = _ctype_ndarray(ctype_scalar, ai["shape"])
|
| 543 |
+
result = result_type.from_address(addr)
|
| 544 |
+
result.__keep = obj
|
| 545 |
+
return result
|
lib/python3.12/site-packages/numpy/ctypeslib.pyi
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# NOTE: Numpy's mypy plugin is used for importing the correct
|
| 2 |
+
# platform-specific `ctypes._SimpleCData[int]` sub-type
|
| 3 |
+
from ctypes import c_int64 as _c_intp
|
| 4 |
+
|
| 5 |
+
import os
|
| 6 |
+
import sys
|
| 7 |
+
import ctypes
|
| 8 |
+
from collections.abc import Iterable, Sequence
|
| 9 |
+
from typing import (
|
| 10 |
+
Literal as L,
|
| 11 |
+
Any,
|
| 12 |
+
Union,
|
| 13 |
+
TypeVar,
|
| 14 |
+
Generic,
|
| 15 |
+
overload,
|
| 16 |
+
ClassVar,
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
from numpy import (
|
| 20 |
+
ndarray,
|
| 21 |
+
dtype,
|
| 22 |
+
generic,
|
| 23 |
+
bool_,
|
| 24 |
+
byte,
|
| 25 |
+
short,
|
| 26 |
+
intc,
|
| 27 |
+
int_,
|
| 28 |
+
longlong,
|
| 29 |
+
ubyte,
|
| 30 |
+
ushort,
|
| 31 |
+
uintc,
|
| 32 |
+
uint,
|
| 33 |
+
ulonglong,
|
| 34 |
+
single,
|
| 35 |
+
double,
|
| 36 |
+
longdouble,
|
| 37 |
+
void,
|
| 38 |
+
)
|
| 39 |
+
from numpy.core._internal import _ctypes
|
| 40 |
+
from numpy.core.multiarray import flagsobj
|
| 41 |
+
from numpy._typing import (
|
| 42 |
+
# Arrays
|
| 43 |
+
NDArray,
|
| 44 |
+
_ArrayLike,
|
| 45 |
+
|
| 46 |
+
# Shapes
|
| 47 |
+
_ShapeLike,
|
| 48 |
+
|
| 49 |
+
# DTypes
|
| 50 |
+
DTypeLike,
|
| 51 |
+
_DTypeLike,
|
| 52 |
+
_VoidDTypeLike,
|
| 53 |
+
_BoolCodes,
|
| 54 |
+
_UByteCodes,
|
| 55 |
+
_UShortCodes,
|
| 56 |
+
_UIntCCodes,
|
| 57 |
+
_UIntCodes,
|
| 58 |
+
_ULongLongCodes,
|
| 59 |
+
_ByteCodes,
|
| 60 |
+
_ShortCodes,
|
| 61 |
+
_IntCCodes,
|
| 62 |
+
_IntCodes,
|
| 63 |
+
_LongLongCodes,
|
| 64 |
+
_SingleCodes,
|
| 65 |
+
_DoubleCodes,
|
| 66 |
+
_LongDoubleCodes,
|
| 67 |
+
)
|
| 68 |
+
|
| 69 |
+
# TODO: Add a proper `_Shape` bound once we've got variadic typevars
|
| 70 |
+
_DType = TypeVar("_DType", bound=dtype[Any])
|
| 71 |
+
_DTypeOptional = TypeVar("_DTypeOptional", bound=None | dtype[Any])
|
| 72 |
+
_SCT = TypeVar("_SCT", bound=generic)
|
| 73 |
+
|
| 74 |
+
_FlagsKind = L[
|
| 75 |
+
'C_CONTIGUOUS', 'CONTIGUOUS', 'C',
|
| 76 |
+
'F_CONTIGUOUS', 'FORTRAN', 'F',
|
| 77 |
+
'ALIGNED', 'A',
|
| 78 |
+
'WRITEABLE', 'W',
|
| 79 |
+
'OWNDATA', 'O',
|
| 80 |
+
'WRITEBACKIFCOPY', 'X',
|
| 81 |
+
]
|
| 82 |
+
|
| 83 |
+
# TODO: Add a shape typevar once we have variadic typevars (PEP 646)
|
| 84 |
+
class _ndptr(ctypes.c_void_p, Generic[_DTypeOptional]):
|
| 85 |
+
# In practice these 4 classvars are defined in the dynamic class
|
| 86 |
+
# returned by `ndpointer`
|
| 87 |
+
_dtype_: ClassVar[_DTypeOptional]
|
| 88 |
+
_shape_: ClassVar[None]
|
| 89 |
+
_ndim_: ClassVar[None | int]
|
| 90 |
+
_flags_: ClassVar[None | list[_FlagsKind]]
|
| 91 |
+
|
| 92 |
+
@overload
|
| 93 |
+
@classmethod
|
| 94 |
+
def from_param(cls: type[_ndptr[None]], obj: ndarray[Any, Any]) -> _ctypes[Any]: ...
|
| 95 |
+
@overload
|
| 96 |
+
@classmethod
|
| 97 |
+
def from_param(cls: type[_ndptr[_DType]], obj: ndarray[Any, _DType]) -> _ctypes[Any]: ...
|
| 98 |
+
|
| 99 |
+
class _concrete_ndptr(_ndptr[_DType]):
|
| 100 |
+
_dtype_: ClassVar[_DType]
|
| 101 |
+
_shape_: ClassVar[tuple[int, ...]]
|
| 102 |
+
@property
|
| 103 |
+
def contents(self) -> ndarray[Any, _DType]: ...
|
| 104 |
+
|
| 105 |
+
def load_library(
|
| 106 |
+
libname: str | bytes | os.PathLike[str] | os.PathLike[bytes],
|
| 107 |
+
loader_path: str | bytes | os.PathLike[str] | os.PathLike[bytes],
|
| 108 |
+
) -> ctypes.CDLL: ...
|
| 109 |
+
|
| 110 |
+
__all__: list[str]
|
| 111 |
+
|
| 112 |
+
c_intp = _c_intp
|
| 113 |
+
|
| 114 |
+
@overload
|
| 115 |
+
def ndpointer(
|
| 116 |
+
dtype: None = ...,
|
| 117 |
+
ndim: int = ...,
|
| 118 |
+
shape: None | _ShapeLike = ...,
|
| 119 |
+
flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,
|
| 120 |
+
) -> type[_ndptr[None]]: ...
|
| 121 |
+
@overload
|
| 122 |
+
def ndpointer(
|
| 123 |
+
dtype: _DTypeLike[_SCT],
|
| 124 |
+
ndim: int = ...,
|
| 125 |
+
*,
|
| 126 |
+
shape: _ShapeLike,
|
| 127 |
+
flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,
|
| 128 |
+
) -> type[_concrete_ndptr[dtype[_SCT]]]: ...
|
| 129 |
+
@overload
|
| 130 |
+
def ndpointer(
|
| 131 |
+
dtype: DTypeLike,
|
| 132 |
+
ndim: int = ...,
|
| 133 |
+
*,
|
| 134 |
+
shape: _ShapeLike,
|
| 135 |
+
flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,
|
| 136 |
+
) -> type[_concrete_ndptr[dtype[Any]]]: ...
|
| 137 |
+
@overload
|
| 138 |
+
def ndpointer(
|
| 139 |
+
dtype: _DTypeLike[_SCT],
|
| 140 |
+
ndim: int = ...,
|
| 141 |
+
shape: None = ...,
|
| 142 |
+
flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,
|
| 143 |
+
) -> type[_ndptr[dtype[_SCT]]]: ...
|
| 144 |
+
@overload
|
| 145 |
+
def ndpointer(
|
| 146 |
+
dtype: DTypeLike,
|
| 147 |
+
ndim: int = ...,
|
| 148 |
+
shape: None = ...,
|
| 149 |
+
flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,
|
| 150 |
+
) -> type[_ndptr[dtype[Any]]]: ...
|
| 151 |
+
|
| 152 |
+
@overload
|
| 153 |
+
def as_ctypes_type(dtype: _BoolCodes | _DTypeLike[bool_] | type[ctypes.c_bool]) -> type[ctypes.c_bool]: ...
|
| 154 |
+
@overload
|
| 155 |
+
def as_ctypes_type(dtype: _ByteCodes | _DTypeLike[byte] | type[ctypes.c_byte]) -> type[ctypes.c_byte]: ...
|
| 156 |
+
@overload
|
| 157 |
+
def as_ctypes_type(dtype: _ShortCodes | _DTypeLike[short] | type[ctypes.c_short]) -> type[ctypes.c_short]: ...
|
| 158 |
+
@overload
|
| 159 |
+
def as_ctypes_type(dtype: _IntCCodes | _DTypeLike[intc] | type[ctypes.c_int]) -> type[ctypes.c_int]: ...
|
| 160 |
+
@overload
|
| 161 |
+
def as_ctypes_type(dtype: _IntCodes | _DTypeLike[int_] | type[int | ctypes.c_long]) -> type[ctypes.c_long]: ...
|
| 162 |
+
@overload
|
| 163 |
+
def as_ctypes_type(dtype: _LongLongCodes | _DTypeLike[longlong] | type[ctypes.c_longlong]) -> type[ctypes.c_longlong]: ...
|
| 164 |
+
@overload
|
| 165 |
+
def as_ctypes_type(dtype: _UByteCodes | _DTypeLike[ubyte] | type[ctypes.c_ubyte]) -> type[ctypes.c_ubyte]: ...
|
| 166 |
+
@overload
|
| 167 |
+
def as_ctypes_type(dtype: _UShortCodes | _DTypeLike[ushort] | type[ctypes.c_ushort]) -> type[ctypes.c_ushort]: ...
|
| 168 |
+
@overload
|
| 169 |
+
def as_ctypes_type(dtype: _UIntCCodes | _DTypeLike[uintc] | type[ctypes.c_uint]) -> type[ctypes.c_uint]: ...
|
| 170 |
+
@overload
|
| 171 |
+
def as_ctypes_type(dtype: _UIntCodes | _DTypeLike[uint] | type[ctypes.c_ulong]) -> type[ctypes.c_ulong]: ...
|
| 172 |
+
@overload
|
| 173 |
+
def as_ctypes_type(dtype: _ULongLongCodes | _DTypeLike[ulonglong] | type[ctypes.c_ulonglong]) -> type[ctypes.c_ulonglong]: ...
|
| 174 |
+
@overload
|
| 175 |
+
def as_ctypes_type(dtype: _SingleCodes | _DTypeLike[single] | type[ctypes.c_float]) -> type[ctypes.c_float]: ...
|
| 176 |
+
@overload
|
| 177 |
+
def as_ctypes_type(dtype: _DoubleCodes | _DTypeLike[double] | type[float | ctypes.c_double]) -> type[ctypes.c_double]: ...
|
| 178 |
+
@overload
|
| 179 |
+
def as_ctypes_type(dtype: _LongDoubleCodes | _DTypeLike[longdouble] | type[ctypes.c_longdouble]) -> type[ctypes.c_longdouble]: ...
|
| 180 |
+
@overload
|
| 181 |
+
def as_ctypes_type(dtype: _VoidDTypeLike) -> type[Any]: ... # `ctypes.Union` or `ctypes.Structure`
|
| 182 |
+
@overload
|
| 183 |
+
def as_ctypes_type(dtype: str) -> type[Any]: ...
|
| 184 |
+
|
| 185 |
+
@overload
|
| 186 |
+
def as_array(obj: ctypes._PointerLike, shape: Sequence[int]) -> NDArray[Any]: ...
|
| 187 |
+
@overload
|
| 188 |
+
def as_array(obj: _ArrayLike[_SCT], shape: None | _ShapeLike = ...) -> NDArray[_SCT]: ...
|
| 189 |
+
@overload
|
| 190 |
+
def as_array(obj: object, shape: None | _ShapeLike = ...) -> NDArray[Any]: ...
|
| 191 |
+
|
| 192 |
+
@overload
|
| 193 |
+
def as_ctypes(obj: bool_) -> ctypes.c_bool: ...
|
| 194 |
+
@overload
|
| 195 |
+
def as_ctypes(obj: byte) -> ctypes.c_byte: ...
|
| 196 |
+
@overload
|
| 197 |
+
def as_ctypes(obj: short) -> ctypes.c_short: ...
|
| 198 |
+
@overload
|
| 199 |
+
def as_ctypes(obj: intc) -> ctypes.c_int: ...
|
| 200 |
+
@overload
|
| 201 |
+
def as_ctypes(obj: int_) -> ctypes.c_long: ...
|
| 202 |
+
@overload
|
| 203 |
+
def as_ctypes(obj: longlong) -> ctypes.c_longlong: ...
|
| 204 |
+
@overload
|
| 205 |
+
def as_ctypes(obj: ubyte) -> ctypes.c_ubyte: ...
|
| 206 |
+
@overload
|
| 207 |
+
def as_ctypes(obj: ushort) -> ctypes.c_ushort: ...
|
| 208 |
+
@overload
|
| 209 |
+
def as_ctypes(obj: uintc) -> ctypes.c_uint: ...
|
| 210 |
+
@overload
|
| 211 |
+
def as_ctypes(obj: uint) -> ctypes.c_ulong: ...
|
| 212 |
+
@overload
|
| 213 |
+
def as_ctypes(obj: ulonglong) -> ctypes.c_ulonglong: ...
|
| 214 |
+
@overload
|
| 215 |
+
def as_ctypes(obj: single) -> ctypes.c_float: ...
|
| 216 |
+
@overload
|
| 217 |
+
def as_ctypes(obj: double) -> ctypes.c_double: ...
|
| 218 |
+
@overload
|
| 219 |
+
def as_ctypes(obj: longdouble) -> ctypes.c_longdouble: ...
|
| 220 |
+
@overload
|
| 221 |
+
def as_ctypes(obj: void) -> Any: ... # `ctypes.Union` or `ctypes.Structure`
|
| 222 |
+
@overload
|
| 223 |
+
def as_ctypes(obj: NDArray[bool_]) -> ctypes.Array[ctypes.c_bool]: ...
|
| 224 |
+
@overload
|
| 225 |
+
def as_ctypes(obj: NDArray[byte]) -> ctypes.Array[ctypes.c_byte]: ...
|
| 226 |
+
@overload
|
| 227 |
+
def as_ctypes(obj: NDArray[short]) -> ctypes.Array[ctypes.c_short]: ...
|
| 228 |
+
@overload
|
| 229 |
+
def as_ctypes(obj: NDArray[intc]) -> ctypes.Array[ctypes.c_int]: ...
|
| 230 |
+
@overload
|
| 231 |
+
def as_ctypes(obj: NDArray[int_]) -> ctypes.Array[ctypes.c_long]: ...
|
| 232 |
+
@overload
|
| 233 |
+
def as_ctypes(obj: NDArray[longlong]) -> ctypes.Array[ctypes.c_longlong]: ...
|
| 234 |
+
@overload
|
| 235 |
+
def as_ctypes(obj: NDArray[ubyte]) -> ctypes.Array[ctypes.c_ubyte]: ...
|
| 236 |
+
@overload
|
| 237 |
+
def as_ctypes(obj: NDArray[ushort]) -> ctypes.Array[ctypes.c_ushort]: ...
|
| 238 |
+
@overload
|
| 239 |
+
def as_ctypes(obj: NDArray[uintc]) -> ctypes.Array[ctypes.c_uint]: ...
|
| 240 |
+
@overload
|
| 241 |
+
def as_ctypes(obj: NDArray[uint]) -> ctypes.Array[ctypes.c_ulong]: ...
|
| 242 |
+
@overload
|
| 243 |
+
def as_ctypes(obj: NDArray[ulonglong]) -> ctypes.Array[ctypes.c_ulonglong]: ...
|
| 244 |
+
@overload
|
| 245 |
+
def as_ctypes(obj: NDArray[single]) -> ctypes.Array[ctypes.c_float]: ...
|
| 246 |
+
@overload
|
| 247 |
+
def as_ctypes(obj: NDArray[double]) -> ctypes.Array[ctypes.c_double]: ...
|
| 248 |
+
@overload
|
| 249 |
+
def as_ctypes(obj: NDArray[longdouble]) -> ctypes.Array[ctypes.c_longdouble]: ...
|
| 250 |
+
@overload
|
| 251 |
+
def as_ctypes(obj: NDArray[void]) -> ctypes.Array[Any]: ... # `ctypes.Union` or `ctypes.Structure`
|
lib/python3.12/site-packages/numpy/dtypes.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
DType classes and utility (:mod:`numpy.dtypes`)
|
| 3 |
+
===============================================
|
| 4 |
+
|
| 5 |
+
This module is home to specific dtypes related functionality and their classes.
|
| 6 |
+
For more general information about dtypes, also see `numpy.dtype` and
|
| 7 |
+
:ref:`arrays.dtypes`.
|
| 8 |
+
|
| 9 |
+
Similar to the builtin ``types`` module, this submodule defines types (classes)
|
| 10 |
+
that are not widely used directly.
|
| 11 |
+
|
| 12 |
+
.. versionadded:: NumPy 1.25
|
| 13 |
+
|
| 14 |
+
The dtypes module is new in NumPy 1.25. Previously DType classes were
|
| 15 |
+
only accessible indirectly.
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
DType classes
|
| 19 |
+
-------------
|
| 20 |
+
|
| 21 |
+
The following are the classes of the corresponding NumPy dtype instances and
|
| 22 |
+
NumPy scalar types. The classes can be used in ``isinstance`` checks and can
|
| 23 |
+
also be instantiated or used directly. Direct use of these classes is not
|
| 24 |
+
typical, since their scalar counterparts (e.g. ``np.float64``) or strings
|
| 25 |
+
like ``"float64"`` can be used.
|
| 26 |
+
|
| 27 |
+
.. list-table::
|
| 28 |
+
:header-rows: 1
|
| 29 |
+
|
| 30 |
+
* - Group
|
| 31 |
+
- DType class
|
| 32 |
+
|
| 33 |
+
* - Boolean
|
| 34 |
+
- ``BoolDType``
|
| 35 |
+
|
| 36 |
+
* - Bit-sized integers
|
| 37 |
+
- ``Int8DType``, ``UInt8DType``, ``Int16DType``, ``UInt16DType``,
|
| 38 |
+
``Int32DType``, ``UInt32DType``, ``Int64DType``, ``UInt64DType``
|
| 39 |
+
|
| 40 |
+
* - C-named integers (may be aliases)
|
| 41 |
+
- ``ByteDType``, ``UByteDType``, ``ShortDType``, ``UShortDType``,
|
| 42 |
+
``IntDType``, ``UIntDType``, ``LongDType``, ``ULongDType``,
|
| 43 |
+
``LongLongDType``, ``ULongLongDType``
|
| 44 |
+
|
| 45 |
+
* - Floating point
|
| 46 |
+
- ``Float16DType``, ``Float32DType``, ``Float64DType``,
|
| 47 |
+
``LongDoubleDType``
|
| 48 |
+
|
| 49 |
+
* - Complex
|
| 50 |
+
- ``Complex64DType``, ``Complex128DType``, ``CLongDoubleDType``
|
| 51 |
+
|
| 52 |
+
* - Strings
|
| 53 |
+
- ``BytesDType``, ``BytesDType``
|
| 54 |
+
|
| 55 |
+
* - Times
|
| 56 |
+
- ``DateTime64DType``, ``TimeDelta64DType``
|
| 57 |
+
|
| 58 |
+
* - Others
|
| 59 |
+
- ``ObjectDType``, ``VoidDType``
|
| 60 |
+
|
| 61 |
+
"""
|
| 62 |
+
|
| 63 |
+
__all__ = []
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def _add_dtype_helper(DType, alias):
|
| 67 |
+
# Function to add DTypes a bit more conveniently without channeling them
|
| 68 |
+
# through `numpy.core._multiarray_umath` namespace or similar.
|
| 69 |
+
from numpy import dtypes
|
| 70 |
+
|
| 71 |
+
setattr(dtypes, DType.__name__, DType)
|
| 72 |
+
__all__.append(DType.__name__)
|
| 73 |
+
|
| 74 |
+
if alias:
|
| 75 |
+
alias = alias.removeprefix("numpy.dtypes.")
|
| 76 |
+
setattr(dtypes, alias, DType)
|
| 77 |
+
__all__.append(alias)
|
lib/python3.12/site-packages/numpy/dtypes.pyi
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
__all__: list[str]
|
| 5 |
+
|
| 6 |
+
# Boolean:
|
| 7 |
+
BoolDType = np.dtype[np.bool_]
|
| 8 |
+
# Sized integers:
|
| 9 |
+
Int8DType = np.dtype[np.int8]
|
| 10 |
+
UInt8DType = np.dtype[np.uint8]
|
| 11 |
+
Int16DType = np.dtype[np.int16]
|
| 12 |
+
UInt16DType = np.dtype[np.uint16]
|
| 13 |
+
Int32DType = np.dtype[np.int32]
|
| 14 |
+
UInt32DType = np.dtype[np.uint32]
|
| 15 |
+
Int64DType = np.dtype[np.int64]
|
| 16 |
+
UInt64DType = np.dtype[np.uint64]
|
| 17 |
+
# Standard C-named version/alias:
|
| 18 |
+
ByteDType = np.dtype[np.byte]
|
| 19 |
+
UByteDType = np.dtype[np.ubyte]
|
| 20 |
+
ShortDType = np.dtype[np.short]
|
| 21 |
+
UShortDType = np.dtype[np.ushort]
|
| 22 |
+
IntDType = np.dtype[np.intc]
|
| 23 |
+
UIntDType = np.dtype[np.uintc]
|
| 24 |
+
LongDType = np.dtype[np.int_] # Unfortunately, the correct scalar
|
| 25 |
+
ULongDType = np.dtype[np.uint] # Unfortunately, the correct scalar
|
| 26 |
+
LongLongDType = np.dtype[np.longlong]
|
| 27 |
+
ULongLongDType = np.dtype[np.ulonglong]
|
| 28 |
+
# Floats
|
| 29 |
+
Float16DType = np.dtype[np.float16]
|
| 30 |
+
Float32DType = np.dtype[np.float32]
|
| 31 |
+
Float64DType = np.dtype[np.float64]
|
| 32 |
+
LongDoubleDType = np.dtype[np.longdouble]
|
| 33 |
+
# Complex:
|
| 34 |
+
Complex64DType = np.dtype[np.complex64]
|
| 35 |
+
Complex128DType = np.dtype[np.complex128]
|
| 36 |
+
CLongDoubleDType = np.dtype[np.clongdouble]
|
| 37 |
+
# Others:
|
| 38 |
+
ObjectDType = np.dtype[np.object_]
|
| 39 |
+
BytesDType = np.dtype[np.bytes_]
|
| 40 |
+
StrDType = np.dtype[np.str_]
|
| 41 |
+
VoidDType = np.dtype[np.void]
|
| 42 |
+
DateTime64DType = np.dtype[np.datetime64]
|
| 43 |
+
TimeDelta64DType = np.dtype[np.timedelta64]
|
lib/python3.12/site-packages/numpy/exceptions.py
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Exceptions and Warnings (:mod:`numpy.exceptions`)
|
| 3 |
+
=================================================
|
| 4 |
+
|
| 5 |
+
General exceptions used by NumPy. Note that some exceptions may be module
|
| 6 |
+
specific, such as linear algebra errors.
|
| 7 |
+
|
| 8 |
+
.. versionadded:: NumPy 1.25
|
| 9 |
+
|
| 10 |
+
The exceptions module is new in NumPy 1.25. Older exceptions remain
|
| 11 |
+
available through the main NumPy namespace for compatibility.
|
| 12 |
+
|
| 13 |
+
.. currentmodule:: numpy.exceptions
|
| 14 |
+
|
| 15 |
+
Warnings
|
| 16 |
+
--------
|
| 17 |
+
.. autosummary::
|
| 18 |
+
:toctree: generated/
|
| 19 |
+
|
| 20 |
+
ComplexWarning Given when converting complex to real.
|
| 21 |
+
VisibleDeprecationWarning Same as a DeprecationWarning, but more visible.
|
| 22 |
+
|
| 23 |
+
Exceptions
|
| 24 |
+
----------
|
| 25 |
+
.. autosummary::
|
| 26 |
+
:toctree: generated/
|
| 27 |
+
|
| 28 |
+
AxisError Given when an axis was invalid.
|
| 29 |
+
DTypePromotionError Given when no common dtype could be found.
|
| 30 |
+
TooHardError Error specific to `numpy.shares_memory`.
|
| 31 |
+
|
| 32 |
+
"""
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
__all__ = [
|
| 36 |
+
"ComplexWarning", "VisibleDeprecationWarning", "ModuleDeprecationWarning",
|
| 37 |
+
"TooHardError", "AxisError", "DTypePromotionError"]
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
# Disallow reloading this module so as to preserve the identities of the
|
| 41 |
+
# classes defined here.
|
| 42 |
+
if '_is_loaded' in globals():
|
| 43 |
+
raise RuntimeError('Reloading numpy._globals is not allowed')
|
| 44 |
+
_is_loaded = True
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class ComplexWarning(RuntimeWarning):
|
| 48 |
+
"""
|
| 49 |
+
The warning raised when casting a complex dtype to a real dtype.
|
| 50 |
+
|
| 51 |
+
As implemented, casting a complex number to a real discards its imaginary
|
| 52 |
+
part, but this behavior may not be what the user actually wants.
|
| 53 |
+
|
| 54 |
+
"""
|
| 55 |
+
pass
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
class ModuleDeprecationWarning(DeprecationWarning):
|
| 59 |
+
"""Module deprecation warning.
|
| 60 |
+
|
| 61 |
+
.. warning::
|
| 62 |
+
|
| 63 |
+
This warning should not be used, since nose testing is not relevant
|
| 64 |
+
anymore.
|
| 65 |
+
|
| 66 |
+
The nose tester turns ordinary Deprecation warnings into test failures.
|
| 67 |
+
That makes it hard to deprecate whole modules, because they get
|
| 68 |
+
imported by default. So this is a special Deprecation warning that the
|
| 69 |
+
nose tester will let pass without making tests fail.
|
| 70 |
+
|
| 71 |
+
"""
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
class VisibleDeprecationWarning(UserWarning):
|
| 75 |
+
"""Visible deprecation warning.
|
| 76 |
+
|
| 77 |
+
By default, python will not show deprecation warnings, so this class
|
| 78 |
+
can be used when a very visible warning is helpful, for example because
|
| 79 |
+
the usage is most likely a user bug.
|
| 80 |
+
|
| 81 |
+
"""
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
# Exception used in shares_memory()
|
| 85 |
+
class TooHardError(RuntimeError):
|
| 86 |
+
"""max_work was exceeded.
|
| 87 |
+
|
| 88 |
+
This is raised whenever the maximum number of candidate solutions
|
| 89 |
+
to consider specified by the ``max_work`` parameter is exceeded.
|
| 90 |
+
Assigning a finite number to max_work may have caused the operation
|
| 91 |
+
to fail.
|
| 92 |
+
|
| 93 |
+
"""
|
| 94 |
+
|
| 95 |
+
pass
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
class AxisError(ValueError, IndexError):
|
| 99 |
+
"""Axis supplied was invalid.
|
| 100 |
+
|
| 101 |
+
This is raised whenever an ``axis`` parameter is specified that is larger
|
| 102 |
+
than the number of array dimensions.
|
| 103 |
+
For compatibility with code written against older numpy versions, which
|
| 104 |
+
raised a mixture of `ValueError` and `IndexError` for this situation, this
|
| 105 |
+
exception subclasses both to ensure that ``except ValueError`` and
|
| 106 |
+
``except IndexError`` statements continue to catch `AxisError`.
|
| 107 |
+
|
| 108 |
+
.. versionadded:: 1.13
|
| 109 |
+
|
| 110 |
+
Parameters
|
| 111 |
+
----------
|
| 112 |
+
axis : int or str
|
| 113 |
+
The out of bounds axis or a custom exception message.
|
| 114 |
+
If an axis is provided, then `ndim` should be specified as well.
|
| 115 |
+
ndim : int, optional
|
| 116 |
+
The number of array dimensions.
|
| 117 |
+
msg_prefix : str, optional
|
| 118 |
+
A prefix for the exception message.
|
| 119 |
+
|
| 120 |
+
Attributes
|
| 121 |
+
----------
|
| 122 |
+
axis : int, optional
|
| 123 |
+
The out of bounds axis or ``None`` if a custom exception
|
| 124 |
+
message was provided. This should be the axis as passed by
|
| 125 |
+
the user, before any normalization to resolve negative indices.
|
| 126 |
+
|
| 127 |
+
.. versionadded:: 1.22
|
| 128 |
+
ndim : int, optional
|
| 129 |
+
The number of array dimensions or ``None`` if a custom exception
|
| 130 |
+
message was provided.
|
| 131 |
+
|
| 132 |
+
.. versionadded:: 1.22
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
Examples
|
| 136 |
+
--------
|
| 137 |
+
>>> array_1d = np.arange(10)
|
| 138 |
+
>>> np.cumsum(array_1d, axis=1)
|
| 139 |
+
Traceback (most recent call last):
|
| 140 |
+
...
|
| 141 |
+
numpy.exceptions.AxisError: axis 1 is out of bounds for array of dimension 1
|
| 142 |
+
|
| 143 |
+
Negative axes are preserved:
|
| 144 |
+
|
| 145 |
+
>>> np.cumsum(array_1d, axis=-2)
|
| 146 |
+
Traceback (most recent call last):
|
| 147 |
+
...
|
| 148 |
+
numpy.exceptions.AxisError: axis -2 is out of bounds for array of dimension 1
|
| 149 |
+
|
| 150 |
+
The class constructor generally takes the axis and arrays'
|
| 151 |
+
dimensionality as arguments:
|
| 152 |
+
|
| 153 |
+
>>> print(np.AxisError(2, 1, msg_prefix='error'))
|
| 154 |
+
error: axis 2 is out of bounds for array of dimension 1
|
| 155 |
+
|
| 156 |
+
Alternatively, a custom exception message can be passed:
|
| 157 |
+
|
| 158 |
+
>>> print(np.AxisError('Custom error message'))
|
| 159 |
+
Custom error message
|
| 160 |
+
|
| 161 |
+
"""
|
| 162 |
+
|
| 163 |
+
__slots__ = ("axis", "ndim", "_msg")
|
| 164 |
+
|
| 165 |
+
def __init__(self, axis, ndim=None, msg_prefix=None):
|
| 166 |
+
if ndim is msg_prefix is None:
|
| 167 |
+
# single-argument form: directly set the error message
|
| 168 |
+
self._msg = axis
|
| 169 |
+
self.axis = None
|
| 170 |
+
self.ndim = None
|
| 171 |
+
else:
|
| 172 |
+
self._msg = msg_prefix
|
| 173 |
+
self.axis = axis
|
| 174 |
+
self.ndim = ndim
|
| 175 |
+
|
| 176 |
+
def __str__(self):
|
| 177 |
+
axis = self.axis
|
| 178 |
+
ndim = self.ndim
|
| 179 |
+
|
| 180 |
+
if axis is ndim is None:
|
| 181 |
+
return self._msg
|
| 182 |
+
else:
|
| 183 |
+
msg = f"axis {axis} is out of bounds for array of dimension {ndim}"
|
| 184 |
+
if self._msg is not None:
|
| 185 |
+
msg = f"{self._msg}: {msg}"
|
| 186 |
+
return msg
|
| 187 |
+
|
| 188 |
+
|
| 189 |
+
class DTypePromotionError(TypeError):
|
| 190 |
+
"""Multiple DTypes could not be converted to a common one.
|
| 191 |
+
|
| 192 |
+
This exception derives from ``TypeError`` and is raised whenever dtypes
|
| 193 |
+
cannot be converted to a single common one. This can be because they
|
| 194 |
+
are of a different category/class or incompatible instances of the same
|
| 195 |
+
one (see Examples).
|
| 196 |
+
|
| 197 |
+
Notes
|
| 198 |
+
-----
|
| 199 |
+
Many functions will use promotion to find the correct result and
|
| 200 |
+
implementation. For these functions the error will typically be chained
|
| 201 |
+
with a more specific error indicating that no implementation was found
|
| 202 |
+
for the input dtypes.
|
| 203 |
+
|
| 204 |
+
Typically promotion should be considered "invalid" between the dtypes of
|
| 205 |
+
two arrays when `arr1 == arr2` can safely return all ``False`` because the
|
| 206 |
+
dtypes are fundamentally different.
|
| 207 |
+
|
| 208 |
+
Examples
|
| 209 |
+
--------
|
| 210 |
+
Datetimes and complex numbers are incompatible classes and cannot be
|
| 211 |
+
promoted:
|
| 212 |
+
|
| 213 |
+
>>> np.result_type(np.dtype("M8[s]"), np.complex128)
|
| 214 |
+
DTypePromotionError: The DType <class 'numpy.dtype[datetime64]'> could not
|
| 215 |
+
be promoted by <class 'numpy.dtype[complex128]'>. This means that no common
|
| 216 |
+
DType exists for the given inputs. For example they cannot be stored in a
|
| 217 |
+
single array unless the dtype is `object`. The full list of DTypes is:
|
| 218 |
+
(<class 'numpy.dtype[datetime64]'>, <class 'numpy.dtype[complex128]'>)
|
| 219 |
+
|
| 220 |
+
For example for structured dtypes, the structure can mismatch and the
|
| 221 |
+
same ``DTypePromotionError`` is given when two structured dtypes with
|
| 222 |
+
a mismatch in their number of fields is given:
|
| 223 |
+
|
| 224 |
+
>>> dtype1 = np.dtype([("field1", np.float64), ("field2", np.int64)])
|
| 225 |
+
>>> dtype2 = np.dtype([("field1", np.float64)])
|
| 226 |
+
>>> np.promote_types(dtype1, dtype2)
|
| 227 |
+
DTypePromotionError: field names `('field1', 'field2')` and `('field1',)`
|
| 228 |
+
mismatch.
|
| 229 |
+
|
| 230 |
+
"""
|
| 231 |
+
pass
|
lib/python3.12/site-packages/numpy/exceptions.pyi
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import overload
|
| 2 |
+
|
| 3 |
+
__all__: list[str]
|
| 4 |
+
|
| 5 |
+
class ComplexWarning(RuntimeWarning): ...
|
| 6 |
+
class ModuleDeprecationWarning(DeprecationWarning): ...
|
| 7 |
+
class VisibleDeprecationWarning(UserWarning): ...
|
| 8 |
+
class TooHardError(RuntimeError): ...
|
| 9 |
+
class DTypePromotionError(TypeError): ...
|
| 10 |
+
|
| 11 |
+
class AxisError(ValueError, IndexError):
|
| 12 |
+
axis: None | int
|
| 13 |
+
ndim: None | int
|
| 14 |
+
@overload
|
| 15 |
+
def __init__(self, axis: str, ndim: None = ..., msg_prefix: None = ...) -> None: ...
|
| 16 |
+
@overload
|
| 17 |
+
def __init__(self, axis: int, ndim: int, msg_prefix: None | str = ...) -> None: ...
|
| 18 |
+
def __str__(self) -> str: ...
|
lib/python3.12/site-packages/numpy/matlib.py
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import warnings
|
| 2 |
+
|
| 3 |
+
# 2018-05-29, PendingDeprecationWarning added to matrix.__new__
|
| 4 |
+
# 2020-01-23, numpy 1.19.0 PendingDeprecatonWarning
|
| 5 |
+
warnings.warn("Importing from numpy.matlib is deprecated since 1.19.0. "
|
| 6 |
+
"The matrix subclass is not the recommended way to represent "
|
| 7 |
+
"matrices or deal with linear algebra (see "
|
| 8 |
+
"https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html). "
|
| 9 |
+
"Please adjust your code to use regular ndarray. ",
|
| 10 |
+
PendingDeprecationWarning, stacklevel=2)
|
| 11 |
+
|
| 12 |
+
import numpy as np
|
| 13 |
+
from numpy.matrixlib.defmatrix import matrix, asmatrix
|
| 14 |
+
# Matlib.py contains all functions in the numpy namespace with a few
|
| 15 |
+
# replacements. See doc/source/reference/routines.matlib.rst for details.
|
| 16 |
+
# Need * as we're copying the numpy namespace.
|
| 17 |
+
from numpy import * # noqa: F403
|
| 18 |
+
|
| 19 |
+
__version__ = np.__version__
|
| 20 |
+
|
| 21 |
+
__all__ = np.__all__[:] # copy numpy namespace
|
| 22 |
+
__all__ += ['rand', 'randn', 'repmat']
|
| 23 |
+
|
| 24 |
+
def empty(shape, dtype=None, order='C'):
|
| 25 |
+
"""Return a new matrix of given shape and type, without initializing entries.
|
| 26 |
+
|
| 27 |
+
Parameters
|
| 28 |
+
----------
|
| 29 |
+
shape : int or tuple of int
|
| 30 |
+
Shape of the empty matrix.
|
| 31 |
+
dtype : data-type, optional
|
| 32 |
+
Desired output data-type.
|
| 33 |
+
order : {'C', 'F'}, optional
|
| 34 |
+
Whether to store multi-dimensional data in row-major
|
| 35 |
+
(C-style) or column-major (Fortran-style) order in
|
| 36 |
+
memory.
|
| 37 |
+
|
| 38 |
+
See Also
|
| 39 |
+
--------
|
| 40 |
+
empty_like, zeros
|
| 41 |
+
|
| 42 |
+
Notes
|
| 43 |
+
-----
|
| 44 |
+
`empty`, unlike `zeros`, does not set the matrix values to zero,
|
| 45 |
+
and may therefore be marginally faster. On the other hand, it requires
|
| 46 |
+
the user to manually set all the values in the array, and should be
|
| 47 |
+
used with caution.
|
| 48 |
+
|
| 49 |
+
Examples
|
| 50 |
+
--------
|
| 51 |
+
>>> import numpy.matlib
|
| 52 |
+
>>> np.matlib.empty((2, 2)) # filled with random data
|
| 53 |
+
matrix([[ 6.76425276e-320, 9.79033856e-307], # random
|
| 54 |
+
[ 7.39337286e-309, 3.22135945e-309]])
|
| 55 |
+
>>> np.matlib.empty((2, 2), dtype=int)
|
| 56 |
+
matrix([[ 6600475, 0], # random
|
| 57 |
+
[ 6586976, 22740995]])
|
| 58 |
+
|
| 59 |
+
"""
|
| 60 |
+
return ndarray.__new__(matrix, shape, dtype, order=order)
|
| 61 |
+
|
| 62 |
+
def ones(shape, dtype=None, order='C'):
|
| 63 |
+
"""
|
| 64 |
+
Matrix of ones.
|
| 65 |
+
|
| 66 |
+
Return a matrix of given shape and type, filled with ones.
|
| 67 |
+
|
| 68 |
+
Parameters
|
| 69 |
+
----------
|
| 70 |
+
shape : {sequence of ints, int}
|
| 71 |
+
Shape of the matrix
|
| 72 |
+
dtype : data-type, optional
|
| 73 |
+
The desired data-type for the matrix, default is np.float64.
|
| 74 |
+
order : {'C', 'F'}, optional
|
| 75 |
+
Whether to store matrix in C- or Fortran-contiguous order,
|
| 76 |
+
default is 'C'.
|
| 77 |
+
|
| 78 |
+
Returns
|
| 79 |
+
-------
|
| 80 |
+
out : matrix
|
| 81 |
+
Matrix of ones of given shape, dtype, and order.
|
| 82 |
+
|
| 83 |
+
See Also
|
| 84 |
+
--------
|
| 85 |
+
ones : Array of ones.
|
| 86 |
+
matlib.zeros : Zero matrix.
|
| 87 |
+
|
| 88 |
+
Notes
|
| 89 |
+
-----
|
| 90 |
+
If `shape` has length one i.e. ``(N,)``, or is a scalar ``N``,
|
| 91 |
+
`out` becomes a single row matrix of shape ``(1,N)``.
|
| 92 |
+
|
| 93 |
+
Examples
|
| 94 |
+
--------
|
| 95 |
+
>>> np.matlib.ones((2,3))
|
| 96 |
+
matrix([[1., 1., 1.],
|
| 97 |
+
[1., 1., 1.]])
|
| 98 |
+
|
| 99 |
+
>>> np.matlib.ones(2)
|
| 100 |
+
matrix([[1., 1.]])
|
| 101 |
+
|
| 102 |
+
"""
|
| 103 |
+
a = ndarray.__new__(matrix, shape, dtype, order=order)
|
| 104 |
+
a.fill(1)
|
| 105 |
+
return a
|
| 106 |
+
|
| 107 |
+
def zeros(shape, dtype=None, order='C'):
|
| 108 |
+
"""
|
| 109 |
+
Return a matrix of given shape and type, filled with zeros.
|
| 110 |
+
|
| 111 |
+
Parameters
|
| 112 |
+
----------
|
| 113 |
+
shape : int or sequence of ints
|
| 114 |
+
Shape of the matrix
|
| 115 |
+
dtype : data-type, optional
|
| 116 |
+
The desired data-type for the matrix, default is float.
|
| 117 |
+
order : {'C', 'F'}, optional
|
| 118 |
+
Whether to store the result in C- or Fortran-contiguous order,
|
| 119 |
+
default is 'C'.
|
| 120 |
+
|
| 121 |
+
Returns
|
| 122 |
+
-------
|
| 123 |
+
out : matrix
|
| 124 |
+
Zero matrix of given shape, dtype, and order.
|
| 125 |
+
|
| 126 |
+
See Also
|
| 127 |
+
--------
|
| 128 |
+
numpy.zeros : Equivalent array function.
|
| 129 |
+
matlib.ones : Return a matrix of ones.
|
| 130 |
+
|
| 131 |
+
Notes
|
| 132 |
+
-----
|
| 133 |
+
If `shape` has length one i.e. ``(N,)``, or is a scalar ``N``,
|
| 134 |
+
`out` becomes a single row matrix of shape ``(1,N)``.
|
| 135 |
+
|
| 136 |
+
Examples
|
| 137 |
+
--------
|
| 138 |
+
>>> import numpy.matlib
|
| 139 |
+
>>> np.matlib.zeros((2, 3))
|
| 140 |
+
matrix([[0., 0., 0.],
|
| 141 |
+
[0., 0., 0.]])
|
| 142 |
+
|
| 143 |
+
>>> np.matlib.zeros(2)
|
| 144 |
+
matrix([[0., 0.]])
|
| 145 |
+
|
| 146 |
+
"""
|
| 147 |
+
a = ndarray.__new__(matrix, shape, dtype, order=order)
|
| 148 |
+
a.fill(0)
|
| 149 |
+
return a
|
| 150 |
+
|
| 151 |
+
def identity(n,dtype=None):
|
| 152 |
+
"""
|
| 153 |
+
Returns the square identity matrix of given size.
|
| 154 |
+
|
| 155 |
+
Parameters
|
| 156 |
+
----------
|
| 157 |
+
n : int
|
| 158 |
+
Size of the returned identity matrix.
|
| 159 |
+
dtype : data-type, optional
|
| 160 |
+
Data-type of the output. Defaults to ``float``.
|
| 161 |
+
|
| 162 |
+
Returns
|
| 163 |
+
-------
|
| 164 |
+
out : matrix
|
| 165 |
+
`n` x `n` matrix with its main diagonal set to one,
|
| 166 |
+
and all other elements zero.
|
| 167 |
+
|
| 168 |
+
See Also
|
| 169 |
+
--------
|
| 170 |
+
numpy.identity : Equivalent array function.
|
| 171 |
+
matlib.eye : More general matrix identity function.
|
| 172 |
+
|
| 173 |
+
Examples
|
| 174 |
+
--------
|
| 175 |
+
>>> import numpy.matlib
|
| 176 |
+
>>> np.matlib.identity(3, dtype=int)
|
| 177 |
+
matrix([[1, 0, 0],
|
| 178 |
+
[0, 1, 0],
|
| 179 |
+
[0, 0, 1]])
|
| 180 |
+
|
| 181 |
+
"""
|
| 182 |
+
a = array([1]+n*[0], dtype=dtype)
|
| 183 |
+
b = empty((n, n), dtype=dtype)
|
| 184 |
+
b.flat = a
|
| 185 |
+
return b
|
| 186 |
+
|
| 187 |
+
def eye(n,M=None, k=0, dtype=float, order='C'):
|
| 188 |
+
"""
|
| 189 |
+
Return a matrix with ones on the diagonal and zeros elsewhere.
|
| 190 |
+
|
| 191 |
+
Parameters
|
| 192 |
+
----------
|
| 193 |
+
n : int
|
| 194 |
+
Number of rows in the output.
|
| 195 |
+
M : int, optional
|
| 196 |
+
Number of columns in the output, defaults to `n`.
|
| 197 |
+
k : int, optional
|
| 198 |
+
Index of the diagonal: 0 refers to the main diagonal,
|
| 199 |
+
a positive value refers to an upper diagonal,
|
| 200 |
+
and a negative value to a lower diagonal.
|
| 201 |
+
dtype : dtype, optional
|
| 202 |
+
Data-type of the returned matrix.
|
| 203 |
+
order : {'C', 'F'}, optional
|
| 204 |
+
Whether the output should be stored in row-major (C-style) or
|
| 205 |
+
column-major (Fortran-style) order in memory.
|
| 206 |
+
|
| 207 |
+
.. versionadded:: 1.14.0
|
| 208 |
+
|
| 209 |
+
Returns
|
| 210 |
+
-------
|
| 211 |
+
I : matrix
|
| 212 |
+
A `n` x `M` matrix where all elements are equal to zero,
|
| 213 |
+
except for the `k`-th diagonal, whose values are equal to one.
|
| 214 |
+
|
| 215 |
+
See Also
|
| 216 |
+
--------
|
| 217 |
+
numpy.eye : Equivalent array function.
|
| 218 |
+
identity : Square identity matrix.
|
| 219 |
+
|
| 220 |
+
Examples
|
| 221 |
+
--------
|
| 222 |
+
>>> import numpy.matlib
|
| 223 |
+
>>> np.matlib.eye(3, k=1, dtype=float)
|
| 224 |
+
matrix([[0., 1., 0.],
|
| 225 |
+
[0., 0., 1.],
|
| 226 |
+
[0., 0., 0.]])
|
| 227 |
+
|
| 228 |
+
"""
|
| 229 |
+
return asmatrix(np.eye(n, M=M, k=k, dtype=dtype, order=order))
|
| 230 |
+
|
| 231 |
+
def rand(*args):
|
| 232 |
+
"""
|
| 233 |
+
Return a matrix of random values with given shape.
|
| 234 |
+
|
| 235 |
+
Create a matrix of the given shape and propagate it with
|
| 236 |
+
random samples from a uniform distribution over ``[0, 1)``.
|
| 237 |
+
|
| 238 |
+
Parameters
|
| 239 |
+
----------
|
| 240 |
+
\\*args : Arguments
|
| 241 |
+
Shape of the output.
|
| 242 |
+
If given as N integers, each integer specifies the size of one
|
| 243 |
+
dimension.
|
| 244 |
+
If given as a tuple, this tuple gives the complete shape.
|
| 245 |
+
|
| 246 |
+
Returns
|
| 247 |
+
-------
|
| 248 |
+
out : ndarray
|
| 249 |
+
The matrix of random values with shape given by `\\*args`.
|
| 250 |
+
|
| 251 |
+
See Also
|
| 252 |
+
--------
|
| 253 |
+
randn, numpy.random.RandomState.rand
|
| 254 |
+
|
| 255 |
+
Examples
|
| 256 |
+
--------
|
| 257 |
+
>>> np.random.seed(123)
|
| 258 |
+
>>> import numpy.matlib
|
| 259 |
+
>>> np.matlib.rand(2, 3)
|
| 260 |
+
matrix([[0.69646919, 0.28613933, 0.22685145],
|
| 261 |
+
[0.55131477, 0.71946897, 0.42310646]])
|
| 262 |
+
>>> np.matlib.rand((2, 3))
|
| 263 |
+
matrix([[0.9807642 , 0.68482974, 0.4809319 ],
|
| 264 |
+
[0.39211752, 0.34317802, 0.72904971]])
|
| 265 |
+
|
| 266 |
+
If the first argument is a tuple, other arguments are ignored:
|
| 267 |
+
|
| 268 |
+
>>> np.matlib.rand((2, 3), 4)
|
| 269 |
+
matrix([[0.43857224, 0.0596779 , 0.39804426],
|
| 270 |
+
[0.73799541, 0.18249173, 0.17545176]])
|
| 271 |
+
|
| 272 |
+
"""
|
| 273 |
+
if isinstance(args[0], tuple):
|
| 274 |
+
args = args[0]
|
| 275 |
+
return asmatrix(np.random.rand(*args))
|
| 276 |
+
|
| 277 |
+
def randn(*args):
|
| 278 |
+
"""
|
| 279 |
+
Return a random matrix with data from the "standard normal" distribution.
|
| 280 |
+
|
| 281 |
+
`randn` generates a matrix filled with random floats sampled from a
|
| 282 |
+
univariate "normal" (Gaussian) distribution of mean 0 and variance 1.
|
| 283 |
+
|
| 284 |
+
Parameters
|
| 285 |
+
----------
|
| 286 |
+
\\*args : Arguments
|
| 287 |
+
Shape of the output.
|
| 288 |
+
If given as N integers, each integer specifies the size of one
|
| 289 |
+
dimension. If given as a tuple, this tuple gives the complete shape.
|
| 290 |
+
|
| 291 |
+
Returns
|
| 292 |
+
-------
|
| 293 |
+
Z : matrix of floats
|
| 294 |
+
A matrix of floating-point samples drawn from the standard normal
|
| 295 |
+
distribution.
|
| 296 |
+
|
| 297 |
+
See Also
|
| 298 |
+
--------
|
| 299 |
+
rand, numpy.random.RandomState.randn
|
| 300 |
+
|
| 301 |
+
Notes
|
| 302 |
+
-----
|
| 303 |
+
For random samples from the normal distribution with mean ``mu`` and
|
| 304 |
+
standard deviation ``sigma``, use::
|
| 305 |
+
|
| 306 |
+
sigma * np.matlib.randn(...) + mu
|
| 307 |
+
|
| 308 |
+
Examples
|
| 309 |
+
--------
|
| 310 |
+
>>> np.random.seed(123)
|
| 311 |
+
>>> import numpy.matlib
|
| 312 |
+
>>> np.matlib.randn(1)
|
| 313 |
+
matrix([[-1.0856306]])
|
| 314 |
+
>>> np.matlib.randn(1, 2, 3)
|
| 315 |
+
matrix([[ 0.99734545, 0.2829785 , -1.50629471],
|
| 316 |
+
[-0.57860025, 1.65143654, -2.42667924]])
|
| 317 |
+
|
| 318 |
+
Two-by-four matrix of samples from the normal distribution with
|
| 319 |
+
mean 3 and standard deviation 2.5:
|
| 320 |
+
|
| 321 |
+
>>> 2.5 * np.matlib.randn((2, 4)) + 3
|
| 322 |
+
matrix([[1.92771843, 6.16484065, 0.83314899, 1.30278462],
|
| 323 |
+
[2.76322758, 6.72847407, 1.40274501, 1.8900451 ]])
|
| 324 |
+
|
| 325 |
+
"""
|
| 326 |
+
if isinstance(args[0], tuple):
|
| 327 |
+
args = args[0]
|
| 328 |
+
return asmatrix(np.random.randn(*args))
|
| 329 |
+
|
| 330 |
+
def repmat(a, m, n):
|
| 331 |
+
"""
|
| 332 |
+
Repeat a 0-D to 2-D array or matrix MxN times.
|
| 333 |
+
|
| 334 |
+
Parameters
|
| 335 |
+
----------
|
| 336 |
+
a : array_like
|
| 337 |
+
The array or matrix to be repeated.
|
| 338 |
+
m, n : int
|
| 339 |
+
The number of times `a` is repeated along the first and second axes.
|
| 340 |
+
|
| 341 |
+
Returns
|
| 342 |
+
-------
|
| 343 |
+
out : ndarray
|
| 344 |
+
The result of repeating `a`.
|
| 345 |
+
|
| 346 |
+
Examples
|
| 347 |
+
--------
|
| 348 |
+
>>> import numpy.matlib
|
| 349 |
+
>>> a0 = np.array(1)
|
| 350 |
+
>>> np.matlib.repmat(a0, 2, 3)
|
| 351 |
+
array([[1, 1, 1],
|
| 352 |
+
[1, 1, 1]])
|
| 353 |
+
|
| 354 |
+
>>> a1 = np.arange(4)
|
| 355 |
+
>>> np.matlib.repmat(a1, 2, 2)
|
| 356 |
+
array([[0, 1, 2, 3, 0, 1, 2, 3],
|
| 357 |
+
[0, 1, 2, 3, 0, 1, 2, 3]])
|
| 358 |
+
|
| 359 |
+
>>> a2 = np.asmatrix(np.arange(6).reshape(2, 3))
|
| 360 |
+
>>> np.matlib.repmat(a2, 2, 3)
|
| 361 |
+
matrix([[0, 1, 2, 0, 1, 2, 0, 1, 2],
|
| 362 |
+
[3, 4, 5, 3, 4, 5, 3, 4, 5],
|
| 363 |
+
[0, 1, 2, 0, 1, 2, 0, 1, 2],
|
| 364 |
+
[3, 4, 5, 3, 4, 5, 3, 4, 5]])
|
| 365 |
+
|
| 366 |
+
"""
|
| 367 |
+
a = asanyarray(a)
|
| 368 |
+
ndim = a.ndim
|
| 369 |
+
if ndim == 0:
|
| 370 |
+
origrows, origcols = (1, 1)
|
| 371 |
+
elif ndim == 1:
|
| 372 |
+
origrows, origcols = (1, a.shape[0])
|
| 373 |
+
else:
|
| 374 |
+
origrows, origcols = a.shape
|
| 375 |
+
rows = origrows * m
|
| 376 |
+
cols = origcols * n
|
| 377 |
+
c = a.reshape(1, a.size).repeat(m, 0).reshape(rows, origcols).repeat(n, 0)
|
| 378 |
+
return c.reshape(rows, cols)
|
lib/python3.12/site-packages/numpy/polynomial/__init__.py
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
A sub-package for efficiently dealing with polynomials.
|
| 3 |
+
|
| 4 |
+
Within the documentation for this sub-package, a "finite power series,"
|
| 5 |
+
i.e., a polynomial (also referred to simply as a "series") is represented
|
| 6 |
+
by a 1-D numpy array of the polynomial's coefficients, ordered from lowest
|
| 7 |
+
order term to highest. For example, array([1,2,3]) represents
|
| 8 |
+
``P_0 + 2*P_1 + 3*P_2``, where P_n is the n-th order basis polynomial
|
| 9 |
+
applicable to the specific module in question, e.g., `polynomial` (which
|
| 10 |
+
"wraps" the "standard" basis) or `chebyshev`. For optimal performance,
|
| 11 |
+
all operations on polynomials, including evaluation at an argument, are
|
| 12 |
+
implemented as operations on the coefficients. Additional (module-specific)
|
| 13 |
+
information can be found in the docstring for the module of interest.
|
| 14 |
+
|
| 15 |
+
This package provides *convenience classes* for each of six different kinds
|
| 16 |
+
of polynomials:
|
| 17 |
+
|
| 18 |
+
======================== ================
|
| 19 |
+
**Name** **Provides**
|
| 20 |
+
======================== ================
|
| 21 |
+
`~polynomial.Polynomial` Power series
|
| 22 |
+
`~chebyshev.Chebyshev` Chebyshev series
|
| 23 |
+
`~legendre.Legendre` Legendre series
|
| 24 |
+
`~laguerre.Laguerre` Laguerre series
|
| 25 |
+
`~hermite.Hermite` Hermite series
|
| 26 |
+
`~hermite_e.HermiteE` HermiteE series
|
| 27 |
+
======================== ================
|
| 28 |
+
|
| 29 |
+
These *convenience classes* provide a consistent interface for creating,
|
| 30 |
+
manipulating, and fitting data with polynomials of different bases.
|
| 31 |
+
The convenience classes are the preferred interface for the `~numpy.polynomial`
|
| 32 |
+
package, and are available from the ``numpy.polynomial`` namespace.
|
| 33 |
+
This eliminates the need to navigate to the corresponding submodules, e.g.
|
| 34 |
+
``np.polynomial.Polynomial`` or ``np.polynomial.Chebyshev`` instead of
|
| 35 |
+
``np.polynomial.polynomial.Polynomial`` or
|
| 36 |
+
``np.polynomial.chebyshev.Chebyshev``, respectively.
|
| 37 |
+
The classes provide a more consistent and concise interface than the
|
| 38 |
+
type-specific functions defined in the submodules for each type of polynomial.
|
| 39 |
+
For example, to fit a Chebyshev polynomial with degree ``1`` to data given
|
| 40 |
+
by arrays ``xdata`` and ``ydata``, the
|
| 41 |
+
`~chebyshev.Chebyshev.fit` class method::
|
| 42 |
+
|
| 43 |
+
>>> from numpy.polynomial import Chebyshev
|
| 44 |
+
>>> c = Chebyshev.fit(xdata, ydata, deg=1)
|
| 45 |
+
|
| 46 |
+
is preferred over the `chebyshev.chebfit` function from the
|
| 47 |
+
``np.polynomial.chebyshev`` module::
|
| 48 |
+
|
| 49 |
+
>>> from numpy.polynomial.chebyshev import chebfit
|
| 50 |
+
>>> c = chebfit(xdata, ydata, deg=1)
|
| 51 |
+
|
| 52 |
+
See :doc:`routines.polynomials.classes` for more details.
|
| 53 |
+
|
| 54 |
+
Convenience Classes
|
| 55 |
+
===================
|
| 56 |
+
|
| 57 |
+
The following lists the various constants and methods common to all of
|
| 58 |
+
the classes representing the various kinds of polynomials. In the following,
|
| 59 |
+
the term ``Poly`` represents any one of the convenience classes (e.g.
|
| 60 |
+
`~polynomial.Polynomial`, `~chebyshev.Chebyshev`, `~hermite.Hermite`, etc.)
|
| 61 |
+
while the lowercase ``p`` represents an **instance** of a polynomial class.
|
| 62 |
+
|
| 63 |
+
Constants
|
| 64 |
+
---------
|
| 65 |
+
|
| 66 |
+
- ``Poly.domain`` -- Default domain
|
| 67 |
+
- ``Poly.window`` -- Default window
|
| 68 |
+
- ``Poly.basis_name`` -- String used to represent the basis
|
| 69 |
+
- ``Poly.maxpower`` -- Maximum value ``n`` such that ``p**n`` is allowed
|
| 70 |
+
- ``Poly.nickname`` -- String used in printing
|
| 71 |
+
|
| 72 |
+
Creation
|
| 73 |
+
--------
|
| 74 |
+
|
| 75 |
+
Methods for creating polynomial instances.
|
| 76 |
+
|
| 77 |
+
- ``Poly.basis(degree)`` -- Basis polynomial of given degree
|
| 78 |
+
- ``Poly.identity()`` -- ``p`` where ``p(x) = x`` for all ``x``
|
| 79 |
+
- ``Poly.fit(x, y, deg)`` -- ``p`` of degree ``deg`` with coefficients
|
| 80 |
+
determined by the least-squares fit to the data ``x``, ``y``
|
| 81 |
+
- ``Poly.fromroots(roots)`` -- ``p`` with specified roots
|
| 82 |
+
- ``p.copy()`` -- Create a copy of ``p``
|
| 83 |
+
|
| 84 |
+
Conversion
|
| 85 |
+
----------
|
| 86 |
+
|
| 87 |
+
Methods for converting a polynomial instance of one kind to another.
|
| 88 |
+
|
| 89 |
+
- ``p.cast(Poly)`` -- Convert ``p`` to instance of kind ``Poly``
|
| 90 |
+
- ``p.convert(Poly)`` -- Convert ``p`` to instance of kind ``Poly`` or map
|
| 91 |
+
between ``domain`` and ``window``
|
| 92 |
+
|
| 93 |
+
Calculus
|
| 94 |
+
--------
|
| 95 |
+
- ``p.deriv()`` -- Take the derivative of ``p``
|
| 96 |
+
- ``p.integ()`` -- Integrate ``p``
|
| 97 |
+
|
| 98 |
+
Validation
|
| 99 |
+
----------
|
| 100 |
+
- ``Poly.has_samecoef(p1, p2)`` -- Check if coefficients match
|
| 101 |
+
- ``Poly.has_samedomain(p1, p2)`` -- Check if domains match
|
| 102 |
+
- ``Poly.has_sametype(p1, p2)`` -- Check if types match
|
| 103 |
+
- ``Poly.has_samewindow(p1, p2)`` -- Check if windows match
|
| 104 |
+
|
| 105 |
+
Misc
|
| 106 |
+
----
|
| 107 |
+
- ``p.linspace()`` -- Return ``x, p(x)`` at equally-spaced points in ``domain``
|
| 108 |
+
- ``p.mapparms()`` -- Return the parameters for the linear mapping between
|
| 109 |
+
``domain`` and ``window``.
|
| 110 |
+
- ``p.roots()`` -- Return the roots of `p`.
|
| 111 |
+
- ``p.trim()`` -- Remove trailing coefficients.
|
| 112 |
+
- ``p.cutdeg(degree)`` -- Truncate p to given degree
|
| 113 |
+
- ``p.truncate(size)`` -- Truncate p to given size
|
| 114 |
+
|
| 115 |
+
"""
|
| 116 |
+
from .polynomial import Polynomial
|
| 117 |
+
from .chebyshev import Chebyshev
|
| 118 |
+
from .legendre import Legendre
|
| 119 |
+
from .hermite import Hermite
|
| 120 |
+
from .hermite_e import HermiteE
|
| 121 |
+
from .laguerre import Laguerre
|
| 122 |
+
|
| 123 |
+
__all__ = [
|
| 124 |
+
"set_default_printstyle",
|
| 125 |
+
"polynomial", "Polynomial",
|
| 126 |
+
"chebyshev", "Chebyshev",
|
| 127 |
+
"legendre", "Legendre",
|
| 128 |
+
"hermite", "Hermite",
|
| 129 |
+
"hermite_e", "HermiteE",
|
| 130 |
+
"laguerre", "Laguerre",
|
| 131 |
+
]
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def set_default_printstyle(style):
|
| 135 |
+
"""
|
| 136 |
+
Set the default format for the string representation of polynomials.
|
| 137 |
+
|
| 138 |
+
Values for ``style`` must be valid inputs to ``__format__``, i.e. 'ascii'
|
| 139 |
+
or 'unicode'.
|
| 140 |
+
|
| 141 |
+
Parameters
|
| 142 |
+
----------
|
| 143 |
+
style : str
|
| 144 |
+
Format string for default printing style. Must be either 'ascii' or
|
| 145 |
+
'unicode'.
|
| 146 |
+
|
| 147 |
+
Notes
|
| 148 |
+
-----
|
| 149 |
+
The default format depends on the platform: 'unicode' is used on
|
| 150 |
+
Unix-based systems and 'ascii' on Windows. This determination is based on
|
| 151 |
+
default font support for the unicode superscript and subscript ranges.
|
| 152 |
+
|
| 153 |
+
Examples
|
| 154 |
+
--------
|
| 155 |
+
>>> p = np.polynomial.Polynomial([1, 2, 3])
|
| 156 |
+
>>> c = np.polynomial.Chebyshev([1, 2, 3])
|
| 157 |
+
>>> np.polynomial.set_default_printstyle('unicode')
|
| 158 |
+
>>> print(p)
|
| 159 |
+
1.0 + 2.0·x + 3.0·x²
|
| 160 |
+
>>> print(c)
|
| 161 |
+
1.0 + 2.0·T₁(x) + 3.0·T₂(x)
|
| 162 |
+
>>> np.polynomial.set_default_printstyle('ascii')
|
| 163 |
+
>>> print(p)
|
| 164 |
+
1.0 + 2.0 x + 3.0 x**2
|
| 165 |
+
>>> print(c)
|
| 166 |
+
1.0 + 2.0 T_1(x) + 3.0 T_2(x)
|
| 167 |
+
>>> # Formatting supersedes all class/package-level defaults
|
| 168 |
+
>>> print(f"{p:unicode}")
|
| 169 |
+
1.0 + 2.0·x + 3.0·x²
|
| 170 |
+
"""
|
| 171 |
+
if style not in ('unicode', 'ascii'):
|
| 172 |
+
raise ValueError(
|
| 173 |
+
f"Unsupported format string '{style}'. Valid options are 'ascii' "
|
| 174 |
+
f"and 'unicode'"
|
| 175 |
+
)
|
| 176 |
+
_use_unicode = True
|
| 177 |
+
if style == 'ascii':
|
| 178 |
+
_use_unicode = False
|
| 179 |
+
from ._polybase import ABCPolyBase
|
| 180 |
+
ABCPolyBase._use_unicode = _use_unicode
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
from numpy._pytesttester import PytestTester
|
| 184 |
+
test = PytestTester(__name__)
|
| 185 |
+
del PytestTester
|
lib/python3.12/site-packages/numpy/polynomial/__init__.pyi
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from numpy._pytesttester import PytestTester
|
| 2 |
+
|
| 3 |
+
from numpy.polynomial import (
|
| 4 |
+
chebyshev as chebyshev,
|
| 5 |
+
hermite as hermite,
|
| 6 |
+
hermite_e as hermite_e,
|
| 7 |
+
laguerre as laguerre,
|
| 8 |
+
legendre as legendre,
|
| 9 |
+
polynomial as polynomial,
|
| 10 |
+
)
|
| 11 |
+
from numpy.polynomial.chebyshev import Chebyshev as Chebyshev
|
| 12 |
+
from numpy.polynomial.hermite import Hermite as Hermite
|
| 13 |
+
from numpy.polynomial.hermite_e import HermiteE as HermiteE
|
| 14 |
+
from numpy.polynomial.laguerre import Laguerre as Laguerre
|
| 15 |
+
from numpy.polynomial.legendre import Legendre as Legendre
|
| 16 |
+
from numpy.polynomial.polynomial import Polynomial as Polynomial
|
| 17 |
+
|
| 18 |
+
__all__: list[str]
|
| 19 |
+
__path__: list[str]
|
| 20 |
+
test: PytestTester
|
| 21 |
+
|
| 22 |
+
def set_default_printstyle(style): ...
|
lib/python3.12/site-packages/numpy/polynomial/_polybase.py
ADDED
|
@@ -0,0 +1,1206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Abstract base class for the various polynomial Classes.
|
| 3 |
+
|
| 4 |
+
The ABCPolyBase class provides the methods needed to implement the common API
|
| 5 |
+
for the various polynomial classes. It operates as a mixin, but uses the
|
| 6 |
+
abc module from the stdlib, hence it is only available for Python >= 2.6.
|
| 7 |
+
|
| 8 |
+
"""
|
| 9 |
+
import os
|
| 10 |
+
import abc
|
| 11 |
+
import numbers
|
| 12 |
+
|
| 13 |
+
import numpy as np
|
| 14 |
+
from . import polyutils as pu
|
| 15 |
+
|
| 16 |
+
__all__ = ['ABCPolyBase']
|
| 17 |
+
|
| 18 |
+
class ABCPolyBase(abc.ABC):
|
| 19 |
+
"""An abstract base class for immutable series classes.
|
| 20 |
+
|
| 21 |
+
ABCPolyBase provides the standard Python numerical methods
|
| 22 |
+
'+', '-', '*', '//', '%', 'divmod', '**', and '()' along with the
|
| 23 |
+
methods listed below.
|
| 24 |
+
|
| 25 |
+
.. versionadded:: 1.9.0
|
| 26 |
+
|
| 27 |
+
Parameters
|
| 28 |
+
----------
|
| 29 |
+
coef : array_like
|
| 30 |
+
Series coefficients in order of increasing degree, i.e.,
|
| 31 |
+
``(1, 2, 3)`` gives ``1*P_0(x) + 2*P_1(x) + 3*P_2(x)``, where
|
| 32 |
+
``P_i`` is the basis polynomials of degree ``i``.
|
| 33 |
+
domain : (2,) array_like, optional
|
| 34 |
+
Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
|
| 35 |
+
to the interval ``[window[0], window[1]]`` by shifting and scaling.
|
| 36 |
+
The default value is the derived class domain.
|
| 37 |
+
window : (2,) array_like, optional
|
| 38 |
+
Window, see domain for its use. The default value is the
|
| 39 |
+
derived class window.
|
| 40 |
+
symbol : str, optional
|
| 41 |
+
Symbol used to represent the independent variable in string
|
| 42 |
+
representations of the polynomial expression, e.g. for printing.
|
| 43 |
+
The symbol must be a valid Python identifier. Default value is 'x'.
|
| 44 |
+
|
| 45 |
+
.. versionadded:: 1.24
|
| 46 |
+
|
| 47 |
+
Attributes
|
| 48 |
+
----------
|
| 49 |
+
coef : (N,) ndarray
|
| 50 |
+
Series coefficients in order of increasing degree.
|
| 51 |
+
domain : (2,) ndarray
|
| 52 |
+
Domain that is mapped to window.
|
| 53 |
+
window : (2,) ndarray
|
| 54 |
+
Window that domain is mapped to.
|
| 55 |
+
symbol : str
|
| 56 |
+
Symbol representing the independent variable.
|
| 57 |
+
|
| 58 |
+
Class Attributes
|
| 59 |
+
----------------
|
| 60 |
+
maxpower : int
|
| 61 |
+
Maximum power allowed, i.e., the largest number ``n`` such that
|
| 62 |
+
``p(x)**n`` is allowed. This is to limit runaway polynomial size.
|
| 63 |
+
domain : (2,) ndarray
|
| 64 |
+
Default domain of the class.
|
| 65 |
+
window : (2,) ndarray
|
| 66 |
+
Default window of the class.
|
| 67 |
+
|
| 68 |
+
"""
|
| 69 |
+
|
| 70 |
+
# Not hashable
|
| 71 |
+
__hash__ = None
|
| 72 |
+
|
| 73 |
+
# Opt out of numpy ufuncs and Python ops with ndarray subclasses.
|
| 74 |
+
__array_ufunc__ = None
|
| 75 |
+
|
| 76 |
+
# Limit runaway size. T_n^m has degree n*m
|
| 77 |
+
maxpower = 100
|
| 78 |
+
|
| 79 |
+
# Unicode character mappings for improved __str__
|
| 80 |
+
_superscript_mapping = str.maketrans({
|
| 81 |
+
"0": "⁰",
|
| 82 |
+
"1": "¹",
|
| 83 |
+
"2": "²",
|
| 84 |
+
"3": "³",
|
| 85 |
+
"4": "⁴",
|
| 86 |
+
"5": "⁵",
|
| 87 |
+
"6": "⁶",
|
| 88 |
+
"7": "⁷",
|
| 89 |
+
"8": "⁸",
|
| 90 |
+
"9": "⁹"
|
| 91 |
+
})
|
| 92 |
+
_subscript_mapping = str.maketrans({
|
| 93 |
+
"0": "₀",
|
| 94 |
+
"1": "₁",
|
| 95 |
+
"2": "₂",
|
| 96 |
+
"3": "₃",
|
| 97 |
+
"4": "₄",
|
| 98 |
+
"5": "₅",
|
| 99 |
+
"6": "₆",
|
| 100 |
+
"7": "₇",
|
| 101 |
+
"8": "₈",
|
| 102 |
+
"9": "₉"
|
| 103 |
+
})
|
| 104 |
+
# Some fonts don't support full unicode character ranges necessary for
|
| 105 |
+
# the full set of superscripts and subscripts, including common/default
|
| 106 |
+
# fonts in Windows shells/terminals. Therefore, default to ascii-only
|
| 107 |
+
# printing on windows.
|
| 108 |
+
_use_unicode = not os.name == 'nt'
|
| 109 |
+
|
| 110 |
+
@property
|
| 111 |
+
def symbol(self):
|
| 112 |
+
return self._symbol
|
| 113 |
+
|
| 114 |
+
@property
|
| 115 |
+
@abc.abstractmethod
|
| 116 |
+
def domain(self):
|
| 117 |
+
pass
|
| 118 |
+
|
| 119 |
+
@property
|
| 120 |
+
@abc.abstractmethod
|
| 121 |
+
def window(self):
|
| 122 |
+
pass
|
| 123 |
+
|
| 124 |
+
@property
|
| 125 |
+
@abc.abstractmethod
|
| 126 |
+
def basis_name(self):
|
| 127 |
+
pass
|
| 128 |
+
|
| 129 |
+
@staticmethod
|
| 130 |
+
@abc.abstractmethod
|
| 131 |
+
def _add(c1, c2):
|
| 132 |
+
pass
|
| 133 |
+
|
| 134 |
+
@staticmethod
|
| 135 |
+
@abc.abstractmethod
|
| 136 |
+
def _sub(c1, c2):
|
| 137 |
+
pass
|
| 138 |
+
|
| 139 |
+
@staticmethod
|
| 140 |
+
@abc.abstractmethod
|
| 141 |
+
def _mul(c1, c2):
|
| 142 |
+
pass
|
| 143 |
+
|
| 144 |
+
@staticmethod
|
| 145 |
+
@abc.abstractmethod
|
| 146 |
+
def _div(c1, c2):
|
| 147 |
+
pass
|
| 148 |
+
|
| 149 |
+
@staticmethod
|
| 150 |
+
@abc.abstractmethod
|
| 151 |
+
def _pow(c, pow, maxpower=None):
|
| 152 |
+
pass
|
| 153 |
+
|
| 154 |
+
@staticmethod
|
| 155 |
+
@abc.abstractmethod
|
| 156 |
+
def _val(x, c):
|
| 157 |
+
pass
|
| 158 |
+
|
| 159 |
+
@staticmethod
|
| 160 |
+
@abc.abstractmethod
|
| 161 |
+
def _int(c, m, k, lbnd, scl):
|
| 162 |
+
pass
|
| 163 |
+
|
| 164 |
+
@staticmethod
|
| 165 |
+
@abc.abstractmethod
|
| 166 |
+
def _der(c, m, scl):
|
| 167 |
+
pass
|
| 168 |
+
|
| 169 |
+
@staticmethod
|
| 170 |
+
@abc.abstractmethod
|
| 171 |
+
def _fit(x, y, deg, rcond, full):
|
| 172 |
+
pass
|
| 173 |
+
|
| 174 |
+
@staticmethod
|
| 175 |
+
@abc.abstractmethod
|
| 176 |
+
def _line(off, scl):
|
| 177 |
+
pass
|
| 178 |
+
|
| 179 |
+
@staticmethod
|
| 180 |
+
@abc.abstractmethod
|
| 181 |
+
def _roots(c):
|
| 182 |
+
pass
|
| 183 |
+
|
| 184 |
+
@staticmethod
|
| 185 |
+
@abc.abstractmethod
|
| 186 |
+
def _fromroots(r):
|
| 187 |
+
pass
|
| 188 |
+
|
| 189 |
+
def has_samecoef(self, other):
|
| 190 |
+
"""Check if coefficients match.
|
| 191 |
+
|
| 192 |
+
.. versionadded:: 1.6.0
|
| 193 |
+
|
| 194 |
+
Parameters
|
| 195 |
+
----------
|
| 196 |
+
other : class instance
|
| 197 |
+
The other class must have the ``coef`` attribute.
|
| 198 |
+
|
| 199 |
+
Returns
|
| 200 |
+
-------
|
| 201 |
+
bool : boolean
|
| 202 |
+
True if the coefficients are the same, False otherwise.
|
| 203 |
+
|
| 204 |
+
"""
|
| 205 |
+
if len(self.coef) != len(other.coef):
|
| 206 |
+
return False
|
| 207 |
+
elif not np.all(self.coef == other.coef):
|
| 208 |
+
return False
|
| 209 |
+
else:
|
| 210 |
+
return True
|
| 211 |
+
|
| 212 |
+
def has_samedomain(self, other):
|
| 213 |
+
"""Check if domains match.
|
| 214 |
+
|
| 215 |
+
.. versionadded:: 1.6.0
|
| 216 |
+
|
| 217 |
+
Parameters
|
| 218 |
+
----------
|
| 219 |
+
other : class instance
|
| 220 |
+
The other class must have the ``domain`` attribute.
|
| 221 |
+
|
| 222 |
+
Returns
|
| 223 |
+
-------
|
| 224 |
+
bool : boolean
|
| 225 |
+
True if the domains are the same, False otherwise.
|
| 226 |
+
|
| 227 |
+
"""
|
| 228 |
+
return np.all(self.domain == other.domain)
|
| 229 |
+
|
| 230 |
+
def has_samewindow(self, other):
|
| 231 |
+
"""Check if windows match.
|
| 232 |
+
|
| 233 |
+
.. versionadded:: 1.6.0
|
| 234 |
+
|
| 235 |
+
Parameters
|
| 236 |
+
----------
|
| 237 |
+
other : class instance
|
| 238 |
+
The other class must have the ``window`` attribute.
|
| 239 |
+
|
| 240 |
+
Returns
|
| 241 |
+
-------
|
| 242 |
+
bool : boolean
|
| 243 |
+
True if the windows are the same, False otherwise.
|
| 244 |
+
|
| 245 |
+
"""
|
| 246 |
+
return np.all(self.window == other.window)
|
| 247 |
+
|
| 248 |
+
def has_sametype(self, other):
|
| 249 |
+
"""Check if types match.
|
| 250 |
+
|
| 251 |
+
.. versionadded:: 1.7.0
|
| 252 |
+
|
| 253 |
+
Parameters
|
| 254 |
+
----------
|
| 255 |
+
other : object
|
| 256 |
+
Class instance.
|
| 257 |
+
|
| 258 |
+
Returns
|
| 259 |
+
-------
|
| 260 |
+
bool : boolean
|
| 261 |
+
True if other is same class as self
|
| 262 |
+
|
| 263 |
+
"""
|
| 264 |
+
return isinstance(other, self.__class__)
|
| 265 |
+
|
| 266 |
+
def _get_coefficients(self, other):
|
| 267 |
+
"""Interpret other as polynomial coefficients.
|
| 268 |
+
|
| 269 |
+
The `other` argument is checked to see if it is of the same
|
| 270 |
+
class as self with identical domain and window. If so,
|
| 271 |
+
return its coefficients, otherwise return `other`.
|
| 272 |
+
|
| 273 |
+
.. versionadded:: 1.9.0
|
| 274 |
+
|
| 275 |
+
Parameters
|
| 276 |
+
----------
|
| 277 |
+
other : anything
|
| 278 |
+
Object to be checked.
|
| 279 |
+
|
| 280 |
+
Returns
|
| 281 |
+
-------
|
| 282 |
+
coef
|
| 283 |
+
The coefficients of`other` if it is a compatible instance,
|
| 284 |
+
of ABCPolyBase, otherwise `other`.
|
| 285 |
+
|
| 286 |
+
Raises
|
| 287 |
+
------
|
| 288 |
+
TypeError
|
| 289 |
+
When `other` is an incompatible instance of ABCPolyBase.
|
| 290 |
+
|
| 291 |
+
"""
|
| 292 |
+
if isinstance(other, ABCPolyBase):
|
| 293 |
+
if not isinstance(other, self.__class__):
|
| 294 |
+
raise TypeError("Polynomial types differ")
|
| 295 |
+
elif not np.all(self.domain == other.domain):
|
| 296 |
+
raise TypeError("Domains differ")
|
| 297 |
+
elif not np.all(self.window == other.window):
|
| 298 |
+
raise TypeError("Windows differ")
|
| 299 |
+
elif self.symbol != other.symbol:
|
| 300 |
+
raise ValueError("Polynomial symbols differ")
|
| 301 |
+
return other.coef
|
| 302 |
+
return other
|
| 303 |
+
|
| 304 |
+
def __init__(self, coef, domain=None, window=None, symbol='x'):
|
| 305 |
+
[coef] = pu.as_series([coef], trim=False)
|
| 306 |
+
self.coef = coef
|
| 307 |
+
|
| 308 |
+
if domain is not None:
|
| 309 |
+
[domain] = pu.as_series([domain], trim=False)
|
| 310 |
+
if len(domain) != 2:
|
| 311 |
+
raise ValueError("Domain has wrong number of elements.")
|
| 312 |
+
self.domain = domain
|
| 313 |
+
|
| 314 |
+
if window is not None:
|
| 315 |
+
[window] = pu.as_series([window], trim=False)
|
| 316 |
+
if len(window) != 2:
|
| 317 |
+
raise ValueError("Window has wrong number of elements.")
|
| 318 |
+
self.window = window
|
| 319 |
+
|
| 320 |
+
# Validation for symbol
|
| 321 |
+
try:
|
| 322 |
+
if not symbol.isidentifier():
|
| 323 |
+
raise ValueError(
|
| 324 |
+
"Symbol string must be a valid Python identifier"
|
| 325 |
+
)
|
| 326 |
+
# If a user passes in something other than a string, the above
|
| 327 |
+
# results in an AttributeError. Catch this and raise a more
|
| 328 |
+
# informative exception
|
| 329 |
+
except AttributeError:
|
| 330 |
+
raise TypeError("Symbol must be a non-empty string")
|
| 331 |
+
|
| 332 |
+
self._symbol = symbol
|
| 333 |
+
|
| 334 |
+
def __repr__(self):
|
| 335 |
+
coef = repr(self.coef)[6:-1]
|
| 336 |
+
domain = repr(self.domain)[6:-1]
|
| 337 |
+
window = repr(self.window)[6:-1]
|
| 338 |
+
name = self.__class__.__name__
|
| 339 |
+
return (f"{name}({coef}, domain={domain}, window={window}, "
|
| 340 |
+
f"symbol='{self.symbol}')")
|
| 341 |
+
|
| 342 |
+
def __format__(self, fmt_str):
|
| 343 |
+
if fmt_str == '':
|
| 344 |
+
return self.__str__()
|
| 345 |
+
if fmt_str not in ('ascii', 'unicode'):
|
| 346 |
+
raise ValueError(
|
| 347 |
+
f"Unsupported format string '{fmt_str}' passed to "
|
| 348 |
+
f"{self.__class__}.__format__. Valid options are "
|
| 349 |
+
f"'ascii' and 'unicode'"
|
| 350 |
+
)
|
| 351 |
+
if fmt_str == 'ascii':
|
| 352 |
+
return self._generate_string(self._str_term_ascii)
|
| 353 |
+
return self._generate_string(self._str_term_unicode)
|
| 354 |
+
|
| 355 |
+
def __str__(self):
|
| 356 |
+
if self._use_unicode:
|
| 357 |
+
return self._generate_string(self._str_term_unicode)
|
| 358 |
+
return self._generate_string(self._str_term_ascii)
|
| 359 |
+
|
| 360 |
+
def _generate_string(self, term_method):
|
| 361 |
+
"""
|
| 362 |
+
Generate the full string representation of the polynomial, using
|
| 363 |
+
``term_method`` to generate each polynomial term.
|
| 364 |
+
"""
|
| 365 |
+
# Get configuration for line breaks
|
| 366 |
+
linewidth = np.get_printoptions().get('linewidth', 75)
|
| 367 |
+
if linewidth < 1:
|
| 368 |
+
linewidth = 1
|
| 369 |
+
out = pu.format_float(self.coef[0])
|
| 370 |
+
for i, coef in enumerate(self.coef[1:]):
|
| 371 |
+
out += " "
|
| 372 |
+
power = str(i + 1)
|
| 373 |
+
# Polynomial coefficient
|
| 374 |
+
# The coefficient array can be an object array with elements that
|
| 375 |
+
# will raise a TypeError with >= 0 (e.g. strings or Python
|
| 376 |
+
# complex). In this case, represent the coefficient as-is.
|
| 377 |
+
try:
|
| 378 |
+
if coef >= 0:
|
| 379 |
+
next_term = f"+ " + pu.format_float(coef, parens=True)
|
| 380 |
+
else:
|
| 381 |
+
next_term = f"- " + pu.format_float(-coef, parens=True)
|
| 382 |
+
except TypeError:
|
| 383 |
+
next_term = f"+ {coef}"
|
| 384 |
+
# Polynomial term
|
| 385 |
+
next_term += term_method(power, self.symbol)
|
| 386 |
+
# Length of the current line with next term added
|
| 387 |
+
line_len = len(out.split('\n')[-1]) + len(next_term)
|
| 388 |
+
# If not the last term in the polynomial, it will be two
|
| 389 |
+
# characters longer due to the +/- with the next term
|
| 390 |
+
if i < len(self.coef[1:]) - 1:
|
| 391 |
+
line_len += 2
|
| 392 |
+
# Handle linebreaking
|
| 393 |
+
if line_len >= linewidth:
|
| 394 |
+
next_term = next_term.replace(" ", "\n", 1)
|
| 395 |
+
out += next_term
|
| 396 |
+
return out
|
| 397 |
+
|
| 398 |
+
@classmethod
|
| 399 |
+
def _str_term_unicode(cls, i, arg_str):
|
| 400 |
+
"""
|
| 401 |
+
String representation of single polynomial term using unicode
|
| 402 |
+
characters for superscripts and subscripts.
|
| 403 |
+
"""
|
| 404 |
+
if cls.basis_name is None:
|
| 405 |
+
raise NotImplementedError(
|
| 406 |
+
"Subclasses must define either a basis_name, or override "
|
| 407 |
+
"_str_term_unicode(cls, i, arg_str)"
|
| 408 |
+
)
|
| 409 |
+
return (f"·{cls.basis_name}{i.translate(cls._subscript_mapping)}"
|
| 410 |
+
f"({arg_str})")
|
| 411 |
+
|
| 412 |
+
@classmethod
|
| 413 |
+
def _str_term_ascii(cls, i, arg_str):
|
| 414 |
+
"""
|
| 415 |
+
String representation of a single polynomial term using ** and _ to
|
| 416 |
+
represent superscripts and subscripts, respectively.
|
| 417 |
+
"""
|
| 418 |
+
if cls.basis_name is None:
|
| 419 |
+
raise NotImplementedError(
|
| 420 |
+
"Subclasses must define either a basis_name, or override "
|
| 421 |
+
"_str_term_ascii(cls, i, arg_str)"
|
| 422 |
+
)
|
| 423 |
+
return f" {cls.basis_name}_{i}({arg_str})"
|
| 424 |
+
|
| 425 |
+
@classmethod
|
| 426 |
+
def _repr_latex_term(cls, i, arg_str, needs_parens):
|
| 427 |
+
if cls.basis_name is None:
|
| 428 |
+
raise NotImplementedError(
|
| 429 |
+
"Subclasses must define either a basis name, or override "
|
| 430 |
+
"_repr_latex_term(i, arg_str, needs_parens)")
|
| 431 |
+
# since we always add parens, we don't care if the expression needs them
|
| 432 |
+
return f"{{{cls.basis_name}}}_{{{i}}}({arg_str})"
|
| 433 |
+
|
| 434 |
+
@staticmethod
|
| 435 |
+
def _repr_latex_scalar(x, parens=False):
|
| 436 |
+
# TODO: we're stuck with disabling math formatting until we handle
|
| 437 |
+
# exponents in this function
|
| 438 |
+
return r'\text{{{}}}'.format(pu.format_float(x, parens=parens))
|
| 439 |
+
|
| 440 |
+
def _repr_latex_(self):
|
| 441 |
+
# get the scaled argument string to the basis functions
|
| 442 |
+
off, scale = self.mapparms()
|
| 443 |
+
if off == 0 and scale == 1:
|
| 444 |
+
term = self.symbol
|
| 445 |
+
needs_parens = False
|
| 446 |
+
elif scale == 1:
|
| 447 |
+
term = f"{self._repr_latex_scalar(off)} + {self.symbol}"
|
| 448 |
+
needs_parens = True
|
| 449 |
+
elif off == 0:
|
| 450 |
+
term = f"{self._repr_latex_scalar(scale)}{self.symbol}"
|
| 451 |
+
needs_parens = True
|
| 452 |
+
else:
|
| 453 |
+
term = (
|
| 454 |
+
f"{self._repr_latex_scalar(off)} + "
|
| 455 |
+
f"{self._repr_latex_scalar(scale)}{self.symbol}"
|
| 456 |
+
)
|
| 457 |
+
needs_parens = True
|
| 458 |
+
|
| 459 |
+
mute = r"\color{{LightGray}}{{{}}}".format
|
| 460 |
+
|
| 461 |
+
parts = []
|
| 462 |
+
for i, c in enumerate(self.coef):
|
| 463 |
+
# prevent duplication of + and - signs
|
| 464 |
+
if i == 0:
|
| 465 |
+
coef_str = f"{self._repr_latex_scalar(c)}"
|
| 466 |
+
elif not isinstance(c, numbers.Real):
|
| 467 |
+
coef_str = f" + ({self._repr_latex_scalar(c)})"
|
| 468 |
+
elif not np.signbit(c):
|
| 469 |
+
coef_str = f" + {self._repr_latex_scalar(c, parens=True)}"
|
| 470 |
+
else:
|
| 471 |
+
coef_str = f" - {self._repr_latex_scalar(-c, parens=True)}"
|
| 472 |
+
|
| 473 |
+
# produce the string for the term
|
| 474 |
+
term_str = self._repr_latex_term(i, term, needs_parens)
|
| 475 |
+
if term_str == '1':
|
| 476 |
+
part = coef_str
|
| 477 |
+
else:
|
| 478 |
+
part = rf"{coef_str}\,{term_str}"
|
| 479 |
+
|
| 480 |
+
if c == 0:
|
| 481 |
+
part = mute(part)
|
| 482 |
+
|
| 483 |
+
parts.append(part)
|
| 484 |
+
|
| 485 |
+
if parts:
|
| 486 |
+
body = ''.join(parts)
|
| 487 |
+
else:
|
| 488 |
+
# in case somehow there are no coefficients at all
|
| 489 |
+
body = '0'
|
| 490 |
+
|
| 491 |
+
return rf"${self.symbol} \mapsto {body}$"
|
| 492 |
+
|
| 493 |
+
|
| 494 |
+
|
| 495 |
+
# Pickle and copy
|
| 496 |
+
|
| 497 |
+
def __getstate__(self):
|
| 498 |
+
ret = self.__dict__.copy()
|
| 499 |
+
ret['coef'] = self.coef.copy()
|
| 500 |
+
ret['domain'] = self.domain.copy()
|
| 501 |
+
ret['window'] = self.window.copy()
|
| 502 |
+
ret['symbol'] = self.symbol
|
| 503 |
+
return ret
|
| 504 |
+
|
| 505 |
+
def __setstate__(self, dict):
|
| 506 |
+
self.__dict__ = dict
|
| 507 |
+
|
| 508 |
+
# Call
|
| 509 |
+
|
| 510 |
+
def __call__(self, arg):
|
| 511 |
+
off, scl = pu.mapparms(self.domain, self.window)
|
| 512 |
+
arg = off + scl*arg
|
| 513 |
+
return self._val(arg, self.coef)
|
| 514 |
+
|
| 515 |
+
def __iter__(self):
|
| 516 |
+
return iter(self.coef)
|
| 517 |
+
|
| 518 |
+
def __len__(self):
|
| 519 |
+
return len(self.coef)
|
| 520 |
+
|
| 521 |
+
# Numeric properties.
|
| 522 |
+
|
| 523 |
+
def __neg__(self):
|
| 524 |
+
return self.__class__(
|
| 525 |
+
-self.coef, self.domain, self.window, self.symbol
|
| 526 |
+
)
|
| 527 |
+
|
| 528 |
+
def __pos__(self):
|
| 529 |
+
return self
|
| 530 |
+
|
| 531 |
+
def __add__(self, other):
|
| 532 |
+
othercoef = self._get_coefficients(other)
|
| 533 |
+
try:
|
| 534 |
+
coef = self._add(self.coef, othercoef)
|
| 535 |
+
except Exception:
|
| 536 |
+
return NotImplemented
|
| 537 |
+
return self.__class__(coef, self.domain, self.window, self.symbol)
|
| 538 |
+
|
| 539 |
+
def __sub__(self, other):
|
| 540 |
+
othercoef = self._get_coefficients(other)
|
| 541 |
+
try:
|
| 542 |
+
coef = self._sub(self.coef, othercoef)
|
| 543 |
+
except Exception:
|
| 544 |
+
return NotImplemented
|
| 545 |
+
return self.__class__(coef, self.domain, self.window, self.symbol)
|
| 546 |
+
|
| 547 |
+
def __mul__(self, other):
|
| 548 |
+
othercoef = self._get_coefficients(other)
|
| 549 |
+
try:
|
| 550 |
+
coef = self._mul(self.coef, othercoef)
|
| 551 |
+
except Exception:
|
| 552 |
+
return NotImplemented
|
| 553 |
+
return self.__class__(coef, self.domain, self.window, self.symbol)
|
| 554 |
+
|
| 555 |
+
def __truediv__(self, other):
|
| 556 |
+
# there is no true divide if the rhs is not a Number, although it
|
| 557 |
+
# could return the first n elements of an infinite series.
|
| 558 |
+
# It is hard to see where n would come from, though.
|
| 559 |
+
if not isinstance(other, numbers.Number) or isinstance(other, bool):
|
| 560 |
+
raise TypeError(
|
| 561 |
+
f"unsupported types for true division: "
|
| 562 |
+
f"'{type(self)}', '{type(other)}'"
|
| 563 |
+
)
|
| 564 |
+
return self.__floordiv__(other)
|
| 565 |
+
|
| 566 |
+
def __floordiv__(self, other):
|
| 567 |
+
res = self.__divmod__(other)
|
| 568 |
+
if res is NotImplemented:
|
| 569 |
+
return res
|
| 570 |
+
return res[0]
|
| 571 |
+
|
| 572 |
+
def __mod__(self, other):
|
| 573 |
+
res = self.__divmod__(other)
|
| 574 |
+
if res is NotImplemented:
|
| 575 |
+
return res
|
| 576 |
+
return res[1]
|
| 577 |
+
|
| 578 |
+
def __divmod__(self, other):
|
| 579 |
+
othercoef = self._get_coefficients(other)
|
| 580 |
+
try:
|
| 581 |
+
quo, rem = self._div(self.coef, othercoef)
|
| 582 |
+
except ZeroDivisionError:
|
| 583 |
+
raise
|
| 584 |
+
except Exception:
|
| 585 |
+
return NotImplemented
|
| 586 |
+
quo = self.__class__(quo, self.domain, self.window, self.symbol)
|
| 587 |
+
rem = self.__class__(rem, self.domain, self.window, self.symbol)
|
| 588 |
+
return quo, rem
|
| 589 |
+
|
| 590 |
+
def __pow__(self, other):
|
| 591 |
+
coef = self._pow(self.coef, other, maxpower=self.maxpower)
|
| 592 |
+
res = self.__class__(coef, self.domain, self.window, self.symbol)
|
| 593 |
+
return res
|
| 594 |
+
|
| 595 |
+
def __radd__(self, other):
|
| 596 |
+
try:
|
| 597 |
+
coef = self._add(other, self.coef)
|
| 598 |
+
except Exception:
|
| 599 |
+
return NotImplemented
|
| 600 |
+
return self.__class__(coef, self.domain, self.window, self.symbol)
|
| 601 |
+
|
| 602 |
+
def __rsub__(self, other):
|
| 603 |
+
try:
|
| 604 |
+
coef = self._sub(other, self.coef)
|
| 605 |
+
except Exception:
|
| 606 |
+
return NotImplemented
|
| 607 |
+
return self.__class__(coef, self.domain, self.window, self.symbol)
|
| 608 |
+
|
| 609 |
+
def __rmul__(self, other):
|
| 610 |
+
try:
|
| 611 |
+
coef = self._mul(other, self.coef)
|
| 612 |
+
except Exception:
|
| 613 |
+
return NotImplemented
|
| 614 |
+
return self.__class__(coef, self.domain, self.window, self.symbol)
|
| 615 |
+
|
| 616 |
+
def __rdiv__(self, other):
|
| 617 |
+
# set to __floordiv__ /.
|
| 618 |
+
return self.__rfloordiv__(other)
|
| 619 |
+
|
| 620 |
+
def __rtruediv__(self, other):
|
| 621 |
+
# An instance of ABCPolyBase is not considered a
|
| 622 |
+
# Number.
|
| 623 |
+
return NotImplemented
|
| 624 |
+
|
| 625 |
+
def __rfloordiv__(self, other):
|
| 626 |
+
res = self.__rdivmod__(other)
|
| 627 |
+
if res is NotImplemented:
|
| 628 |
+
return res
|
| 629 |
+
return res[0]
|
| 630 |
+
|
| 631 |
+
def __rmod__(self, other):
|
| 632 |
+
res = self.__rdivmod__(other)
|
| 633 |
+
if res is NotImplemented:
|
| 634 |
+
return res
|
| 635 |
+
return res[1]
|
| 636 |
+
|
| 637 |
+
def __rdivmod__(self, other):
|
| 638 |
+
try:
|
| 639 |
+
quo, rem = self._div(other, self.coef)
|
| 640 |
+
except ZeroDivisionError:
|
| 641 |
+
raise
|
| 642 |
+
except Exception:
|
| 643 |
+
return NotImplemented
|
| 644 |
+
quo = self.__class__(quo, self.domain, self.window, self.symbol)
|
| 645 |
+
rem = self.__class__(rem, self.domain, self.window, self.symbol)
|
| 646 |
+
return quo, rem
|
| 647 |
+
|
| 648 |
+
def __eq__(self, other):
|
| 649 |
+
res = (isinstance(other, self.__class__) and
|
| 650 |
+
np.all(self.domain == other.domain) and
|
| 651 |
+
np.all(self.window == other.window) and
|
| 652 |
+
(self.coef.shape == other.coef.shape) and
|
| 653 |
+
np.all(self.coef == other.coef) and
|
| 654 |
+
(self.symbol == other.symbol))
|
| 655 |
+
return res
|
| 656 |
+
|
| 657 |
+
def __ne__(self, other):
|
| 658 |
+
return not self.__eq__(other)
|
| 659 |
+
|
| 660 |
+
#
|
| 661 |
+
# Extra methods.
|
| 662 |
+
#
|
| 663 |
+
|
| 664 |
+
def copy(self):
|
| 665 |
+
"""Return a copy.
|
| 666 |
+
|
| 667 |
+
Returns
|
| 668 |
+
-------
|
| 669 |
+
new_series : series
|
| 670 |
+
Copy of self.
|
| 671 |
+
|
| 672 |
+
"""
|
| 673 |
+
return self.__class__(self.coef, self.domain, self.window, self.symbol)
|
| 674 |
+
|
| 675 |
+
def degree(self):
|
| 676 |
+
"""The degree of the series.
|
| 677 |
+
|
| 678 |
+
.. versionadded:: 1.5.0
|
| 679 |
+
|
| 680 |
+
Returns
|
| 681 |
+
-------
|
| 682 |
+
degree : int
|
| 683 |
+
Degree of the series, one less than the number of coefficients.
|
| 684 |
+
|
| 685 |
+
Examples
|
| 686 |
+
--------
|
| 687 |
+
|
| 688 |
+
Create a polynomial object for ``1 + 7*x + 4*x**2``:
|
| 689 |
+
|
| 690 |
+
>>> poly = np.polynomial.Polynomial([1, 7, 4])
|
| 691 |
+
>>> print(poly)
|
| 692 |
+
1.0 + 7.0·x + 4.0·x²
|
| 693 |
+
>>> poly.degree()
|
| 694 |
+
2
|
| 695 |
+
|
| 696 |
+
Note that this method does not check for non-zero coefficients.
|
| 697 |
+
You must trim the polynomial to remove any trailing zeroes:
|
| 698 |
+
|
| 699 |
+
>>> poly = np.polynomial.Polynomial([1, 7, 0])
|
| 700 |
+
>>> print(poly)
|
| 701 |
+
1.0 + 7.0·x + 0.0·x²
|
| 702 |
+
>>> poly.degree()
|
| 703 |
+
2
|
| 704 |
+
>>> poly.trim().degree()
|
| 705 |
+
1
|
| 706 |
+
|
| 707 |
+
"""
|
| 708 |
+
return len(self) - 1
|
| 709 |
+
|
| 710 |
+
def cutdeg(self, deg):
|
| 711 |
+
"""Truncate series to the given degree.
|
| 712 |
+
|
| 713 |
+
Reduce the degree of the series to `deg` by discarding the
|
| 714 |
+
high order terms. If `deg` is greater than the current degree a
|
| 715 |
+
copy of the current series is returned. This can be useful in least
|
| 716 |
+
squares where the coefficients of the high degree terms may be very
|
| 717 |
+
small.
|
| 718 |
+
|
| 719 |
+
.. versionadded:: 1.5.0
|
| 720 |
+
|
| 721 |
+
Parameters
|
| 722 |
+
----------
|
| 723 |
+
deg : non-negative int
|
| 724 |
+
The series is reduced to degree `deg` by discarding the high
|
| 725 |
+
order terms. The value of `deg` must be a non-negative integer.
|
| 726 |
+
|
| 727 |
+
Returns
|
| 728 |
+
-------
|
| 729 |
+
new_series : series
|
| 730 |
+
New instance of series with reduced degree.
|
| 731 |
+
|
| 732 |
+
"""
|
| 733 |
+
return self.truncate(deg + 1)
|
| 734 |
+
|
| 735 |
+
def trim(self, tol=0):
|
| 736 |
+
"""Remove trailing coefficients
|
| 737 |
+
|
| 738 |
+
Remove trailing coefficients until a coefficient is reached whose
|
| 739 |
+
absolute value greater than `tol` or the beginning of the series is
|
| 740 |
+
reached. If all the coefficients would be removed the series is set
|
| 741 |
+
to ``[0]``. A new series instance is returned with the new
|
| 742 |
+
coefficients. The current instance remains unchanged.
|
| 743 |
+
|
| 744 |
+
Parameters
|
| 745 |
+
----------
|
| 746 |
+
tol : non-negative number.
|
| 747 |
+
All trailing coefficients less than `tol` will be removed.
|
| 748 |
+
|
| 749 |
+
Returns
|
| 750 |
+
-------
|
| 751 |
+
new_series : series
|
| 752 |
+
New instance of series with trimmed coefficients.
|
| 753 |
+
|
| 754 |
+
"""
|
| 755 |
+
coef = pu.trimcoef(self.coef, tol)
|
| 756 |
+
return self.__class__(coef, self.domain, self.window, self.symbol)
|
| 757 |
+
|
| 758 |
+
def truncate(self, size):
|
| 759 |
+
"""Truncate series to length `size`.
|
| 760 |
+
|
| 761 |
+
Reduce the series to length `size` by discarding the high
|
| 762 |
+
degree terms. The value of `size` must be a positive integer. This
|
| 763 |
+
can be useful in least squares where the coefficients of the
|
| 764 |
+
high degree terms may be very small.
|
| 765 |
+
|
| 766 |
+
Parameters
|
| 767 |
+
----------
|
| 768 |
+
size : positive int
|
| 769 |
+
The series is reduced to length `size` by discarding the high
|
| 770 |
+
degree terms. The value of `size` must be a positive integer.
|
| 771 |
+
|
| 772 |
+
Returns
|
| 773 |
+
-------
|
| 774 |
+
new_series : series
|
| 775 |
+
New instance of series with truncated coefficients.
|
| 776 |
+
|
| 777 |
+
"""
|
| 778 |
+
isize = int(size)
|
| 779 |
+
if isize != size or isize < 1:
|
| 780 |
+
raise ValueError("size must be a positive integer")
|
| 781 |
+
if isize >= len(self.coef):
|
| 782 |
+
coef = self.coef
|
| 783 |
+
else:
|
| 784 |
+
coef = self.coef[:isize]
|
| 785 |
+
return self.__class__(coef, self.domain, self.window, self.symbol)
|
| 786 |
+
|
| 787 |
+
def convert(self, domain=None, kind=None, window=None):
|
| 788 |
+
"""Convert series to a different kind and/or domain and/or window.
|
| 789 |
+
|
| 790 |
+
Parameters
|
| 791 |
+
----------
|
| 792 |
+
domain : array_like, optional
|
| 793 |
+
The domain of the converted series. If the value is None,
|
| 794 |
+
the default domain of `kind` is used.
|
| 795 |
+
kind : class, optional
|
| 796 |
+
The polynomial series type class to which the current instance
|
| 797 |
+
should be converted. If kind is None, then the class of the
|
| 798 |
+
current instance is used.
|
| 799 |
+
window : array_like, optional
|
| 800 |
+
The window of the converted series. If the value is None,
|
| 801 |
+
the default window of `kind` is used.
|
| 802 |
+
|
| 803 |
+
Returns
|
| 804 |
+
-------
|
| 805 |
+
new_series : series
|
| 806 |
+
The returned class can be of different type than the current
|
| 807 |
+
instance and/or have a different domain and/or different
|
| 808 |
+
window.
|
| 809 |
+
|
| 810 |
+
Notes
|
| 811 |
+
-----
|
| 812 |
+
Conversion between domains and class types can result in
|
| 813 |
+
numerically ill defined series.
|
| 814 |
+
|
| 815 |
+
"""
|
| 816 |
+
if kind is None:
|
| 817 |
+
kind = self.__class__
|
| 818 |
+
if domain is None:
|
| 819 |
+
domain = kind.domain
|
| 820 |
+
if window is None:
|
| 821 |
+
window = kind.window
|
| 822 |
+
return self(kind.identity(domain, window=window, symbol=self.symbol))
|
| 823 |
+
|
| 824 |
+
def mapparms(self):
|
| 825 |
+
"""Return the mapping parameters.
|
| 826 |
+
|
| 827 |
+
The returned values define a linear map ``off + scl*x`` that is
|
| 828 |
+
applied to the input arguments before the series is evaluated. The
|
| 829 |
+
map depends on the ``domain`` and ``window``; if the current
|
| 830 |
+
``domain`` is equal to the ``window`` the resulting map is the
|
| 831 |
+
identity. If the coefficients of the series instance are to be
|
| 832 |
+
used by themselves outside this class, then the linear function
|
| 833 |
+
must be substituted for the ``x`` in the standard representation of
|
| 834 |
+
the base polynomials.
|
| 835 |
+
|
| 836 |
+
Returns
|
| 837 |
+
-------
|
| 838 |
+
off, scl : float or complex
|
| 839 |
+
The mapping function is defined by ``off + scl*x``.
|
| 840 |
+
|
| 841 |
+
Notes
|
| 842 |
+
-----
|
| 843 |
+
If the current domain is the interval ``[l1, r1]`` and the window
|
| 844 |
+
is ``[l2, r2]``, then the linear mapping function ``L`` is
|
| 845 |
+
defined by the equations::
|
| 846 |
+
|
| 847 |
+
L(l1) = l2
|
| 848 |
+
L(r1) = r2
|
| 849 |
+
|
| 850 |
+
"""
|
| 851 |
+
return pu.mapparms(self.domain, self.window)
|
| 852 |
+
|
| 853 |
+
def integ(self, m=1, k=[], lbnd=None):
|
| 854 |
+
"""Integrate.
|
| 855 |
+
|
| 856 |
+
Return a series instance that is the definite integral of the
|
| 857 |
+
current series.
|
| 858 |
+
|
| 859 |
+
Parameters
|
| 860 |
+
----------
|
| 861 |
+
m : non-negative int
|
| 862 |
+
The number of integrations to perform.
|
| 863 |
+
k : array_like
|
| 864 |
+
Integration constants. The first constant is applied to the
|
| 865 |
+
first integration, the second to the second, and so on. The
|
| 866 |
+
list of values must less than or equal to `m` in length and any
|
| 867 |
+
missing values are set to zero.
|
| 868 |
+
lbnd : Scalar
|
| 869 |
+
The lower bound of the definite integral.
|
| 870 |
+
|
| 871 |
+
Returns
|
| 872 |
+
-------
|
| 873 |
+
new_series : series
|
| 874 |
+
A new series representing the integral. The domain is the same
|
| 875 |
+
as the domain of the integrated series.
|
| 876 |
+
|
| 877 |
+
"""
|
| 878 |
+
off, scl = self.mapparms()
|
| 879 |
+
if lbnd is None:
|
| 880 |
+
lbnd = 0
|
| 881 |
+
else:
|
| 882 |
+
lbnd = off + scl*lbnd
|
| 883 |
+
coef = self._int(self.coef, m, k, lbnd, 1./scl)
|
| 884 |
+
return self.__class__(coef, self.domain, self.window, self.symbol)
|
| 885 |
+
|
| 886 |
+
def deriv(self, m=1):
|
| 887 |
+
"""Differentiate.
|
| 888 |
+
|
| 889 |
+
Return a series instance of that is the derivative of the current
|
| 890 |
+
series.
|
| 891 |
+
|
| 892 |
+
Parameters
|
| 893 |
+
----------
|
| 894 |
+
m : non-negative int
|
| 895 |
+
Find the derivative of order `m`.
|
| 896 |
+
|
| 897 |
+
Returns
|
| 898 |
+
-------
|
| 899 |
+
new_series : series
|
| 900 |
+
A new series representing the derivative. The domain is the same
|
| 901 |
+
as the domain of the differentiated series.
|
| 902 |
+
|
| 903 |
+
"""
|
| 904 |
+
off, scl = self.mapparms()
|
| 905 |
+
coef = self._der(self.coef, m, scl)
|
| 906 |
+
return self.__class__(coef, self.domain, self.window, self.symbol)
|
| 907 |
+
|
| 908 |
+
def roots(self):
|
| 909 |
+
"""Return the roots of the series polynomial.
|
| 910 |
+
|
| 911 |
+
Compute the roots for the series. Note that the accuracy of the
|
| 912 |
+
roots decreases the further outside the `domain` they lie.
|
| 913 |
+
|
| 914 |
+
Returns
|
| 915 |
+
-------
|
| 916 |
+
roots : ndarray
|
| 917 |
+
Array containing the roots of the series.
|
| 918 |
+
|
| 919 |
+
"""
|
| 920 |
+
roots = self._roots(self.coef)
|
| 921 |
+
return pu.mapdomain(roots, self.window, self.domain)
|
| 922 |
+
|
| 923 |
+
def linspace(self, n=100, domain=None):
|
| 924 |
+
"""Return x, y values at equally spaced points in domain.
|
| 925 |
+
|
| 926 |
+
Returns the x, y values at `n` linearly spaced points across the
|
| 927 |
+
domain. Here y is the value of the polynomial at the points x. By
|
| 928 |
+
default the domain is the same as that of the series instance.
|
| 929 |
+
This method is intended mostly as a plotting aid.
|
| 930 |
+
|
| 931 |
+
.. versionadded:: 1.5.0
|
| 932 |
+
|
| 933 |
+
Parameters
|
| 934 |
+
----------
|
| 935 |
+
n : int, optional
|
| 936 |
+
Number of point pairs to return. The default value is 100.
|
| 937 |
+
domain : {None, array_like}, optional
|
| 938 |
+
If not None, the specified domain is used instead of that of
|
| 939 |
+
the calling instance. It should be of the form ``[beg,end]``.
|
| 940 |
+
The default is None which case the class domain is used.
|
| 941 |
+
|
| 942 |
+
Returns
|
| 943 |
+
-------
|
| 944 |
+
x, y : ndarray
|
| 945 |
+
x is equal to linspace(self.domain[0], self.domain[1], n) and
|
| 946 |
+
y is the series evaluated at element of x.
|
| 947 |
+
|
| 948 |
+
"""
|
| 949 |
+
if domain is None:
|
| 950 |
+
domain = self.domain
|
| 951 |
+
x = np.linspace(domain[0], domain[1], n)
|
| 952 |
+
y = self(x)
|
| 953 |
+
return x, y
|
| 954 |
+
|
| 955 |
+
@classmethod
|
| 956 |
+
def fit(cls, x, y, deg, domain=None, rcond=None, full=False, w=None,
|
| 957 |
+
window=None, symbol='x'):
|
| 958 |
+
"""Least squares fit to data.
|
| 959 |
+
|
| 960 |
+
Return a series instance that is the least squares fit to the data
|
| 961 |
+
`y` sampled at `x`. The domain of the returned instance can be
|
| 962 |
+
specified and this will often result in a superior fit with less
|
| 963 |
+
chance of ill conditioning.
|
| 964 |
+
|
| 965 |
+
Parameters
|
| 966 |
+
----------
|
| 967 |
+
x : array_like, shape (M,)
|
| 968 |
+
x-coordinates of the M sample points ``(x[i], y[i])``.
|
| 969 |
+
y : array_like, shape (M,)
|
| 970 |
+
y-coordinates of the M sample points ``(x[i], y[i])``.
|
| 971 |
+
deg : int or 1-D array_like
|
| 972 |
+
Degree(s) of the fitting polynomials. If `deg` is a single integer
|
| 973 |
+
all terms up to and including the `deg`'th term are included in the
|
| 974 |
+
fit. For NumPy versions >= 1.11.0 a list of integers specifying the
|
| 975 |
+
degrees of the terms to include may be used instead.
|
| 976 |
+
domain : {None, [beg, end], []}, optional
|
| 977 |
+
Domain to use for the returned series. If ``None``,
|
| 978 |
+
then a minimal domain that covers the points `x` is chosen. If
|
| 979 |
+
``[]`` the class domain is used. The default value was the
|
| 980 |
+
class domain in NumPy 1.4 and ``None`` in later versions.
|
| 981 |
+
The ``[]`` option was added in numpy 1.5.0.
|
| 982 |
+
rcond : float, optional
|
| 983 |
+
Relative condition number of the fit. Singular values smaller
|
| 984 |
+
than this relative to the largest singular value will be
|
| 985 |
+
ignored. The default value is len(x)*eps, where eps is the
|
| 986 |
+
relative precision of the float type, about 2e-16 in most
|
| 987 |
+
cases.
|
| 988 |
+
full : bool, optional
|
| 989 |
+
Switch determining nature of return value. When it is False
|
| 990 |
+
(the default) just the coefficients are returned, when True
|
| 991 |
+
diagnostic information from the singular value decomposition is
|
| 992 |
+
also returned.
|
| 993 |
+
w : array_like, shape (M,), optional
|
| 994 |
+
Weights. If not None, the weight ``w[i]`` applies to the unsquared
|
| 995 |
+
residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
|
| 996 |
+
chosen so that the errors of the products ``w[i]*y[i]`` all have
|
| 997 |
+
the same variance. When using inverse-variance weighting, use
|
| 998 |
+
``w[i] = 1/sigma(y[i])``. The default value is None.
|
| 999 |
+
|
| 1000 |
+
.. versionadded:: 1.5.0
|
| 1001 |
+
window : {[beg, end]}, optional
|
| 1002 |
+
Window to use for the returned series. The default
|
| 1003 |
+
value is the default class domain
|
| 1004 |
+
|
| 1005 |
+
.. versionadded:: 1.6.0
|
| 1006 |
+
symbol : str, optional
|
| 1007 |
+
Symbol representing the independent variable. Default is 'x'.
|
| 1008 |
+
|
| 1009 |
+
Returns
|
| 1010 |
+
-------
|
| 1011 |
+
new_series : series
|
| 1012 |
+
A series that represents the least squares fit to the data and
|
| 1013 |
+
has the domain and window specified in the call. If the
|
| 1014 |
+
coefficients for the unscaled and unshifted basis polynomials are
|
| 1015 |
+
of interest, do ``new_series.convert().coef``.
|
| 1016 |
+
|
| 1017 |
+
[resid, rank, sv, rcond] : list
|
| 1018 |
+
These values are only returned if ``full == True``
|
| 1019 |
+
|
| 1020 |
+
- resid -- sum of squared residuals of the least squares fit
|
| 1021 |
+
- rank -- the numerical rank of the scaled Vandermonde matrix
|
| 1022 |
+
- sv -- singular values of the scaled Vandermonde matrix
|
| 1023 |
+
- rcond -- value of `rcond`.
|
| 1024 |
+
|
| 1025 |
+
For more details, see `linalg.lstsq`.
|
| 1026 |
+
|
| 1027 |
+
"""
|
| 1028 |
+
if domain is None:
|
| 1029 |
+
domain = pu.getdomain(x)
|
| 1030 |
+
elif type(domain) is list and len(domain) == 0:
|
| 1031 |
+
domain = cls.domain
|
| 1032 |
+
|
| 1033 |
+
if window is None:
|
| 1034 |
+
window = cls.window
|
| 1035 |
+
|
| 1036 |
+
xnew = pu.mapdomain(x, domain, window)
|
| 1037 |
+
res = cls._fit(xnew, y, deg, w=w, rcond=rcond, full=full)
|
| 1038 |
+
if full:
|
| 1039 |
+
[coef, status] = res
|
| 1040 |
+
return (
|
| 1041 |
+
cls(coef, domain=domain, window=window, symbol=symbol), status
|
| 1042 |
+
)
|
| 1043 |
+
else:
|
| 1044 |
+
coef = res
|
| 1045 |
+
return cls(coef, domain=domain, window=window, symbol=symbol)
|
| 1046 |
+
|
| 1047 |
+
@classmethod
|
| 1048 |
+
def fromroots(cls, roots, domain=[], window=None, symbol='x'):
|
| 1049 |
+
"""Return series instance that has the specified roots.
|
| 1050 |
+
|
| 1051 |
+
Returns a series representing the product
|
| 1052 |
+
``(x - r[0])*(x - r[1])*...*(x - r[n-1])``, where ``r`` is a
|
| 1053 |
+
list of roots.
|
| 1054 |
+
|
| 1055 |
+
Parameters
|
| 1056 |
+
----------
|
| 1057 |
+
roots : array_like
|
| 1058 |
+
List of roots.
|
| 1059 |
+
domain : {[], None, array_like}, optional
|
| 1060 |
+
Domain for the resulting series. If None the domain is the
|
| 1061 |
+
interval from the smallest root to the largest. If [] the
|
| 1062 |
+
domain is the class domain. The default is [].
|
| 1063 |
+
window : {None, array_like}, optional
|
| 1064 |
+
Window for the returned series. If None the class window is
|
| 1065 |
+
used. The default is None.
|
| 1066 |
+
symbol : str, optional
|
| 1067 |
+
Symbol representing the independent variable. Default is 'x'.
|
| 1068 |
+
|
| 1069 |
+
Returns
|
| 1070 |
+
-------
|
| 1071 |
+
new_series : series
|
| 1072 |
+
Series with the specified roots.
|
| 1073 |
+
|
| 1074 |
+
"""
|
| 1075 |
+
[roots] = pu.as_series([roots], trim=False)
|
| 1076 |
+
if domain is None:
|
| 1077 |
+
domain = pu.getdomain(roots)
|
| 1078 |
+
elif type(domain) is list and len(domain) == 0:
|
| 1079 |
+
domain = cls.domain
|
| 1080 |
+
|
| 1081 |
+
if window is None:
|
| 1082 |
+
window = cls.window
|
| 1083 |
+
|
| 1084 |
+
deg = len(roots)
|
| 1085 |
+
off, scl = pu.mapparms(domain, window)
|
| 1086 |
+
rnew = off + scl*roots
|
| 1087 |
+
coef = cls._fromroots(rnew) / scl**deg
|
| 1088 |
+
return cls(coef, domain=domain, window=window, symbol=symbol)
|
| 1089 |
+
|
| 1090 |
+
@classmethod
|
| 1091 |
+
def identity(cls, domain=None, window=None, symbol='x'):
|
| 1092 |
+
"""Identity function.
|
| 1093 |
+
|
| 1094 |
+
If ``p`` is the returned series, then ``p(x) == x`` for all
|
| 1095 |
+
values of x.
|
| 1096 |
+
|
| 1097 |
+
Parameters
|
| 1098 |
+
----------
|
| 1099 |
+
domain : {None, array_like}, optional
|
| 1100 |
+
If given, the array must be of the form ``[beg, end]``, where
|
| 1101 |
+
``beg`` and ``end`` are the endpoints of the domain. If None is
|
| 1102 |
+
given then the class domain is used. The default is None.
|
| 1103 |
+
window : {None, array_like}, optional
|
| 1104 |
+
If given, the resulting array must be if the form
|
| 1105 |
+
``[beg, end]``, where ``beg`` and ``end`` are the endpoints of
|
| 1106 |
+
the window. If None is given then the class window is used. The
|
| 1107 |
+
default is None.
|
| 1108 |
+
symbol : str, optional
|
| 1109 |
+
Symbol representing the independent variable. Default is 'x'.
|
| 1110 |
+
|
| 1111 |
+
Returns
|
| 1112 |
+
-------
|
| 1113 |
+
new_series : series
|
| 1114 |
+
Series of representing the identity.
|
| 1115 |
+
|
| 1116 |
+
"""
|
| 1117 |
+
if domain is None:
|
| 1118 |
+
domain = cls.domain
|
| 1119 |
+
if window is None:
|
| 1120 |
+
window = cls.window
|
| 1121 |
+
off, scl = pu.mapparms(window, domain)
|
| 1122 |
+
coef = cls._line(off, scl)
|
| 1123 |
+
return cls(coef, domain, window, symbol)
|
| 1124 |
+
|
| 1125 |
+
@classmethod
|
| 1126 |
+
def basis(cls, deg, domain=None, window=None, symbol='x'):
|
| 1127 |
+
"""Series basis polynomial of degree `deg`.
|
| 1128 |
+
|
| 1129 |
+
Returns the series representing the basis polynomial of degree `deg`.
|
| 1130 |
+
|
| 1131 |
+
.. versionadded:: 1.7.0
|
| 1132 |
+
|
| 1133 |
+
Parameters
|
| 1134 |
+
----------
|
| 1135 |
+
deg : int
|
| 1136 |
+
Degree of the basis polynomial for the series. Must be >= 0.
|
| 1137 |
+
domain : {None, array_like}, optional
|
| 1138 |
+
If given, the array must be of the form ``[beg, end]``, where
|
| 1139 |
+
``beg`` and ``end`` are the endpoints of the domain. If None is
|
| 1140 |
+
given then the class domain is used. The default is None.
|
| 1141 |
+
window : {None, array_like}, optional
|
| 1142 |
+
If given, the resulting array must be if the form
|
| 1143 |
+
``[beg, end]``, where ``beg`` and ``end`` are the endpoints of
|
| 1144 |
+
the window. If None is given then the class window is used. The
|
| 1145 |
+
default is None.
|
| 1146 |
+
symbol : str, optional
|
| 1147 |
+
Symbol representing the independent variable. Default is 'x'.
|
| 1148 |
+
|
| 1149 |
+
Returns
|
| 1150 |
+
-------
|
| 1151 |
+
new_series : series
|
| 1152 |
+
A series with the coefficient of the `deg` term set to one and
|
| 1153 |
+
all others zero.
|
| 1154 |
+
|
| 1155 |
+
"""
|
| 1156 |
+
if domain is None:
|
| 1157 |
+
domain = cls.domain
|
| 1158 |
+
if window is None:
|
| 1159 |
+
window = cls.window
|
| 1160 |
+
ideg = int(deg)
|
| 1161 |
+
|
| 1162 |
+
if ideg != deg or ideg < 0:
|
| 1163 |
+
raise ValueError("deg must be non-negative integer")
|
| 1164 |
+
return cls([0]*ideg + [1], domain, window, symbol)
|
| 1165 |
+
|
| 1166 |
+
@classmethod
|
| 1167 |
+
def cast(cls, series, domain=None, window=None):
|
| 1168 |
+
"""Convert series to series of this class.
|
| 1169 |
+
|
| 1170 |
+
The `series` is expected to be an instance of some polynomial
|
| 1171 |
+
series of one of the types supported by by the numpy.polynomial
|
| 1172 |
+
module, but could be some other class that supports the convert
|
| 1173 |
+
method.
|
| 1174 |
+
|
| 1175 |
+
.. versionadded:: 1.7.0
|
| 1176 |
+
|
| 1177 |
+
Parameters
|
| 1178 |
+
----------
|
| 1179 |
+
series : series
|
| 1180 |
+
The series instance to be converted.
|
| 1181 |
+
domain : {None, array_like}, optional
|
| 1182 |
+
If given, the array must be of the form ``[beg, end]``, where
|
| 1183 |
+
``beg`` and ``end`` are the endpoints of the domain. If None is
|
| 1184 |
+
given then the class domain is used. The default is None.
|
| 1185 |
+
window : {None, array_like}, optional
|
| 1186 |
+
If given, the resulting array must be if the form
|
| 1187 |
+
``[beg, end]``, where ``beg`` and ``end`` are the endpoints of
|
| 1188 |
+
the window. If None is given then the class window is used. The
|
| 1189 |
+
default is None.
|
| 1190 |
+
|
| 1191 |
+
Returns
|
| 1192 |
+
-------
|
| 1193 |
+
new_series : series
|
| 1194 |
+
A series of the same kind as the calling class and equal to
|
| 1195 |
+
`series` when evaluated.
|
| 1196 |
+
|
| 1197 |
+
See Also
|
| 1198 |
+
--------
|
| 1199 |
+
convert : similar instance method
|
| 1200 |
+
|
| 1201 |
+
"""
|
| 1202 |
+
if domain is None:
|
| 1203 |
+
domain = cls.domain
|
| 1204 |
+
if window is None:
|
| 1205 |
+
window = cls.window
|
| 1206 |
+
return series.convert(domain, cls, window)
|
lib/python3.12/site-packages/numpy/polynomial/_polybase.pyi
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import abc
|
| 2 |
+
from typing import Any, ClassVar
|
| 3 |
+
|
| 4 |
+
__all__: list[str]
|
| 5 |
+
|
| 6 |
+
class ABCPolyBase(abc.ABC):
|
| 7 |
+
__hash__: ClassVar[None] # type: ignore[assignment]
|
| 8 |
+
__array_ufunc__: ClassVar[None]
|
| 9 |
+
maxpower: ClassVar[int]
|
| 10 |
+
coef: Any
|
| 11 |
+
@property
|
| 12 |
+
def symbol(self) -> str: ...
|
| 13 |
+
@property
|
| 14 |
+
@abc.abstractmethod
|
| 15 |
+
def domain(self): ...
|
| 16 |
+
@property
|
| 17 |
+
@abc.abstractmethod
|
| 18 |
+
def window(self): ...
|
| 19 |
+
@property
|
| 20 |
+
@abc.abstractmethod
|
| 21 |
+
def basis_name(self): ...
|
| 22 |
+
def has_samecoef(self, other): ...
|
| 23 |
+
def has_samedomain(self, other): ...
|
| 24 |
+
def has_samewindow(self, other): ...
|
| 25 |
+
def has_sametype(self, other): ...
|
| 26 |
+
def __init__(self, coef, domain=..., window=..., symbol: str = ...) -> None: ...
|
| 27 |
+
def __format__(self, fmt_str): ...
|
| 28 |
+
def __call__(self, arg): ...
|
| 29 |
+
def __iter__(self): ...
|
| 30 |
+
def __len__(self): ...
|
| 31 |
+
def __neg__(self): ...
|
| 32 |
+
def __pos__(self): ...
|
| 33 |
+
def __add__(self, other): ...
|
| 34 |
+
def __sub__(self, other): ...
|
| 35 |
+
def __mul__(self, other): ...
|
| 36 |
+
def __truediv__(self, other): ...
|
| 37 |
+
def __floordiv__(self, other): ...
|
| 38 |
+
def __mod__(self, other): ...
|
| 39 |
+
def __divmod__(self, other): ...
|
| 40 |
+
def __pow__(self, other): ...
|
| 41 |
+
def __radd__(self, other): ...
|
| 42 |
+
def __rsub__(self, other): ...
|
| 43 |
+
def __rmul__(self, other): ...
|
| 44 |
+
def __rdiv__(self, other): ...
|
| 45 |
+
def __rtruediv__(self, other): ...
|
| 46 |
+
def __rfloordiv__(self, other): ...
|
| 47 |
+
def __rmod__(self, other): ...
|
| 48 |
+
def __rdivmod__(self, other): ...
|
| 49 |
+
def __eq__(self, other): ...
|
| 50 |
+
def __ne__(self, other): ...
|
| 51 |
+
def copy(self): ...
|
| 52 |
+
def degree(self): ...
|
| 53 |
+
def cutdeg(self, deg): ...
|
| 54 |
+
def trim(self, tol=...): ...
|
| 55 |
+
def truncate(self, size): ...
|
| 56 |
+
def convert(self, domain=..., kind=..., window=...): ...
|
| 57 |
+
def mapparms(self): ...
|
| 58 |
+
def integ(self, m=..., k = ..., lbnd=...): ...
|
| 59 |
+
def deriv(self, m=...): ...
|
| 60 |
+
def roots(self): ...
|
| 61 |
+
def linspace(self, n=..., domain=...): ...
|
| 62 |
+
@classmethod
|
| 63 |
+
def fit(cls, x, y, deg, domain=..., rcond=..., full=..., w=..., window=...): ...
|
| 64 |
+
@classmethod
|
| 65 |
+
def fromroots(cls, roots, domain = ..., window=...): ...
|
| 66 |
+
@classmethod
|
| 67 |
+
def identity(cls, domain=..., window=...): ...
|
| 68 |
+
@classmethod
|
| 69 |
+
def basis(cls, deg, domain=..., window=...): ...
|
| 70 |
+
@classmethod
|
| 71 |
+
def cast(cls, series, domain=..., window=...): ...
|
lib/python3.12/site-packages/numpy/polynomial/chebyshev.py
ADDED
|
@@ -0,0 +1,2082 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
====================================================
|
| 3 |
+
Chebyshev Series (:mod:`numpy.polynomial.chebyshev`)
|
| 4 |
+
====================================================
|
| 5 |
+
|
| 6 |
+
This module provides a number of objects (mostly functions) useful for
|
| 7 |
+
dealing with Chebyshev series, including a `Chebyshev` class that
|
| 8 |
+
encapsulates the usual arithmetic operations. (General information
|
| 9 |
+
on how this module represents and works with such polynomials is in the
|
| 10 |
+
docstring for its "parent" sub-package, `numpy.polynomial`).
|
| 11 |
+
|
| 12 |
+
Classes
|
| 13 |
+
-------
|
| 14 |
+
|
| 15 |
+
.. autosummary::
|
| 16 |
+
:toctree: generated/
|
| 17 |
+
|
| 18 |
+
Chebyshev
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
Constants
|
| 22 |
+
---------
|
| 23 |
+
|
| 24 |
+
.. autosummary::
|
| 25 |
+
:toctree: generated/
|
| 26 |
+
|
| 27 |
+
chebdomain
|
| 28 |
+
chebzero
|
| 29 |
+
chebone
|
| 30 |
+
chebx
|
| 31 |
+
|
| 32 |
+
Arithmetic
|
| 33 |
+
----------
|
| 34 |
+
|
| 35 |
+
.. autosummary::
|
| 36 |
+
:toctree: generated/
|
| 37 |
+
|
| 38 |
+
chebadd
|
| 39 |
+
chebsub
|
| 40 |
+
chebmulx
|
| 41 |
+
chebmul
|
| 42 |
+
chebdiv
|
| 43 |
+
chebpow
|
| 44 |
+
chebval
|
| 45 |
+
chebval2d
|
| 46 |
+
chebval3d
|
| 47 |
+
chebgrid2d
|
| 48 |
+
chebgrid3d
|
| 49 |
+
|
| 50 |
+
Calculus
|
| 51 |
+
--------
|
| 52 |
+
|
| 53 |
+
.. autosummary::
|
| 54 |
+
:toctree: generated/
|
| 55 |
+
|
| 56 |
+
chebder
|
| 57 |
+
chebint
|
| 58 |
+
|
| 59 |
+
Misc Functions
|
| 60 |
+
--------------
|
| 61 |
+
|
| 62 |
+
.. autosummary::
|
| 63 |
+
:toctree: generated/
|
| 64 |
+
|
| 65 |
+
chebfromroots
|
| 66 |
+
chebroots
|
| 67 |
+
chebvander
|
| 68 |
+
chebvander2d
|
| 69 |
+
chebvander3d
|
| 70 |
+
chebgauss
|
| 71 |
+
chebweight
|
| 72 |
+
chebcompanion
|
| 73 |
+
chebfit
|
| 74 |
+
chebpts1
|
| 75 |
+
chebpts2
|
| 76 |
+
chebtrim
|
| 77 |
+
chebline
|
| 78 |
+
cheb2poly
|
| 79 |
+
poly2cheb
|
| 80 |
+
chebinterpolate
|
| 81 |
+
|
| 82 |
+
See also
|
| 83 |
+
--------
|
| 84 |
+
`numpy.polynomial`
|
| 85 |
+
|
| 86 |
+
Notes
|
| 87 |
+
-----
|
| 88 |
+
The implementations of multiplication, division, integration, and
|
| 89 |
+
differentiation use the algebraic identities [1]_:
|
| 90 |
+
|
| 91 |
+
.. math::
|
| 92 |
+
T_n(x) = \\frac{z^n + z^{-n}}{2} \\\\
|
| 93 |
+
z\\frac{dx}{dz} = \\frac{z - z^{-1}}{2}.
|
| 94 |
+
|
| 95 |
+
where
|
| 96 |
+
|
| 97 |
+
.. math:: x = \\frac{z + z^{-1}}{2}.
|
| 98 |
+
|
| 99 |
+
These identities allow a Chebyshev series to be expressed as a finite,
|
| 100 |
+
symmetric Laurent series. In this module, this sort of Laurent series
|
| 101 |
+
is referred to as a "z-series."
|
| 102 |
+
|
| 103 |
+
References
|
| 104 |
+
----------
|
| 105 |
+
.. [1] A. T. Benjamin, et al., "Combinatorial Trigonometry with Chebyshev
|
| 106 |
+
Polynomials," *Journal of Statistical Planning and Inference 14*, 2008
|
| 107 |
+
(https://web.archive.org/web/20080221202153/https://www.math.hmc.edu/~benjamin/papers/CombTrig.pdf, pg. 4)
|
| 108 |
+
|
| 109 |
+
"""
|
| 110 |
+
import numpy as np
|
| 111 |
+
import numpy.linalg as la
|
| 112 |
+
from numpy.core.multiarray import normalize_axis_index
|
| 113 |
+
|
| 114 |
+
from . import polyutils as pu
|
| 115 |
+
from ._polybase import ABCPolyBase
|
| 116 |
+
|
| 117 |
+
__all__ = [
|
| 118 |
+
'chebzero', 'chebone', 'chebx', 'chebdomain', 'chebline', 'chebadd',
|
| 119 |
+
'chebsub', 'chebmulx', 'chebmul', 'chebdiv', 'chebpow', 'chebval',
|
| 120 |
+
'chebder', 'chebint', 'cheb2poly', 'poly2cheb', 'chebfromroots',
|
| 121 |
+
'chebvander', 'chebfit', 'chebtrim', 'chebroots', 'chebpts1',
|
| 122 |
+
'chebpts2', 'Chebyshev', 'chebval2d', 'chebval3d', 'chebgrid2d',
|
| 123 |
+
'chebgrid3d', 'chebvander2d', 'chebvander3d', 'chebcompanion',
|
| 124 |
+
'chebgauss', 'chebweight', 'chebinterpolate']
|
| 125 |
+
|
| 126 |
+
chebtrim = pu.trimcoef
|
| 127 |
+
|
| 128 |
+
#
|
| 129 |
+
# A collection of functions for manipulating z-series. These are private
|
| 130 |
+
# functions and do minimal error checking.
|
| 131 |
+
#
|
| 132 |
+
|
| 133 |
+
def _cseries_to_zseries(c):
|
| 134 |
+
"""Convert Chebyshev series to z-series.
|
| 135 |
+
|
| 136 |
+
Convert a Chebyshev series to the equivalent z-series. The result is
|
| 137 |
+
never an empty array. The dtype of the return is the same as that of
|
| 138 |
+
the input. No checks are run on the arguments as this routine is for
|
| 139 |
+
internal use.
|
| 140 |
+
|
| 141 |
+
Parameters
|
| 142 |
+
----------
|
| 143 |
+
c : 1-D ndarray
|
| 144 |
+
Chebyshev coefficients, ordered from low to high
|
| 145 |
+
|
| 146 |
+
Returns
|
| 147 |
+
-------
|
| 148 |
+
zs : 1-D ndarray
|
| 149 |
+
Odd length symmetric z-series, ordered from low to high.
|
| 150 |
+
|
| 151 |
+
"""
|
| 152 |
+
n = c.size
|
| 153 |
+
zs = np.zeros(2*n-1, dtype=c.dtype)
|
| 154 |
+
zs[n-1:] = c/2
|
| 155 |
+
return zs + zs[::-1]
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
def _zseries_to_cseries(zs):
|
| 159 |
+
"""Convert z-series to a Chebyshev series.
|
| 160 |
+
|
| 161 |
+
Convert a z series to the equivalent Chebyshev series. The result is
|
| 162 |
+
never an empty array. The dtype of the return is the same as that of
|
| 163 |
+
the input. No checks are run on the arguments as this routine is for
|
| 164 |
+
internal use.
|
| 165 |
+
|
| 166 |
+
Parameters
|
| 167 |
+
----------
|
| 168 |
+
zs : 1-D ndarray
|
| 169 |
+
Odd length symmetric z-series, ordered from low to high.
|
| 170 |
+
|
| 171 |
+
Returns
|
| 172 |
+
-------
|
| 173 |
+
c : 1-D ndarray
|
| 174 |
+
Chebyshev coefficients, ordered from low to high.
|
| 175 |
+
|
| 176 |
+
"""
|
| 177 |
+
n = (zs.size + 1)//2
|
| 178 |
+
c = zs[n-1:].copy()
|
| 179 |
+
c[1:n] *= 2
|
| 180 |
+
return c
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
def _zseries_mul(z1, z2):
|
| 184 |
+
"""Multiply two z-series.
|
| 185 |
+
|
| 186 |
+
Multiply two z-series to produce a z-series.
|
| 187 |
+
|
| 188 |
+
Parameters
|
| 189 |
+
----------
|
| 190 |
+
z1, z2 : 1-D ndarray
|
| 191 |
+
The arrays must be 1-D but this is not checked.
|
| 192 |
+
|
| 193 |
+
Returns
|
| 194 |
+
-------
|
| 195 |
+
product : 1-D ndarray
|
| 196 |
+
The product z-series.
|
| 197 |
+
|
| 198 |
+
Notes
|
| 199 |
+
-----
|
| 200 |
+
This is simply convolution. If symmetric/anti-symmetric z-series are
|
| 201 |
+
denoted by S/A then the following rules apply:
|
| 202 |
+
|
| 203 |
+
S*S, A*A -> S
|
| 204 |
+
S*A, A*S -> A
|
| 205 |
+
|
| 206 |
+
"""
|
| 207 |
+
return np.convolve(z1, z2)
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
def _zseries_div(z1, z2):
|
| 211 |
+
"""Divide the first z-series by the second.
|
| 212 |
+
|
| 213 |
+
Divide `z1` by `z2` and return the quotient and remainder as z-series.
|
| 214 |
+
Warning: this implementation only applies when both z1 and z2 have the
|
| 215 |
+
same symmetry, which is sufficient for present purposes.
|
| 216 |
+
|
| 217 |
+
Parameters
|
| 218 |
+
----------
|
| 219 |
+
z1, z2 : 1-D ndarray
|
| 220 |
+
The arrays must be 1-D and have the same symmetry, but this is not
|
| 221 |
+
checked.
|
| 222 |
+
|
| 223 |
+
Returns
|
| 224 |
+
-------
|
| 225 |
+
|
| 226 |
+
(quotient, remainder) : 1-D ndarrays
|
| 227 |
+
Quotient and remainder as z-series.
|
| 228 |
+
|
| 229 |
+
Notes
|
| 230 |
+
-----
|
| 231 |
+
This is not the same as polynomial division on account of the desired form
|
| 232 |
+
of the remainder. If symmetric/anti-symmetric z-series are denoted by S/A
|
| 233 |
+
then the following rules apply:
|
| 234 |
+
|
| 235 |
+
S/S -> S,S
|
| 236 |
+
A/A -> S,A
|
| 237 |
+
|
| 238 |
+
The restriction to types of the same symmetry could be fixed but seems like
|
| 239 |
+
unneeded generality. There is no natural form for the remainder in the case
|
| 240 |
+
where there is no symmetry.
|
| 241 |
+
|
| 242 |
+
"""
|
| 243 |
+
z1 = z1.copy()
|
| 244 |
+
z2 = z2.copy()
|
| 245 |
+
lc1 = len(z1)
|
| 246 |
+
lc2 = len(z2)
|
| 247 |
+
if lc2 == 1:
|
| 248 |
+
z1 /= z2
|
| 249 |
+
return z1, z1[:1]*0
|
| 250 |
+
elif lc1 < lc2:
|
| 251 |
+
return z1[:1]*0, z1
|
| 252 |
+
else:
|
| 253 |
+
dlen = lc1 - lc2
|
| 254 |
+
scl = z2[0]
|
| 255 |
+
z2 /= scl
|
| 256 |
+
quo = np.empty(dlen + 1, dtype=z1.dtype)
|
| 257 |
+
i = 0
|
| 258 |
+
j = dlen
|
| 259 |
+
while i < j:
|
| 260 |
+
r = z1[i]
|
| 261 |
+
quo[i] = z1[i]
|
| 262 |
+
quo[dlen - i] = r
|
| 263 |
+
tmp = r*z2
|
| 264 |
+
z1[i:i+lc2] -= tmp
|
| 265 |
+
z1[j:j+lc2] -= tmp
|
| 266 |
+
i += 1
|
| 267 |
+
j -= 1
|
| 268 |
+
r = z1[i]
|
| 269 |
+
quo[i] = r
|
| 270 |
+
tmp = r*z2
|
| 271 |
+
z1[i:i+lc2] -= tmp
|
| 272 |
+
quo /= scl
|
| 273 |
+
rem = z1[i+1:i-1+lc2].copy()
|
| 274 |
+
return quo, rem
|
| 275 |
+
|
| 276 |
+
|
| 277 |
+
def _zseries_der(zs):
|
| 278 |
+
"""Differentiate a z-series.
|
| 279 |
+
|
| 280 |
+
The derivative is with respect to x, not z. This is achieved using the
|
| 281 |
+
chain rule and the value of dx/dz given in the module notes.
|
| 282 |
+
|
| 283 |
+
Parameters
|
| 284 |
+
----------
|
| 285 |
+
zs : z-series
|
| 286 |
+
The z-series to differentiate.
|
| 287 |
+
|
| 288 |
+
Returns
|
| 289 |
+
-------
|
| 290 |
+
derivative : z-series
|
| 291 |
+
The derivative
|
| 292 |
+
|
| 293 |
+
Notes
|
| 294 |
+
-----
|
| 295 |
+
The zseries for x (ns) has been multiplied by two in order to avoid
|
| 296 |
+
using floats that are incompatible with Decimal and likely other
|
| 297 |
+
specialized scalar types. This scaling has been compensated by
|
| 298 |
+
multiplying the value of zs by two also so that the two cancels in the
|
| 299 |
+
division.
|
| 300 |
+
|
| 301 |
+
"""
|
| 302 |
+
n = len(zs)//2
|
| 303 |
+
ns = np.array([-1, 0, 1], dtype=zs.dtype)
|
| 304 |
+
zs *= np.arange(-n, n+1)*2
|
| 305 |
+
d, r = _zseries_div(zs, ns)
|
| 306 |
+
return d
|
| 307 |
+
|
| 308 |
+
|
| 309 |
+
def _zseries_int(zs):
|
| 310 |
+
"""Integrate a z-series.
|
| 311 |
+
|
| 312 |
+
The integral is with respect to x, not z. This is achieved by a change
|
| 313 |
+
of variable using dx/dz given in the module notes.
|
| 314 |
+
|
| 315 |
+
Parameters
|
| 316 |
+
----------
|
| 317 |
+
zs : z-series
|
| 318 |
+
The z-series to integrate
|
| 319 |
+
|
| 320 |
+
Returns
|
| 321 |
+
-------
|
| 322 |
+
integral : z-series
|
| 323 |
+
The indefinite integral
|
| 324 |
+
|
| 325 |
+
Notes
|
| 326 |
+
-----
|
| 327 |
+
The zseries for x (ns) has been multiplied by two in order to avoid
|
| 328 |
+
using floats that are incompatible with Decimal and likely other
|
| 329 |
+
specialized scalar types. This scaling has been compensated by
|
| 330 |
+
dividing the resulting zs by two.
|
| 331 |
+
|
| 332 |
+
"""
|
| 333 |
+
n = 1 + len(zs)//2
|
| 334 |
+
ns = np.array([-1, 0, 1], dtype=zs.dtype)
|
| 335 |
+
zs = _zseries_mul(zs, ns)
|
| 336 |
+
div = np.arange(-n, n+1)*2
|
| 337 |
+
zs[:n] /= div[:n]
|
| 338 |
+
zs[n+1:] /= div[n+1:]
|
| 339 |
+
zs[n] = 0
|
| 340 |
+
return zs
|
| 341 |
+
|
| 342 |
+
#
|
| 343 |
+
# Chebyshev series functions
|
| 344 |
+
#
|
| 345 |
+
|
| 346 |
+
|
| 347 |
+
def poly2cheb(pol):
|
| 348 |
+
"""
|
| 349 |
+
Convert a polynomial to a Chebyshev series.
|
| 350 |
+
|
| 351 |
+
Convert an array representing the coefficients of a polynomial (relative
|
| 352 |
+
to the "standard" basis) ordered from lowest degree to highest, to an
|
| 353 |
+
array of the coefficients of the equivalent Chebyshev series, ordered
|
| 354 |
+
from lowest to highest degree.
|
| 355 |
+
|
| 356 |
+
Parameters
|
| 357 |
+
----------
|
| 358 |
+
pol : array_like
|
| 359 |
+
1-D array containing the polynomial coefficients
|
| 360 |
+
|
| 361 |
+
Returns
|
| 362 |
+
-------
|
| 363 |
+
c : ndarray
|
| 364 |
+
1-D array containing the coefficients of the equivalent Chebyshev
|
| 365 |
+
series.
|
| 366 |
+
|
| 367 |
+
See Also
|
| 368 |
+
--------
|
| 369 |
+
cheb2poly
|
| 370 |
+
|
| 371 |
+
Notes
|
| 372 |
+
-----
|
| 373 |
+
The easy way to do conversions between polynomial basis sets
|
| 374 |
+
is to use the convert method of a class instance.
|
| 375 |
+
|
| 376 |
+
Examples
|
| 377 |
+
--------
|
| 378 |
+
>>> from numpy import polynomial as P
|
| 379 |
+
>>> p = P.Polynomial(range(4))
|
| 380 |
+
>>> p
|
| 381 |
+
Polynomial([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1])
|
| 382 |
+
>>> c = p.convert(kind=P.Chebyshev)
|
| 383 |
+
>>> c
|
| 384 |
+
Chebyshev([1. , 3.25, 1. , 0.75], domain=[-1., 1.], window=[-1., 1.])
|
| 385 |
+
>>> P.chebyshev.poly2cheb(range(4))
|
| 386 |
+
array([1. , 3.25, 1. , 0.75])
|
| 387 |
+
|
| 388 |
+
"""
|
| 389 |
+
[pol] = pu.as_series([pol])
|
| 390 |
+
deg = len(pol) - 1
|
| 391 |
+
res = 0
|
| 392 |
+
for i in range(deg, -1, -1):
|
| 393 |
+
res = chebadd(chebmulx(res), pol[i])
|
| 394 |
+
return res
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
def cheb2poly(c):
|
| 398 |
+
"""
|
| 399 |
+
Convert a Chebyshev series to a polynomial.
|
| 400 |
+
|
| 401 |
+
Convert an array representing the coefficients of a Chebyshev series,
|
| 402 |
+
ordered from lowest degree to highest, to an array of the coefficients
|
| 403 |
+
of the equivalent polynomial (relative to the "standard" basis) ordered
|
| 404 |
+
from lowest to highest degree.
|
| 405 |
+
|
| 406 |
+
Parameters
|
| 407 |
+
----------
|
| 408 |
+
c : array_like
|
| 409 |
+
1-D array containing the Chebyshev series coefficients, ordered
|
| 410 |
+
from lowest order term to highest.
|
| 411 |
+
|
| 412 |
+
Returns
|
| 413 |
+
-------
|
| 414 |
+
pol : ndarray
|
| 415 |
+
1-D array containing the coefficients of the equivalent polynomial
|
| 416 |
+
(relative to the "standard" basis) ordered from lowest order term
|
| 417 |
+
to highest.
|
| 418 |
+
|
| 419 |
+
See Also
|
| 420 |
+
--------
|
| 421 |
+
poly2cheb
|
| 422 |
+
|
| 423 |
+
Notes
|
| 424 |
+
-----
|
| 425 |
+
The easy way to do conversions between polynomial basis sets
|
| 426 |
+
is to use the convert method of a class instance.
|
| 427 |
+
|
| 428 |
+
Examples
|
| 429 |
+
--------
|
| 430 |
+
>>> from numpy import polynomial as P
|
| 431 |
+
>>> c = P.Chebyshev(range(4))
|
| 432 |
+
>>> c
|
| 433 |
+
Chebyshev([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1])
|
| 434 |
+
>>> p = c.convert(kind=P.Polynomial)
|
| 435 |
+
>>> p
|
| 436 |
+
Polynomial([-2., -8., 4., 12.], domain=[-1., 1.], window=[-1., 1.])
|
| 437 |
+
>>> P.chebyshev.cheb2poly(range(4))
|
| 438 |
+
array([-2., -8., 4., 12.])
|
| 439 |
+
|
| 440 |
+
"""
|
| 441 |
+
from .polynomial import polyadd, polysub, polymulx
|
| 442 |
+
|
| 443 |
+
[c] = pu.as_series([c])
|
| 444 |
+
n = len(c)
|
| 445 |
+
if n < 3:
|
| 446 |
+
return c
|
| 447 |
+
else:
|
| 448 |
+
c0 = c[-2]
|
| 449 |
+
c1 = c[-1]
|
| 450 |
+
# i is the current degree of c1
|
| 451 |
+
for i in range(n - 1, 1, -1):
|
| 452 |
+
tmp = c0
|
| 453 |
+
c0 = polysub(c[i - 2], c1)
|
| 454 |
+
c1 = polyadd(tmp, polymulx(c1)*2)
|
| 455 |
+
return polyadd(c0, polymulx(c1))
|
| 456 |
+
|
| 457 |
+
|
| 458 |
+
#
|
| 459 |
+
# These are constant arrays are of integer type so as to be compatible
|
| 460 |
+
# with the widest range of other types, such as Decimal.
|
| 461 |
+
#
|
| 462 |
+
|
| 463 |
+
# Chebyshev default domain.
|
| 464 |
+
chebdomain = np.array([-1, 1])
|
| 465 |
+
|
| 466 |
+
# Chebyshev coefficients representing zero.
|
| 467 |
+
chebzero = np.array([0])
|
| 468 |
+
|
| 469 |
+
# Chebyshev coefficients representing one.
|
| 470 |
+
chebone = np.array([1])
|
| 471 |
+
|
| 472 |
+
# Chebyshev coefficients representing the identity x.
|
| 473 |
+
chebx = np.array([0, 1])
|
| 474 |
+
|
| 475 |
+
|
| 476 |
+
def chebline(off, scl):
|
| 477 |
+
"""
|
| 478 |
+
Chebyshev series whose graph is a straight line.
|
| 479 |
+
|
| 480 |
+
Parameters
|
| 481 |
+
----------
|
| 482 |
+
off, scl : scalars
|
| 483 |
+
The specified line is given by ``off + scl*x``.
|
| 484 |
+
|
| 485 |
+
Returns
|
| 486 |
+
-------
|
| 487 |
+
y : ndarray
|
| 488 |
+
This module's representation of the Chebyshev series for
|
| 489 |
+
``off + scl*x``.
|
| 490 |
+
|
| 491 |
+
See Also
|
| 492 |
+
--------
|
| 493 |
+
numpy.polynomial.polynomial.polyline
|
| 494 |
+
numpy.polynomial.legendre.legline
|
| 495 |
+
numpy.polynomial.laguerre.lagline
|
| 496 |
+
numpy.polynomial.hermite.hermline
|
| 497 |
+
numpy.polynomial.hermite_e.hermeline
|
| 498 |
+
|
| 499 |
+
Examples
|
| 500 |
+
--------
|
| 501 |
+
>>> import numpy.polynomial.chebyshev as C
|
| 502 |
+
>>> C.chebline(3,2)
|
| 503 |
+
array([3, 2])
|
| 504 |
+
>>> C.chebval(-3, C.chebline(3,2)) # should be -3
|
| 505 |
+
-3.0
|
| 506 |
+
|
| 507 |
+
"""
|
| 508 |
+
if scl != 0:
|
| 509 |
+
return np.array([off, scl])
|
| 510 |
+
else:
|
| 511 |
+
return np.array([off])
|
| 512 |
+
|
| 513 |
+
|
| 514 |
+
def chebfromroots(roots):
|
| 515 |
+
"""
|
| 516 |
+
Generate a Chebyshev series with given roots.
|
| 517 |
+
|
| 518 |
+
The function returns the coefficients of the polynomial
|
| 519 |
+
|
| 520 |
+
.. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
|
| 521 |
+
|
| 522 |
+
in Chebyshev form, where the `r_n` are the roots specified in `roots`.
|
| 523 |
+
If a zero has multiplicity n, then it must appear in `roots` n times.
|
| 524 |
+
For instance, if 2 is a root of multiplicity three and 3 is a root of
|
| 525 |
+
multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
|
| 526 |
+
roots can appear in any order.
|
| 527 |
+
|
| 528 |
+
If the returned coefficients are `c`, then
|
| 529 |
+
|
| 530 |
+
.. math:: p(x) = c_0 + c_1 * T_1(x) + ... + c_n * T_n(x)
|
| 531 |
+
|
| 532 |
+
The coefficient of the last term is not generally 1 for monic
|
| 533 |
+
polynomials in Chebyshev form.
|
| 534 |
+
|
| 535 |
+
Parameters
|
| 536 |
+
----------
|
| 537 |
+
roots : array_like
|
| 538 |
+
Sequence containing the roots.
|
| 539 |
+
|
| 540 |
+
Returns
|
| 541 |
+
-------
|
| 542 |
+
out : ndarray
|
| 543 |
+
1-D array of coefficients. If all roots are real then `out` is a
|
| 544 |
+
real array, if some of the roots are complex, then `out` is complex
|
| 545 |
+
even if all the coefficients in the result are real (see Examples
|
| 546 |
+
below).
|
| 547 |
+
|
| 548 |
+
See Also
|
| 549 |
+
--------
|
| 550 |
+
numpy.polynomial.polynomial.polyfromroots
|
| 551 |
+
numpy.polynomial.legendre.legfromroots
|
| 552 |
+
numpy.polynomial.laguerre.lagfromroots
|
| 553 |
+
numpy.polynomial.hermite.hermfromroots
|
| 554 |
+
numpy.polynomial.hermite_e.hermefromroots
|
| 555 |
+
|
| 556 |
+
Examples
|
| 557 |
+
--------
|
| 558 |
+
>>> import numpy.polynomial.chebyshev as C
|
| 559 |
+
>>> C.chebfromroots((-1,0,1)) # x^3 - x relative to the standard basis
|
| 560 |
+
array([ 0. , -0.25, 0. , 0.25])
|
| 561 |
+
>>> j = complex(0,1)
|
| 562 |
+
>>> C.chebfromroots((-j,j)) # x^2 + 1 relative to the standard basis
|
| 563 |
+
array([1.5+0.j, 0. +0.j, 0.5+0.j])
|
| 564 |
+
|
| 565 |
+
"""
|
| 566 |
+
return pu._fromroots(chebline, chebmul, roots)
|
| 567 |
+
|
| 568 |
+
|
| 569 |
+
def chebadd(c1, c2):
|
| 570 |
+
"""
|
| 571 |
+
Add one Chebyshev series to another.
|
| 572 |
+
|
| 573 |
+
Returns the sum of two Chebyshev series `c1` + `c2`. The arguments
|
| 574 |
+
are sequences of coefficients ordered from lowest order term to
|
| 575 |
+
highest, i.e., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``.
|
| 576 |
+
|
| 577 |
+
Parameters
|
| 578 |
+
----------
|
| 579 |
+
c1, c2 : array_like
|
| 580 |
+
1-D arrays of Chebyshev series coefficients ordered from low to
|
| 581 |
+
high.
|
| 582 |
+
|
| 583 |
+
Returns
|
| 584 |
+
-------
|
| 585 |
+
out : ndarray
|
| 586 |
+
Array representing the Chebyshev series of their sum.
|
| 587 |
+
|
| 588 |
+
See Also
|
| 589 |
+
--------
|
| 590 |
+
chebsub, chebmulx, chebmul, chebdiv, chebpow
|
| 591 |
+
|
| 592 |
+
Notes
|
| 593 |
+
-----
|
| 594 |
+
Unlike multiplication, division, etc., the sum of two Chebyshev series
|
| 595 |
+
is a Chebyshev series (without having to "reproject" the result onto
|
| 596 |
+
the basis set) so addition, just like that of "standard" polynomials,
|
| 597 |
+
is simply "component-wise."
|
| 598 |
+
|
| 599 |
+
Examples
|
| 600 |
+
--------
|
| 601 |
+
>>> from numpy.polynomial import chebyshev as C
|
| 602 |
+
>>> c1 = (1,2,3)
|
| 603 |
+
>>> c2 = (3,2,1)
|
| 604 |
+
>>> C.chebadd(c1,c2)
|
| 605 |
+
array([4., 4., 4.])
|
| 606 |
+
|
| 607 |
+
"""
|
| 608 |
+
return pu._add(c1, c2)
|
| 609 |
+
|
| 610 |
+
|
| 611 |
+
def chebsub(c1, c2):
|
| 612 |
+
"""
|
| 613 |
+
Subtract one Chebyshev series from another.
|
| 614 |
+
|
| 615 |
+
Returns the difference of two Chebyshev series `c1` - `c2`. The
|
| 616 |
+
sequences of coefficients are from lowest order term to highest, i.e.,
|
| 617 |
+
[1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``.
|
| 618 |
+
|
| 619 |
+
Parameters
|
| 620 |
+
----------
|
| 621 |
+
c1, c2 : array_like
|
| 622 |
+
1-D arrays of Chebyshev series coefficients ordered from low to
|
| 623 |
+
high.
|
| 624 |
+
|
| 625 |
+
Returns
|
| 626 |
+
-------
|
| 627 |
+
out : ndarray
|
| 628 |
+
Of Chebyshev series coefficients representing their difference.
|
| 629 |
+
|
| 630 |
+
See Also
|
| 631 |
+
--------
|
| 632 |
+
chebadd, chebmulx, chebmul, chebdiv, chebpow
|
| 633 |
+
|
| 634 |
+
Notes
|
| 635 |
+
-----
|
| 636 |
+
Unlike multiplication, division, etc., the difference of two Chebyshev
|
| 637 |
+
series is a Chebyshev series (without having to "reproject" the result
|
| 638 |
+
onto the basis set) so subtraction, just like that of "standard"
|
| 639 |
+
polynomials, is simply "component-wise."
|
| 640 |
+
|
| 641 |
+
Examples
|
| 642 |
+
--------
|
| 643 |
+
>>> from numpy.polynomial import chebyshev as C
|
| 644 |
+
>>> c1 = (1,2,3)
|
| 645 |
+
>>> c2 = (3,2,1)
|
| 646 |
+
>>> C.chebsub(c1,c2)
|
| 647 |
+
array([-2., 0., 2.])
|
| 648 |
+
>>> C.chebsub(c2,c1) # -C.chebsub(c1,c2)
|
| 649 |
+
array([ 2., 0., -2.])
|
| 650 |
+
|
| 651 |
+
"""
|
| 652 |
+
return pu._sub(c1, c2)
|
| 653 |
+
|
| 654 |
+
|
| 655 |
+
def chebmulx(c):
|
| 656 |
+
"""Multiply a Chebyshev series by x.
|
| 657 |
+
|
| 658 |
+
Multiply the polynomial `c` by x, where x is the independent
|
| 659 |
+
variable.
|
| 660 |
+
|
| 661 |
+
|
| 662 |
+
Parameters
|
| 663 |
+
----------
|
| 664 |
+
c : array_like
|
| 665 |
+
1-D array of Chebyshev series coefficients ordered from low to
|
| 666 |
+
high.
|
| 667 |
+
|
| 668 |
+
Returns
|
| 669 |
+
-------
|
| 670 |
+
out : ndarray
|
| 671 |
+
Array representing the result of the multiplication.
|
| 672 |
+
|
| 673 |
+
Notes
|
| 674 |
+
-----
|
| 675 |
+
|
| 676 |
+
.. versionadded:: 1.5.0
|
| 677 |
+
|
| 678 |
+
Examples
|
| 679 |
+
--------
|
| 680 |
+
>>> from numpy.polynomial import chebyshev as C
|
| 681 |
+
>>> C.chebmulx([1,2,3])
|
| 682 |
+
array([1. , 2.5, 1. , 1.5])
|
| 683 |
+
|
| 684 |
+
"""
|
| 685 |
+
# c is a trimmed copy
|
| 686 |
+
[c] = pu.as_series([c])
|
| 687 |
+
# The zero series needs special treatment
|
| 688 |
+
if len(c) == 1 and c[0] == 0:
|
| 689 |
+
return c
|
| 690 |
+
|
| 691 |
+
prd = np.empty(len(c) + 1, dtype=c.dtype)
|
| 692 |
+
prd[0] = c[0]*0
|
| 693 |
+
prd[1] = c[0]
|
| 694 |
+
if len(c) > 1:
|
| 695 |
+
tmp = c[1:]/2
|
| 696 |
+
prd[2:] = tmp
|
| 697 |
+
prd[0:-2] += tmp
|
| 698 |
+
return prd
|
| 699 |
+
|
| 700 |
+
|
| 701 |
+
def chebmul(c1, c2):
|
| 702 |
+
"""
|
| 703 |
+
Multiply one Chebyshev series by another.
|
| 704 |
+
|
| 705 |
+
Returns the product of two Chebyshev series `c1` * `c2`. The arguments
|
| 706 |
+
are sequences of coefficients, from lowest order "term" to highest,
|
| 707 |
+
e.g., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``.
|
| 708 |
+
|
| 709 |
+
Parameters
|
| 710 |
+
----------
|
| 711 |
+
c1, c2 : array_like
|
| 712 |
+
1-D arrays of Chebyshev series coefficients ordered from low to
|
| 713 |
+
high.
|
| 714 |
+
|
| 715 |
+
Returns
|
| 716 |
+
-------
|
| 717 |
+
out : ndarray
|
| 718 |
+
Of Chebyshev series coefficients representing their product.
|
| 719 |
+
|
| 720 |
+
See Also
|
| 721 |
+
--------
|
| 722 |
+
chebadd, chebsub, chebmulx, chebdiv, chebpow
|
| 723 |
+
|
| 724 |
+
Notes
|
| 725 |
+
-----
|
| 726 |
+
In general, the (polynomial) product of two C-series results in terms
|
| 727 |
+
that are not in the Chebyshev polynomial basis set. Thus, to express
|
| 728 |
+
the product as a C-series, it is typically necessary to "reproject"
|
| 729 |
+
the product onto said basis set, which typically produces
|
| 730 |
+
"unintuitive live" (but correct) results; see Examples section below.
|
| 731 |
+
|
| 732 |
+
Examples
|
| 733 |
+
--------
|
| 734 |
+
>>> from numpy.polynomial import chebyshev as C
|
| 735 |
+
>>> c1 = (1,2,3)
|
| 736 |
+
>>> c2 = (3,2,1)
|
| 737 |
+
>>> C.chebmul(c1,c2) # multiplication requires "reprojection"
|
| 738 |
+
array([ 6.5, 12. , 12. , 4. , 1.5])
|
| 739 |
+
|
| 740 |
+
"""
|
| 741 |
+
# c1, c2 are trimmed copies
|
| 742 |
+
[c1, c2] = pu.as_series([c1, c2])
|
| 743 |
+
z1 = _cseries_to_zseries(c1)
|
| 744 |
+
z2 = _cseries_to_zseries(c2)
|
| 745 |
+
prd = _zseries_mul(z1, z2)
|
| 746 |
+
ret = _zseries_to_cseries(prd)
|
| 747 |
+
return pu.trimseq(ret)
|
| 748 |
+
|
| 749 |
+
|
| 750 |
+
def chebdiv(c1, c2):
|
| 751 |
+
"""
|
| 752 |
+
Divide one Chebyshev series by another.
|
| 753 |
+
|
| 754 |
+
Returns the quotient-with-remainder of two Chebyshev series
|
| 755 |
+
`c1` / `c2`. The arguments are sequences of coefficients from lowest
|
| 756 |
+
order "term" to highest, e.g., [1,2,3] represents the series
|
| 757 |
+
``T_0 + 2*T_1 + 3*T_2``.
|
| 758 |
+
|
| 759 |
+
Parameters
|
| 760 |
+
----------
|
| 761 |
+
c1, c2 : array_like
|
| 762 |
+
1-D arrays of Chebyshev series coefficients ordered from low to
|
| 763 |
+
high.
|
| 764 |
+
|
| 765 |
+
Returns
|
| 766 |
+
-------
|
| 767 |
+
[quo, rem] : ndarrays
|
| 768 |
+
Of Chebyshev series coefficients representing the quotient and
|
| 769 |
+
remainder.
|
| 770 |
+
|
| 771 |
+
See Also
|
| 772 |
+
--------
|
| 773 |
+
chebadd, chebsub, chebmulx, chebmul, chebpow
|
| 774 |
+
|
| 775 |
+
Notes
|
| 776 |
+
-----
|
| 777 |
+
In general, the (polynomial) division of one C-series by another
|
| 778 |
+
results in quotient and remainder terms that are not in the Chebyshev
|
| 779 |
+
polynomial basis set. Thus, to express these results as C-series, it
|
| 780 |
+
is typically necessary to "reproject" the results onto said basis
|
| 781 |
+
set, which typically produces "unintuitive" (but correct) results;
|
| 782 |
+
see Examples section below.
|
| 783 |
+
|
| 784 |
+
Examples
|
| 785 |
+
--------
|
| 786 |
+
>>> from numpy.polynomial import chebyshev as C
|
| 787 |
+
>>> c1 = (1,2,3)
|
| 788 |
+
>>> c2 = (3,2,1)
|
| 789 |
+
>>> C.chebdiv(c1,c2) # quotient "intuitive," remainder not
|
| 790 |
+
(array([3.]), array([-8., -4.]))
|
| 791 |
+
>>> c2 = (0,1,2,3)
|
| 792 |
+
>>> C.chebdiv(c2,c1) # neither "intuitive"
|
| 793 |
+
(array([0., 2.]), array([-2., -4.]))
|
| 794 |
+
|
| 795 |
+
"""
|
| 796 |
+
# c1, c2 are trimmed copies
|
| 797 |
+
[c1, c2] = pu.as_series([c1, c2])
|
| 798 |
+
if c2[-1] == 0:
|
| 799 |
+
raise ZeroDivisionError()
|
| 800 |
+
|
| 801 |
+
# note: this is more efficient than `pu._div(chebmul, c1, c2)`
|
| 802 |
+
lc1 = len(c1)
|
| 803 |
+
lc2 = len(c2)
|
| 804 |
+
if lc1 < lc2:
|
| 805 |
+
return c1[:1]*0, c1
|
| 806 |
+
elif lc2 == 1:
|
| 807 |
+
return c1/c2[-1], c1[:1]*0
|
| 808 |
+
else:
|
| 809 |
+
z1 = _cseries_to_zseries(c1)
|
| 810 |
+
z2 = _cseries_to_zseries(c2)
|
| 811 |
+
quo, rem = _zseries_div(z1, z2)
|
| 812 |
+
quo = pu.trimseq(_zseries_to_cseries(quo))
|
| 813 |
+
rem = pu.trimseq(_zseries_to_cseries(rem))
|
| 814 |
+
return quo, rem
|
| 815 |
+
|
| 816 |
+
|
| 817 |
+
def chebpow(c, pow, maxpower=16):
|
| 818 |
+
"""Raise a Chebyshev series to a power.
|
| 819 |
+
|
| 820 |
+
Returns the Chebyshev series `c` raised to the power `pow`. The
|
| 821 |
+
argument `c` is a sequence of coefficients ordered from low to high.
|
| 822 |
+
i.e., [1,2,3] is the series ``T_0 + 2*T_1 + 3*T_2.``
|
| 823 |
+
|
| 824 |
+
Parameters
|
| 825 |
+
----------
|
| 826 |
+
c : array_like
|
| 827 |
+
1-D array of Chebyshev series coefficients ordered from low to
|
| 828 |
+
high.
|
| 829 |
+
pow : integer
|
| 830 |
+
Power to which the series will be raised
|
| 831 |
+
maxpower : integer, optional
|
| 832 |
+
Maximum power allowed. This is mainly to limit growth of the series
|
| 833 |
+
to unmanageable size. Default is 16
|
| 834 |
+
|
| 835 |
+
Returns
|
| 836 |
+
-------
|
| 837 |
+
coef : ndarray
|
| 838 |
+
Chebyshev series of power.
|
| 839 |
+
|
| 840 |
+
See Also
|
| 841 |
+
--------
|
| 842 |
+
chebadd, chebsub, chebmulx, chebmul, chebdiv
|
| 843 |
+
|
| 844 |
+
Examples
|
| 845 |
+
--------
|
| 846 |
+
>>> from numpy.polynomial import chebyshev as C
|
| 847 |
+
>>> C.chebpow([1, 2, 3, 4], 2)
|
| 848 |
+
array([15.5, 22. , 16. , ..., 12.5, 12. , 8. ])
|
| 849 |
+
|
| 850 |
+
"""
|
| 851 |
+
# note: this is more efficient than `pu._pow(chebmul, c1, c2)`, as it
|
| 852 |
+
# avoids converting between z and c series repeatedly
|
| 853 |
+
|
| 854 |
+
# c is a trimmed copy
|
| 855 |
+
[c] = pu.as_series([c])
|
| 856 |
+
power = int(pow)
|
| 857 |
+
if power != pow or power < 0:
|
| 858 |
+
raise ValueError("Power must be a non-negative integer.")
|
| 859 |
+
elif maxpower is not None and power > maxpower:
|
| 860 |
+
raise ValueError("Power is too large")
|
| 861 |
+
elif power == 0:
|
| 862 |
+
return np.array([1], dtype=c.dtype)
|
| 863 |
+
elif power == 1:
|
| 864 |
+
return c
|
| 865 |
+
else:
|
| 866 |
+
# This can be made more efficient by using powers of two
|
| 867 |
+
# in the usual way.
|
| 868 |
+
zs = _cseries_to_zseries(c)
|
| 869 |
+
prd = zs
|
| 870 |
+
for i in range(2, power + 1):
|
| 871 |
+
prd = np.convolve(prd, zs)
|
| 872 |
+
return _zseries_to_cseries(prd)
|
| 873 |
+
|
| 874 |
+
|
| 875 |
+
def chebder(c, m=1, scl=1, axis=0):
|
| 876 |
+
"""
|
| 877 |
+
Differentiate a Chebyshev series.
|
| 878 |
+
|
| 879 |
+
Returns the Chebyshev series coefficients `c` differentiated `m` times
|
| 880 |
+
along `axis`. At each iteration the result is multiplied by `scl` (the
|
| 881 |
+
scaling factor is for use in a linear change of variable). The argument
|
| 882 |
+
`c` is an array of coefficients from low to high degree along each
|
| 883 |
+
axis, e.g., [1,2,3] represents the series ``1*T_0 + 2*T_1 + 3*T_2``
|
| 884 |
+
while [[1,2],[1,2]] represents ``1*T_0(x)*T_0(y) + 1*T_1(x)*T_0(y) +
|
| 885 |
+
2*T_0(x)*T_1(y) + 2*T_1(x)*T_1(y)`` if axis=0 is ``x`` and axis=1 is
|
| 886 |
+
``y``.
|
| 887 |
+
|
| 888 |
+
Parameters
|
| 889 |
+
----------
|
| 890 |
+
c : array_like
|
| 891 |
+
Array of Chebyshev series coefficients. If c is multidimensional
|
| 892 |
+
the different axis correspond to different variables with the
|
| 893 |
+
degree in each axis given by the corresponding index.
|
| 894 |
+
m : int, optional
|
| 895 |
+
Number of derivatives taken, must be non-negative. (Default: 1)
|
| 896 |
+
scl : scalar, optional
|
| 897 |
+
Each differentiation is multiplied by `scl`. The end result is
|
| 898 |
+
multiplication by ``scl**m``. This is for use in a linear change of
|
| 899 |
+
variable. (Default: 1)
|
| 900 |
+
axis : int, optional
|
| 901 |
+
Axis over which the derivative is taken. (Default: 0).
|
| 902 |
+
|
| 903 |
+
.. versionadded:: 1.7.0
|
| 904 |
+
|
| 905 |
+
Returns
|
| 906 |
+
-------
|
| 907 |
+
der : ndarray
|
| 908 |
+
Chebyshev series of the derivative.
|
| 909 |
+
|
| 910 |
+
See Also
|
| 911 |
+
--------
|
| 912 |
+
chebint
|
| 913 |
+
|
| 914 |
+
Notes
|
| 915 |
+
-----
|
| 916 |
+
In general, the result of differentiating a C-series needs to be
|
| 917 |
+
"reprojected" onto the C-series basis set. Thus, typically, the
|
| 918 |
+
result of this function is "unintuitive," albeit correct; see Examples
|
| 919 |
+
section below.
|
| 920 |
+
|
| 921 |
+
Examples
|
| 922 |
+
--------
|
| 923 |
+
>>> from numpy.polynomial import chebyshev as C
|
| 924 |
+
>>> c = (1,2,3,4)
|
| 925 |
+
>>> C.chebder(c)
|
| 926 |
+
array([14., 12., 24.])
|
| 927 |
+
>>> C.chebder(c,3)
|
| 928 |
+
array([96.])
|
| 929 |
+
>>> C.chebder(c,scl=-1)
|
| 930 |
+
array([-14., -12., -24.])
|
| 931 |
+
>>> C.chebder(c,2,-1)
|
| 932 |
+
array([12., 96.])
|
| 933 |
+
|
| 934 |
+
"""
|
| 935 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 936 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 937 |
+
c = c.astype(np.double)
|
| 938 |
+
cnt = pu._deprecate_as_int(m, "the order of derivation")
|
| 939 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 940 |
+
if cnt < 0:
|
| 941 |
+
raise ValueError("The order of derivation must be non-negative")
|
| 942 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 943 |
+
|
| 944 |
+
if cnt == 0:
|
| 945 |
+
return c
|
| 946 |
+
|
| 947 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 948 |
+
n = len(c)
|
| 949 |
+
if cnt >= n:
|
| 950 |
+
c = c[:1]*0
|
| 951 |
+
else:
|
| 952 |
+
for i in range(cnt):
|
| 953 |
+
n = n - 1
|
| 954 |
+
c *= scl
|
| 955 |
+
der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
|
| 956 |
+
for j in range(n, 2, -1):
|
| 957 |
+
der[j - 1] = (2*j)*c[j]
|
| 958 |
+
c[j - 2] += (j*c[j])/(j - 2)
|
| 959 |
+
if n > 1:
|
| 960 |
+
der[1] = 4*c[2]
|
| 961 |
+
der[0] = c[1]
|
| 962 |
+
c = der
|
| 963 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 964 |
+
return c
|
| 965 |
+
|
| 966 |
+
|
| 967 |
+
def chebint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
|
| 968 |
+
"""
|
| 969 |
+
Integrate a Chebyshev series.
|
| 970 |
+
|
| 971 |
+
Returns the Chebyshev series coefficients `c` integrated `m` times from
|
| 972 |
+
`lbnd` along `axis`. At each iteration the resulting series is
|
| 973 |
+
**multiplied** by `scl` and an integration constant, `k`, is added.
|
| 974 |
+
The scaling factor is for use in a linear change of variable. ("Buyer
|
| 975 |
+
beware": note that, depending on what one is doing, one may want `scl`
|
| 976 |
+
to be the reciprocal of what one might expect; for more information,
|
| 977 |
+
see the Notes section below.) The argument `c` is an array of
|
| 978 |
+
coefficients from low to high degree along each axis, e.g., [1,2,3]
|
| 979 |
+
represents the series ``T_0 + 2*T_1 + 3*T_2`` while [[1,2],[1,2]]
|
| 980 |
+
represents ``1*T_0(x)*T_0(y) + 1*T_1(x)*T_0(y) + 2*T_0(x)*T_1(y) +
|
| 981 |
+
2*T_1(x)*T_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
|
| 982 |
+
|
| 983 |
+
Parameters
|
| 984 |
+
----------
|
| 985 |
+
c : array_like
|
| 986 |
+
Array of Chebyshev series coefficients. If c is multidimensional
|
| 987 |
+
the different axis correspond to different variables with the
|
| 988 |
+
degree in each axis given by the corresponding index.
|
| 989 |
+
m : int, optional
|
| 990 |
+
Order of integration, must be positive. (Default: 1)
|
| 991 |
+
k : {[], list, scalar}, optional
|
| 992 |
+
Integration constant(s). The value of the first integral at zero
|
| 993 |
+
is the first value in the list, the value of the second integral
|
| 994 |
+
at zero is the second value, etc. If ``k == []`` (the default),
|
| 995 |
+
all constants are set to zero. If ``m == 1``, a single scalar can
|
| 996 |
+
be given instead of a list.
|
| 997 |
+
lbnd : scalar, optional
|
| 998 |
+
The lower bound of the integral. (Default: 0)
|
| 999 |
+
scl : scalar, optional
|
| 1000 |
+
Following each integration the result is *multiplied* by `scl`
|
| 1001 |
+
before the integration constant is added. (Default: 1)
|
| 1002 |
+
axis : int, optional
|
| 1003 |
+
Axis over which the integral is taken. (Default: 0).
|
| 1004 |
+
|
| 1005 |
+
.. versionadded:: 1.7.0
|
| 1006 |
+
|
| 1007 |
+
Returns
|
| 1008 |
+
-------
|
| 1009 |
+
S : ndarray
|
| 1010 |
+
C-series coefficients of the integral.
|
| 1011 |
+
|
| 1012 |
+
Raises
|
| 1013 |
+
------
|
| 1014 |
+
ValueError
|
| 1015 |
+
If ``m < 1``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or
|
| 1016 |
+
``np.ndim(scl) != 0``.
|
| 1017 |
+
|
| 1018 |
+
See Also
|
| 1019 |
+
--------
|
| 1020 |
+
chebder
|
| 1021 |
+
|
| 1022 |
+
Notes
|
| 1023 |
+
-----
|
| 1024 |
+
Note that the result of each integration is *multiplied* by `scl`.
|
| 1025 |
+
Why is this important to note? Say one is making a linear change of
|
| 1026 |
+
variable :math:`u = ax + b` in an integral relative to `x`. Then
|
| 1027 |
+
:math:`dx = du/a`, so one will need to set `scl` equal to
|
| 1028 |
+
:math:`1/a`- perhaps not what one would have first thought.
|
| 1029 |
+
|
| 1030 |
+
Also note that, in general, the result of integrating a C-series needs
|
| 1031 |
+
to be "reprojected" onto the C-series basis set. Thus, typically,
|
| 1032 |
+
the result of this function is "unintuitive," albeit correct; see
|
| 1033 |
+
Examples section below.
|
| 1034 |
+
|
| 1035 |
+
Examples
|
| 1036 |
+
--------
|
| 1037 |
+
>>> from numpy.polynomial import chebyshev as C
|
| 1038 |
+
>>> c = (1,2,3)
|
| 1039 |
+
>>> C.chebint(c)
|
| 1040 |
+
array([ 0.5, -0.5, 0.5, 0.5])
|
| 1041 |
+
>>> C.chebint(c,3)
|
| 1042 |
+
array([ 0.03125 , -0.1875 , 0.04166667, -0.05208333, 0.01041667, # may vary
|
| 1043 |
+
0.00625 ])
|
| 1044 |
+
>>> C.chebint(c, k=3)
|
| 1045 |
+
array([ 3.5, -0.5, 0.5, 0.5])
|
| 1046 |
+
>>> C.chebint(c,lbnd=-2)
|
| 1047 |
+
array([ 8.5, -0.5, 0.5, 0.5])
|
| 1048 |
+
>>> C.chebint(c,scl=-2)
|
| 1049 |
+
array([-1., 1., -1., -1.])
|
| 1050 |
+
|
| 1051 |
+
"""
|
| 1052 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 1053 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 1054 |
+
c = c.astype(np.double)
|
| 1055 |
+
if not np.iterable(k):
|
| 1056 |
+
k = [k]
|
| 1057 |
+
cnt = pu._deprecate_as_int(m, "the order of integration")
|
| 1058 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 1059 |
+
if cnt < 0:
|
| 1060 |
+
raise ValueError("The order of integration must be non-negative")
|
| 1061 |
+
if len(k) > cnt:
|
| 1062 |
+
raise ValueError("Too many integration constants")
|
| 1063 |
+
if np.ndim(lbnd) != 0:
|
| 1064 |
+
raise ValueError("lbnd must be a scalar.")
|
| 1065 |
+
if np.ndim(scl) != 0:
|
| 1066 |
+
raise ValueError("scl must be a scalar.")
|
| 1067 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 1068 |
+
|
| 1069 |
+
if cnt == 0:
|
| 1070 |
+
return c
|
| 1071 |
+
|
| 1072 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 1073 |
+
k = list(k) + [0]*(cnt - len(k))
|
| 1074 |
+
for i in range(cnt):
|
| 1075 |
+
n = len(c)
|
| 1076 |
+
c *= scl
|
| 1077 |
+
if n == 1 and np.all(c[0] == 0):
|
| 1078 |
+
c[0] += k[i]
|
| 1079 |
+
else:
|
| 1080 |
+
tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
|
| 1081 |
+
tmp[0] = c[0]*0
|
| 1082 |
+
tmp[1] = c[0]
|
| 1083 |
+
if n > 1:
|
| 1084 |
+
tmp[2] = c[1]/4
|
| 1085 |
+
for j in range(2, n):
|
| 1086 |
+
tmp[j + 1] = c[j]/(2*(j + 1))
|
| 1087 |
+
tmp[j - 1] -= c[j]/(2*(j - 1))
|
| 1088 |
+
tmp[0] += k[i] - chebval(lbnd, tmp)
|
| 1089 |
+
c = tmp
|
| 1090 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 1091 |
+
return c
|
| 1092 |
+
|
| 1093 |
+
|
| 1094 |
+
def chebval(x, c, tensor=True):
|
| 1095 |
+
"""
|
| 1096 |
+
Evaluate a Chebyshev series at points x.
|
| 1097 |
+
|
| 1098 |
+
If `c` is of length `n + 1`, this function returns the value:
|
| 1099 |
+
|
| 1100 |
+
.. math:: p(x) = c_0 * T_0(x) + c_1 * T_1(x) + ... + c_n * T_n(x)
|
| 1101 |
+
|
| 1102 |
+
The parameter `x` is converted to an array only if it is a tuple or a
|
| 1103 |
+
list, otherwise it is treated as a scalar. In either case, either `x`
|
| 1104 |
+
or its elements must support multiplication and addition both with
|
| 1105 |
+
themselves and with the elements of `c`.
|
| 1106 |
+
|
| 1107 |
+
If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If
|
| 1108 |
+
`c` is multidimensional, then the shape of the result depends on the
|
| 1109 |
+
value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
|
| 1110 |
+
x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
|
| 1111 |
+
scalars have shape (,).
|
| 1112 |
+
|
| 1113 |
+
Trailing zeros in the coefficients will be used in the evaluation, so
|
| 1114 |
+
they should be avoided if efficiency is a concern.
|
| 1115 |
+
|
| 1116 |
+
Parameters
|
| 1117 |
+
----------
|
| 1118 |
+
x : array_like, compatible object
|
| 1119 |
+
If `x` is a list or tuple, it is converted to an ndarray, otherwise
|
| 1120 |
+
it is left unchanged and treated as a scalar. In either case, `x`
|
| 1121 |
+
or its elements must support addition and multiplication with
|
| 1122 |
+
themselves and with the elements of `c`.
|
| 1123 |
+
c : array_like
|
| 1124 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 1125 |
+
degree n are contained in c[n]. If `c` is multidimensional the
|
| 1126 |
+
remaining indices enumerate multiple polynomials. In the two
|
| 1127 |
+
dimensional case the coefficients may be thought of as stored in
|
| 1128 |
+
the columns of `c`.
|
| 1129 |
+
tensor : boolean, optional
|
| 1130 |
+
If True, the shape of the coefficient array is extended with ones
|
| 1131 |
+
on the right, one for each dimension of `x`. Scalars have dimension 0
|
| 1132 |
+
for this action. The result is that every column of coefficients in
|
| 1133 |
+
`c` is evaluated for every element of `x`. If False, `x` is broadcast
|
| 1134 |
+
over the columns of `c` for the evaluation. This keyword is useful
|
| 1135 |
+
when `c` is multidimensional. The default value is True.
|
| 1136 |
+
|
| 1137 |
+
.. versionadded:: 1.7.0
|
| 1138 |
+
|
| 1139 |
+
Returns
|
| 1140 |
+
-------
|
| 1141 |
+
values : ndarray, algebra_like
|
| 1142 |
+
The shape of the return value is described above.
|
| 1143 |
+
|
| 1144 |
+
See Also
|
| 1145 |
+
--------
|
| 1146 |
+
chebval2d, chebgrid2d, chebval3d, chebgrid3d
|
| 1147 |
+
|
| 1148 |
+
Notes
|
| 1149 |
+
-----
|
| 1150 |
+
The evaluation uses Clenshaw recursion, aka synthetic division.
|
| 1151 |
+
|
| 1152 |
+
"""
|
| 1153 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 1154 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 1155 |
+
c = c.astype(np.double)
|
| 1156 |
+
if isinstance(x, (tuple, list)):
|
| 1157 |
+
x = np.asarray(x)
|
| 1158 |
+
if isinstance(x, np.ndarray) and tensor:
|
| 1159 |
+
c = c.reshape(c.shape + (1,)*x.ndim)
|
| 1160 |
+
|
| 1161 |
+
if len(c) == 1:
|
| 1162 |
+
c0 = c[0]
|
| 1163 |
+
c1 = 0
|
| 1164 |
+
elif len(c) == 2:
|
| 1165 |
+
c0 = c[0]
|
| 1166 |
+
c1 = c[1]
|
| 1167 |
+
else:
|
| 1168 |
+
x2 = 2*x
|
| 1169 |
+
c0 = c[-2]
|
| 1170 |
+
c1 = c[-1]
|
| 1171 |
+
for i in range(3, len(c) + 1):
|
| 1172 |
+
tmp = c0
|
| 1173 |
+
c0 = c[-i] - c1
|
| 1174 |
+
c1 = tmp + c1*x2
|
| 1175 |
+
return c0 + c1*x
|
| 1176 |
+
|
| 1177 |
+
|
| 1178 |
+
def chebval2d(x, y, c):
|
| 1179 |
+
"""
|
| 1180 |
+
Evaluate a 2-D Chebyshev series at points (x, y).
|
| 1181 |
+
|
| 1182 |
+
This function returns the values:
|
| 1183 |
+
|
| 1184 |
+
.. math:: p(x,y) = \\sum_{i,j} c_{i,j} * T_i(x) * T_j(y)
|
| 1185 |
+
|
| 1186 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 1187 |
+
tuples or a lists, otherwise they are treated as a scalars and they
|
| 1188 |
+
must have the same shape after conversion. In either case, either `x`
|
| 1189 |
+
and `y` or their elements must support multiplication and addition both
|
| 1190 |
+
with themselves and with the elements of `c`.
|
| 1191 |
+
|
| 1192 |
+
If `c` is a 1-D array a one is implicitly appended to its shape to make
|
| 1193 |
+
it 2-D. The shape of the result will be c.shape[2:] + x.shape.
|
| 1194 |
+
|
| 1195 |
+
Parameters
|
| 1196 |
+
----------
|
| 1197 |
+
x, y : array_like, compatible objects
|
| 1198 |
+
The two dimensional series is evaluated at the points `(x, y)`,
|
| 1199 |
+
where `x` and `y` must have the same shape. If `x` or `y` is a list
|
| 1200 |
+
or tuple, it is first converted to an ndarray, otherwise it is left
|
| 1201 |
+
unchanged and if it isn't an ndarray it is treated as a scalar.
|
| 1202 |
+
c : array_like
|
| 1203 |
+
Array of coefficients ordered so that the coefficient of the term
|
| 1204 |
+
of multi-degree i,j is contained in ``c[i,j]``. If `c` has
|
| 1205 |
+
dimension greater than 2 the remaining indices enumerate multiple
|
| 1206 |
+
sets of coefficients.
|
| 1207 |
+
|
| 1208 |
+
Returns
|
| 1209 |
+
-------
|
| 1210 |
+
values : ndarray, compatible object
|
| 1211 |
+
The values of the two dimensional Chebyshev series at points formed
|
| 1212 |
+
from pairs of corresponding values from `x` and `y`.
|
| 1213 |
+
|
| 1214 |
+
See Also
|
| 1215 |
+
--------
|
| 1216 |
+
chebval, chebgrid2d, chebval3d, chebgrid3d
|
| 1217 |
+
|
| 1218 |
+
Notes
|
| 1219 |
+
-----
|
| 1220 |
+
|
| 1221 |
+
.. versionadded:: 1.7.0
|
| 1222 |
+
|
| 1223 |
+
"""
|
| 1224 |
+
return pu._valnd(chebval, c, x, y)
|
| 1225 |
+
|
| 1226 |
+
|
| 1227 |
+
def chebgrid2d(x, y, c):
|
| 1228 |
+
"""
|
| 1229 |
+
Evaluate a 2-D Chebyshev series on the Cartesian product of x and y.
|
| 1230 |
+
|
| 1231 |
+
This function returns the values:
|
| 1232 |
+
|
| 1233 |
+
.. math:: p(a,b) = \\sum_{i,j} c_{i,j} * T_i(a) * T_j(b),
|
| 1234 |
+
|
| 1235 |
+
where the points `(a, b)` consist of all pairs formed by taking
|
| 1236 |
+
`a` from `x` and `b` from `y`. The resulting points form a grid with
|
| 1237 |
+
`x` in the first dimension and `y` in the second.
|
| 1238 |
+
|
| 1239 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 1240 |
+
tuples or a lists, otherwise they are treated as a scalars. In either
|
| 1241 |
+
case, either `x` and `y` or their elements must support multiplication
|
| 1242 |
+
and addition both with themselves and with the elements of `c`.
|
| 1243 |
+
|
| 1244 |
+
If `c` has fewer than two dimensions, ones are implicitly appended to
|
| 1245 |
+
its shape to make it 2-D. The shape of the result will be c.shape[2:] +
|
| 1246 |
+
x.shape + y.shape.
|
| 1247 |
+
|
| 1248 |
+
Parameters
|
| 1249 |
+
----------
|
| 1250 |
+
x, y : array_like, compatible objects
|
| 1251 |
+
The two dimensional series is evaluated at the points in the
|
| 1252 |
+
Cartesian product of `x` and `y`. If `x` or `y` is a list or
|
| 1253 |
+
tuple, it is first converted to an ndarray, otherwise it is left
|
| 1254 |
+
unchanged and, if it isn't an ndarray, it is treated as a scalar.
|
| 1255 |
+
c : array_like
|
| 1256 |
+
Array of coefficients ordered so that the coefficient of the term of
|
| 1257 |
+
multi-degree i,j is contained in `c[i,j]`. If `c` has dimension
|
| 1258 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 1259 |
+
coefficients.
|
| 1260 |
+
|
| 1261 |
+
Returns
|
| 1262 |
+
-------
|
| 1263 |
+
values : ndarray, compatible object
|
| 1264 |
+
The values of the two dimensional Chebyshev series at points in the
|
| 1265 |
+
Cartesian product of `x` and `y`.
|
| 1266 |
+
|
| 1267 |
+
See Also
|
| 1268 |
+
--------
|
| 1269 |
+
chebval, chebval2d, chebval3d, chebgrid3d
|
| 1270 |
+
|
| 1271 |
+
Notes
|
| 1272 |
+
-----
|
| 1273 |
+
|
| 1274 |
+
.. versionadded:: 1.7.0
|
| 1275 |
+
|
| 1276 |
+
"""
|
| 1277 |
+
return pu._gridnd(chebval, c, x, y)
|
| 1278 |
+
|
| 1279 |
+
|
| 1280 |
+
def chebval3d(x, y, z, c):
|
| 1281 |
+
"""
|
| 1282 |
+
Evaluate a 3-D Chebyshev series at points (x, y, z).
|
| 1283 |
+
|
| 1284 |
+
This function returns the values:
|
| 1285 |
+
|
| 1286 |
+
.. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * T_i(x) * T_j(y) * T_k(z)
|
| 1287 |
+
|
| 1288 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if
|
| 1289 |
+
they are tuples or a lists, otherwise they are treated as a scalars and
|
| 1290 |
+
they must have the same shape after conversion. In either case, either
|
| 1291 |
+
`x`, `y`, and `z` or their elements must support multiplication and
|
| 1292 |
+
addition both with themselves and with the elements of `c`.
|
| 1293 |
+
|
| 1294 |
+
If `c` has fewer than 3 dimensions, ones are implicitly appended to its
|
| 1295 |
+
shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1296 |
+
x.shape.
|
| 1297 |
+
|
| 1298 |
+
Parameters
|
| 1299 |
+
----------
|
| 1300 |
+
x, y, z : array_like, compatible object
|
| 1301 |
+
The three dimensional series is evaluated at the points
|
| 1302 |
+
`(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If
|
| 1303 |
+
any of `x`, `y`, or `z` is a list or tuple, it is first converted
|
| 1304 |
+
to an ndarray, otherwise it is left unchanged and if it isn't an
|
| 1305 |
+
ndarray it is treated as a scalar.
|
| 1306 |
+
c : array_like
|
| 1307 |
+
Array of coefficients ordered so that the coefficient of the term of
|
| 1308 |
+
multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
|
| 1309 |
+
greater than 3 the remaining indices enumerate multiple sets of
|
| 1310 |
+
coefficients.
|
| 1311 |
+
|
| 1312 |
+
Returns
|
| 1313 |
+
-------
|
| 1314 |
+
values : ndarray, compatible object
|
| 1315 |
+
The values of the multidimensional polynomial on points formed with
|
| 1316 |
+
triples of corresponding values from `x`, `y`, and `z`.
|
| 1317 |
+
|
| 1318 |
+
See Also
|
| 1319 |
+
--------
|
| 1320 |
+
chebval, chebval2d, chebgrid2d, chebgrid3d
|
| 1321 |
+
|
| 1322 |
+
Notes
|
| 1323 |
+
-----
|
| 1324 |
+
|
| 1325 |
+
.. versionadded:: 1.7.0
|
| 1326 |
+
|
| 1327 |
+
"""
|
| 1328 |
+
return pu._valnd(chebval, c, x, y, z)
|
| 1329 |
+
|
| 1330 |
+
|
| 1331 |
+
def chebgrid3d(x, y, z, c):
|
| 1332 |
+
"""
|
| 1333 |
+
Evaluate a 3-D Chebyshev series on the Cartesian product of x, y, and z.
|
| 1334 |
+
|
| 1335 |
+
This function returns the values:
|
| 1336 |
+
|
| 1337 |
+
.. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * T_i(a) * T_j(b) * T_k(c)
|
| 1338 |
+
|
| 1339 |
+
where the points `(a, b, c)` consist of all triples formed by taking
|
| 1340 |
+
`a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
|
| 1341 |
+
a grid with `x` in the first dimension, `y` in the second, and `z` in
|
| 1342 |
+
the third.
|
| 1343 |
+
|
| 1344 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if they
|
| 1345 |
+
are tuples or a lists, otherwise they are treated as a scalars. In
|
| 1346 |
+
either case, either `x`, `y`, and `z` or their elements must support
|
| 1347 |
+
multiplication and addition both with themselves and with the elements
|
| 1348 |
+
of `c`.
|
| 1349 |
+
|
| 1350 |
+
If `c` has fewer than three dimensions, ones are implicitly appended to
|
| 1351 |
+
its shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1352 |
+
x.shape + y.shape + z.shape.
|
| 1353 |
+
|
| 1354 |
+
Parameters
|
| 1355 |
+
----------
|
| 1356 |
+
x, y, z : array_like, compatible objects
|
| 1357 |
+
The three dimensional series is evaluated at the points in the
|
| 1358 |
+
Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a
|
| 1359 |
+
list or tuple, it is first converted to an ndarray, otherwise it is
|
| 1360 |
+
left unchanged and, if it isn't an ndarray, it is treated as a
|
| 1361 |
+
scalar.
|
| 1362 |
+
c : array_like
|
| 1363 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 1364 |
+
degree i,j are contained in ``c[i,j]``. If `c` has dimension
|
| 1365 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 1366 |
+
coefficients.
|
| 1367 |
+
|
| 1368 |
+
Returns
|
| 1369 |
+
-------
|
| 1370 |
+
values : ndarray, compatible object
|
| 1371 |
+
The values of the two dimensional polynomial at points in the Cartesian
|
| 1372 |
+
product of `x` and `y`.
|
| 1373 |
+
|
| 1374 |
+
See Also
|
| 1375 |
+
--------
|
| 1376 |
+
chebval, chebval2d, chebgrid2d, chebval3d
|
| 1377 |
+
|
| 1378 |
+
Notes
|
| 1379 |
+
-----
|
| 1380 |
+
|
| 1381 |
+
.. versionadded:: 1.7.0
|
| 1382 |
+
|
| 1383 |
+
"""
|
| 1384 |
+
return pu._gridnd(chebval, c, x, y, z)
|
| 1385 |
+
|
| 1386 |
+
|
| 1387 |
+
def chebvander(x, deg):
|
| 1388 |
+
"""Pseudo-Vandermonde matrix of given degree.
|
| 1389 |
+
|
| 1390 |
+
Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
|
| 1391 |
+
`x`. The pseudo-Vandermonde matrix is defined by
|
| 1392 |
+
|
| 1393 |
+
.. math:: V[..., i] = T_i(x),
|
| 1394 |
+
|
| 1395 |
+
where `0 <= i <= deg`. The leading indices of `V` index the elements of
|
| 1396 |
+
`x` and the last index is the degree of the Chebyshev polynomial.
|
| 1397 |
+
|
| 1398 |
+
If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
|
| 1399 |
+
matrix ``V = chebvander(x, n)``, then ``np.dot(V, c)`` and
|
| 1400 |
+
``chebval(x, c)`` are the same up to roundoff. This equivalence is
|
| 1401 |
+
useful both for least squares fitting and for the evaluation of a large
|
| 1402 |
+
number of Chebyshev series of the same degree and sample points.
|
| 1403 |
+
|
| 1404 |
+
Parameters
|
| 1405 |
+
----------
|
| 1406 |
+
x : array_like
|
| 1407 |
+
Array of points. The dtype is converted to float64 or complex128
|
| 1408 |
+
depending on whether any of the elements are complex. If `x` is
|
| 1409 |
+
scalar it is converted to a 1-D array.
|
| 1410 |
+
deg : int
|
| 1411 |
+
Degree of the resulting matrix.
|
| 1412 |
+
|
| 1413 |
+
Returns
|
| 1414 |
+
-------
|
| 1415 |
+
vander : ndarray
|
| 1416 |
+
The pseudo Vandermonde matrix. The shape of the returned matrix is
|
| 1417 |
+
``x.shape + (deg + 1,)``, where The last index is the degree of the
|
| 1418 |
+
corresponding Chebyshev polynomial. The dtype will be the same as
|
| 1419 |
+
the converted `x`.
|
| 1420 |
+
|
| 1421 |
+
"""
|
| 1422 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1423 |
+
if ideg < 0:
|
| 1424 |
+
raise ValueError("deg must be non-negative")
|
| 1425 |
+
|
| 1426 |
+
x = np.array(x, copy=False, ndmin=1) + 0.0
|
| 1427 |
+
dims = (ideg + 1,) + x.shape
|
| 1428 |
+
dtyp = x.dtype
|
| 1429 |
+
v = np.empty(dims, dtype=dtyp)
|
| 1430 |
+
# Use forward recursion to generate the entries.
|
| 1431 |
+
v[0] = x*0 + 1
|
| 1432 |
+
if ideg > 0:
|
| 1433 |
+
x2 = 2*x
|
| 1434 |
+
v[1] = x
|
| 1435 |
+
for i in range(2, ideg + 1):
|
| 1436 |
+
v[i] = v[i-1]*x2 - v[i-2]
|
| 1437 |
+
return np.moveaxis(v, 0, -1)
|
| 1438 |
+
|
| 1439 |
+
|
| 1440 |
+
def chebvander2d(x, y, deg):
|
| 1441 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1442 |
+
|
| 1443 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1444 |
+
points `(x, y)`. The pseudo-Vandermonde matrix is defined by
|
| 1445 |
+
|
| 1446 |
+
.. math:: V[..., (deg[1] + 1)*i + j] = T_i(x) * T_j(y),
|
| 1447 |
+
|
| 1448 |
+
where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
|
| 1449 |
+
`V` index the points `(x, y)` and the last index encodes the degrees of
|
| 1450 |
+
the Chebyshev polynomials.
|
| 1451 |
+
|
| 1452 |
+
If ``V = chebvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
|
| 1453 |
+
correspond to the elements of a 2-D coefficient array `c` of shape
|
| 1454 |
+
(xdeg + 1, ydeg + 1) in the order
|
| 1455 |
+
|
| 1456 |
+
.. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
|
| 1457 |
+
|
| 1458 |
+
and ``np.dot(V, c.flat)`` and ``chebval2d(x, y, c)`` will be the same
|
| 1459 |
+
up to roundoff. This equivalence is useful both for least squares
|
| 1460 |
+
fitting and for the evaluation of a large number of 2-D Chebyshev
|
| 1461 |
+
series of the same degrees and sample points.
|
| 1462 |
+
|
| 1463 |
+
Parameters
|
| 1464 |
+
----------
|
| 1465 |
+
x, y : array_like
|
| 1466 |
+
Arrays of point coordinates, all of the same shape. The dtypes
|
| 1467 |
+
will be converted to either float64 or complex128 depending on
|
| 1468 |
+
whether any of the elements are complex. Scalars are converted to
|
| 1469 |
+
1-D arrays.
|
| 1470 |
+
deg : list of ints
|
| 1471 |
+
List of maximum degrees of the form [x_deg, y_deg].
|
| 1472 |
+
|
| 1473 |
+
Returns
|
| 1474 |
+
-------
|
| 1475 |
+
vander2d : ndarray
|
| 1476 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1477 |
+
:math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same
|
| 1478 |
+
as the converted `x` and `y`.
|
| 1479 |
+
|
| 1480 |
+
See Also
|
| 1481 |
+
--------
|
| 1482 |
+
chebvander, chebvander3d, chebval2d, chebval3d
|
| 1483 |
+
|
| 1484 |
+
Notes
|
| 1485 |
+
-----
|
| 1486 |
+
|
| 1487 |
+
.. versionadded:: 1.7.0
|
| 1488 |
+
|
| 1489 |
+
"""
|
| 1490 |
+
return pu._vander_nd_flat((chebvander, chebvander), (x, y), deg)
|
| 1491 |
+
|
| 1492 |
+
|
| 1493 |
+
def chebvander3d(x, y, z, deg):
|
| 1494 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1495 |
+
|
| 1496 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1497 |
+
points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
|
| 1498 |
+
then The pseudo-Vandermonde matrix is defined by
|
| 1499 |
+
|
| 1500 |
+
.. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = T_i(x)*T_j(y)*T_k(z),
|
| 1501 |
+
|
| 1502 |
+
where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading
|
| 1503 |
+
indices of `V` index the points `(x, y, z)` and the last index encodes
|
| 1504 |
+
the degrees of the Chebyshev polynomials.
|
| 1505 |
+
|
| 1506 |
+
If ``V = chebvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
|
| 1507 |
+
of `V` correspond to the elements of a 3-D coefficient array `c` of
|
| 1508 |
+
shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
|
| 1509 |
+
|
| 1510 |
+
.. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
|
| 1511 |
+
|
| 1512 |
+
and ``np.dot(V, c.flat)`` and ``chebval3d(x, y, z, c)`` will be the
|
| 1513 |
+
same up to roundoff. This equivalence is useful both for least squares
|
| 1514 |
+
fitting and for the evaluation of a large number of 3-D Chebyshev
|
| 1515 |
+
series of the same degrees and sample points.
|
| 1516 |
+
|
| 1517 |
+
Parameters
|
| 1518 |
+
----------
|
| 1519 |
+
x, y, z : array_like
|
| 1520 |
+
Arrays of point coordinates, all of the same shape. The dtypes will
|
| 1521 |
+
be converted to either float64 or complex128 depending on whether
|
| 1522 |
+
any of the elements are complex. Scalars are converted to 1-D
|
| 1523 |
+
arrays.
|
| 1524 |
+
deg : list of ints
|
| 1525 |
+
List of maximum degrees of the form [x_deg, y_deg, z_deg].
|
| 1526 |
+
|
| 1527 |
+
Returns
|
| 1528 |
+
-------
|
| 1529 |
+
vander3d : ndarray
|
| 1530 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1531 |
+
:math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will
|
| 1532 |
+
be the same as the converted `x`, `y`, and `z`.
|
| 1533 |
+
|
| 1534 |
+
See Also
|
| 1535 |
+
--------
|
| 1536 |
+
chebvander, chebvander3d, chebval2d, chebval3d
|
| 1537 |
+
|
| 1538 |
+
Notes
|
| 1539 |
+
-----
|
| 1540 |
+
|
| 1541 |
+
.. versionadded:: 1.7.0
|
| 1542 |
+
|
| 1543 |
+
"""
|
| 1544 |
+
return pu._vander_nd_flat((chebvander, chebvander, chebvander), (x, y, z), deg)
|
| 1545 |
+
|
| 1546 |
+
|
| 1547 |
+
def chebfit(x, y, deg, rcond=None, full=False, w=None):
|
| 1548 |
+
"""
|
| 1549 |
+
Least squares fit of Chebyshev series to data.
|
| 1550 |
+
|
| 1551 |
+
Return the coefficients of a Chebyshev series of degree `deg` that is the
|
| 1552 |
+
least squares fit to the data values `y` given at points `x`. If `y` is
|
| 1553 |
+
1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
|
| 1554 |
+
fits are done, one for each column of `y`, and the resulting
|
| 1555 |
+
coefficients are stored in the corresponding columns of a 2-D return.
|
| 1556 |
+
The fitted polynomial(s) are in the form
|
| 1557 |
+
|
| 1558 |
+
.. math:: p(x) = c_0 + c_1 * T_1(x) + ... + c_n * T_n(x),
|
| 1559 |
+
|
| 1560 |
+
where `n` is `deg`.
|
| 1561 |
+
|
| 1562 |
+
Parameters
|
| 1563 |
+
----------
|
| 1564 |
+
x : array_like, shape (M,)
|
| 1565 |
+
x-coordinates of the M sample points ``(x[i], y[i])``.
|
| 1566 |
+
y : array_like, shape (M,) or (M, K)
|
| 1567 |
+
y-coordinates of the sample points. Several data sets of sample
|
| 1568 |
+
points sharing the same x-coordinates can be fitted at once by
|
| 1569 |
+
passing in a 2D-array that contains one dataset per column.
|
| 1570 |
+
deg : int or 1-D array_like
|
| 1571 |
+
Degree(s) of the fitting polynomials. If `deg` is a single integer,
|
| 1572 |
+
all terms up to and including the `deg`'th term are included in the
|
| 1573 |
+
fit. For NumPy versions >= 1.11.0 a list of integers specifying the
|
| 1574 |
+
degrees of the terms to include may be used instead.
|
| 1575 |
+
rcond : float, optional
|
| 1576 |
+
Relative condition number of the fit. Singular values smaller than
|
| 1577 |
+
this relative to the largest singular value will be ignored. The
|
| 1578 |
+
default value is len(x)*eps, where eps is the relative precision of
|
| 1579 |
+
the float type, about 2e-16 in most cases.
|
| 1580 |
+
full : bool, optional
|
| 1581 |
+
Switch determining nature of return value. When it is False (the
|
| 1582 |
+
default) just the coefficients are returned, when True diagnostic
|
| 1583 |
+
information from the singular value decomposition is also returned.
|
| 1584 |
+
w : array_like, shape (`M`,), optional
|
| 1585 |
+
Weights. If not None, the weight ``w[i]`` applies to the unsquared
|
| 1586 |
+
residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
|
| 1587 |
+
chosen so that the errors of the products ``w[i]*y[i]`` all have the
|
| 1588 |
+
same variance. When using inverse-variance weighting, use
|
| 1589 |
+
``w[i] = 1/sigma(y[i])``. The default value is None.
|
| 1590 |
+
|
| 1591 |
+
.. versionadded:: 1.5.0
|
| 1592 |
+
|
| 1593 |
+
Returns
|
| 1594 |
+
-------
|
| 1595 |
+
coef : ndarray, shape (M,) or (M, K)
|
| 1596 |
+
Chebyshev coefficients ordered from low to high. If `y` was 2-D,
|
| 1597 |
+
the coefficients for the data in column k of `y` are in column
|
| 1598 |
+
`k`.
|
| 1599 |
+
|
| 1600 |
+
[residuals, rank, singular_values, rcond] : list
|
| 1601 |
+
These values are only returned if ``full == True``
|
| 1602 |
+
|
| 1603 |
+
- residuals -- sum of squared residuals of the least squares fit
|
| 1604 |
+
- rank -- the numerical rank of the scaled Vandermonde matrix
|
| 1605 |
+
- singular_values -- singular values of the scaled Vandermonde matrix
|
| 1606 |
+
- rcond -- value of `rcond`.
|
| 1607 |
+
|
| 1608 |
+
For more details, see `numpy.linalg.lstsq`.
|
| 1609 |
+
|
| 1610 |
+
Warns
|
| 1611 |
+
-----
|
| 1612 |
+
RankWarning
|
| 1613 |
+
The rank of the coefficient matrix in the least-squares fit is
|
| 1614 |
+
deficient. The warning is only raised if ``full == False``. The
|
| 1615 |
+
warnings can be turned off by
|
| 1616 |
+
|
| 1617 |
+
>>> import warnings
|
| 1618 |
+
>>> warnings.simplefilter('ignore', np.RankWarning)
|
| 1619 |
+
|
| 1620 |
+
See Also
|
| 1621 |
+
--------
|
| 1622 |
+
numpy.polynomial.polynomial.polyfit
|
| 1623 |
+
numpy.polynomial.legendre.legfit
|
| 1624 |
+
numpy.polynomial.laguerre.lagfit
|
| 1625 |
+
numpy.polynomial.hermite.hermfit
|
| 1626 |
+
numpy.polynomial.hermite_e.hermefit
|
| 1627 |
+
chebval : Evaluates a Chebyshev series.
|
| 1628 |
+
chebvander : Vandermonde matrix of Chebyshev series.
|
| 1629 |
+
chebweight : Chebyshev weight function.
|
| 1630 |
+
numpy.linalg.lstsq : Computes a least-squares fit from the matrix.
|
| 1631 |
+
scipy.interpolate.UnivariateSpline : Computes spline fits.
|
| 1632 |
+
|
| 1633 |
+
Notes
|
| 1634 |
+
-----
|
| 1635 |
+
The solution is the coefficients of the Chebyshev series `p` that
|
| 1636 |
+
minimizes the sum of the weighted squared errors
|
| 1637 |
+
|
| 1638 |
+
.. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
|
| 1639 |
+
|
| 1640 |
+
where :math:`w_j` are the weights. This problem is solved by setting up
|
| 1641 |
+
as the (typically) overdetermined matrix equation
|
| 1642 |
+
|
| 1643 |
+
.. math:: V(x) * c = w * y,
|
| 1644 |
+
|
| 1645 |
+
where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
|
| 1646 |
+
coefficients to be solved for, `w` are the weights, and `y` are the
|
| 1647 |
+
observed values. This equation is then solved using the singular value
|
| 1648 |
+
decomposition of `V`.
|
| 1649 |
+
|
| 1650 |
+
If some of the singular values of `V` are so small that they are
|
| 1651 |
+
neglected, then a `RankWarning` will be issued. This means that the
|
| 1652 |
+
coefficient values may be poorly determined. Using a lower order fit
|
| 1653 |
+
will usually get rid of the warning. The `rcond` parameter can also be
|
| 1654 |
+
set to a value smaller than its default, but the resulting fit may be
|
| 1655 |
+
spurious and have large contributions from roundoff error.
|
| 1656 |
+
|
| 1657 |
+
Fits using Chebyshev series are usually better conditioned than fits
|
| 1658 |
+
using power series, but much can depend on the distribution of the
|
| 1659 |
+
sample points and the smoothness of the data. If the quality of the fit
|
| 1660 |
+
is inadequate splines may be a good alternative.
|
| 1661 |
+
|
| 1662 |
+
References
|
| 1663 |
+
----------
|
| 1664 |
+
.. [1] Wikipedia, "Curve fitting",
|
| 1665 |
+
https://en.wikipedia.org/wiki/Curve_fitting
|
| 1666 |
+
|
| 1667 |
+
Examples
|
| 1668 |
+
--------
|
| 1669 |
+
|
| 1670 |
+
"""
|
| 1671 |
+
return pu._fit(chebvander, x, y, deg, rcond, full, w)
|
| 1672 |
+
|
| 1673 |
+
|
| 1674 |
+
def chebcompanion(c):
|
| 1675 |
+
"""Return the scaled companion matrix of c.
|
| 1676 |
+
|
| 1677 |
+
The basis polynomials are scaled so that the companion matrix is
|
| 1678 |
+
symmetric when `c` is a Chebyshev basis polynomial. This provides
|
| 1679 |
+
better eigenvalue estimates than the unscaled case and for basis
|
| 1680 |
+
polynomials the eigenvalues are guaranteed to be real if
|
| 1681 |
+
`numpy.linalg.eigvalsh` is used to obtain them.
|
| 1682 |
+
|
| 1683 |
+
Parameters
|
| 1684 |
+
----------
|
| 1685 |
+
c : array_like
|
| 1686 |
+
1-D array of Chebyshev series coefficients ordered from low to high
|
| 1687 |
+
degree.
|
| 1688 |
+
|
| 1689 |
+
Returns
|
| 1690 |
+
-------
|
| 1691 |
+
mat : ndarray
|
| 1692 |
+
Scaled companion matrix of dimensions (deg, deg).
|
| 1693 |
+
|
| 1694 |
+
Notes
|
| 1695 |
+
-----
|
| 1696 |
+
|
| 1697 |
+
.. versionadded:: 1.7.0
|
| 1698 |
+
|
| 1699 |
+
"""
|
| 1700 |
+
# c is a trimmed copy
|
| 1701 |
+
[c] = pu.as_series([c])
|
| 1702 |
+
if len(c) < 2:
|
| 1703 |
+
raise ValueError('Series must have maximum degree of at least 1.')
|
| 1704 |
+
if len(c) == 2:
|
| 1705 |
+
return np.array([[-c[0]/c[1]]])
|
| 1706 |
+
|
| 1707 |
+
n = len(c) - 1
|
| 1708 |
+
mat = np.zeros((n, n), dtype=c.dtype)
|
| 1709 |
+
scl = np.array([1.] + [np.sqrt(.5)]*(n-1))
|
| 1710 |
+
top = mat.reshape(-1)[1::n+1]
|
| 1711 |
+
bot = mat.reshape(-1)[n::n+1]
|
| 1712 |
+
top[0] = np.sqrt(.5)
|
| 1713 |
+
top[1:] = 1/2
|
| 1714 |
+
bot[...] = top
|
| 1715 |
+
mat[:, -1] -= (c[:-1]/c[-1])*(scl/scl[-1])*.5
|
| 1716 |
+
return mat
|
| 1717 |
+
|
| 1718 |
+
|
| 1719 |
+
def chebroots(c):
|
| 1720 |
+
"""
|
| 1721 |
+
Compute the roots of a Chebyshev series.
|
| 1722 |
+
|
| 1723 |
+
Return the roots (a.k.a. "zeros") of the polynomial
|
| 1724 |
+
|
| 1725 |
+
.. math:: p(x) = \\sum_i c[i] * T_i(x).
|
| 1726 |
+
|
| 1727 |
+
Parameters
|
| 1728 |
+
----------
|
| 1729 |
+
c : 1-D array_like
|
| 1730 |
+
1-D array of coefficients.
|
| 1731 |
+
|
| 1732 |
+
Returns
|
| 1733 |
+
-------
|
| 1734 |
+
out : ndarray
|
| 1735 |
+
Array of the roots of the series. If all the roots are real,
|
| 1736 |
+
then `out` is also real, otherwise it is complex.
|
| 1737 |
+
|
| 1738 |
+
See Also
|
| 1739 |
+
--------
|
| 1740 |
+
numpy.polynomial.polynomial.polyroots
|
| 1741 |
+
numpy.polynomial.legendre.legroots
|
| 1742 |
+
numpy.polynomial.laguerre.lagroots
|
| 1743 |
+
numpy.polynomial.hermite.hermroots
|
| 1744 |
+
numpy.polynomial.hermite_e.hermeroots
|
| 1745 |
+
|
| 1746 |
+
Notes
|
| 1747 |
+
-----
|
| 1748 |
+
The root estimates are obtained as the eigenvalues of the companion
|
| 1749 |
+
matrix, Roots far from the origin of the complex plane may have large
|
| 1750 |
+
errors due to the numerical instability of the series for such
|
| 1751 |
+
values. Roots with multiplicity greater than 1 will also show larger
|
| 1752 |
+
errors as the value of the series near such points is relatively
|
| 1753 |
+
insensitive to errors in the roots. Isolated roots near the origin can
|
| 1754 |
+
be improved by a few iterations of Newton's method.
|
| 1755 |
+
|
| 1756 |
+
The Chebyshev series basis polynomials aren't powers of `x` so the
|
| 1757 |
+
results of this function may seem unintuitive.
|
| 1758 |
+
|
| 1759 |
+
Examples
|
| 1760 |
+
--------
|
| 1761 |
+
>>> import numpy.polynomial.chebyshev as cheb
|
| 1762 |
+
>>> cheb.chebroots((-1, 1,-1, 1)) # T3 - T2 + T1 - T0 has real roots
|
| 1763 |
+
array([ -5.00000000e-01, 2.60860684e-17, 1.00000000e+00]) # may vary
|
| 1764 |
+
|
| 1765 |
+
"""
|
| 1766 |
+
# c is a trimmed copy
|
| 1767 |
+
[c] = pu.as_series([c])
|
| 1768 |
+
if len(c) < 2:
|
| 1769 |
+
return np.array([], dtype=c.dtype)
|
| 1770 |
+
if len(c) == 2:
|
| 1771 |
+
return np.array([-c[0]/c[1]])
|
| 1772 |
+
|
| 1773 |
+
# rotated companion matrix reduces error
|
| 1774 |
+
m = chebcompanion(c)[::-1,::-1]
|
| 1775 |
+
r = la.eigvals(m)
|
| 1776 |
+
r.sort()
|
| 1777 |
+
return r
|
| 1778 |
+
|
| 1779 |
+
|
| 1780 |
+
def chebinterpolate(func, deg, args=()):
|
| 1781 |
+
"""Interpolate a function at the Chebyshev points of the first kind.
|
| 1782 |
+
|
| 1783 |
+
Returns the Chebyshev series that interpolates `func` at the Chebyshev
|
| 1784 |
+
points of the first kind in the interval [-1, 1]. The interpolating
|
| 1785 |
+
series tends to a minmax approximation to `func` with increasing `deg`
|
| 1786 |
+
if the function is continuous in the interval.
|
| 1787 |
+
|
| 1788 |
+
.. versionadded:: 1.14.0
|
| 1789 |
+
|
| 1790 |
+
Parameters
|
| 1791 |
+
----------
|
| 1792 |
+
func : function
|
| 1793 |
+
The function to be approximated. It must be a function of a single
|
| 1794 |
+
variable of the form ``f(x, a, b, c...)``, where ``a, b, c...`` are
|
| 1795 |
+
extra arguments passed in the `args` parameter.
|
| 1796 |
+
deg : int
|
| 1797 |
+
Degree of the interpolating polynomial
|
| 1798 |
+
args : tuple, optional
|
| 1799 |
+
Extra arguments to be used in the function call. Default is no extra
|
| 1800 |
+
arguments.
|
| 1801 |
+
|
| 1802 |
+
Returns
|
| 1803 |
+
-------
|
| 1804 |
+
coef : ndarray, shape (deg + 1,)
|
| 1805 |
+
Chebyshev coefficients of the interpolating series ordered from low to
|
| 1806 |
+
high.
|
| 1807 |
+
|
| 1808 |
+
Examples
|
| 1809 |
+
--------
|
| 1810 |
+
>>> import numpy.polynomial.chebyshev as C
|
| 1811 |
+
>>> C.chebfromfunction(lambda x: np.tanh(x) + 0.5, 8)
|
| 1812 |
+
array([ 5.00000000e-01, 8.11675684e-01, -9.86864911e-17,
|
| 1813 |
+
-5.42457905e-02, -2.71387850e-16, 4.51658839e-03,
|
| 1814 |
+
2.46716228e-17, -3.79694221e-04, -3.26899002e-16])
|
| 1815 |
+
|
| 1816 |
+
Notes
|
| 1817 |
+
-----
|
| 1818 |
+
|
| 1819 |
+
The Chebyshev polynomials used in the interpolation are orthogonal when
|
| 1820 |
+
sampled at the Chebyshev points of the first kind. If it is desired to
|
| 1821 |
+
constrain some of the coefficients they can simply be set to the desired
|
| 1822 |
+
value after the interpolation, no new interpolation or fit is needed. This
|
| 1823 |
+
is especially useful if it is known apriori that some of coefficients are
|
| 1824 |
+
zero. For instance, if the function is even then the coefficients of the
|
| 1825 |
+
terms of odd degree in the result can be set to zero.
|
| 1826 |
+
|
| 1827 |
+
"""
|
| 1828 |
+
deg = np.asarray(deg)
|
| 1829 |
+
|
| 1830 |
+
# check arguments.
|
| 1831 |
+
if deg.ndim > 0 or deg.dtype.kind not in 'iu' or deg.size == 0:
|
| 1832 |
+
raise TypeError("deg must be an int")
|
| 1833 |
+
if deg < 0:
|
| 1834 |
+
raise ValueError("expected deg >= 0")
|
| 1835 |
+
|
| 1836 |
+
order = deg + 1
|
| 1837 |
+
xcheb = chebpts1(order)
|
| 1838 |
+
yfunc = func(xcheb, *args)
|
| 1839 |
+
m = chebvander(xcheb, deg)
|
| 1840 |
+
c = np.dot(m.T, yfunc)
|
| 1841 |
+
c[0] /= order
|
| 1842 |
+
c[1:] /= 0.5*order
|
| 1843 |
+
|
| 1844 |
+
return c
|
| 1845 |
+
|
| 1846 |
+
|
| 1847 |
+
def chebgauss(deg):
|
| 1848 |
+
"""
|
| 1849 |
+
Gauss-Chebyshev quadrature.
|
| 1850 |
+
|
| 1851 |
+
Computes the sample points and weights for Gauss-Chebyshev quadrature.
|
| 1852 |
+
These sample points and weights will correctly integrate polynomials of
|
| 1853 |
+
degree :math:`2*deg - 1` or less over the interval :math:`[-1, 1]` with
|
| 1854 |
+
the weight function :math:`f(x) = 1/\\sqrt{1 - x^2}`.
|
| 1855 |
+
|
| 1856 |
+
Parameters
|
| 1857 |
+
----------
|
| 1858 |
+
deg : int
|
| 1859 |
+
Number of sample points and weights. It must be >= 1.
|
| 1860 |
+
|
| 1861 |
+
Returns
|
| 1862 |
+
-------
|
| 1863 |
+
x : ndarray
|
| 1864 |
+
1-D ndarray containing the sample points.
|
| 1865 |
+
y : ndarray
|
| 1866 |
+
1-D ndarray containing the weights.
|
| 1867 |
+
|
| 1868 |
+
Notes
|
| 1869 |
+
-----
|
| 1870 |
+
|
| 1871 |
+
.. versionadded:: 1.7.0
|
| 1872 |
+
|
| 1873 |
+
The results have only been tested up to degree 100, higher degrees may
|
| 1874 |
+
be problematic. For Gauss-Chebyshev there are closed form solutions for
|
| 1875 |
+
the sample points and weights. If n = `deg`, then
|
| 1876 |
+
|
| 1877 |
+
.. math:: x_i = \\cos(\\pi (2 i - 1) / (2 n))
|
| 1878 |
+
|
| 1879 |
+
.. math:: w_i = \\pi / n
|
| 1880 |
+
|
| 1881 |
+
"""
|
| 1882 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1883 |
+
if ideg <= 0:
|
| 1884 |
+
raise ValueError("deg must be a positive integer")
|
| 1885 |
+
|
| 1886 |
+
x = np.cos(np.pi * np.arange(1, 2*ideg, 2) / (2.0*ideg))
|
| 1887 |
+
w = np.ones(ideg)*(np.pi/ideg)
|
| 1888 |
+
|
| 1889 |
+
return x, w
|
| 1890 |
+
|
| 1891 |
+
|
| 1892 |
+
def chebweight(x):
|
| 1893 |
+
"""
|
| 1894 |
+
The weight function of the Chebyshev polynomials.
|
| 1895 |
+
|
| 1896 |
+
The weight function is :math:`1/\\sqrt{1 - x^2}` and the interval of
|
| 1897 |
+
integration is :math:`[-1, 1]`. The Chebyshev polynomials are
|
| 1898 |
+
orthogonal, but not normalized, with respect to this weight function.
|
| 1899 |
+
|
| 1900 |
+
Parameters
|
| 1901 |
+
----------
|
| 1902 |
+
x : array_like
|
| 1903 |
+
Values at which the weight function will be computed.
|
| 1904 |
+
|
| 1905 |
+
Returns
|
| 1906 |
+
-------
|
| 1907 |
+
w : ndarray
|
| 1908 |
+
The weight function at `x`.
|
| 1909 |
+
|
| 1910 |
+
Notes
|
| 1911 |
+
-----
|
| 1912 |
+
|
| 1913 |
+
.. versionadded:: 1.7.0
|
| 1914 |
+
|
| 1915 |
+
"""
|
| 1916 |
+
w = 1./(np.sqrt(1. + x) * np.sqrt(1. - x))
|
| 1917 |
+
return w
|
| 1918 |
+
|
| 1919 |
+
|
| 1920 |
+
def chebpts1(npts):
|
| 1921 |
+
"""
|
| 1922 |
+
Chebyshev points of the first kind.
|
| 1923 |
+
|
| 1924 |
+
The Chebyshev points of the first kind are the points ``cos(x)``,
|
| 1925 |
+
where ``x = [pi*(k + .5)/npts for k in range(npts)]``.
|
| 1926 |
+
|
| 1927 |
+
Parameters
|
| 1928 |
+
----------
|
| 1929 |
+
npts : int
|
| 1930 |
+
Number of sample points desired.
|
| 1931 |
+
|
| 1932 |
+
Returns
|
| 1933 |
+
-------
|
| 1934 |
+
pts : ndarray
|
| 1935 |
+
The Chebyshev points of the first kind.
|
| 1936 |
+
|
| 1937 |
+
See Also
|
| 1938 |
+
--------
|
| 1939 |
+
chebpts2
|
| 1940 |
+
|
| 1941 |
+
Notes
|
| 1942 |
+
-----
|
| 1943 |
+
|
| 1944 |
+
.. versionadded:: 1.5.0
|
| 1945 |
+
|
| 1946 |
+
"""
|
| 1947 |
+
_npts = int(npts)
|
| 1948 |
+
if _npts != npts:
|
| 1949 |
+
raise ValueError("npts must be integer")
|
| 1950 |
+
if _npts < 1:
|
| 1951 |
+
raise ValueError("npts must be >= 1")
|
| 1952 |
+
|
| 1953 |
+
x = 0.5 * np.pi / _npts * np.arange(-_npts+1, _npts+1, 2)
|
| 1954 |
+
return np.sin(x)
|
| 1955 |
+
|
| 1956 |
+
|
| 1957 |
+
def chebpts2(npts):
|
| 1958 |
+
"""
|
| 1959 |
+
Chebyshev points of the second kind.
|
| 1960 |
+
|
| 1961 |
+
The Chebyshev points of the second kind are the points ``cos(x)``,
|
| 1962 |
+
where ``x = [pi*k/(npts - 1) for k in range(npts)]`` sorted in ascending
|
| 1963 |
+
order.
|
| 1964 |
+
|
| 1965 |
+
Parameters
|
| 1966 |
+
----------
|
| 1967 |
+
npts : int
|
| 1968 |
+
Number of sample points desired.
|
| 1969 |
+
|
| 1970 |
+
Returns
|
| 1971 |
+
-------
|
| 1972 |
+
pts : ndarray
|
| 1973 |
+
The Chebyshev points of the second kind.
|
| 1974 |
+
|
| 1975 |
+
Notes
|
| 1976 |
+
-----
|
| 1977 |
+
|
| 1978 |
+
.. versionadded:: 1.5.0
|
| 1979 |
+
|
| 1980 |
+
"""
|
| 1981 |
+
_npts = int(npts)
|
| 1982 |
+
if _npts != npts:
|
| 1983 |
+
raise ValueError("npts must be integer")
|
| 1984 |
+
if _npts < 2:
|
| 1985 |
+
raise ValueError("npts must be >= 2")
|
| 1986 |
+
|
| 1987 |
+
x = np.linspace(-np.pi, 0, _npts)
|
| 1988 |
+
return np.cos(x)
|
| 1989 |
+
|
| 1990 |
+
|
| 1991 |
+
#
|
| 1992 |
+
# Chebyshev series class
|
| 1993 |
+
#
|
| 1994 |
+
|
| 1995 |
+
class Chebyshev(ABCPolyBase):
|
| 1996 |
+
"""A Chebyshev series class.
|
| 1997 |
+
|
| 1998 |
+
The Chebyshev class provides the standard Python numerical methods
|
| 1999 |
+
'+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
|
| 2000 |
+
methods listed below.
|
| 2001 |
+
|
| 2002 |
+
Parameters
|
| 2003 |
+
----------
|
| 2004 |
+
coef : array_like
|
| 2005 |
+
Chebyshev coefficients in order of increasing degree, i.e.,
|
| 2006 |
+
``(1, 2, 3)`` gives ``1*T_0(x) + 2*T_1(x) + 3*T_2(x)``.
|
| 2007 |
+
domain : (2,) array_like, optional
|
| 2008 |
+
Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
|
| 2009 |
+
to the interval ``[window[0], window[1]]`` by shifting and scaling.
|
| 2010 |
+
The default value is [-1, 1].
|
| 2011 |
+
window : (2,) array_like, optional
|
| 2012 |
+
Window, see `domain` for its use. The default value is [-1, 1].
|
| 2013 |
+
|
| 2014 |
+
.. versionadded:: 1.6.0
|
| 2015 |
+
symbol : str, optional
|
| 2016 |
+
Symbol used to represent the independent variable in string
|
| 2017 |
+
representations of the polynomial expression, e.g. for printing.
|
| 2018 |
+
The symbol must be a valid Python identifier. Default value is 'x'.
|
| 2019 |
+
|
| 2020 |
+
.. versionadded:: 1.24
|
| 2021 |
+
|
| 2022 |
+
"""
|
| 2023 |
+
# Virtual Functions
|
| 2024 |
+
_add = staticmethod(chebadd)
|
| 2025 |
+
_sub = staticmethod(chebsub)
|
| 2026 |
+
_mul = staticmethod(chebmul)
|
| 2027 |
+
_div = staticmethod(chebdiv)
|
| 2028 |
+
_pow = staticmethod(chebpow)
|
| 2029 |
+
_val = staticmethod(chebval)
|
| 2030 |
+
_int = staticmethod(chebint)
|
| 2031 |
+
_der = staticmethod(chebder)
|
| 2032 |
+
_fit = staticmethod(chebfit)
|
| 2033 |
+
_line = staticmethod(chebline)
|
| 2034 |
+
_roots = staticmethod(chebroots)
|
| 2035 |
+
_fromroots = staticmethod(chebfromroots)
|
| 2036 |
+
|
| 2037 |
+
@classmethod
|
| 2038 |
+
def interpolate(cls, func, deg, domain=None, args=()):
|
| 2039 |
+
"""Interpolate a function at the Chebyshev points of the first kind.
|
| 2040 |
+
|
| 2041 |
+
Returns the series that interpolates `func` at the Chebyshev points of
|
| 2042 |
+
the first kind scaled and shifted to the `domain`. The resulting series
|
| 2043 |
+
tends to a minmax approximation of `func` when the function is
|
| 2044 |
+
continuous in the domain.
|
| 2045 |
+
|
| 2046 |
+
.. versionadded:: 1.14.0
|
| 2047 |
+
|
| 2048 |
+
Parameters
|
| 2049 |
+
----------
|
| 2050 |
+
func : function
|
| 2051 |
+
The function to be interpolated. It must be a function of a single
|
| 2052 |
+
variable of the form ``f(x, a, b, c...)``, where ``a, b, c...`` are
|
| 2053 |
+
extra arguments passed in the `args` parameter.
|
| 2054 |
+
deg : int
|
| 2055 |
+
Degree of the interpolating polynomial.
|
| 2056 |
+
domain : {None, [beg, end]}, optional
|
| 2057 |
+
Domain over which `func` is interpolated. The default is None, in
|
| 2058 |
+
which case the domain is [-1, 1].
|
| 2059 |
+
args : tuple, optional
|
| 2060 |
+
Extra arguments to be used in the function call. Default is no
|
| 2061 |
+
extra arguments.
|
| 2062 |
+
|
| 2063 |
+
Returns
|
| 2064 |
+
-------
|
| 2065 |
+
polynomial : Chebyshev instance
|
| 2066 |
+
Interpolating Chebyshev instance.
|
| 2067 |
+
|
| 2068 |
+
Notes
|
| 2069 |
+
-----
|
| 2070 |
+
See `numpy.polynomial.chebfromfunction` for more details.
|
| 2071 |
+
|
| 2072 |
+
"""
|
| 2073 |
+
if domain is None:
|
| 2074 |
+
domain = cls.domain
|
| 2075 |
+
xfunc = lambda x: func(pu.mapdomain(x, cls.window, domain), *args)
|
| 2076 |
+
coef = chebinterpolate(xfunc, deg)
|
| 2077 |
+
return cls(coef, domain=domain)
|
| 2078 |
+
|
| 2079 |
+
# Virtual properties
|
| 2080 |
+
domain = np.array(chebdomain)
|
| 2081 |
+
window = np.array(chebdomain)
|
| 2082 |
+
basis_name = 'T'
|
lib/python3.12/site-packages/numpy/polynomial/chebyshev.pyi
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any
|
| 2 |
+
|
| 3 |
+
from numpy import ndarray, dtype, int_
|
| 4 |
+
from numpy.polynomial._polybase import ABCPolyBase
|
| 5 |
+
from numpy.polynomial.polyutils import trimcoef
|
| 6 |
+
|
| 7 |
+
__all__: list[str]
|
| 8 |
+
|
| 9 |
+
chebtrim = trimcoef
|
| 10 |
+
|
| 11 |
+
def poly2cheb(pol): ...
|
| 12 |
+
def cheb2poly(c): ...
|
| 13 |
+
|
| 14 |
+
chebdomain: ndarray[Any, dtype[int_]]
|
| 15 |
+
chebzero: ndarray[Any, dtype[int_]]
|
| 16 |
+
chebone: ndarray[Any, dtype[int_]]
|
| 17 |
+
chebx: ndarray[Any, dtype[int_]]
|
| 18 |
+
|
| 19 |
+
def chebline(off, scl): ...
|
| 20 |
+
def chebfromroots(roots): ...
|
| 21 |
+
def chebadd(c1, c2): ...
|
| 22 |
+
def chebsub(c1, c2): ...
|
| 23 |
+
def chebmulx(c): ...
|
| 24 |
+
def chebmul(c1, c2): ...
|
| 25 |
+
def chebdiv(c1, c2): ...
|
| 26 |
+
def chebpow(c, pow, maxpower=...): ...
|
| 27 |
+
def chebder(c, m=..., scl=..., axis=...): ...
|
| 28 |
+
def chebint(c, m=..., k = ..., lbnd=..., scl=..., axis=...): ...
|
| 29 |
+
def chebval(x, c, tensor=...): ...
|
| 30 |
+
def chebval2d(x, y, c): ...
|
| 31 |
+
def chebgrid2d(x, y, c): ...
|
| 32 |
+
def chebval3d(x, y, z, c): ...
|
| 33 |
+
def chebgrid3d(x, y, z, c): ...
|
| 34 |
+
def chebvander(x, deg): ...
|
| 35 |
+
def chebvander2d(x, y, deg): ...
|
| 36 |
+
def chebvander3d(x, y, z, deg): ...
|
| 37 |
+
def chebfit(x, y, deg, rcond=..., full=..., w=...): ...
|
| 38 |
+
def chebcompanion(c): ...
|
| 39 |
+
def chebroots(c): ...
|
| 40 |
+
def chebinterpolate(func, deg, args = ...): ...
|
| 41 |
+
def chebgauss(deg): ...
|
| 42 |
+
def chebweight(x): ...
|
| 43 |
+
def chebpts1(npts): ...
|
| 44 |
+
def chebpts2(npts): ...
|
| 45 |
+
|
| 46 |
+
class Chebyshev(ABCPolyBase):
|
| 47 |
+
@classmethod
|
| 48 |
+
def interpolate(cls, func, deg, domain=..., args = ...): ...
|
| 49 |
+
domain: Any
|
| 50 |
+
window: Any
|
| 51 |
+
basis_name: Any
|
lib/python3.12/site-packages/numpy/polynomial/hermite.py
ADDED
|
@@ -0,0 +1,1703 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
==============================================================
|
| 3 |
+
Hermite Series, "Physicists" (:mod:`numpy.polynomial.hermite`)
|
| 4 |
+
==============================================================
|
| 5 |
+
|
| 6 |
+
This module provides a number of objects (mostly functions) useful for
|
| 7 |
+
dealing with Hermite series, including a `Hermite` class that
|
| 8 |
+
encapsulates the usual arithmetic operations. (General information
|
| 9 |
+
on how this module represents and works with such polynomials is in the
|
| 10 |
+
docstring for its "parent" sub-package, `numpy.polynomial`).
|
| 11 |
+
|
| 12 |
+
Classes
|
| 13 |
+
-------
|
| 14 |
+
.. autosummary::
|
| 15 |
+
:toctree: generated/
|
| 16 |
+
|
| 17 |
+
Hermite
|
| 18 |
+
|
| 19 |
+
Constants
|
| 20 |
+
---------
|
| 21 |
+
.. autosummary::
|
| 22 |
+
:toctree: generated/
|
| 23 |
+
|
| 24 |
+
hermdomain
|
| 25 |
+
hermzero
|
| 26 |
+
hermone
|
| 27 |
+
hermx
|
| 28 |
+
|
| 29 |
+
Arithmetic
|
| 30 |
+
----------
|
| 31 |
+
.. autosummary::
|
| 32 |
+
:toctree: generated/
|
| 33 |
+
|
| 34 |
+
hermadd
|
| 35 |
+
hermsub
|
| 36 |
+
hermmulx
|
| 37 |
+
hermmul
|
| 38 |
+
hermdiv
|
| 39 |
+
hermpow
|
| 40 |
+
hermval
|
| 41 |
+
hermval2d
|
| 42 |
+
hermval3d
|
| 43 |
+
hermgrid2d
|
| 44 |
+
hermgrid3d
|
| 45 |
+
|
| 46 |
+
Calculus
|
| 47 |
+
--------
|
| 48 |
+
.. autosummary::
|
| 49 |
+
:toctree: generated/
|
| 50 |
+
|
| 51 |
+
hermder
|
| 52 |
+
hermint
|
| 53 |
+
|
| 54 |
+
Misc Functions
|
| 55 |
+
--------------
|
| 56 |
+
.. autosummary::
|
| 57 |
+
:toctree: generated/
|
| 58 |
+
|
| 59 |
+
hermfromroots
|
| 60 |
+
hermroots
|
| 61 |
+
hermvander
|
| 62 |
+
hermvander2d
|
| 63 |
+
hermvander3d
|
| 64 |
+
hermgauss
|
| 65 |
+
hermweight
|
| 66 |
+
hermcompanion
|
| 67 |
+
hermfit
|
| 68 |
+
hermtrim
|
| 69 |
+
hermline
|
| 70 |
+
herm2poly
|
| 71 |
+
poly2herm
|
| 72 |
+
|
| 73 |
+
See also
|
| 74 |
+
--------
|
| 75 |
+
`numpy.polynomial`
|
| 76 |
+
|
| 77 |
+
"""
|
| 78 |
+
import numpy as np
|
| 79 |
+
import numpy.linalg as la
|
| 80 |
+
from numpy.core.multiarray import normalize_axis_index
|
| 81 |
+
|
| 82 |
+
from . import polyutils as pu
|
| 83 |
+
from ._polybase import ABCPolyBase
|
| 84 |
+
|
| 85 |
+
__all__ = [
|
| 86 |
+
'hermzero', 'hermone', 'hermx', 'hermdomain', 'hermline', 'hermadd',
|
| 87 |
+
'hermsub', 'hermmulx', 'hermmul', 'hermdiv', 'hermpow', 'hermval',
|
| 88 |
+
'hermder', 'hermint', 'herm2poly', 'poly2herm', 'hermfromroots',
|
| 89 |
+
'hermvander', 'hermfit', 'hermtrim', 'hermroots', 'Hermite',
|
| 90 |
+
'hermval2d', 'hermval3d', 'hermgrid2d', 'hermgrid3d', 'hermvander2d',
|
| 91 |
+
'hermvander3d', 'hermcompanion', 'hermgauss', 'hermweight']
|
| 92 |
+
|
| 93 |
+
hermtrim = pu.trimcoef
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def poly2herm(pol):
|
| 97 |
+
"""
|
| 98 |
+
poly2herm(pol)
|
| 99 |
+
|
| 100 |
+
Convert a polynomial to a Hermite series.
|
| 101 |
+
|
| 102 |
+
Convert an array representing the coefficients of a polynomial (relative
|
| 103 |
+
to the "standard" basis) ordered from lowest degree to highest, to an
|
| 104 |
+
array of the coefficients of the equivalent Hermite series, ordered
|
| 105 |
+
from lowest to highest degree.
|
| 106 |
+
|
| 107 |
+
Parameters
|
| 108 |
+
----------
|
| 109 |
+
pol : array_like
|
| 110 |
+
1-D array containing the polynomial coefficients
|
| 111 |
+
|
| 112 |
+
Returns
|
| 113 |
+
-------
|
| 114 |
+
c : ndarray
|
| 115 |
+
1-D array containing the coefficients of the equivalent Hermite
|
| 116 |
+
series.
|
| 117 |
+
|
| 118 |
+
See Also
|
| 119 |
+
--------
|
| 120 |
+
herm2poly
|
| 121 |
+
|
| 122 |
+
Notes
|
| 123 |
+
-----
|
| 124 |
+
The easy way to do conversions between polynomial basis sets
|
| 125 |
+
is to use the convert method of a class instance.
|
| 126 |
+
|
| 127 |
+
Examples
|
| 128 |
+
--------
|
| 129 |
+
>>> from numpy.polynomial.hermite import poly2herm
|
| 130 |
+
>>> poly2herm(np.arange(4))
|
| 131 |
+
array([1. , 2.75 , 0.5 , 0.375])
|
| 132 |
+
|
| 133 |
+
"""
|
| 134 |
+
[pol] = pu.as_series([pol])
|
| 135 |
+
deg = len(pol) - 1
|
| 136 |
+
res = 0
|
| 137 |
+
for i in range(deg, -1, -1):
|
| 138 |
+
res = hermadd(hermmulx(res), pol[i])
|
| 139 |
+
return res
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
def herm2poly(c):
|
| 143 |
+
"""
|
| 144 |
+
Convert a Hermite series to a polynomial.
|
| 145 |
+
|
| 146 |
+
Convert an array representing the coefficients of a Hermite series,
|
| 147 |
+
ordered from lowest degree to highest, to an array of the coefficients
|
| 148 |
+
of the equivalent polynomial (relative to the "standard" basis) ordered
|
| 149 |
+
from lowest to highest degree.
|
| 150 |
+
|
| 151 |
+
Parameters
|
| 152 |
+
----------
|
| 153 |
+
c : array_like
|
| 154 |
+
1-D array containing the Hermite series coefficients, ordered
|
| 155 |
+
from lowest order term to highest.
|
| 156 |
+
|
| 157 |
+
Returns
|
| 158 |
+
-------
|
| 159 |
+
pol : ndarray
|
| 160 |
+
1-D array containing the coefficients of the equivalent polynomial
|
| 161 |
+
(relative to the "standard" basis) ordered from lowest order term
|
| 162 |
+
to highest.
|
| 163 |
+
|
| 164 |
+
See Also
|
| 165 |
+
--------
|
| 166 |
+
poly2herm
|
| 167 |
+
|
| 168 |
+
Notes
|
| 169 |
+
-----
|
| 170 |
+
The easy way to do conversions between polynomial basis sets
|
| 171 |
+
is to use the convert method of a class instance.
|
| 172 |
+
|
| 173 |
+
Examples
|
| 174 |
+
--------
|
| 175 |
+
>>> from numpy.polynomial.hermite import herm2poly
|
| 176 |
+
>>> herm2poly([ 1. , 2.75 , 0.5 , 0.375])
|
| 177 |
+
array([0., 1., 2., 3.])
|
| 178 |
+
|
| 179 |
+
"""
|
| 180 |
+
from .polynomial import polyadd, polysub, polymulx
|
| 181 |
+
|
| 182 |
+
[c] = pu.as_series([c])
|
| 183 |
+
n = len(c)
|
| 184 |
+
if n == 1:
|
| 185 |
+
return c
|
| 186 |
+
if n == 2:
|
| 187 |
+
c[1] *= 2
|
| 188 |
+
return c
|
| 189 |
+
else:
|
| 190 |
+
c0 = c[-2]
|
| 191 |
+
c1 = c[-1]
|
| 192 |
+
# i is the current degree of c1
|
| 193 |
+
for i in range(n - 1, 1, -1):
|
| 194 |
+
tmp = c0
|
| 195 |
+
c0 = polysub(c[i - 2], c1*(2*(i - 1)))
|
| 196 |
+
c1 = polyadd(tmp, polymulx(c1)*2)
|
| 197 |
+
return polyadd(c0, polymulx(c1)*2)
|
| 198 |
+
|
| 199 |
+
#
|
| 200 |
+
# These are constant arrays are of integer type so as to be compatible
|
| 201 |
+
# with the widest range of other types, such as Decimal.
|
| 202 |
+
#
|
| 203 |
+
|
| 204 |
+
# Hermite
|
| 205 |
+
hermdomain = np.array([-1, 1])
|
| 206 |
+
|
| 207 |
+
# Hermite coefficients representing zero.
|
| 208 |
+
hermzero = np.array([0])
|
| 209 |
+
|
| 210 |
+
# Hermite coefficients representing one.
|
| 211 |
+
hermone = np.array([1])
|
| 212 |
+
|
| 213 |
+
# Hermite coefficients representing the identity x.
|
| 214 |
+
hermx = np.array([0, 1/2])
|
| 215 |
+
|
| 216 |
+
|
| 217 |
+
def hermline(off, scl):
|
| 218 |
+
"""
|
| 219 |
+
Hermite series whose graph is a straight line.
|
| 220 |
+
|
| 221 |
+
|
| 222 |
+
|
| 223 |
+
Parameters
|
| 224 |
+
----------
|
| 225 |
+
off, scl : scalars
|
| 226 |
+
The specified line is given by ``off + scl*x``.
|
| 227 |
+
|
| 228 |
+
Returns
|
| 229 |
+
-------
|
| 230 |
+
y : ndarray
|
| 231 |
+
This module's representation of the Hermite series for
|
| 232 |
+
``off + scl*x``.
|
| 233 |
+
|
| 234 |
+
See Also
|
| 235 |
+
--------
|
| 236 |
+
numpy.polynomial.polynomial.polyline
|
| 237 |
+
numpy.polynomial.chebyshev.chebline
|
| 238 |
+
numpy.polynomial.legendre.legline
|
| 239 |
+
numpy.polynomial.laguerre.lagline
|
| 240 |
+
numpy.polynomial.hermite_e.hermeline
|
| 241 |
+
|
| 242 |
+
Examples
|
| 243 |
+
--------
|
| 244 |
+
>>> from numpy.polynomial.hermite import hermline, hermval
|
| 245 |
+
>>> hermval(0,hermline(3, 2))
|
| 246 |
+
3.0
|
| 247 |
+
>>> hermval(1,hermline(3, 2))
|
| 248 |
+
5.0
|
| 249 |
+
|
| 250 |
+
"""
|
| 251 |
+
if scl != 0:
|
| 252 |
+
return np.array([off, scl/2])
|
| 253 |
+
else:
|
| 254 |
+
return np.array([off])
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
def hermfromroots(roots):
|
| 258 |
+
"""
|
| 259 |
+
Generate a Hermite series with given roots.
|
| 260 |
+
|
| 261 |
+
The function returns the coefficients of the polynomial
|
| 262 |
+
|
| 263 |
+
.. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
|
| 264 |
+
|
| 265 |
+
in Hermite form, where the `r_n` are the roots specified in `roots`.
|
| 266 |
+
If a zero has multiplicity n, then it must appear in `roots` n times.
|
| 267 |
+
For instance, if 2 is a root of multiplicity three and 3 is a root of
|
| 268 |
+
multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
|
| 269 |
+
roots can appear in any order.
|
| 270 |
+
|
| 271 |
+
If the returned coefficients are `c`, then
|
| 272 |
+
|
| 273 |
+
.. math:: p(x) = c_0 + c_1 * H_1(x) + ... + c_n * H_n(x)
|
| 274 |
+
|
| 275 |
+
The coefficient of the last term is not generally 1 for monic
|
| 276 |
+
polynomials in Hermite form.
|
| 277 |
+
|
| 278 |
+
Parameters
|
| 279 |
+
----------
|
| 280 |
+
roots : array_like
|
| 281 |
+
Sequence containing the roots.
|
| 282 |
+
|
| 283 |
+
Returns
|
| 284 |
+
-------
|
| 285 |
+
out : ndarray
|
| 286 |
+
1-D array of coefficients. If all roots are real then `out` is a
|
| 287 |
+
real array, if some of the roots are complex, then `out` is complex
|
| 288 |
+
even if all the coefficients in the result are real (see Examples
|
| 289 |
+
below).
|
| 290 |
+
|
| 291 |
+
See Also
|
| 292 |
+
--------
|
| 293 |
+
numpy.polynomial.polynomial.polyfromroots
|
| 294 |
+
numpy.polynomial.legendre.legfromroots
|
| 295 |
+
numpy.polynomial.laguerre.lagfromroots
|
| 296 |
+
numpy.polynomial.chebyshev.chebfromroots
|
| 297 |
+
numpy.polynomial.hermite_e.hermefromroots
|
| 298 |
+
|
| 299 |
+
Examples
|
| 300 |
+
--------
|
| 301 |
+
>>> from numpy.polynomial.hermite import hermfromroots, hermval
|
| 302 |
+
>>> coef = hermfromroots((-1, 0, 1))
|
| 303 |
+
>>> hermval((-1, 0, 1), coef)
|
| 304 |
+
array([0., 0., 0.])
|
| 305 |
+
>>> coef = hermfromroots((-1j, 1j))
|
| 306 |
+
>>> hermval((-1j, 1j), coef)
|
| 307 |
+
array([0.+0.j, 0.+0.j])
|
| 308 |
+
|
| 309 |
+
"""
|
| 310 |
+
return pu._fromroots(hermline, hermmul, roots)
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
def hermadd(c1, c2):
|
| 314 |
+
"""
|
| 315 |
+
Add one Hermite series to another.
|
| 316 |
+
|
| 317 |
+
Returns the sum of two Hermite series `c1` + `c2`. The arguments
|
| 318 |
+
are sequences of coefficients ordered from lowest order term to
|
| 319 |
+
highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 320 |
+
|
| 321 |
+
Parameters
|
| 322 |
+
----------
|
| 323 |
+
c1, c2 : array_like
|
| 324 |
+
1-D arrays of Hermite series coefficients ordered from low to
|
| 325 |
+
high.
|
| 326 |
+
|
| 327 |
+
Returns
|
| 328 |
+
-------
|
| 329 |
+
out : ndarray
|
| 330 |
+
Array representing the Hermite series of their sum.
|
| 331 |
+
|
| 332 |
+
See Also
|
| 333 |
+
--------
|
| 334 |
+
hermsub, hermmulx, hermmul, hermdiv, hermpow
|
| 335 |
+
|
| 336 |
+
Notes
|
| 337 |
+
-----
|
| 338 |
+
Unlike multiplication, division, etc., the sum of two Hermite series
|
| 339 |
+
is a Hermite series (without having to "reproject" the result onto
|
| 340 |
+
the basis set) so addition, just like that of "standard" polynomials,
|
| 341 |
+
is simply "component-wise."
|
| 342 |
+
|
| 343 |
+
Examples
|
| 344 |
+
--------
|
| 345 |
+
>>> from numpy.polynomial.hermite import hermadd
|
| 346 |
+
>>> hermadd([1, 2, 3], [1, 2, 3, 4])
|
| 347 |
+
array([2., 4., 6., 4.])
|
| 348 |
+
|
| 349 |
+
"""
|
| 350 |
+
return pu._add(c1, c2)
|
| 351 |
+
|
| 352 |
+
|
| 353 |
+
def hermsub(c1, c2):
|
| 354 |
+
"""
|
| 355 |
+
Subtract one Hermite series from another.
|
| 356 |
+
|
| 357 |
+
Returns the difference of two Hermite series `c1` - `c2`. The
|
| 358 |
+
sequences of coefficients are from lowest order term to highest, i.e.,
|
| 359 |
+
[1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 360 |
+
|
| 361 |
+
Parameters
|
| 362 |
+
----------
|
| 363 |
+
c1, c2 : array_like
|
| 364 |
+
1-D arrays of Hermite series coefficients ordered from low to
|
| 365 |
+
high.
|
| 366 |
+
|
| 367 |
+
Returns
|
| 368 |
+
-------
|
| 369 |
+
out : ndarray
|
| 370 |
+
Of Hermite series coefficients representing their difference.
|
| 371 |
+
|
| 372 |
+
See Also
|
| 373 |
+
--------
|
| 374 |
+
hermadd, hermmulx, hermmul, hermdiv, hermpow
|
| 375 |
+
|
| 376 |
+
Notes
|
| 377 |
+
-----
|
| 378 |
+
Unlike multiplication, division, etc., the difference of two Hermite
|
| 379 |
+
series is a Hermite series (without having to "reproject" the result
|
| 380 |
+
onto the basis set) so subtraction, just like that of "standard"
|
| 381 |
+
polynomials, is simply "component-wise."
|
| 382 |
+
|
| 383 |
+
Examples
|
| 384 |
+
--------
|
| 385 |
+
>>> from numpy.polynomial.hermite import hermsub
|
| 386 |
+
>>> hermsub([1, 2, 3, 4], [1, 2, 3])
|
| 387 |
+
array([0., 0., 0., 4.])
|
| 388 |
+
|
| 389 |
+
"""
|
| 390 |
+
return pu._sub(c1, c2)
|
| 391 |
+
|
| 392 |
+
|
| 393 |
+
def hermmulx(c):
|
| 394 |
+
"""Multiply a Hermite series by x.
|
| 395 |
+
|
| 396 |
+
Multiply the Hermite series `c` by x, where x is the independent
|
| 397 |
+
variable.
|
| 398 |
+
|
| 399 |
+
|
| 400 |
+
Parameters
|
| 401 |
+
----------
|
| 402 |
+
c : array_like
|
| 403 |
+
1-D array of Hermite series coefficients ordered from low to
|
| 404 |
+
high.
|
| 405 |
+
|
| 406 |
+
Returns
|
| 407 |
+
-------
|
| 408 |
+
out : ndarray
|
| 409 |
+
Array representing the result of the multiplication.
|
| 410 |
+
|
| 411 |
+
See Also
|
| 412 |
+
--------
|
| 413 |
+
hermadd, hermsub, hermmul, hermdiv, hermpow
|
| 414 |
+
|
| 415 |
+
Notes
|
| 416 |
+
-----
|
| 417 |
+
The multiplication uses the recursion relationship for Hermite
|
| 418 |
+
polynomials in the form
|
| 419 |
+
|
| 420 |
+
.. math::
|
| 421 |
+
|
| 422 |
+
xP_i(x) = (P_{i + 1}(x)/2 + i*P_{i - 1}(x))
|
| 423 |
+
|
| 424 |
+
Examples
|
| 425 |
+
--------
|
| 426 |
+
>>> from numpy.polynomial.hermite import hermmulx
|
| 427 |
+
>>> hermmulx([1, 2, 3])
|
| 428 |
+
array([2. , 6.5, 1. , 1.5])
|
| 429 |
+
|
| 430 |
+
"""
|
| 431 |
+
# c is a trimmed copy
|
| 432 |
+
[c] = pu.as_series([c])
|
| 433 |
+
# The zero series needs special treatment
|
| 434 |
+
if len(c) == 1 and c[0] == 0:
|
| 435 |
+
return c
|
| 436 |
+
|
| 437 |
+
prd = np.empty(len(c) + 1, dtype=c.dtype)
|
| 438 |
+
prd[0] = c[0]*0
|
| 439 |
+
prd[1] = c[0]/2
|
| 440 |
+
for i in range(1, len(c)):
|
| 441 |
+
prd[i + 1] = c[i]/2
|
| 442 |
+
prd[i - 1] += c[i]*i
|
| 443 |
+
return prd
|
| 444 |
+
|
| 445 |
+
|
| 446 |
+
def hermmul(c1, c2):
|
| 447 |
+
"""
|
| 448 |
+
Multiply one Hermite series by another.
|
| 449 |
+
|
| 450 |
+
Returns the product of two Hermite series `c1` * `c2`. The arguments
|
| 451 |
+
are sequences of coefficients, from lowest order "term" to highest,
|
| 452 |
+
e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 453 |
+
|
| 454 |
+
Parameters
|
| 455 |
+
----------
|
| 456 |
+
c1, c2 : array_like
|
| 457 |
+
1-D arrays of Hermite series coefficients ordered from low to
|
| 458 |
+
high.
|
| 459 |
+
|
| 460 |
+
Returns
|
| 461 |
+
-------
|
| 462 |
+
out : ndarray
|
| 463 |
+
Of Hermite series coefficients representing their product.
|
| 464 |
+
|
| 465 |
+
See Also
|
| 466 |
+
--------
|
| 467 |
+
hermadd, hermsub, hermmulx, hermdiv, hermpow
|
| 468 |
+
|
| 469 |
+
Notes
|
| 470 |
+
-----
|
| 471 |
+
In general, the (polynomial) product of two C-series results in terms
|
| 472 |
+
that are not in the Hermite polynomial basis set. Thus, to express
|
| 473 |
+
the product as a Hermite series, it is necessary to "reproject" the
|
| 474 |
+
product onto said basis set, which may produce "unintuitive" (but
|
| 475 |
+
correct) results; see Examples section below.
|
| 476 |
+
|
| 477 |
+
Examples
|
| 478 |
+
--------
|
| 479 |
+
>>> from numpy.polynomial.hermite import hermmul
|
| 480 |
+
>>> hermmul([1, 2, 3], [0, 1, 2])
|
| 481 |
+
array([52., 29., 52., 7., 6.])
|
| 482 |
+
|
| 483 |
+
"""
|
| 484 |
+
# s1, s2 are trimmed copies
|
| 485 |
+
[c1, c2] = pu.as_series([c1, c2])
|
| 486 |
+
|
| 487 |
+
if len(c1) > len(c2):
|
| 488 |
+
c = c2
|
| 489 |
+
xs = c1
|
| 490 |
+
else:
|
| 491 |
+
c = c1
|
| 492 |
+
xs = c2
|
| 493 |
+
|
| 494 |
+
if len(c) == 1:
|
| 495 |
+
c0 = c[0]*xs
|
| 496 |
+
c1 = 0
|
| 497 |
+
elif len(c) == 2:
|
| 498 |
+
c0 = c[0]*xs
|
| 499 |
+
c1 = c[1]*xs
|
| 500 |
+
else:
|
| 501 |
+
nd = len(c)
|
| 502 |
+
c0 = c[-2]*xs
|
| 503 |
+
c1 = c[-1]*xs
|
| 504 |
+
for i in range(3, len(c) + 1):
|
| 505 |
+
tmp = c0
|
| 506 |
+
nd = nd - 1
|
| 507 |
+
c0 = hermsub(c[-i]*xs, c1*(2*(nd - 1)))
|
| 508 |
+
c1 = hermadd(tmp, hermmulx(c1)*2)
|
| 509 |
+
return hermadd(c0, hermmulx(c1)*2)
|
| 510 |
+
|
| 511 |
+
|
| 512 |
+
def hermdiv(c1, c2):
|
| 513 |
+
"""
|
| 514 |
+
Divide one Hermite series by another.
|
| 515 |
+
|
| 516 |
+
Returns the quotient-with-remainder of two Hermite series
|
| 517 |
+
`c1` / `c2`. The arguments are sequences of coefficients from lowest
|
| 518 |
+
order "term" to highest, e.g., [1,2,3] represents the series
|
| 519 |
+
``P_0 + 2*P_1 + 3*P_2``.
|
| 520 |
+
|
| 521 |
+
Parameters
|
| 522 |
+
----------
|
| 523 |
+
c1, c2 : array_like
|
| 524 |
+
1-D arrays of Hermite series coefficients ordered from low to
|
| 525 |
+
high.
|
| 526 |
+
|
| 527 |
+
Returns
|
| 528 |
+
-------
|
| 529 |
+
[quo, rem] : ndarrays
|
| 530 |
+
Of Hermite series coefficients representing the quotient and
|
| 531 |
+
remainder.
|
| 532 |
+
|
| 533 |
+
See Also
|
| 534 |
+
--------
|
| 535 |
+
hermadd, hermsub, hermmulx, hermmul, hermpow
|
| 536 |
+
|
| 537 |
+
Notes
|
| 538 |
+
-----
|
| 539 |
+
In general, the (polynomial) division of one Hermite series by another
|
| 540 |
+
results in quotient and remainder terms that are not in the Hermite
|
| 541 |
+
polynomial basis set. Thus, to express these results as a Hermite
|
| 542 |
+
series, it is necessary to "reproject" the results onto the Hermite
|
| 543 |
+
basis set, which may produce "unintuitive" (but correct) results; see
|
| 544 |
+
Examples section below.
|
| 545 |
+
|
| 546 |
+
Examples
|
| 547 |
+
--------
|
| 548 |
+
>>> from numpy.polynomial.hermite import hermdiv
|
| 549 |
+
>>> hermdiv([ 52., 29., 52., 7., 6.], [0, 1, 2])
|
| 550 |
+
(array([1., 2., 3.]), array([0.]))
|
| 551 |
+
>>> hermdiv([ 54., 31., 52., 7., 6.], [0, 1, 2])
|
| 552 |
+
(array([1., 2., 3.]), array([2., 2.]))
|
| 553 |
+
>>> hermdiv([ 53., 30., 52., 7., 6.], [0, 1, 2])
|
| 554 |
+
(array([1., 2., 3.]), array([1., 1.]))
|
| 555 |
+
|
| 556 |
+
"""
|
| 557 |
+
return pu._div(hermmul, c1, c2)
|
| 558 |
+
|
| 559 |
+
|
| 560 |
+
def hermpow(c, pow, maxpower=16):
|
| 561 |
+
"""Raise a Hermite series to a power.
|
| 562 |
+
|
| 563 |
+
Returns the Hermite series `c` raised to the power `pow`. The
|
| 564 |
+
argument `c` is a sequence of coefficients ordered from low to high.
|
| 565 |
+
i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.``
|
| 566 |
+
|
| 567 |
+
Parameters
|
| 568 |
+
----------
|
| 569 |
+
c : array_like
|
| 570 |
+
1-D array of Hermite series coefficients ordered from low to
|
| 571 |
+
high.
|
| 572 |
+
pow : integer
|
| 573 |
+
Power to which the series will be raised
|
| 574 |
+
maxpower : integer, optional
|
| 575 |
+
Maximum power allowed. This is mainly to limit growth of the series
|
| 576 |
+
to unmanageable size. Default is 16
|
| 577 |
+
|
| 578 |
+
Returns
|
| 579 |
+
-------
|
| 580 |
+
coef : ndarray
|
| 581 |
+
Hermite series of power.
|
| 582 |
+
|
| 583 |
+
See Also
|
| 584 |
+
--------
|
| 585 |
+
hermadd, hermsub, hermmulx, hermmul, hermdiv
|
| 586 |
+
|
| 587 |
+
Examples
|
| 588 |
+
--------
|
| 589 |
+
>>> from numpy.polynomial.hermite import hermpow
|
| 590 |
+
>>> hermpow([1, 2, 3], 2)
|
| 591 |
+
array([81., 52., 82., 12., 9.])
|
| 592 |
+
|
| 593 |
+
"""
|
| 594 |
+
return pu._pow(hermmul, c, pow, maxpower)
|
| 595 |
+
|
| 596 |
+
|
| 597 |
+
def hermder(c, m=1, scl=1, axis=0):
|
| 598 |
+
"""
|
| 599 |
+
Differentiate a Hermite series.
|
| 600 |
+
|
| 601 |
+
Returns the Hermite series coefficients `c` differentiated `m` times
|
| 602 |
+
along `axis`. At each iteration the result is multiplied by `scl` (the
|
| 603 |
+
scaling factor is for use in a linear change of variable). The argument
|
| 604 |
+
`c` is an array of coefficients from low to high degree along each
|
| 605 |
+
axis, e.g., [1,2,3] represents the series ``1*H_0 + 2*H_1 + 3*H_2``
|
| 606 |
+
while [[1,2],[1,2]] represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) +
|
| 607 |
+
2*H_0(x)*H_1(y) + 2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is
|
| 608 |
+
``y``.
|
| 609 |
+
|
| 610 |
+
Parameters
|
| 611 |
+
----------
|
| 612 |
+
c : array_like
|
| 613 |
+
Array of Hermite series coefficients. If `c` is multidimensional the
|
| 614 |
+
different axis correspond to different variables with the degree in
|
| 615 |
+
each axis given by the corresponding index.
|
| 616 |
+
m : int, optional
|
| 617 |
+
Number of derivatives taken, must be non-negative. (Default: 1)
|
| 618 |
+
scl : scalar, optional
|
| 619 |
+
Each differentiation is multiplied by `scl`. The end result is
|
| 620 |
+
multiplication by ``scl**m``. This is for use in a linear change of
|
| 621 |
+
variable. (Default: 1)
|
| 622 |
+
axis : int, optional
|
| 623 |
+
Axis over which the derivative is taken. (Default: 0).
|
| 624 |
+
|
| 625 |
+
.. versionadded:: 1.7.0
|
| 626 |
+
|
| 627 |
+
Returns
|
| 628 |
+
-------
|
| 629 |
+
der : ndarray
|
| 630 |
+
Hermite series of the derivative.
|
| 631 |
+
|
| 632 |
+
See Also
|
| 633 |
+
--------
|
| 634 |
+
hermint
|
| 635 |
+
|
| 636 |
+
Notes
|
| 637 |
+
-----
|
| 638 |
+
In general, the result of differentiating a Hermite series does not
|
| 639 |
+
resemble the same operation on a power series. Thus the result of this
|
| 640 |
+
function may be "unintuitive," albeit correct; see Examples section
|
| 641 |
+
below.
|
| 642 |
+
|
| 643 |
+
Examples
|
| 644 |
+
--------
|
| 645 |
+
>>> from numpy.polynomial.hermite import hermder
|
| 646 |
+
>>> hermder([ 1. , 0.5, 0.5, 0.5])
|
| 647 |
+
array([1., 2., 3.])
|
| 648 |
+
>>> hermder([-0.5, 1./2., 1./8., 1./12., 1./16.], m=2)
|
| 649 |
+
array([1., 2., 3.])
|
| 650 |
+
|
| 651 |
+
"""
|
| 652 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 653 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 654 |
+
c = c.astype(np.double)
|
| 655 |
+
cnt = pu._deprecate_as_int(m, "the order of derivation")
|
| 656 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 657 |
+
if cnt < 0:
|
| 658 |
+
raise ValueError("The order of derivation must be non-negative")
|
| 659 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 660 |
+
|
| 661 |
+
if cnt == 0:
|
| 662 |
+
return c
|
| 663 |
+
|
| 664 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 665 |
+
n = len(c)
|
| 666 |
+
if cnt >= n:
|
| 667 |
+
c = c[:1]*0
|
| 668 |
+
else:
|
| 669 |
+
for i in range(cnt):
|
| 670 |
+
n = n - 1
|
| 671 |
+
c *= scl
|
| 672 |
+
der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
|
| 673 |
+
for j in range(n, 0, -1):
|
| 674 |
+
der[j - 1] = (2*j)*c[j]
|
| 675 |
+
c = der
|
| 676 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 677 |
+
return c
|
| 678 |
+
|
| 679 |
+
|
| 680 |
+
def hermint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
|
| 681 |
+
"""
|
| 682 |
+
Integrate a Hermite series.
|
| 683 |
+
|
| 684 |
+
Returns the Hermite series coefficients `c` integrated `m` times from
|
| 685 |
+
`lbnd` along `axis`. At each iteration the resulting series is
|
| 686 |
+
**multiplied** by `scl` and an integration constant, `k`, is added.
|
| 687 |
+
The scaling factor is for use in a linear change of variable. ("Buyer
|
| 688 |
+
beware": note that, depending on what one is doing, one may want `scl`
|
| 689 |
+
to be the reciprocal of what one might expect; for more information,
|
| 690 |
+
see the Notes section below.) The argument `c` is an array of
|
| 691 |
+
coefficients from low to high degree along each axis, e.g., [1,2,3]
|
| 692 |
+
represents the series ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]]
|
| 693 |
+
represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) +
|
| 694 |
+
2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
|
| 695 |
+
|
| 696 |
+
Parameters
|
| 697 |
+
----------
|
| 698 |
+
c : array_like
|
| 699 |
+
Array of Hermite series coefficients. If c is multidimensional the
|
| 700 |
+
different axis correspond to different variables with the degree in
|
| 701 |
+
each axis given by the corresponding index.
|
| 702 |
+
m : int, optional
|
| 703 |
+
Order of integration, must be positive. (Default: 1)
|
| 704 |
+
k : {[], list, scalar}, optional
|
| 705 |
+
Integration constant(s). The value of the first integral at
|
| 706 |
+
``lbnd`` is the first value in the list, the value of the second
|
| 707 |
+
integral at ``lbnd`` is the second value, etc. If ``k == []`` (the
|
| 708 |
+
default), all constants are set to zero. If ``m == 1``, a single
|
| 709 |
+
scalar can be given instead of a list.
|
| 710 |
+
lbnd : scalar, optional
|
| 711 |
+
The lower bound of the integral. (Default: 0)
|
| 712 |
+
scl : scalar, optional
|
| 713 |
+
Following each integration the result is *multiplied* by `scl`
|
| 714 |
+
before the integration constant is added. (Default: 1)
|
| 715 |
+
axis : int, optional
|
| 716 |
+
Axis over which the integral is taken. (Default: 0).
|
| 717 |
+
|
| 718 |
+
.. versionadded:: 1.7.0
|
| 719 |
+
|
| 720 |
+
Returns
|
| 721 |
+
-------
|
| 722 |
+
S : ndarray
|
| 723 |
+
Hermite series coefficients of the integral.
|
| 724 |
+
|
| 725 |
+
Raises
|
| 726 |
+
------
|
| 727 |
+
ValueError
|
| 728 |
+
If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or
|
| 729 |
+
``np.ndim(scl) != 0``.
|
| 730 |
+
|
| 731 |
+
See Also
|
| 732 |
+
--------
|
| 733 |
+
hermder
|
| 734 |
+
|
| 735 |
+
Notes
|
| 736 |
+
-----
|
| 737 |
+
Note that the result of each integration is *multiplied* by `scl`.
|
| 738 |
+
Why is this important to note? Say one is making a linear change of
|
| 739 |
+
variable :math:`u = ax + b` in an integral relative to `x`. Then
|
| 740 |
+
:math:`dx = du/a`, so one will need to set `scl` equal to
|
| 741 |
+
:math:`1/a` - perhaps not what one would have first thought.
|
| 742 |
+
|
| 743 |
+
Also note that, in general, the result of integrating a C-series needs
|
| 744 |
+
to be "reprojected" onto the C-series basis set. Thus, typically,
|
| 745 |
+
the result of this function is "unintuitive," albeit correct; see
|
| 746 |
+
Examples section below.
|
| 747 |
+
|
| 748 |
+
Examples
|
| 749 |
+
--------
|
| 750 |
+
>>> from numpy.polynomial.hermite import hermint
|
| 751 |
+
>>> hermint([1,2,3]) # integrate once, value 0 at 0.
|
| 752 |
+
array([1. , 0.5, 0.5, 0.5])
|
| 753 |
+
>>> hermint([1,2,3], m=2) # integrate twice, value & deriv 0 at 0
|
| 754 |
+
array([-0.5 , 0.5 , 0.125 , 0.08333333, 0.0625 ]) # may vary
|
| 755 |
+
>>> hermint([1,2,3], k=1) # integrate once, value 1 at 0.
|
| 756 |
+
array([2. , 0.5, 0.5, 0.5])
|
| 757 |
+
>>> hermint([1,2,3], lbnd=-1) # integrate once, value 0 at -1
|
| 758 |
+
array([-2. , 0.5, 0.5, 0.5])
|
| 759 |
+
>>> hermint([1,2,3], m=2, k=[1,2], lbnd=-1)
|
| 760 |
+
array([ 1.66666667, -0.5 , 0.125 , 0.08333333, 0.0625 ]) # may vary
|
| 761 |
+
|
| 762 |
+
"""
|
| 763 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 764 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 765 |
+
c = c.astype(np.double)
|
| 766 |
+
if not np.iterable(k):
|
| 767 |
+
k = [k]
|
| 768 |
+
cnt = pu._deprecate_as_int(m, "the order of integration")
|
| 769 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 770 |
+
if cnt < 0:
|
| 771 |
+
raise ValueError("The order of integration must be non-negative")
|
| 772 |
+
if len(k) > cnt:
|
| 773 |
+
raise ValueError("Too many integration constants")
|
| 774 |
+
if np.ndim(lbnd) != 0:
|
| 775 |
+
raise ValueError("lbnd must be a scalar.")
|
| 776 |
+
if np.ndim(scl) != 0:
|
| 777 |
+
raise ValueError("scl must be a scalar.")
|
| 778 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 779 |
+
|
| 780 |
+
if cnt == 0:
|
| 781 |
+
return c
|
| 782 |
+
|
| 783 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 784 |
+
k = list(k) + [0]*(cnt - len(k))
|
| 785 |
+
for i in range(cnt):
|
| 786 |
+
n = len(c)
|
| 787 |
+
c *= scl
|
| 788 |
+
if n == 1 and np.all(c[0] == 0):
|
| 789 |
+
c[0] += k[i]
|
| 790 |
+
else:
|
| 791 |
+
tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
|
| 792 |
+
tmp[0] = c[0]*0
|
| 793 |
+
tmp[1] = c[0]/2
|
| 794 |
+
for j in range(1, n):
|
| 795 |
+
tmp[j + 1] = c[j]/(2*(j + 1))
|
| 796 |
+
tmp[0] += k[i] - hermval(lbnd, tmp)
|
| 797 |
+
c = tmp
|
| 798 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 799 |
+
return c
|
| 800 |
+
|
| 801 |
+
|
| 802 |
+
def hermval(x, c, tensor=True):
|
| 803 |
+
"""
|
| 804 |
+
Evaluate an Hermite series at points x.
|
| 805 |
+
|
| 806 |
+
If `c` is of length `n + 1`, this function returns the value:
|
| 807 |
+
|
| 808 |
+
.. math:: p(x) = c_0 * H_0(x) + c_1 * H_1(x) + ... + c_n * H_n(x)
|
| 809 |
+
|
| 810 |
+
The parameter `x` is converted to an array only if it is a tuple or a
|
| 811 |
+
list, otherwise it is treated as a scalar. In either case, either `x`
|
| 812 |
+
or its elements must support multiplication and addition both with
|
| 813 |
+
themselves and with the elements of `c`.
|
| 814 |
+
|
| 815 |
+
If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If
|
| 816 |
+
`c` is multidimensional, then the shape of the result depends on the
|
| 817 |
+
value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
|
| 818 |
+
x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
|
| 819 |
+
scalars have shape (,).
|
| 820 |
+
|
| 821 |
+
Trailing zeros in the coefficients will be used in the evaluation, so
|
| 822 |
+
they should be avoided if efficiency is a concern.
|
| 823 |
+
|
| 824 |
+
Parameters
|
| 825 |
+
----------
|
| 826 |
+
x : array_like, compatible object
|
| 827 |
+
If `x` is a list or tuple, it is converted to an ndarray, otherwise
|
| 828 |
+
it is left unchanged and treated as a scalar. In either case, `x`
|
| 829 |
+
or its elements must support addition and multiplication with
|
| 830 |
+
themselves and with the elements of `c`.
|
| 831 |
+
c : array_like
|
| 832 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 833 |
+
degree n are contained in c[n]. If `c` is multidimensional the
|
| 834 |
+
remaining indices enumerate multiple polynomials. In the two
|
| 835 |
+
dimensional case the coefficients may be thought of as stored in
|
| 836 |
+
the columns of `c`.
|
| 837 |
+
tensor : boolean, optional
|
| 838 |
+
If True, the shape of the coefficient array is extended with ones
|
| 839 |
+
on the right, one for each dimension of `x`. Scalars have dimension 0
|
| 840 |
+
for this action. The result is that every column of coefficients in
|
| 841 |
+
`c` is evaluated for every element of `x`. If False, `x` is broadcast
|
| 842 |
+
over the columns of `c` for the evaluation. This keyword is useful
|
| 843 |
+
when `c` is multidimensional. The default value is True.
|
| 844 |
+
|
| 845 |
+
.. versionadded:: 1.7.0
|
| 846 |
+
|
| 847 |
+
Returns
|
| 848 |
+
-------
|
| 849 |
+
values : ndarray, algebra_like
|
| 850 |
+
The shape of the return value is described above.
|
| 851 |
+
|
| 852 |
+
See Also
|
| 853 |
+
--------
|
| 854 |
+
hermval2d, hermgrid2d, hermval3d, hermgrid3d
|
| 855 |
+
|
| 856 |
+
Notes
|
| 857 |
+
-----
|
| 858 |
+
The evaluation uses Clenshaw recursion, aka synthetic division.
|
| 859 |
+
|
| 860 |
+
Examples
|
| 861 |
+
--------
|
| 862 |
+
>>> from numpy.polynomial.hermite import hermval
|
| 863 |
+
>>> coef = [1,2,3]
|
| 864 |
+
>>> hermval(1, coef)
|
| 865 |
+
11.0
|
| 866 |
+
>>> hermval([[1,2],[3,4]], coef)
|
| 867 |
+
array([[ 11., 51.],
|
| 868 |
+
[115., 203.]])
|
| 869 |
+
|
| 870 |
+
"""
|
| 871 |
+
c = np.array(c, ndmin=1, copy=False)
|
| 872 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 873 |
+
c = c.astype(np.double)
|
| 874 |
+
if isinstance(x, (tuple, list)):
|
| 875 |
+
x = np.asarray(x)
|
| 876 |
+
if isinstance(x, np.ndarray) and tensor:
|
| 877 |
+
c = c.reshape(c.shape + (1,)*x.ndim)
|
| 878 |
+
|
| 879 |
+
x2 = x*2
|
| 880 |
+
if len(c) == 1:
|
| 881 |
+
c0 = c[0]
|
| 882 |
+
c1 = 0
|
| 883 |
+
elif len(c) == 2:
|
| 884 |
+
c0 = c[0]
|
| 885 |
+
c1 = c[1]
|
| 886 |
+
else:
|
| 887 |
+
nd = len(c)
|
| 888 |
+
c0 = c[-2]
|
| 889 |
+
c1 = c[-1]
|
| 890 |
+
for i in range(3, len(c) + 1):
|
| 891 |
+
tmp = c0
|
| 892 |
+
nd = nd - 1
|
| 893 |
+
c0 = c[-i] - c1*(2*(nd - 1))
|
| 894 |
+
c1 = tmp + c1*x2
|
| 895 |
+
return c0 + c1*x2
|
| 896 |
+
|
| 897 |
+
|
| 898 |
+
def hermval2d(x, y, c):
|
| 899 |
+
"""
|
| 900 |
+
Evaluate a 2-D Hermite series at points (x, y).
|
| 901 |
+
|
| 902 |
+
This function returns the values:
|
| 903 |
+
|
| 904 |
+
.. math:: p(x,y) = \\sum_{i,j} c_{i,j} * H_i(x) * H_j(y)
|
| 905 |
+
|
| 906 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 907 |
+
tuples or a lists, otherwise they are treated as a scalars and they
|
| 908 |
+
must have the same shape after conversion. In either case, either `x`
|
| 909 |
+
and `y` or their elements must support multiplication and addition both
|
| 910 |
+
with themselves and with the elements of `c`.
|
| 911 |
+
|
| 912 |
+
If `c` is a 1-D array a one is implicitly appended to its shape to make
|
| 913 |
+
it 2-D. The shape of the result will be c.shape[2:] + x.shape.
|
| 914 |
+
|
| 915 |
+
Parameters
|
| 916 |
+
----------
|
| 917 |
+
x, y : array_like, compatible objects
|
| 918 |
+
The two dimensional series is evaluated at the points `(x, y)`,
|
| 919 |
+
where `x` and `y` must have the same shape. If `x` or `y` is a list
|
| 920 |
+
or tuple, it is first converted to an ndarray, otherwise it is left
|
| 921 |
+
unchanged and if it isn't an ndarray it is treated as a scalar.
|
| 922 |
+
c : array_like
|
| 923 |
+
Array of coefficients ordered so that the coefficient of the term
|
| 924 |
+
of multi-degree i,j is contained in ``c[i,j]``. If `c` has
|
| 925 |
+
dimension greater than two the remaining indices enumerate multiple
|
| 926 |
+
sets of coefficients.
|
| 927 |
+
|
| 928 |
+
Returns
|
| 929 |
+
-------
|
| 930 |
+
values : ndarray, compatible object
|
| 931 |
+
The values of the two dimensional polynomial at points formed with
|
| 932 |
+
pairs of corresponding values from `x` and `y`.
|
| 933 |
+
|
| 934 |
+
See Also
|
| 935 |
+
--------
|
| 936 |
+
hermval, hermgrid2d, hermval3d, hermgrid3d
|
| 937 |
+
|
| 938 |
+
Notes
|
| 939 |
+
-----
|
| 940 |
+
|
| 941 |
+
.. versionadded:: 1.7.0
|
| 942 |
+
|
| 943 |
+
"""
|
| 944 |
+
return pu._valnd(hermval, c, x, y)
|
| 945 |
+
|
| 946 |
+
|
| 947 |
+
def hermgrid2d(x, y, c):
|
| 948 |
+
"""
|
| 949 |
+
Evaluate a 2-D Hermite series on the Cartesian product of x and y.
|
| 950 |
+
|
| 951 |
+
This function returns the values:
|
| 952 |
+
|
| 953 |
+
.. math:: p(a,b) = \\sum_{i,j} c_{i,j} * H_i(a) * H_j(b)
|
| 954 |
+
|
| 955 |
+
where the points `(a, b)` consist of all pairs formed by taking
|
| 956 |
+
`a` from `x` and `b` from `y`. The resulting points form a grid with
|
| 957 |
+
`x` in the first dimension and `y` in the second.
|
| 958 |
+
|
| 959 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 960 |
+
tuples or a lists, otherwise they are treated as a scalars. In either
|
| 961 |
+
case, either `x` and `y` or their elements must support multiplication
|
| 962 |
+
and addition both with themselves and with the elements of `c`.
|
| 963 |
+
|
| 964 |
+
If `c` has fewer than two dimensions, ones are implicitly appended to
|
| 965 |
+
its shape to make it 2-D. The shape of the result will be c.shape[2:] +
|
| 966 |
+
x.shape.
|
| 967 |
+
|
| 968 |
+
Parameters
|
| 969 |
+
----------
|
| 970 |
+
x, y : array_like, compatible objects
|
| 971 |
+
The two dimensional series is evaluated at the points in the
|
| 972 |
+
Cartesian product of `x` and `y`. If `x` or `y` is a list or
|
| 973 |
+
tuple, it is first converted to an ndarray, otherwise it is left
|
| 974 |
+
unchanged and, if it isn't an ndarray, it is treated as a scalar.
|
| 975 |
+
c : array_like
|
| 976 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 977 |
+
degree i,j are contained in ``c[i,j]``. If `c` has dimension
|
| 978 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 979 |
+
coefficients.
|
| 980 |
+
|
| 981 |
+
Returns
|
| 982 |
+
-------
|
| 983 |
+
values : ndarray, compatible object
|
| 984 |
+
The values of the two dimensional polynomial at points in the Cartesian
|
| 985 |
+
product of `x` and `y`.
|
| 986 |
+
|
| 987 |
+
See Also
|
| 988 |
+
--------
|
| 989 |
+
hermval, hermval2d, hermval3d, hermgrid3d
|
| 990 |
+
|
| 991 |
+
Notes
|
| 992 |
+
-----
|
| 993 |
+
|
| 994 |
+
.. versionadded:: 1.7.0
|
| 995 |
+
|
| 996 |
+
"""
|
| 997 |
+
return pu._gridnd(hermval, c, x, y)
|
| 998 |
+
|
| 999 |
+
|
| 1000 |
+
def hermval3d(x, y, z, c):
|
| 1001 |
+
"""
|
| 1002 |
+
Evaluate a 3-D Hermite series at points (x, y, z).
|
| 1003 |
+
|
| 1004 |
+
This function returns the values:
|
| 1005 |
+
|
| 1006 |
+
.. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * H_i(x) * H_j(y) * H_k(z)
|
| 1007 |
+
|
| 1008 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if
|
| 1009 |
+
they are tuples or a lists, otherwise they are treated as a scalars and
|
| 1010 |
+
they must have the same shape after conversion. In either case, either
|
| 1011 |
+
`x`, `y`, and `z` or their elements must support multiplication and
|
| 1012 |
+
addition both with themselves and with the elements of `c`.
|
| 1013 |
+
|
| 1014 |
+
If `c` has fewer than 3 dimensions, ones are implicitly appended to its
|
| 1015 |
+
shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1016 |
+
x.shape.
|
| 1017 |
+
|
| 1018 |
+
Parameters
|
| 1019 |
+
----------
|
| 1020 |
+
x, y, z : array_like, compatible object
|
| 1021 |
+
The three dimensional series is evaluated at the points
|
| 1022 |
+
`(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If
|
| 1023 |
+
any of `x`, `y`, or `z` is a list or tuple, it is first converted
|
| 1024 |
+
to an ndarray, otherwise it is left unchanged and if it isn't an
|
| 1025 |
+
ndarray it is treated as a scalar.
|
| 1026 |
+
c : array_like
|
| 1027 |
+
Array of coefficients ordered so that the coefficient of the term of
|
| 1028 |
+
multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
|
| 1029 |
+
greater than 3 the remaining indices enumerate multiple sets of
|
| 1030 |
+
coefficients.
|
| 1031 |
+
|
| 1032 |
+
Returns
|
| 1033 |
+
-------
|
| 1034 |
+
values : ndarray, compatible object
|
| 1035 |
+
The values of the multidimensional polynomial on points formed with
|
| 1036 |
+
triples of corresponding values from `x`, `y`, and `z`.
|
| 1037 |
+
|
| 1038 |
+
See Also
|
| 1039 |
+
--------
|
| 1040 |
+
hermval, hermval2d, hermgrid2d, hermgrid3d
|
| 1041 |
+
|
| 1042 |
+
Notes
|
| 1043 |
+
-----
|
| 1044 |
+
|
| 1045 |
+
.. versionadded:: 1.7.0
|
| 1046 |
+
|
| 1047 |
+
"""
|
| 1048 |
+
return pu._valnd(hermval, c, x, y, z)
|
| 1049 |
+
|
| 1050 |
+
|
| 1051 |
+
def hermgrid3d(x, y, z, c):
|
| 1052 |
+
"""
|
| 1053 |
+
Evaluate a 3-D Hermite series on the Cartesian product of x, y, and z.
|
| 1054 |
+
|
| 1055 |
+
This function returns the values:
|
| 1056 |
+
|
| 1057 |
+
.. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * H_i(a) * H_j(b) * H_k(c)
|
| 1058 |
+
|
| 1059 |
+
where the points `(a, b, c)` consist of all triples formed by taking
|
| 1060 |
+
`a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
|
| 1061 |
+
a grid with `x` in the first dimension, `y` in the second, and `z` in
|
| 1062 |
+
the third.
|
| 1063 |
+
|
| 1064 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if they
|
| 1065 |
+
are tuples or a lists, otherwise they are treated as a scalars. In
|
| 1066 |
+
either case, either `x`, `y`, and `z` or their elements must support
|
| 1067 |
+
multiplication and addition both with themselves and with the elements
|
| 1068 |
+
of `c`.
|
| 1069 |
+
|
| 1070 |
+
If `c` has fewer than three dimensions, ones are implicitly appended to
|
| 1071 |
+
its shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1072 |
+
x.shape + y.shape + z.shape.
|
| 1073 |
+
|
| 1074 |
+
Parameters
|
| 1075 |
+
----------
|
| 1076 |
+
x, y, z : array_like, compatible objects
|
| 1077 |
+
The three dimensional series is evaluated at the points in the
|
| 1078 |
+
Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a
|
| 1079 |
+
list or tuple, it is first converted to an ndarray, otherwise it is
|
| 1080 |
+
left unchanged and, if it isn't an ndarray, it is treated as a
|
| 1081 |
+
scalar.
|
| 1082 |
+
c : array_like
|
| 1083 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 1084 |
+
degree i,j are contained in ``c[i,j]``. If `c` has dimension
|
| 1085 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 1086 |
+
coefficients.
|
| 1087 |
+
|
| 1088 |
+
Returns
|
| 1089 |
+
-------
|
| 1090 |
+
values : ndarray, compatible object
|
| 1091 |
+
The values of the two dimensional polynomial at points in the Cartesian
|
| 1092 |
+
product of `x` and `y`.
|
| 1093 |
+
|
| 1094 |
+
See Also
|
| 1095 |
+
--------
|
| 1096 |
+
hermval, hermval2d, hermgrid2d, hermval3d
|
| 1097 |
+
|
| 1098 |
+
Notes
|
| 1099 |
+
-----
|
| 1100 |
+
|
| 1101 |
+
.. versionadded:: 1.7.0
|
| 1102 |
+
|
| 1103 |
+
"""
|
| 1104 |
+
return pu._gridnd(hermval, c, x, y, z)
|
| 1105 |
+
|
| 1106 |
+
|
| 1107 |
+
def hermvander(x, deg):
|
| 1108 |
+
"""Pseudo-Vandermonde matrix of given degree.
|
| 1109 |
+
|
| 1110 |
+
Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
|
| 1111 |
+
`x`. The pseudo-Vandermonde matrix is defined by
|
| 1112 |
+
|
| 1113 |
+
.. math:: V[..., i] = H_i(x),
|
| 1114 |
+
|
| 1115 |
+
where `0 <= i <= deg`. The leading indices of `V` index the elements of
|
| 1116 |
+
`x` and the last index is the degree of the Hermite polynomial.
|
| 1117 |
+
|
| 1118 |
+
If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
|
| 1119 |
+
array ``V = hermvander(x, n)``, then ``np.dot(V, c)`` and
|
| 1120 |
+
``hermval(x, c)`` are the same up to roundoff. This equivalence is
|
| 1121 |
+
useful both for least squares fitting and for the evaluation of a large
|
| 1122 |
+
number of Hermite series of the same degree and sample points.
|
| 1123 |
+
|
| 1124 |
+
Parameters
|
| 1125 |
+
----------
|
| 1126 |
+
x : array_like
|
| 1127 |
+
Array of points. The dtype is converted to float64 or complex128
|
| 1128 |
+
depending on whether any of the elements are complex. If `x` is
|
| 1129 |
+
scalar it is converted to a 1-D array.
|
| 1130 |
+
deg : int
|
| 1131 |
+
Degree of the resulting matrix.
|
| 1132 |
+
|
| 1133 |
+
Returns
|
| 1134 |
+
-------
|
| 1135 |
+
vander : ndarray
|
| 1136 |
+
The pseudo-Vandermonde matrix. The shape of the returned matrix is
|
| 1137 |
+
``x.shape + (deg + 1,)``, where The last index is the degree of the
|
| 1138 |
+
corresponding Hermite polynomial. The dtype will be the same as
|
| 1139 |
+
the converted `x`.
|
| 1140 |
+
|
| 1141 |
+
Examples
|
| 1142 |
+
--------
|
| 1143 |
+
>>> from numpy.polynomial.hermite import hermvander
|
| 1144 |
+
>>> x = np.array([-1, 0, 1])
|
| 1145 |
+
>>> hermvander(x, 3)
|
| 1146 |
+
array([[ 1., -2., 2., 4.],
|
| 1147 |
+
[ 1., 0., -2., -0.],
|
| 1148 |
+
[ 1., 2., 2., -4.]])
|
| 1149 |
+
|
| 1150 |
+
"""
|
| 1151 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1152 |
+
if ideg < 0:
|
| 1153 |
+
raise ValueError("deg must be non-negative")
|
| 1154 |
+
|
| 1155 |
+
x = np.array(x, copy=False, ndmin=1) + 0.0
|
| 1156 |
+
dims = (ideg + 1,) + x.shape
|
| 1157 |
+
dtyp = x.dtype
|
| 1158 |
+
v = np.empty(dims, dtype=dtyp)
|
| 1159 |
+
v[0] = x*0 + 1
|
| 1160 |
+
if ideg > 0:
|
| 1161 |
+
x2 = x*2
|
| 1162 |
+
v[1] = x2
|
| 1163 |
+
for i in range(2, ideg + 1):
|
| 1164 |
+
v[i] = (v[i-1]*x2 - v[i-2]*(2*(i - 1)))
|
| 1165 |
+
return np.moveaxis(v, 0, -1)
|
| 1166 |
+
|
| 1167 |
+
|
| 1168 |
+
def hermvander2d(x, y, deg):
|
| 1169 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1170 |
+
|
| 1171 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1172 |
+
points `(x, y)`. The pseudo-Vandermonde matrix is defined by
|
| 1173 |
+
|
| 1174 |
+
.. math:: V[..., (deg[1] + 1)*i + j] = H_i(x) * H_j(y),
|
| 1175 |
+
|
| 1176 |
+
where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
|
| 1177 |
+
`V` index the points `(x, y)` and the last index encodes the degrees of
|
| 1178 |
+
the Hermite polynomials.
|
| 1179 |
+
|
| 1180 |
+
If ``V = hermvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
|
| 1181 |
+
correspond to the elements of a 2-D coefficient array `c` of shape
|
| 1182 |
+
(xdeg + 1, ydeg + 1) in the order
|
| 1183 |
+
|
| 1184 |
+
.. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
|
| 1185 |
+
|
| 1186 |
+
and ``np.dot(V, c.flat)`` and ``hermval2d(x, y, c)`` will be the same
|
| 1187 |
+
up to roundoff. This equivalence is useful both for least squares
|
| 1188 |
+
fitting and for the evaluation of a large number of 2-D Hermite
|
| 1189 |
+
series of the same degrees and sample points.
|
| 1190 |
+
|
| 1191 |
+
Parameters
|
| 1192 |
+
----------
|
| 1193 |
+
x, y : array_like
|
| 1194 |
+
Arrays of point coordinates, all of the same shape. The dtypes
|
| 1195 |
+
will be converted to either float64 or complex128 depending on
|
| 1196 |
+
whether any of the elements are complex. Scalars are converted to 1-D
|
| 1197 |
+
arrays.
|
| 1198 |
+
deg : list of ints
|
| 1199 |
+
List of maximum degrees of the form [x_deg, y_deg].
|
| 1200 |
+
|
| 1201 |
+
Returns
|
| 1202 |
+
-------
|
| 1203 |
+
vander2d : ndarray
|
| 1204 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1205 |
+
:math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same
|
| 1206 |
+
as the converted `x` and `y`.
|
| 1207 |
+
|
| 1208 |
+
See Also
|
| 1209 |
+
--------
|
| 1210 |
+
hermvander, hermvander3d, hermval2d, hermval3d
|
| 1211 |
+
|
| 1212 |
+
Notes
|
| 1213 |
+
-----
|
| 1214 |
+
|
| 1215 |
+
.. versionadded:: 1.7.0
|
| 1216 |
+
|
| 1217 |
+
"""
|
| 1218 |
+
return pu._vander_nd_flat((hermvander, hermvander), (x, y), deg)
|
| 1219 |
+
|
| 1220 |
+
|
| 1221 |
+
def hermvander3d(x, y, z, deg):
|
| 1222 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1223 |
+
|
| 1224 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1225 |
+
points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
|
| 1226 |
+
then The pseudo-Vandermonde matrix is defined by
|
| 1227 |
+
|
| 1228 |
+
.. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = H_i(x)*H_j(y)*H_k(z),
|
| 1229 |
+
|
| 1230 |
+
where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading
|
| 1231 |
+
indices of `V` index the points `(x, y, z)` and the last index encodes
|
| 1232 |
+
the degrees of the Hermite polynomials.
|
| 1233 |
+
|
| 1234 |
+
If ``V = hermvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
|
| 1235 |
+
of `V` correspond to the elements of a 3-D coefficient array `c` of
|
| 1236 |
+
shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
|
| 1237 |
+
|
| 1238 |
+
.. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
|
| 1239 |
+
|
| 1240 |
+
and ``np.dot(V, c.flat)`` and ``hermval3d(x, y, z, c)`` will be the
|
| 1241 |
+
same up to roundoff. This equivalence is useful both for least squares
|
| 1242 |
+
fitting and for the evaluation of a large number of 3-D Hermite
|
| 1243 |
+
series of the same degrees and sample points.
|
| 1244 |
+
|
| 1245 |
+
Parameters
|
| 1246 |
+
----------
|
| 1247 |
+
x, y, z : array_like
|
| 1248 |
+
Arrays of point coordinates, all of the same shape. The dtypes will
|
| 1249 |
+
be converted to either float64 or complex128 depending on whether
|
| 1250 |
+
any of the elements are complex. Scalars are converted to 1-D
|
| 1251 |
+
arrays.
|
| 1252 |
+
deg : list of ints
|
| 1253 |
+
List of maximum degrees of the form [x_deg, y_deg, z_deg].
|
| 1254 |
+
|
| 1255 |
+
Returns
|
| 1256 |
+
-------
|
| 1257 |
+
vander3d : ndarray
|
| 1258 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1259 |
+
:math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will
|
| 1260 |
+
be the same as the converted `x`, `y`, and `z`.
|
| 1261 |
+
|
| 1262 |
+
See Also
|
| 1263 |
+
--------
|
| 1264 |
+
hermvander, hermvander3d, hermval2d, hermval3d
|
| 1265 |
+
|
| 1266 |
+
Notes
|
| 1267 |
+
-----
|
| 1268 |
+
|
| 1269 |
+
.. versionadded:: 1.7.0
|
| 1270 |
+
|
| 1271 |
+
"""
|
| 1272 |
+
return pu._vander_nd_flat((hermvander, hermvander, hermvander), (x, y, z), deg)
|
| 1273 |
+
|
| 1274 |
+
|
| 1275 |
+
def hermfit(x, y, deg, rcond=None, full=False, w=None):
|
| 1276 |
+
"""
|
| 1277 |
+
Least squares fit of Hermite series to data.
|
| 1278 |
+
|
| 1279 |
+
Return the coefficients of a Hermite series of degree `deg` that is the
|
| 1280 |
+
least squares fit to the data values `y` given at points `x`. If `y` is
|
| 1281 |
+
1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
|
| 1282 |
+
fits are done, one for each column of `y`, and the resulting
|
| 1283 |
+
coefficients are stored in the corresponding columns of a 2-D return.
|
| 1284 |
+
The fitted polynomial(s) are in the form
|
| 1285 |
+
|
| 1286 |
+
.. math:: p(x) = c_0 + c_1 * H_1(x) + ... + c_n * H_n(x),
|
| 1287 |
+
|
| 1288 |
+
where `n` is `deg`.
|
| 1289 |
+
|
| 1290 |
+
Parameters
|
| 1291 |
+
----------
|
| 1292 |
+
x : array_like, shape (M,)
|
| 1293 |
+
x-coordinates of the M sample points ``(x[i], y[i])``.
|
| 1294 |
+
y : array_like, shape (M,) or (M, K)
|
| 1295 |
+
y-coordinates of the sample points. Several data sets of sample
|
| 1296 |
+
points sharing the same x-coordinates can be fitted at once by
|
| 1297 |
+
passing in a 2D-array that contains one dataset per column.
|
| 1298 |
+
deg : int or 1-D array_like
|
| 1299 |
+
Degree(s) of the fitting polynomials. If `deg` is a single integer
|
| 1300 |
+
all terms up to and including the `deg`'th term are included in the
|
| 1301 |
+
fit. For NumPy versions >= 1.11.0 a list of integers specifying the
|
| 1302 |
+
degrees of the terms to include may be used instead.
|
| 1303 |
+
rcond : float, optional
|
| 1304 |
+
Relative condition number of the fit. Singular values smaller than
|
| 1305 |
+
this relative to the largest singular value will be ignored. The
|
| 1306 |
+
default value is len(x)*eps, where eps is the relative precision of
|
| 1307 |
+
the float type, about 2e-16 in most cases.
|
| 1308 |
+
full : bool, optional
|
| 1309 |
+
Switch determining nature of return value. When it is False (the
|
| 1310 |
+
default) just the coefficients are returned, when True diagnostic
|
| 1311 |
+
information from the singular value decomposition is also returned.
|
| 1312 |
+
w : array_like, shape (`M`,), optional
|
| 1313 |
+
Weights. If not None, the weight ``w[i]`` applies to the unsquared
|
| 1314 |
+
residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
|
| 1315 |
+
chosen so that the errors of the products ``w[i]*y[i]`` all have the
|
| 1316 |
+
same variance. When using inverse-variance weighting, use
|
| 1317 |
+
``w[i] = 1/sigma(y[i])``. The default value is None.
|
| 1318 |
+
|
| 1319 |
+
Returns
|
| 1320 |
+
-------
|
| 1321 |
+
coef : ndarray, shape (M,) or (M, K)
|
| 1322 |
+
Hermite coefficients ordered from low to high. If `y` was 2-D,
|
| 1323 |
+
the coefficients for the data in column k of `y` are in column
|
| 1324 |
+
`k`.
|
| 1325 |
+
|
| 1326 |
+
[residuals, rank, singular_values, rcond] : list
|
| 1327 |
+
These values are only returned if ``full == True``
|
| 1328 |
+
|
| 1329 |
+
- residuals -- sum of squared residuals of the least squares fit
|
| 1330 |
+
- rank -- the numerical rank of the scaled Vandermonde matrix
|
| 1331 |
+
- singular_values -- singular values of the scaled Vandermonde matrix
|
| 1332 |
+
- rcond -- value of `rcond`.
|
| 1333 |
+
|
| 1334 |
+
For more details, see `numpy.linalg.lstsq`.
|
| 1335 |
+
|
| 1336 |
+
Warns
|
| 1337 |
+
-----
|
| 1338 |
+
RankWarning
|
| 1339 |
+
The rank of the coefficient matrix in the least-squares fit is
|
| 1340 |
+
deficient. The warning is only raised if ``full == False``. The
|
| 1341 |
+
warnings can be turned off by
|
| 1342 |
+
|
| 1343 |
+
>>> import warnings
|
| 1344 |
+
>>> warnings.simplefilter('ignore', np.RankWarning)
|
| 1345 |
+
|
| 1346 |
+
See Also
|
| 1347 |
+
--------
|
| 1348 |
+
numpy.polynomial.chebyshev.chebfit
|
| 1349 |
+
numpy.polynomial.legendre.legfit
|
| 1350 |
+
numpy.polynomial.laguerre.lagfit
|
| 1351 |
+
numpy.polynomial.polynomial.polyfit
|
| 1352 |
+
numpy.polynomial.hermite_e.hermefit
|
| 1353 |
+
hermval : Evaluates a Hermite series.
|
| 1354 |
+
hermvander : Vandermonde matrix of Hermite series.
|
| 1355 |
+
hermweight : Hermite weight function
|
| 1356 |
+
numpy.linalg.lstsq : Computes a least-squares fit from the matrix.
|
| 1357 |
+
scipy.interpolate.UnivariateSpline : Computes spline fits.
|
| 1358 |
+
|
| 1359 |
+
Notes
|
| 1360 |
+
-----
|
| 1361 |
+
The solution is the coefficients of the Hermite series `p` that
|
| 1362 |
+
minimizes the sum of the weighted squared errors
|
| 1363 |
+
|
| 1364 |
+
.. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
|
| 1365 |
+
|
| 1366 |
+
where the :math:`w_j` are the weights. This problem is solved by
|
| 1367 |
+
setting up the (typically) overdetermined matrix equation
|
| 1368 |
+
|
| 1369 |
+
.. math:: V(x) * c = w * y,
|
| 1370 |
+
|
| 1371 |
+
where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
|
| 1372 |
+
coefficients to be solved for, `w` are the weights, `y` are the
|
| 1373 |
+
observed values. This equation is then solved using the singular value
|
| 1374 |
+
decomposition of `V`.
|
| 1375 |
+
|
| 1376 |
+
If some of the singular values of `V` are so small that they are
|
| 1377 |
+
neglected, then a `RankWarning` will be issued. This means that the
|
| 1378 |
+
coefficient values may be poorly determined. Using a lower order fit
|
| 1379 |
+
will usually get rid of the warning. The `rcond` parameter can also be
|
| 1380 |
+
set to a value smaller than its default, but the resulting fit may be
|
| 1381 |
+
spurious and have large contributions from roundoff error.
|
| 1382 |
+
|
| 1383 |
+
Fits using Hermite series are probably most useful when the data can be
|
| 1384 |
+
approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the Hermite
|
| 1385 |
+
weight. In that case the weight ``sqrt(w(x[i]))`` should be used
|
| 1386 |
+
together with data values ``y[i]/sqrt(w(x[i]))``. The weight function is
|
| 1387 |
+
available as `hermweight`.
|
| 1388 |
+
|
| 1389 |
+
References
|
| 1390 |
+
----------
|
| 1391 |
+
.. [1] Wikipedia, "Curve fitting",
|
| 1392 |
+
https://en.wikipedia.org/wiki/Curve_fitting
|
| 1393 |
+
|
| 1394 |
+
Examples
|
| 1395 |
+
--------
|
| 1396 |
+
>>> from numpy.polynomial.hermite import hermfit, hermval
|
| 1397 |
+
>>> x = np.linspace(-10, 10)
|
| 1398 |
+
>>> err = np.random.randn(len(x))/10
|
| 1399 |
+
>>> y = hermval(x, [1, 2, 3]) + err
|
| 1400 |
+
>>> hermfit(x, y, 2)
|
| 1401 |
+
array([1.0218, 1.9986, 2.9999]) # may vary
|
| 1402 |
+
|
| 1403 |
+
"""
|
| 1404 |
+
return pu._fit(hermvander, x, y, deg, rcond, full, w)
|
| 1405 |
+
|
| 1406 |
+
|
| 1407 |
+
def hermcompanion(c):
|
| 1408 |
+
"""Return the scaled companion matrix of c.
|
| 1409 |
+
|
| 1410 |
+
The basis polynomials are scaled so that the companion matrix is
|
| 1411 |
+
symmetric when `c` is an Hermite basis polynomial. This provides
|
| 1412 |
+
better eigenvalue estimates than the unscaled case and for basis
|
| 1413 |
+
polynomials the eigenvalues are guaranteed to be real if
|
| 1414 |
+
`numpy.linalg.eigvalsh` is used to obtain them.
|
| 1415 |
+
|
| 1416 |
+
Parameters
|
| 1417 |
+
----------
|
| 1418 |
+
c : array_like
|
| 1419 |
+
1-D array of Hermite series coefficients ordered from low to high
|
| 1420 |
+
degree.
|
| 1421 |
+
|
| 1422 |
+
Returns
|
| 1423 |
+
-------
|
| 1424 |
+
mat : ndarray
|
| 1425 |
+
Scaled companion matrix of dimensions (deg, deg).
|
| 1426 |
+
|
| 1427 |
+
Notes
|
| 1428 |
+
-----
|
| 1429 |
+
|
| 1430 |
+
.. versionadded:: 1.7.0
|
| 1431 |
+
|
| 1432 |
+
"""
|
| 1433 |
+
# c is a trimmed copy
|
| 1434 |
+
[c] = pu.as_series([c])
|
| 1435 |
+
if len(c) < 2:
|
| 1436 |
+
raise ValueError('Series must have maximum degree of at least 1.')
|
| 1437 |
+
if len(c) == 2:
|
| 1438 |
+
return np.array([[-.5*c[0]/c[1]]])
|
| 1439 |
+
|
| 1440 |
+
n = len(c) - 1
|
| 1441 |
+
mat = np.zeros((n, n), dtype=c.dtype)
|
| 1442 |
+
scl = np.hstack((1., 1./np.sqrt(2.*np.arange(n - 1, 0, -1))))
|
| 1443 |
+
scl = np.multiply.accumulate(scl)[::-1]
|
| 1444 |
+
top = mat.reshape(-1)[1::n+1]
|
| 1445 |
+
bot = mat.reshape(-1)[n::n+1]
|
| 1446 |
+
top[...] = np.sqrt(.5*np.arange(1, n))
|
| 1447 |
+
bot[...] = top
|
| 1448 |
+
mat[:, -1] -= scl*c[:-1]/(2.0*c[-1])
|
| 1449 |
+
return mat
|
| 1450 |
+
|
| 1451 |
+
|
| 1452 |
+
def hermroots(c):
|
| 1453 |
+
"""
|
| 1454 |
+
Compute the roots of a Hermite series.
|
| 1455 |
+
|
| 1456 |
+
Return the roots (a.k.a. "zeros") of the polynomial
|
| 1457 |
+
|
| 1458 |
+
.. math:: p(x) = \\sum_i c[i] * H_i(x).
|
| 1459 |
+
|
| 1460 |
+
Parameters
|
| 1461 |
+
----------
|
| 1462 |
+
c : 1-D array_like
|
| 1463 |
+
1-D array of coefficients.
|
| 1464 |
+
|
| 1465 |
+
Returns
|
| 1466 |
+
-------
|
| 1467 |
+
out : ndarray
|
| 1468 |
+
Array of the roots of the series. If all the roots are real,
|
| 1469 |
+
then `out` is also real, otherwise it is complex.
|
| 1470 |
+
|
| 1471 |
+
See Also
|
| 1472 |
+
--------
|
| 1473 |
+
numpy.polynomial.polynomial.polyroots
|
| 1474 |
+
numpy.polynomial.legendre.legroots
|
| 1475 |
+
numpy.polynomial.laguerre.lagroots
|
| 1476 |
+
numpy.polynomial.chebyshev.chebroots
|
| 1477 |
+
numpy.polynomial.hermite_e.hermeroots
|
| 1478 |
+
|
| 1479 |
+
Notes
|
| 1480 |
+
-----
|
| 1481 |
+
The root estimates are obtained as the eigenvalues of the companion
|
| 1482 |
+
matrix, Roots far from the origin of the complex plane may have large
|
| 1483 |
+
errors due to the numerical instability of the series for such
|
| 1484 |
+
values. Roots with multiplicity greater than 1 will also show larger
|
| 1485 |
+
errors as the value of the series near such points is relatively
|
| 1486 |
+
insensitive to errors in the roots. Isolated roots near the origin can
|
| 1487 |
+
be improved by a few iterations of Newton's method.
|
| 1488 |
+
|
| 1489 |
+
The Hermite series basis polynomials aren't powers of `x` so the
|
| 1490 |
+
results of this function may seem unintuitive.
|
| 1491 |
+
|
| 1492 |
+
Examples
|
| 1493 |
+
--------
|
| 1494 |
+
>>> from numpy.polynomial.hermite import hermroots, hermfromroots
|
| 1495 |
+
>>> coef = hermfromroots([-1, 0, 1])
|
| 1496 |
+
>>> coef
|
| 1497 |
+
array([0. , 0.25 , 0. , 0.125])
|
| 1498 |
+
>>> hermroots(coef)
|
| 1499 |
+
array([-1.00000000e+00, -1.38777878e-17, 1.00000000e+00])
|
| 1500 |
+
|
| 1501 |
+
"""
|
| 1502 |
+
# c is a trimmed copy
|
| 1503 |
+
[c] = pu.as_series([c])
|
| 1504 |
+
if len(c) <= 1:
|
| 1505 |
+
return np.array([], dtype=c.dtype)
|
| 1506 |
+
if len(c) == 2:
|
| 1507 |
+
return np.array([-.5*c[0]/c[1]])
|
| 1508 |
+
|
| 1509 |
+
# rotated companion matrix reduces error
|
| 1510 |
+
m = hermcompanion(c)[::-1,::-1]
|
| 1511 |
+
r = la.eigvals(m)
|
| 1512 |
+
r.sort()
|
| 1513 |
+
return r
|
| 1514 |
+
|
| 1515 |
+
|
| 1516 |
+
def _normed_hermite_n(x, n):
|
| 1517 |
+
"""
|
| 1518 |
+
Evaluate a normalized Hermite polynomial.
|
| 1519 |
+
|
| 1520 |
+
Compute the value of the normalized Hermite polynomial of degree ``n``
|
| 1521 |
+
at the points ``x``.
|
| 1522 |
+
|
| 1523 |
+
|
| 1524 |
+
Parameters
|
| 1525 |
+
----------
|
| 1526 |
+
x : ndarray of double.
|
| 1527 |
+
Points at which to evaluate the function
|
| 1528 |
+
n : int
|
| 1529 |
+
Degree of the normalized Hermite function to be evaluated.
|
| 1530 |
+
|
| 1531 |
+
Returns
|
| 1532 |
+
-------
|
| 1533 |
+
values : ndarray
|
| 1534 |
+
The shape of the return value is described above.
|
| 1535 |
+
|
| 1536 |
+
Notes
|
| 1537 |
+
-----
|
| 1538 |
+
.. versionadded:: 1.10.0
|
| 1539 |
+
|
| 1540 |
+
This function is needed for finding the Gauss points and integration
|
| 1541 |
+
weights for high degrees. The values of the standard Hermite functions
|
| 1542 |
+
overflow when n >= 207.
|
| 1543 |
+
|
| 1544 |
+
"""
|
| 1545 |
+
if n == 0:
|
| 1546 |
+
return np.full(x.shape, 1/np.sqrt(np.sqrt(np.pi)))
|
| 1547 |
+
|
| 1548 |
+
c0 = 0.
|
| 1549 |
+
c1 = 1./np.sqrt(np.sqrt(np.pi))
|
| 1550 |
+
nd = float(n)
|
| 1551 |
+
for i in range(n - 1):
|
| 1552 |
+
tmp = c0
|
| 1553 |
+
c0 = -c1*np.sqrt((nd - 1.)/nd)
|
| 1554 |
+
c1 = tmp + c1*x*np.sqrt(2./nd)
|
| 1555 |
+
nd = nd - 1.0
|
| 1556 |
+
return c0 + c1*x*np.sqrt(2)
|
| 1557 |
+
|
| 1558 |
+
|
| 1559 |
+
def hermgauss(deg):
|
| 1560 |
+
"""
|
| 1561 |
+
Gauss-Hermite quadrature.
|
| 1562 |
+
|
| 1563 |
+
Computes the sample points and weights for Gauss-Hermite quadrature.
|
| 1564 |
+
These sample points and weights will correctly integrate polynomials of
|
| 1565 |
+
degree :math:`2*deg - 1` or less over the interval :math:`[-\\inf, \\inf]`
|
| 1566 |
+
with the weight function :math:`f(x) = \\exp(-x^2)`.
|
| 1567 |
+
|
| 1568 |
+
Parameters
|
| 1569 |
+
----------
|
| 1570 |
+
deg : int
|
| 1571 |
+
Number of sample points and weights. It must be >= 1.
|
| 1572 |
+
|
| 1573 |
+
Returns
|
| 1574 |
+
-------
|
| 1575 |
+
x : ndarray
|
| 1576 |
+
1-D ndarray containing the sample points.
|
| 1577 |
+
y : ndarray
|
| 1578 |
+
1-D ndarray containing the weights.
|
| 1579 |
+
|
| 1580 |
+
Notes
|
| 1581 |
+
-----
|
| 1582 |
+
|
| 1583 |
+
.. versionadded:: 1.7.0
|
| 1584 |
+
|
| 1585 |
+
The results have only been tested up to degree 100, higher degrees may
|
| 1586 |
+
be problematic. The weights are determined by using the fact that
|
| 1587 |
+
|
| 1588 |
+
.. math:: w_k = c / (H'_n(x_k) * H_{n-1}(x_k))
|
| 1589 |
+
|
| 1590 |
+
where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
|
| 1591 |
+
is the k'th root of :math:`H_n`, and then scaling the results to get
|
| 1592 |
+
the right value when integrating 1.
|
| 1593 |
+
|
| 1594 |
+
"""
|
| 1595 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1596 |
+
if ideg <= 0:
|
| 1597 |
+
raise ValueError("deg must be a positive integer")
|
| 1598 |
+
|
| 1599 |
+
# first approximation of roots. We use the fact that the companion
|
| 1600 |
+
# matrix is symmetric in this case in order to obtain better zeros.
|
| 1601 |
+
c = np.array([0]*deg + [1], dtype=np.float64)
|
| 1602 |
+
m = hermcompanion(c)
|
| 1603 |
+
x = la.eigvalsh(m)
|
| 1604 |
+
|
| 1605 |
+
# improve roots by one application of Newton
|
| 1606 |
+
dy = _normed_hermite_n(x, ideg)
|
| 1607 |
+
df = _normed_hermite_n(x, ideg - 1) * np.sqrt(2*ideg)
|
| 1608 |
+
x -= dy/df
|
| 1609 |
+
|
| 1610 |
+
# compute the weights. We scale the factor to avoid possible numerical
|
| 1611 |
+
# overflow.
|
| 1612 |
+
fm = _normed_hermite_n(x, ideg - 1)
|
| 1613 |
+
fm /= np.abs(fm).max()
|
| 1614 |
+
w = 1/(fm * fm)
|
| 1615 |
+
|
| 1616 |
+
# for Hermite we can also symmetrize
|
| 1617 |
+
w = (w + w[::-1])/2
|
| 1618 |
+
x = (x - x[::-1])/2
|
| 1619 |
+
|
| 1620 |
+
# scale w to get the right value
|
| 1621 |
+
w *= np.sqrt(np.pi) / w.sum()
|
| 1622 |
+
|
| 1623 |
+
return x, w
|
| 1624 |
+
|
| 1625 |
+
|
| 1626 |
+
def hermweight(x):
|
| 1627 |
+
"""
|
| 1628 |
+
Weight function of the Hermite polynomials.
|
| 1629 |
+
|
| 1630 |
+
The weight function is :math:`\\exp(-x^2)` and the interval of
|
| 1631 |
+
integration is :math:`[-\\inf, \\inf]`. the Hermite polynomials are
|
| 1632 |
+
orthogonal, but not normalized, with respect to this weight function.
|
| 1633 |
+
|
| 1634 |
+
Parameters
|
| 1635 |
+
----------
|
| 1636 |
+
x : array_like
|
| 1637 |
+
Values at which the weight function will be computed.
|
| 1638 |
+
|
| 1639 |
+
Returns
|
| 1640 |
+
-------
|
| 1641 |
+
w : ndarray
|
| 1642 |
+
The weight function at `x`.
|
| 1643 |
+
|
| 1644 |
+
Notes
|
| 1645 |
+
-----
|
| 1646 |
+
|
| 1647 |
+
.. versionadded:: 1.7.0
|
| 1648 |
+
|
| 1649 |
+
"""
|
| 1650 |
+
w = np.exp(-x**2)
|
| 1651 |
+
return w
|
| 1652 |
+
|
| 1653 |
+
|
| 1654 |
+
#
|
| 1655 |
+
# Hermite series class
|
| 1656 |
+
#
|
| 1657 |
+
|
| 1658 |
+
class Hermite(ABCPolyBase):
|
| 1659 |
+
"""An Hermite series class.
|
| 1660 |
+
|
| 1661 |
+
The Hermite class provides the standard Python numerical methods
|
| 1662 |
+
'+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
|
| 1663 |
+
attributes and methods listed in the `ABCPolyBase` documentation.
|
| 1664 |
+
|
| 1665 |
+
Parameters
|
| 1666 |
+
----------
|
| 1667 |
+
coef : array_like
|
| 1668 |
+
Hermite coefficients in order of increasing degree, i.e,
|
| 1669 |
+
``(1, 2, 3)`` gives ``1*H_0(x) + 2*H_1(X) + 3*H_2(x)``.
|
| 1670 |
+
domain : (2,) array_like, optional
|
| 1671 |
+
Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
|
| 1672 |
+
to the interval ``[window[0], window[1]]`` by shifting and scaling.
|
| 1673 |
+
The default value is [-1, 1].
|
| 1674 |
+
window : (2,) array_like, optional
|
| 1675 |
+
Window, see `domain` for its use. The default value is [-1, 1].
|
| 1676 |
+
|
| 1677 |
+
.. versionadded:: 1.6.0
|
| 1678 |
+
symbol : str, optional
|
| 1679 |
+
Symbol used to represent the independent variable in string
|
| 1680 |
+
representations of the polynomial expression, e.g. for printing.
|
| 1681 |
+
The symbol must be a valid Python identifier. Default value is 'x'.
|
| 1682 |
+
|
| 1683 |
+
.. versionadded:: 1.24
|
| 1684 |
+
|
| 1685 |
+
"""
|
| 1686 |
+
# Virtual Functions
|
| 1687 |
+
_add = staticmethod(hermadd)
|
| 1688 |
+
_sub = staticmethod(hermsub)
|
| 1689 |
+
_mul = staticmethod(hermmul)
|
| 1690 |
+
_div = staticmethod(hermdiv)
|
| 1691 |
+
_pow = staticmethod(hermpow)
|
| 1692 |
+
_val = staticmethod(hermval)
|
| 1693 |
+
_int = staticmethod(hermint)
|
| 1694 |
+
_der = staticmethod(hermder)
|
| 1695 |
+
_fit = staticmethod(hermfit)
|
| 1696 |
+
_line = staticmethod(hermline)
|
| 1697 |
+
_roots = staticmethod(hermroots)
|
| 1698 |
+
_fromroots = staticmethod(hermfromroots)
|
| 1699 |
+
|
| 1700 |
+
# Virtual properties
|
| 1701 |
+
domain = np.array(hermdomain)
|
| 1702 |
+
window = np.array(hermdomain)
|
| 1703 |
+
basis_name = 'H'
|
lib/python3.12/site-packages/numpy/polynomial/hermite.pyi
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any
|
| 2 |
+
|
| 3 |
+
from numpy import ndarray, dtype, int_, float_
|
| 4 |
+
from numpy.polynomial._polybase import ABCPolyBase
|
| 5 |
+
from numpy.polynomial.polyutils import trimcoef
|
| 6 |
+
|
| 7 |
+
__all__: list[str]
|
| 8 |
+
|
| 9 |
+
hermtrim = trimcoef
|
| 10 |
+
|
| 11 |
+
def poly2herm(pol): ...
|
| 12 |
+
def herm2poly(c): ...
|
| 13 |
+
|
| 14 |
+
hermdomain: ndarray[Any, dtype[int_]]
|
| 15 |
+
hermzero: ndarray[Any, dtype[int_]]
|
| 16 |
+
hermone: ndarray[Any, dtype[int_]]
|
| 17 |
+
hermx: ndarray[Any, dtype[float_]]
|
| 18 |
+
|
| 19 |
+
def hermline(off, scl): ...
|
| 20 |
+
def hermfromroots(roots): ...
|
| 21 |
+
def hermadd(c1, c2): ...
|
| 22 |
+
def hermsub(c1, c2): ...
|
| 23 |
+
def hermmulx(c): ...
|
| 24 |
+
def hermmul(c1, c2): ...
|
| 25 |
+
def hermdiv(c1, c2): ...
|
| 26 |
+
def hermpow(c, pow, maxpower=...): ...
|
| 27 |
+
def hermder(c, m=..., scl=..., axis=...): ...
|
| 28 |
+
def hermint(c, m=..., k = ..., lbnd=..., scl=..., axis=...): ...
|
| 29 |
+
def hermval(x, c, tensor=...): ...
|
| 30 |
+
def hermval2d(x, y, c): ...
|
| 31 |
+
def hermgrid2d(x, y, c): ...
|
| 32 |
+
def hermval3d(x, y, z, c): ...
|
| 33 |
+
def hermgrid3d(x, y, z, c): ...
|
| 34 |
+
def hermvander(x, deg): ...
|
| 35 |
+
def hermvander2d(x, y, deg): ...
|
| 36 |
+
def hermvander3d(x, y, z, deg): ...
|
| 37 |
+
def hermfit(x, y, deg, rcond=..., full=..., w=...): ...
|
| 38 |
+
def hermcompanion(c): ...
|
| 39 |
+
def hermroots(c): ...
|
| 40 |
+
def hermgauss(deg): ...
|
| 41 |
+
def hermweight(x): ...
|
| 42 |
+
|
| 43 |
+
class Hermite(ABCPolyBase):
|
| 44 |
+
domain: Any
|
| 45 |
+
window: Any
|
| 46 |
+
basis_name: Any
|
lib/python3.12/site-packages/numpy/polynomial/hermite_e.py
ADDED
|
@@ -0,0 +1,1695 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
===================================================================
|
| 3 |
+
HermiteE Series, "Probabilists" (:mod:`numpy.polynomial.hermite_e`)
|
| 4 |
+
===================================================================
|
| 5 |
+
|
| 6 |
+
This module provides a number of objects (mostly functions) useful for
|
| 7 |
+
dealing with Hermite_e series, including a `HermiteE` class that
|
| 8 |
+
encapsulates the usual arithmetic operations. (General information
|
| 9 |
+
on how this module represents and works with such polynomials is in the
|
| 10 |
+
docstring for its "parent" sub-package, `numpy.polynomial`).
|
| 11 |
+
|
| 12 |
+
Classes
|
| 13 |
+
-------
|
| 14 |
+
.. autosummary::
|
| 15 |
+
:toctree: generated/
|
| 16 |
+
|
| 17 |
+
HermiteE
|
| 18 |
+
|
| 19 |
+
Constants
|
| 20 |
+
---------
|
| 21 |
+
.. autosummary::
|
| 22 |
+
:toctree: generated/
|
| 23 |
+
|
| 24 |
+
hermedomain
|
| 25 |
+
hermezero
|
| 26 |
+
hermeone
|
| 27 |
+
hermex
|
| 28 |
+
|
| 29 |
+
Arithmetic
|
| 30 |
+
----------
|
| 31 |
+
.. autosummary::
|
| 32 |
+
:toctree: generated/
|
| 33 |
+
|
| 34 |
+
hermeadd
|
| 35 |
+
hermesub
|
| 36 |
+
hermemulx
|
| 37 |
+
hermemul
|
| 38 |
+
hermediv
|
| 39 |
+
hermepow
|
| 40 |
+
hermeval
|
| 41 |
+
hermeval2d
|
| 42 |
+
hermeval3d
|
| 43 |
+
hermegrid2d
|
| 44 |
+
hermegrid3d
|
| 45 |
+
|
| 46 |
+
Calculus
|
| 47 |
+
--------
|
| 48 |
+
.. autosummary::
|
| 49 |
+
:toctree: generated/
|
| 50 |
+
|
| 51 |
+
hermeder
|
| 52 |
+
hermeint
|
| 53 |
+
|
| 54 |
+
Misc Functions
|
| 55 |
+
--------------
|
| 56 |
+
.. autosummary::
|
| 57 |
+
:toctree: generated/
|
| 58 |
+
|
| 59 |
+
hermefromroots
|
| 60 |
+
hermeroots
|
| 61 |
+
hermevander
|
| 62 |
+
hermevander2d
|
| 63 |
+
hermevander3d
|
| 64 |
+
hermegauss
|
| 65 |
+
hermeweight
|
| 66 |
+
hermecompanion
|
| 67 |
+
hermefit
|
| 68 |
+
hermetrim
|
| 69 |
+
hermeline
|
| 70 |
+
herme2poly
|
| 71 |
+
poly2herme
|
| 72 |
+
|
| 73 |
+
See also
|
| 74 |
+
--------
|
| 75 |
+
`numpy.polynomial`
|
| 76 |
+
|
| 77 |
+
"""
|
| 78 |
+
import numpy as np
|
| 79 |
+
import numpy.linalg as la
|
| 80 |
+
from numpy.core.multiarray import normalize_axis_index
|
| 81 |
+
|
| 82 |
+
from . import polyutils as pu
|
| 83 |
+
from ._polybase import ABCPolyBase
|
| 84 |
+
|
| 85 |
+
__all__ = [
|
| 86 |
+
'hermezero', 'hermeone', 'hermex', 'hermedomain', 'hermeline',
|
| 87 |
+
'hermeadd', 'hermesub', 'hermemulx', 'hermemul', 'hermediv',
|
| 88 |
+
'hermepow', 'hermeval', 'hermeder', 'hermeint', 'herme2poly',
|
| 89 |
+
'poly2herme', 'hermefromroots', 'hermevander', 'hermefit', 'hermetrim',
|
| 90 |
+
'hermeroots', 'HermiteE', 'hermeval2d', 'hermeval3d', 'hermegrid2d',
|
| 91 |
+
'hermegrid3d', 'hermevander2d', 'hermevander3d', 'hermecompanion',
|
| 92 |
+
'hermegauss', 'hermeweight']
|
| 93 |
+
|
| 94 |
+
hermetrim = pu.trimcoef
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
def poly2herme(pol):
|
| 98 |
+
"""
|
| 99 |
+
poly2herme(pol)
|
| 100 |
+
|
| 101 |
+
Convert a polynomial to a Hermite series.
|
| 102 |
+
|
| 103 |
+
Convert an array representing the coefficients of a polynomial (relative
|
| 104 |
+
to the "standard" basis) ordered from lowest degree to highest, to an
|
| 105 |
+
array of the coefficients of the equivalent Hermite series, ordered
|
| 106 |
+
from lowest to highest degree.
|
| 107 |
+
|
| 108 |
+
Parameters
|
| 109 |
+
----------
|
| 110 |
+
pol : array_like
|
| 111 |
+
1-D array containing the polynomial coefficients
|
| 112 |
+
|
| 113 |
+
Returns
|
| 114 |
+
-------
|
| 115 |
+
c : ndarray
|
| 116 |
+
1-D array containing the coefficients of the equivalent Hermite
|
| 117 |
+
series.
|
| 118 |
+
|
| 119 |
+
See Also
|
| 120 |
+
--------
|
| 121 |
+
herme2poly
|
| 122 |
+
|
| 123 |
+
Notes
|
| 124 |
+
-----
|
| 125 |
+
The easy way to do conversions between polynomial basis sets
|
| 126 |
+
is to use the convert method of a class instance.
|
| 127 |
+
|
| 128 |
+
Examples
|
| 129 |
+
--------
|
| 130 |
+
>>> from numpy.polynomial.hermite_e import poly2herme
|
| 131 |
+
>>> poly2herme(np.arange(4))
|
| 132 |
+
array([ 2., 10., 2., 3.])
|
| 133 |
+
|
| 134 |
+
"""
|
| 135 |
+
[pol] = pu.as_series([pol])
|
| 136 |
+
deg = len(pol) - 1
|
| 137 |
+
res = 0
|
| 138 |
+
for i in range(deg, -1, -1):
|
| 139 |
+
res = hermeadd(hermemulx(res), pol[i])
|
| 140 |
+
return res
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
def herme2poly(c):
|
| 144 |
+
"""
|
| 145 |
+
Convert a Hermite series to a polynomial.
|
| 146 |
+
|
| 147 |
+
Convert an array representing the coefficients of a Hermite series,
|
| 148 |
+
ordered from lowest degree to highest, to an array of the coefficients
|
| 149 |
+
of the equivalent polynomial (relative to the "standard" basis) ordered
|
| 150 |
+
from lowest to highest degree.
|
| 151 |
+
|
| 152 |
+
Parameters
|
| 153 |
+
----------
|
| 154 |
+
c : array_like
|
| 155 |
+
1-D array containing the Hermite series coefficients, ordered
|
| 156 |
+
from lowest order term to highest.
|
| 157 |
+
|
| 158 |
+
Returns
|
| 159 |
+
-------
|
| 160 |
+
pol : ndarray
|
| 161 |
+
1-D array containing the coefficients of the equivalent polynomial
|
| 162 |
+
(relative to the "standard" basis) ordered from lowest order term
|
| 163 |
+
to highest.
|
| 164 |
+
|
| 165 |
+
See Also
|
| 166 |
+
--------
|
| 167 |
+
poly2herme
|
| 168 |
+
|
| 169 |
+
Notes
|
| 170 |
+
-----
|
| 171 |
+
The easy way to do conversions between polynomial basis sets
|
| 172 |
+
is to use the convert method of a class instance.
|
| 173 |
+
|
| 174 |
+
Examples
|
| 175 |
+
--------
|
| 176 |
+
>>> from numpy.polynomial.hermite_e import herme2poly
|
| 177 |
+
>>> herme2poly([ 2., 10., 2., 3.])
|
| 178 |
+
array([0., 1., 2., 3.])
|
| 179 |
+
|
| 180 |
+
"""
|
| 181 |
+
from .polynomial import polyadd, polysub, polymulx
|
| 182 |
+
|
| 183 |
+
[c] = pu.as_series([c])
|
| 184 |
+
n = len(c)
|
| 185 |
+
if n == 1:
|
| 186 |
+
return c
|
| 187 |
+
if n == 2:
|
| 188 |
+
return c
|
| 189 |
+
else:
|
| 190 |
+
c0 = c[-2]
|
| 191 |
+
c1 = c[-1]
|
| 192 |
+
# i is the current degree of c1
|
| 193 |
+
for i in range(n - 1, 1, -1):
|
| 194 |
+
tmp = c0
|
| 195 |
+
c0 = polysub(c[i - 2], c1*(i - 1))
|
| 196 |
+
c1 = polyadd(tmp, polymulx(c1))
|
| 197 |
+
return polyadd(c0, polymulx(c1))
|
| 198 |
+
|
| 199 |
+
#
|
| 200 |
+
# These are constant arrays are of integer type so as to be compatible
|
| 201 |
+
# with the widest range of other types, such as Decimal.
|
| 202 |
+
#
|
| 203 |
+
|
| 204 |
+
# Hermite
|
| 205 |
+
hermedomain = np.array([-1, 1])
|
| 206 |
+
|
| 207 |
+
# Hermite coefficients representing zero.
|
| 208 |
+
hermezero = np.array([0])
|
| 209 |
+
|
| 210 |
+
# Hermite coefficients representing one.
|
| 211 |
+
hermeone = np.array([1])
|
| 212 |
+
|
| 213 |
+
# Hermite coefficients representing the identity x.
|
| 214 |
+
hermex = np.array([0, 1])
|
| 215 |
+
|
| 216 |
+
|
| 217 |
+
def hermeline(off, scl):
|
| 218 |
+
"""
|
| 219 |
+
Hermite series whose graph is a straight line.
|
| 220 |
+
|
| 221 |
+
Parameters
|
| 222 |
+
----------
|
| 223 |
+
off, scl : scalars
|
| 224 |
+
The specified line is given by ``off + scl*x``.
|
| 225 |
+
|
| 226 |
+
Returns
|
| 227 |
+
-------
|
| 228 |
+
y : ndarray
|
| 229 |
+
This module's representation of the Hermite series for
|
| 230 |
+
``off + scl*x``.
|
| 231 |
+
|
| 232 |
+
See Also
|
| 233 |
+
--------
|
| 234 |
+
numpy.polynomial.polynomial.polyline
|
| 235 |
+
numpy.polynomial.chebyshev.chebline
|
| 236 |
+
numpy.polynomial.legendre.legline
|
| 237 |
+
numpy.polynomial.laguerre.lagline
|
| 238 |
+
numpy.polynomial.hermite.hermline
|
| 239 |
+
|
| 240 |
+
Examples
|
| 241 |
+
--------
|
| 242 |
+
>>> from numpy.polynomial.hermite_e import hermeline
|
| 243 |
+
>>> from numpy.polynomial.hermite_e import hermeline, hermeval
|
| 244 |
+
>>> hermeval(0,hermeline(3, 2))
|
| 245 |
+
3.0
|
| 246 |
+
>>> hermeval(1,hermeline(3, 2))
|
| 247 |
+
5.0
|
| 248 |
+
|
| 249 |
+
"""
|
| 250 |
+
if scl != 0:
|
| 251 |
+
return np.array([off, scl])
|
| 252 |
+
else:
|
| 253 |
+
return np.array([off])
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
def hermefromroots(roots):
|
| 257 |
+
"""
|
| 258 |
+
Generate a HermiteE series with given roots.
|
| 259 |
+
|
| 260 |
+
The function returns the coefficients of the polynomial
|
| 261 |
+
|
| 262 |
+
.. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
|
| 263 |
+
|
| 264 |
+
in HermiteE form, where the `r_n` are the roots specified in `roots`.
|
| 265 |
+
If a zero has multiplicity n, then it must appear in `roots` n times.
|
| 266 |
+
For instance, if 2 is a root of multiplicity three and 3 is a root of
|
| 267 |
+
multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
|
| 268 |
+
roots can appear in any order.
|
| 269 |
+
|
| 270 |
+
If the returned coefficients are `c`, then
|
| 271 |
+
|
| 272 |
+
.. math:: p(x) = c_0 + c_1 * He_1(x) + ... + c_n * He_n(x)
|
| 273 |
+
|
| 274 |
+
The coefficient of the last term is not generally 1 for monic
|
| 275 |
+
polynomials in HermiteE form.
|
| 276 |
+
|
| 277 |
+
Parameters
|
| 278 |
+
----------
|
| 279 |
+
roots : array_like
|
| 280 |
+
Sequence containing the roots.
|
| 281 |
+
|
| 282 |
+
Returns
|
| 283 |
+
-------
|
| 284 |
+
out : ndarray
|
| 285 |
+
1-D array of coefficients. If all roots are real then `out` is a
|
| 286 |
+
real array, if some of the roots are complex, then `out` is complex
|
| 287 |
+
even if all the coefficients in the result are real (see Examples
|
| 288 |
+
below).
|
| 289 |
+
|
| 290 |
+
See Also
|
| 291 |
+
--------
|
| 292 |
+
numpy.polynomial.polynomial.polyfromroots
|
| 293 |
+
numpy.polynomial.legendre.legfromroots
|
| 294 |
+
numpy.polynomial.laguerre.lagfromroots
|
| 295 |
+
numpy.polynomial.hermite.hermfromroots
|
| 296 |
+
numpy.polynomial.chebyshev.chebfromroots
|
| 297 |
+
|
| 298 |
+
Examples
|
| 299 |
+
--------
|
| 300 |
+
>>> from numpy.polynomial.hermite_e import hermefromroots, hermeval
|
| 301 |
+
>>> coef = hermefromroots((-1, 0, 1))
|
| 302 |
+
>>> hermeval((-1, 0, 1), coef)
|
| 303 |
+
array([0., 0., 0.])
|
| 304 |
+
>>> coef = hermefromroots((-1j, 1j))
|
| 305 |
+
>>> hermeval((-1j, 1j), coef)
|
| 306 |
+
array([0.+0.j, 0.+0.j])
|
| 307 |
+
|
| 308 |
+
"""
|
| 309 |
+
return pu._fromroots(hermeline, hermemul, roots)
|
| 310 |
+
|
| 311 |
+
|
| 312 |
+
def hermeadd(c1, c2):
|
| 313 |
+
"""
|
| 314 |
+
Add one Hermite series to another.
|
| 315 |
+
|
| 316 |
+
Returns the sum of two Hermite series `c1` + `c2`. The arguments
|
| 317 |
+
are sequences of coefficients ordered from lowest order term to
|
| 318 |
+
highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 319 |
+
|
| 320 |
+
Parameters
|
| 321 |
+
----------
|
| 322 |
+
c1, c2 : array_like
|
| 323 |
+
1-D arrays of Hermite series coefficients ordered from low to
|
| 324 |
+
high.
|
| 325 |
+
|
| 326 |
+
Returns
|
| 327 |
+
-------
|
| 328 |
+
out : ndarray
|
| 329 |
+
Array representing the Hermite series of their sum.
|
| 330 |
+
|
| 331 |
+
See Also
|
| 332 |
+
--------
|
| 333 |
+
hermesub, hermemulx, hermemul, hermediv, hermepow
|
| 334 |
+
|
| 335 |
+
Notes
|
| 336 |
+
-----
|
| 337 |
+
Unlike multiplication, division, etc., the sum of two Hermite series
|
| 338 |
+
is a Hermite series (without having to "reproject" the result onto
|
| 339 |
+
the basis set) so addition, just like that of "standard" polynomials,
|
| 340 |
+
is simply "component-wise."
|
| 341 |
+
|
| 342 |
+
Examples
|
| 343 |
+
--------
|
| 344 |
+
>>> from numpy.polynomial.hermite_e import hermeadd
|
| 345 |
+
>>> hermeadd([1, 2, 3], [1, 2, 3, 4])
|
| 346 |
+
array([2., 4., 6., 4.])
|
| 347 |
+
|
| 348 |
+
"""
|
| 349 |
+
return pu._add(c1, c2)
|
| 350 |
+
|
| 351 |
+
|
| 352 |
+
def hermesub(c1, c2):
|
| 353 |
+
"""
|
| 354 |
+
Subtract one Hermite series from another.
|
| 355 |
+
|
| 356 |
+
Returns the difference of two Hermite series `c1` - `c2`. The
|
| 357 |
+
sequences of coefficients are from lowest order term to highest, i.e.,
|
| 358 |
+
[1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 359 |
+
|
| 360 |
+
Parameters
|
| 361 |
+
----------
|
| 362 |
+
c1, c2 : array_like
|
| 363 |
+
1-D arrays of Hermite series coefficients ordered from low to
|
| 364 |
+
high.
|
| 365 |
+
|
| 366 |
+
Returns
|
| 367 |
+
-------
|
| 368 |
+
out : ndarray
|
| 369 |
+
Of Hermite series coefficients representing their difference.
|
| 370 |
+
|
| 371 |
+
See Also
|
| 372 |
+
--------
|
| 373 |
+
hermeadd, hermemulx, hermemul, hermediv, hermepow
|
| 374 |
+
|
| 375 |
+
Notes
|
| 376 |
+
-----
|
| 377 |
+
Unlike multiplication, division, etc., the difference of two Hermite
|
| 378 |
+
series is a Hermite series (without having to "reproject" the result
|
| 379 |
+
onto the basis set) so subtraction, just like that of "standard"
|
| 380 |
+
polynomials, is simply "component-wise."
|
| 381 |
+
|
| 382 |
+
Examples
|
| 383 |
+
--------
|
| 384 |
+
>>> from numpy.polynomial.hermite_e import hermesub
|
| 385 |
+
>>> hermesub([1, 2, 3, 4], [1, 2, 3])
|
| 386 |
+
array([0., 0., 0., 4.])
|
| 387 |
+
|
| 388 |
+
"""
|
| 389 |
+
return pu._sub(c1, c2)
|
| 390 |
+
|
| 391 |
+
|
| 392 |
+
def hermemulx(c):
|
| 393 |
+
"""Multiply a Hermite series by x.
|
| 394 |
+
|
| 395 |
+
Multiply the Hermite series `c` by x, where x is the independent
|
| 396 |
+
variable.
|
| 397 |
+
|
| 398 |
+
|
| 399 |
+
Parameters
|
| 400 |
+
----------
|
| 401 |
+
c : array_like
|
| 402 |
+
1-D array of Hermite series coefficients ordered from low to
|
| 403 |
+
high.
|
| 404 |
+
|
| 405 |
+
Returns
|
| 406 |
+
-------
|
| 407 |
+
out : ndarray
|
| 408 |
+
Array representing the result of the multiplication.
|
| 409 |
+
|
| 410 |
+
Notes
|
| 411 |
+
-----
|
| 412 |
+
The multiplication uses the recursion relationship for Hermite
|
| 413 |
+
polynomials in the form
|
| 414 |
+
|
| 415 |
+
.. math::
|
| 416 |
+
|
| 417 |
+
xP_i(x) = (P_{i + 1}(x) + iP_{i - 1}(x)))
|
| 418 |
+
|
| 419 |
+
Examples
|
| 420 |
+
--------
|
| 421 |
+
>>> from numpy.polynomial.hermite_e import hermemulx
|
| 422 |
+
>>> hermemulx([1, 2, 3])
|
| 423 |
+
array([2., 7., 2., 3.])
|
| 424 |
+
|
| 425 |
+
"""
|
| 426 |
+
# c is a trimmed copy
|
| 427 |
+
[c] = pu.as_series([c])
|
| 428 |
+
# The zero series needs special treatment
|
| 429 |
+
if len(c) == 1 and c[0] == 0:
|
| 430 |
+
return c
|
| 431 |
+
|
| 432 |
+
prd = np.empty(len(c) + 1, dtype=c.dtype)
|
| 433 |
+
prd[0] = c[0]*0
|
| 434 |
+
prd[1] = c[0]
|
| 435 |
+
for i in range(1, len(c)):
|
| 436 |
+
prd[i + 1] = c[i]
|
| 437 |
+
prd[i - 1] += c[i]*i
|
| 438 |
+
return prd
|
| 439 |
+
|
| 440 |
+
|
| 441 |
+
def hermemul(c1, c2):
|
| 442 |
+
"""
|
| 443 |
+
Multiply one Hermite series by another.
|
| 444 |
+
|
| 445 |
+
Returns the product of two Hermite series `c1` * `c2`. The arguments
|
| 446 |
+
are sequences of coefficients, from lowest order "term" to highest,
|
| 447 |
+
e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 448 |
+
|
| 449 |
+
Parameters
|
| 450 |
+
----------
|
| 451 |
+
c1, c2 : array_like
|
| 452 |
+
1-D arrays of Hermite series coefficients ordered from low to
|
| 453 |
+
high.
|
| 454 |
+
|
| 455 |
+
Returns
|
| 456 |
+
-------
|
| 457 |
+
out : ndarray
|
| 458 |
+
Of Hermite series coefficients representing their product.
|
| 459 |
+
|
| 460 |
+
See Also
|
| 461 |
+
--------
|
| 462 |
+
hermeadd, hermesub, hermemulx, hermediv, hermepow
|
| 463 |
+
|
| 464 |
+
Notes
|
| 465 |
+
-----
|
| 466 |
+
In general, the (polynomial) product of two C-series results in terms
|
| 467 |
+
that are not in the Hermite polynomial basis set. Thus, to express
|
| 468 |
+
the product as a Hermite series, it is necessary to "reproject" the
|
| 469 |
+
product onto said basis set, which may produce "unintuitive" (but
|
| 470 |
+
correct) results; see Examples section below.
|
| 471 |
+
|
| 472 |
+
Examples
|
| 473 |
+
--------
|
| 474 |
+
>>> from numpy.polynomial.hermite_e import hermemul
|
| 475 |
+
>>> hermemul([1, 2, 3], [0, 1, 2])
|
| 476 |
+
array([14., 15., 28., 7., 6.])
|
| 477 |
+
|
| 478 |
+
"""
|
| 479 |
+
# s1, s2 are trimmed copies
|
| 480 |
+
[c1, c2] = pu.as_series([c1, c2])
|
| 481 |
+
|
| 482 |
+
if len(c1) > len(c2):
|
| 483 |
+
c = c2
|
| 484 |
+
xs = c1
|
| 485 |
+
else:
|
| 486 |
+
c = c1
|
| 487 |
+
xs = c2
|
| 488 |
+
|
| 489 |
+
if len(c) == 1:
|
| 490 |
+
c0 = c[0]*xs
|
| 491 |
+
c1 = 0
|
| 492 |
+
elif len(c) == 2:
|
| 493 |
+
c0 = c[0]*xs
|
| 494 |
+
c1 = c[1]*xs
|
| 495 |
+
else:
|
| 496 |
+
nd = len(c)
|
| 497 |
+
c0 = c[-2]*xs
|
| 498 |
+
c1 = c[-1]*xs
|
| 499 |
+
for i in range(3, len(c) + 1):
|
| 500 |
+
tmp = c0
|
| 501 |
+
nd = nd - 1
|
| 502 |
+
c0 = hermesub(c[-i]*xs, c1*(nd - 1))
|
| 503 |
+
c1 = hermeadd(tmp, hermemulx(c1))
|
| 504 |
+
return hermeadd(c0, hermemulx(c1))
|
| 505 |
+
|
| 506 |
+
|
| 507 |
+
def hermediv(c1, c2):
|
| 508 |
+
"""
|
| 509 |
+
Divide one Hermite series by another.
|
| 510 |
+
|
| 511 |
+
Returns the quotient-with-remainder of two Hermite series
|
| 512 |
+
`c1` / `c2`. The arguments are sequences of coefficients from lowest
|
| 513 |
+
order "term" to highest, e.g., [1,2,3] represents the series
|
| 514 |
+
``P_0 + 2*P_1 + 3*P_2``.
|
| 515 |
+
|
| 516 |
+
Parameters
|
| 517 |
+
----------
|
| 518 |
+
c1, c2 : array_like
|
| 519 |
+
1-D arrays of Hermite series coefficients ordered from low to
|
| 520 |
+
high.
|
| 521 |
+
|
| 522 |
+
Returns
|
| 523 |
+
-------
|
| 524 |
+
[quo, rem] : ndarrays
|
| 525 |
+
Of Hermite series coefficients representing the quotient and
|
| 526 |
+
remainder.
|
| 527 |
+
|
| 528 |
+
See Also
|
| 529 |
+
--------
|
| 530 |
+
hermeadd, hermesub, hermemulx, hermemul, hermepow
|
| 531 |
+
|
| 532 |
+
Notes
|
| 533 |
+
-----
|
| 534 |
+
In general, the (polynomial) division of one Hermite series by another
|
| 535 |
+
results in quotient and remainder terms that are not in the Hermite
|
| 536 |
+
polynomial basis set. Thus, to express these results as a Hermite
|
| 537 |
+
series, it is necessary to "reproject" the results onto the Hermite
|
| 538 |
+
basis set, which may produce "unintuitive" (but correct) results; see
|
| 539 |
+
Examples section below.
|
| 540 |
+
|
| 541 |
+
Examples
|
| 542 |
+
--------
|
| 543 |
+
>>> from numpy.polynomial.hermite_e import hermediv
|
| 544 |
+
>>> hermediv([ 14., 15., 28., 7., 6.], [0, 1, 2])
|
| 545 |
+
(array([1., 2., 3.]), array([0.]))
|
| 546 |
+
>>> hermediv([ 15., 17., 28., 7., 6.], [0, 1, 2])
|
| 547 |
+
(array([1., 2., 3.]), array([1., 2.]))
|
| 548 |
+
|
| 549 |
+
"""
|
| 550 |
+
return pu._div(hermemul, c1, c2)
|
| 551 |
+
|
| 552 |
+
|
| 553 |
+
def hermepow(c, pow, maxpower=16):
|
| 554 |
+
"""Raise a Hermite series to a power.
|
| 555 |
+
|
| 556 |
+
Returns the Hermite series `c` raised to the power `pow`. The
|
| 557 |
+
argument `c` is a sequence of coefficients ordered from low to high.
|
| 558 |
+
i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.``
|
| 559 |
+
|
| 560 |
+
Parameters
|
| 561 |
+
----------
|
| 562 |
+
c : array_like
|
| 563 |
+
1-D array of Hermite series coefficients ordered from low to
|
| 564 |
+
high.
|
| 565 |
+
pow : integer
|
| 566 |
+
Power to which the series will be raised
|
| 567 |
+
maxpower : integer, optional
|
| 568 |
+
Maximum power allowed. This is mainly to limit growth of the series
|
| 569 |
+
to unmanageable size. Default is 16
|
| 570 |
+
|
| 571 |
+
Returns
|
| 572 |
+
-------
|
| 573 |
+
coef : ndarray
|
| 574 |
+
Hermite series of power.
|
| 575 |
+
|
| 576 |
+
See Also
|
| 577 |
+
--------
|
| 578 |
+
hermeadd, hermesub, hermemulx, hermemul, hermediv
|
| 579 |
+
|
| 580 |
+
Examples
|
| 581 |
+
--------
|
| 582 |
+
>>> from numpy.polynomial.hermite_e import hermepow
|
| 583 |
+
>>> hermepow([1, 2, 3], 2)
|
| 584 |
+
array([23., 28., 46., 12., 9.])
|
| 585 |
+
|
| 586 |
+
"""
|
| 587 |
+
return pu._pow(hermemul, c, pow, maxpower)
|
| 588 |
+
|
| 589 |
+
|
| 590 |
+
def hermeder(c, m=1, scl=1, axis=0):
|
| 591 |
+
"""
|
| 592 |
+
Differentiate a Hermite_e series.
|
| 593 |
+
|
| 594 |
+
Returns the series coefficients `c` differentiated `m` times along
|
| 595 |
+
`axis`. At each iteration the result is multiplied by `scl` (the
|
| 596 |
+
scaling factor is for use in a linear change of variable). The argument
|
| 597 |
+
`c` is an array of coefficients from low to high degree along each
|
| 598 |
+
axis, e.g., [1,2,3] represents the series ``1*He_0 + 2*He_1 + 3*He_2``
|
| 599 |
+
while [[1,2],[1,2]] represents ``1*He_0(x)*He_0(y) + 1*He_1(x)*He_0(y)
|
| 600 |
+
+ 2*He_0(x)*He_1(y) + 2*He_1(x)*He_1(y)`` if axis=0 is ``x`` and axis=1
|
| 601 |
+
is ``y``.
|
| 602 |
+
|
| 603 |
+
Parameters
|
| 604 |
+
----------
|
| 605 |
+
c : array_like
|
| 606 |
+
Array of Hermite_e series coefficients. If `c` is multidimensional
|
| 607 |
+
the different axis correspond to different variables with the
|
| 608 |
+
degree in each axis given by the corresponding index.
|
| 609 |
+
m : int, optional
|
| 610 |
+
Number of derivatives taken, must be non-negative. (Default: 1)
|
| 611 |
+
scl : scalar, optional
|
| 612 |
+
Each differentiation is multiplied by `scl`. The end result is
|
| 613 |
+
multiplication by ``scl**m``. This is for use in a linear change of
|
| 614 |
+
variable. (Default: 1)
|
| 615 |
+
axis : int, optional
|
| 616 |
+
Axis over which the derivative is taken. (Default: 0).
|
| 617 |
+
|
| 618 |
+
.. versionadded:: 1.7.0
|
| 619 |
+
|
| 620 |
+
Returns
|
| 621 |
+
-------
|
| 622 |
+
der : ndarray
|
| 623 |
+
Hermite series of the derivative.
|
| 624 |
+
|
| 625 |
+
See Also
|
| 626 |
+
--------
|
| 627 |
+
hermeint
|
| 628 |
+
|
| 629 |
+
Notes
|
| 630 |
+
-----
|
| 631 |
+
In general, the result of differentiating a Hermite series does not
|
| 632 |
+
resemble the same operation on a power series. Thus the result of this
|
| 633 |
+
function may be "unintuitive," albeit correct; see Examples section
|
| 634 |
+
below.
|
| 635 |
+
|
| 636 |
+
Examples
|
| 637 |
+
--------
|
| 638 |
+
>>> from numpy.polynomial.hermite_e import hermeder
|
| 639 |
+
>>> hermeder([ 1., 1., 1., 1.])
|
| 640 |
+
array([1., 2., 3.])
|
| 641 |
+
>>> hermeder([-0.25, 1., 1./2., 1./3., 1./4 ], m=2)
|
| 642 |
+
array([1., 2., 3.])
|
| 643 |
+
|
| 644 |
+
"""
|
| 645 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 646 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 647 |
+
c = c.astype(np.double)
|
| 648 |
+
cnt = pu._deprecate_as_int(m, "the order of derivation")
|
| 649 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 650 |
+
if cnt < 0:
|
| 651 |
+
raise ValueError("The order of derivation must be non-negative")
|
| 652 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 653 |
+
|
| 654 |
+
if cnt == 0:
|
| 655 |
+
return c
|
| 656 |
+
|
| 657 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 658 |
+
n = len(c)
|
| 659 |
+
if cnt >= n:
|
| 660 |
+
return c[:1]*0
|
| 661 |
+
else:
|
| 662 |
+
for i in range(cnt):
|
| 663 |
+
n = n - 1
|
| 664 |
+
c *= scl
|
| 665 |
+
der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
|
| 666 |
+
for j in range(n, 0, -1):
|
| 667 |
+
der[j - 1] = j*c[j]
|
| 668 |
+
c = der
|
| 669 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 670 |
+
return c
|
| 671 |
+
|
| 672 |
+
|
| 673 |
+
def hermeint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
|
| 674 |
+
"""
|
| 675 |
+
Integrate a Hermite_e series.
|
| 676 |
+
|
| 677 |
+
Returns the Hermite_e series coefficients `c` integrated `m` times from
|
| 678 |
+
`lbnd` along `axis`. At each iteration the resulting series is
|
| 679 |
+
**multiplied** by `scl` and an integration constant, `k`, is added.
|
| 680 |
+
The scaling factor is for use in a linear change of variable. ("Buyer
|
| 681 |
+
beware": note that, depending on what one is doing, one may want `scl`
|
| 682 |
+
to be the reciprocal of what one might expect; for more information,
|
| 683 |
+
see the Notes section below.) The argument `c` is an array of
|
| 684 |
+
coefficients from low to high degree along each axis, e.g., [1,2,3]
|
| 685 |
+
represents the series ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]]
|
| 686 |
+
represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) +
|
| 687 |
+
2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
|
| 688 |
+
|
| 689 |
+
Parameters
|
| 690 |
+
----------
|
| 691 |
+
c : array_like
|
| 692 |
+
Array of Hermite_e series coefficients. If c is multidimensional
|
| 693 |
+
the different axis correspond to different variables with the
|
| 694 |
+
degree in each axis given by the corresponding index.
|
| 695 |
+
m : int, optional
|
| 696 |
+
Order of integration, must be positive. (Default: 1)
|
| 697 |
+
k : {[], list, scalar}, optional
|
| 698 |
+
Integration constant(s). The value of the first integral at
|
| 699 |
+
``lbnd`` is the first value in the list, the value of the second
|
| 700 |
+
integral at ``lbnd`` is the second value, etc. If ``k == []`` (the
|
| 701 |
+
default), all constants are set to zero. If ``m == 1``, a single
|
| 702 |
+
scalar can be given instead of a list.
|
| 703 |
+
lbnd : scalar, optional
|
| 704 |
+
The lower bound of the integral. (Default: 0)
|
| 705 |
+
scl : scalar, optional
|
| 706 |
+
Following each integration the result is *multiplied* by `scl`
|
| 707 |
+
before the integration constant is added. (Default: 1)
|
| 708 |
+
axis : int, optional
|
| 709 |
+
Axis over which the integral is taken. (Default: 0).
|
| 710 |
+
|
| 711 |
+
.. versionadded:: 1.7.0
|
| 712 |
+
|
| 713 |
+
Returns
|
| 714 |
+
-------
|
| 715 |
+
S : ndarray
|
| 716 |
+
Hermite_e series coefficients of the integral.
|
| 717 |
+
|
| 718 |
+
Raises
|
| 719 |
+
------
|
| 720 |
+
ValueError
|
| 721 |
+
If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or
|
| 722 |
+
``np.ndim(scl) != 0``.
|
| 723 |
+
|
| 724 |
+
See Also
|
| 725 |
+
--------
|
| 726 |
+
hermeder
|
| 727 |
+
|
| 728 |
+
Notes
|
| 729 |
+
-----
|
| 730 |
+
Note that the result of each integration is *multiplied* by `scl`.
|
| 731 |
+
Why is this important to note? Say one is making a linear change of
|
| 732 |
+
variable :math:`u = ax + b` in an integral relative to `x`. Then
|
| 733 |
+
:math:`dx = du/a`, so one will need to set `scl` equal to
|
| 734 |
+
:math:`1/a` - perhaps not what one would have first thought.
|
| 735 |
+
|
| 736 |
+
Also note that, in general, the result of integrating a C-series needs
|
| 737 |
+
to be "reprojected" onto the C-series basis set. Thus, typically,
|
| 738 |
+
the result of this function is "unintuitive," albeit correct; see
|
| 739 |
+
Examples section below.
|
| 740 |
+
|
| 741 |
+
Examples
|
| 742 |
+
--------
|
| 743 |
+
>>> from numpy.polynomial.hermite_e import hermeint
|
| 744 |
+
>>> hermeint([1, 2, 3]) # integrate once, value 0 at 0.
|
| 745 |
+
array([1., 1., 1., 1.])
|
| 746 |
+
>>> hermeint([1, 2, 3], m=2) # integrate twice, value & deriv 0 at 0
|
| 747 |
+
array([-0.25 , 1. , 0.5 , 0.33333333, 0.25 ]) # may vary
|
| 748 |
+
>>> hermeint([1, 2, 3], k=1) # integrate once, value 1 at 0.
|
| 749 |
+
array([2., 1., 1., 1.])
|
| 750 |
+
>>> hermeint([1, 2, 3], lbnd=-1) # integrate once, value 0 at -1
|
| 751 |
+
array([-1., 1., 1., 1.])
|
| 752 |
+
>>> hermeint([1, 2, 3], m=2, k=[1, 2], lbnd=-1)
|
| 753 |
+
array([ 1.83333333, 0. , 0.5 , 0.33333333, 0.25 ]) # may vary
|
| 754 |
+
|
| 755 |
+
"""
|
| 756 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 757 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 758 |
+
c = c.astype(np.double)
|
| 759 |
+
if not np.iterable(k):
|
| 760 |
+
k = [k]
|
| 761 |
+
cnt = pu._deprecate_as_int(m, "the order of integration")
|
| 762 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 763 |
+
if cnt < 0:
|
| 764 |
+
raise ValueError("The order of integration must be non-negative")
|
| 765 |
+
if len(k) > cnt:
|
| 766 |
+
raise ValueError("Too many integration constants")
|
| 767 |
+
if np.ndim(lbnd) != 0:
|
| 768 |
+
raise ValueError("lbnd must be a scalar.")
|
| 769 |
+
if np.ndim(scl) != 0:
|
| 770 |
+
raise ValueError("scl must be a scalar.")
|
| 771 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 772 |
+
|
| 773 |
+
if cnt == 0:
|
| 774 |
+
return c
|
| 775 |
+
|
| 776 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 777 |
+
k = list(k) + [0]*(cnt - len(k))
|
| 778 |
+
for i in range(cnt):
|
| 779 |
+
n = len(c)
|
| 780 |
+
c *= scl
|
| 781 |
+
if n == 1 and np.all(c[0] == 0):
|
| 782 |
+
c[0] += k[i]
|
| 783 |
+
else:
|
| 784 |
+
tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
|
| 785 |
+
tmp[0] = c[0]*0
|
| 786 |
+
tmp[1] = c[0]
|
| 787 |
+
for j in range(1, n):
|
| 788 |
+
tmp[j + 1] = c[j]/(j + 1)
|
| 789 |
+
tmp[0] += k[i] - hermeval(lbnd, tmp)
|
| 790 |
+
c = tmp
|
| 791 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 792 |
+
return c
|
| 793 |
+
|
| 794 |
+
|
| 795 |
+
def hermeval(x, c, tensor=True):
|
| 796 |
+
"""
|
| 797 |
+
Evaluate an HermiteE series at points x.
|
| 798 |
+
|
| 799 |
+
If `c` is of length `n + 1`, this function returns the value:
|
| 800 |
+
|
| 801 |
+
.. math:: p(x) = c_0 * He_0(x) + c_1 * He_1(x) + ... + c_n * He_n(x)
|
| 802 |
+
|
| 803 |
+
The parameter `x` is converted to an array only if it is a tuple or a
|
| 804 |
+
list, otherwise it is treated as a scalar. In either case, either `x`
|
| 805 |
+
or its elements must support multiplication and addition both with
|
| 806 |
+
themselves and with the elements of `c`.
|
| 807 |
+
|
| 808 |
+
If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If
|
| 809 |
+
`c` is multidimensional, then the shape of the result depends on the
|
| 810 |
+
value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
|
| 811 |
+
x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
|
| 812 |
+
scalars have shape (,).
|
| 813 |
+
|
| 814 |
+
Trailing zeros in the coefficients will be used in the evaluation, so
|
| 815 |
+
they should be avoided if efficiency is a concern.
|
| 816 |
+
|
| 817 |
+
Parameters
|
| 818 |
+
----------
|
| 819 |
+
x : array_like, compatible object
|
| 820 |
+
If `x` is a list or tuple, it is converted to an ndarray, otherwise
|
| 821 |
+
it is left unchanged and treated as a scalar. In either case, `x`
|
| 822 |
+
or its elements must support addition and multiplication with
|
| 823 |
+
with themselves and with the elements of `c`.
|
| 824 |
+
c : array_like
|
| 825 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 826 |
+
degree n are contained in c[n]. If `c` is multidimensional the
|
| 827 |
+
remaining indices enumerate multiple polynomials. In the two
|
| 828 |
+
dimensional case the coefficients may be thought of as stored in
|
| 829 |
+
the columns of `c`.
|
| 830 |
+
tensor : boolean, optional
|
| 831 |
+
If True, the shape of the coefficient array is extended with ones
|
| 832 |
+
on the right, one for each dimension of `x`. Scalars have dimension 0
|
| 833 |
+
for this action. The result is that every column of coefficients in
|
| 834 |
+
`c` is evaluated for every element of `x`. If False, `x` is broadcast
|
| 835 |
+
over the columns of `c` for the evaluation. This keyword is useful
|
| 836 |
+
when `c` is multidimensional. The default value is True.
|
| 837 |
+
|
| 838 |
+
.. versionadded:: 1.7.0
|
| 839 |
+
|
| 840 |
+
Returns
|
| 841 |
+
-------
|
| 842 |
+
values : ndarray, algebra_like
|
| 843 |
+
The shape of the return value is described above.
|
| 844 |
+
|
| 845 |
+
See Also
|
| 846 |
+
--------
|
| 847 |
+
hermeval2d, hermegrid2d, hermeval3d, hermegrid3d
|
| 848 |
+
|
| 849 |
+
Notes
|
| 850 |
+
-----
|
| 851 |
+
The evaluation uses Clenshaw recursion, aka synthetic division.
|
| 852 |
+
|
| 853 |
+
Examples
|
| 854 |
+
--------
|
| 855 |
+
>>> from numpy.polynomial.hermite_e import hermeval
|
| 856 |
+
>>> coef = [1,2,3]
|
| 857 |
+
>>> hermeval(1, coef)
|
| 858 |
+
3.0
|
| 859 |
+
>>> hermeval([[1,2],[3,4]], coef)
|
| 860 |
+
array([[ 3., 14.],
|
| 861 |
+
[31., 54.]])
|
| 862 |
+
|
| 863 |
+
"""
|
| 864 |
+
c = np.array(c, ndmin=1, copy=False)
|
| 865 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 866 |
+
c = c.astype(np.double)
|
| 867 |
+
if isinstance(x, (tuple, list)):
|
| 868 |
+
x = np.asarray(x)
|
| 869 |
+
if isinstance(x, np.ndarray) and tensor:
|
| 870 |
+
c = c.reshape(c.shape + (1,)*x.ndim)
|
| 871 |
+
|
| 872 |
+
if len(c) == 1:
|
| 873 |
+
c0 = c[0]
|
| 874 |
+
c1 = 0
|
| 875 |
+
elif len(c) == 2:
|
| 876 |
+
c0 = c[0]
|
| 877 |
+
c1 = c[1]
|
| 878 |
+
else:
|
| 879 |
+
nd = len(c)
|
| 880 |
+
c0 = c[-2]
|
| 881 |
+
c1 = c[-1]
|
| 882 |
+
for i in range(3, len(c) + 1):
|
| 883 |
+
tmp = c0
|
| 884 |
+
nd = nd - 1
|
| 885 |
+
c0 = c[-i] - c1*(nd - 1)
|
| 886 |
+
c1 = tmp + c1*x
|
| 887 |
+
return c0 + c1*x
|
| 888 |
+
|
| 889 |
+
|
| 890 |
+
def hermeval2d(x, y, c):
|
| 891 |
+
"""
|
| 892 |
+
Evaluate a 2-D HermiteE series at points (x, y).
|
| 893 |
+
|
| 894 |
+
This function returns the values:
|
| 895 |
+
|
| 896 |
+
.. math:: p(x,y) = \\sum_{i,j} c_{i,j} * He_i(x) * He_j(y)
|
| 897 |
+
|
| 898 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 899 |
+
tuples or a lists, otherwise they are treated as a scalars and they
|
| 900 |
+
must have the same shape after conversion. In either case, either `x`
|
| 901 |
+
and `y` or their elements must support multiplication and addition both
|
| 902 |
+
with themselves and with the elements of `c`.
|
| 903 |
+
|
| 904 |
+
If `c` is a 1-D array a one is implicitly appended to its shape to make
|
| 905 |
+
it 2-D. The shape of the result will be c.shape[2:] + x.shape.
|
| 906 |
+
|
| 907 |
+
Parameters
|
| 908 |
+
----------
|
| 909 |
+
x, y : array_like, compatible objects
|
| 910 |
+
The two dimensional series is evaluated at the points `(x, y)`,
|
| 911 |
+
where `x` and `y` must have the same shape. If `x` or `y` is a list
|
| 912 |
+
or tuple, it is first converted to an ndarray, otherwise it is left
|
| 913 |
+
unchanged and if it isn't an ndarray it is treated as a scalar.
|
| 914 |
+
c : array_like
|
| 915 |
+
Array of coefficients ordered so that the coefficient of the term
|
| 916 |
+
of multi-degree i,j is contained in ``c[i,j]``. If `c` has
|
| 917 |
+
dimension greater than two the remaining indices enumerate multiple
|
| 918 |
+
sets of coefficients.
|
| 919 |
+
|
| 920 |
+
Returns
|
| 921 |
+
-------
|
| 922 |
+
values : ndarray, compatible object
|
| 923 |
+
The values of the two dimensional polynomial at points formed with
|
| 924 |
+
pairs of corresponding values from `x` and `y`.
|
| 925 |
+
|
| 926 |
+
See Also
|
| 927 |
+
--------
|
| 928 |
+
hermeval, hermegrid2d, hermeval3d, hermegrid3d
|
| 929 |
+
|
| 930 |
+
Notes
|
| 931 |
+
-----
|
| 932 |
+
|
| 933 |
+
.. versionadded:: 1.7.0
|
| 934 |
+
|
| 935 |
+
"""
|
| 936 |
+
return pu._valnd(hermeval, c, x, y)
|
| 937 |
+
|
| 938 |
+
|
| 939 |
+
def hermegrid2d(x, y, c):
|
| 940 |
+
"""
|
| 941 |
+
Evaluate a 2-D HermiteE series on the Cartesian product of x and y.
|
| 942 |
+
|
| 943 |
+
This function returns the values:
|
| 944 |
+
|
| 945 |
+
.. math:: p(a,b) = \\sum_{i,j} c_{i,j} * H_i(a) * H_j(b)
|
| 946 |
+
|
| 947 |
+
where the points `(a, b)` consist of all pairs formed by taking
|
| 948 |
+
`a` from `x` and `b` from `y`. The resulting points form a grid with
|
| 949 |
+
`x` in the first dimension and `y` in the second.
|
| 950 |
+
|
| 951 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 952 |
+
tuples or a lists, otherwise they are treated as a scalars. In either
|
| 953 |
+
case, either `x` and `y` or their elements must support multiplication
|
| 954 |
+
and addition both with themselves and with the elements of `c`.
|
| 955 |
+
|
| 956 |
+
If `c` has fewer than two dimensions, ones are implicitly appended to
|
| 957 |
+
its shape to make it 2-D. The shape of the result will be c.shape[2:] +
|
| 958 |
+
x.shape.
|
| 959 |
+
|
| 960 |
+
Parameters
|
| 961 |
+
----------
|
| 962 |
+
x, y : array_like, compatible objects
|
| 963 |
+
The two dimensional series is evaluated at the points in the
|
| 964 |
+
Cartesian product of `x` and `y`. If `x` or `y` is a list or
|
| 965 |
+
tuple, it is first converted to an ndarray, otherwise it is left
|
| 966 |
+
unchanged and, if it isn't an ndarray, it is treated as a scalar.
|
| 967 |
+
c : array_like
|
| 968 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 969 |
+
degree i,j are contained in ``c[i,j]``. If `c` has dimension
|
| 970 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 971 |
+
coefficients.
|
| 972 |
+
|
| 973 |
+
Returns
|
| 974 |
+
-------
|
| 975 |
+
values : ndarray, compatible object
|
| 976 |
+
The values of the two dimensional polynomial at points in the Cartesian
|
| 977 |
+
product of `x` and `y`.
|
| 978 |
+
|
| 979 |
+
See Also
|
| 980 |
+
--------
|
| 981 |
+
hermeval, hermeval2d, hermeval3d, hermegrid3d
|
| 982 |
+
|
| 983 |
+
Notes
|
| 984 |
+
-----
|
| 985 |
+
|
| 986 |
+
.. versionadded:: 1.7.0
|
| 987 |
+
|
| 988 |
+
"""
|
| 989 |
+
return pu._gridnd(hermeval, c, x, y)
|
| 990 |
+
|
| 991 |
+
|
| 992 |
+
def hermeval3d(x, y, z, c):
|
| 993 |
+
"""
|
| 994 |
+
Evaluate a 3-D Hermite_e series at points (x, y, z).
|
| 995 |
+
|
| 996 |
+
This function returns the values:
|
| 997 |
+
|
| 998 |
+
.. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * He_i(x) * He_j(y) * He_k(z)
|
| 999 |
+
|
| 1000 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if
|
| 1001 |
+
they are tuples or a lists, otherwise they are treated as a scalars and
|
| 1002 |
+
they must have the same shape after conversion. In either case, either
|
| 1003 |
+
`x`, `y`, and `z` or their elements must support multiplication and
|
| 1004 |
+
addition both with themselves and with the elements of `c`.
|
| 1005 |
+
|
| 1006 |
+
If `c` has fewer than 3 dimensions, ones are implicitly appended to its
|
| 1007 |
+
shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1008 |
+
x.shape.
|
| 1009 |
+
|
| 1010 |
+
Parameters
|
| 1011 |
+
----------
|
| 1012 |
+
x, y, z : array_like, compatible object
|
| 1013 |
+
The three dimensional series is evaluated at the points
|
| 1014 |
+
`(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If
|
| 1015 |
+
any of `x`, `y`, or `z` is a list or tuple, it is first converted
|
| 1016 |
+
to an ndarray, otherwise it is left unchanged and if it isn't an
|
| 1017 |
+
ndarray it is treated as a scalar.
|
| 1018 |
+
c : array_like
|
| 1019 |
+
Array of coefficients ordered so that the coefficient of the term of
|
| 1020 |
+
multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
|
| 1021 |
+
greater than 3 the remaining indices enumerate multiple sets of
|
| 1022 |
+
coefficients.
|
| 1023 |
+
|
| 1024 |
+
Returns
|
| 1025 |
+
-------
|
| 1026 |
+
values : ndarray, compatible object
|
| 1027 |
+
The values of the multidimensional polynomial on points formed with
|
| 1028 |
+
triples of corresponding values from `x`, `y`, and `z`.
|
| 1029 |
+
|
| 1030 |
+
See Also
|
| 1031 |
+
--------
|
| 1032 |
+
hermeval, hermeval2d, hermegrid2d, hermegrid3d
|
| 1033 |
+
|
| 1034 |
+
Notes
|
| 1035 |
+
-----
|
| 1036 |
+
|
| 1037 |
+
.. versionadded:: 1.7.0
|
| 1038 |
+
|
| 1039 |
+
"""
|
| 1040 |
+
return pu._valnd(hermeval, c, x, y, z)
|
| 1041 |
+
|
| 1042 |
+
|
| 1043 |
+
def hermegrid3d(x, y, z, c):
|
| 1044 |
+
"""
|
| 1045 |
+
Evaluate a 3-D HermiteE series on the Cartesian product of x, y, and z.
|
| 1046 |
+
|
| 1047 |
+
This function returns the values:
|
| 1048 |
+
|
| 1049 |
+
.. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * He_i(a) * He_j(b) * He_k(c)
|
| 1050 |
+
|
| 1051 |
+
where the points `(a, b, c)` consist of all triples formed by taking
|
| 1052 |
+
`a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
|
| 1053 |
+
a grid with `x` in the first dimension, `y` in the second, and `z` in
|
| 1054 |
+
the third.
|
| 1055 |
+
|
| 1056 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if they
|
| 1057 |
+
are tuples or a lists, otherwise they are treated as a scalars. In
|
| 1058 |
+
either case, either `x`, `y`, and `z` or their elements must support
|
| 1059 |
+
multiplication and addition both with themselves and with the elements
|
| 1060 |
+
of `c`.
|
| 1061 |
+
|
| 1062 |
+
If `c` has fewer than three dimensions, ones are implicitly appended to
|
| 1063 |
+
its shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1064 |
+
x.shape + y.shape + z.shape.
|
| 1065 |
+
|
| 1066 |
+
Parameters
|
| 1067 |
+
----------
|
| 1068 |
+
x, y, z : array_like, compatible objects
|
| 1069 |
+
The three dimensional series is evaluated at the points in the
|
| 1070 |
+
Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a
|
| 1071 |
+
list or tuple, it is first converted to an ndarray, otherwise it is
|
| 1072 |
+
left unchanged and, if it isn't an ndarray, it is treated as a
|
| 1073 |
+
scalar.
|
| 1074 |
+
c : array_like
|
| 1075 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 1076 |
+
degree i,j are contained in ``c[i,j]``. If `c` has dimension
|
| 1077 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 1078 |
+
coefficients.
|
| 1079 |
+
|
| 1080 |
+
Returns
|
| 1081 |
+
-------
|
| 1082 |
+
values : ndarray, compatible object
|
| 1083 |
+
The values of the two dimensional polynomial at points in the Cartesian
|
| 1084 |
+
product of `x` and `y`.
|
| 1085 |
+
|
| 1086 |
+
See Also
|
| 1087 |
+
--------
|
| 1088 |
+
hermeval, hermeval2d, hermegrid2d, hermeval3d
|
| 1089 |
+
|
| 1090 |
+
Notes
|
| 1091 |
+
-----
|
| 1092 |
+
|
| 1093 |
+
.. versionadded:: 1.7.0
|
| 1094 |
+
|
| 1095 |
+
"""
|
| 1096 |
+
return pu._gridnd(hermeval, c, x, y, z)
|
| 1097 |
+
|
| 1098 |
+
|
| 1099 |
+
def hermevander(x, deg):
|
| 1100 |
+
"""Pseudo-Vandermonde matrix of given degree.
|
| 1101 |
+
|
| 1102 |
+
Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
|
| 1103 |
+
`x`. The pseudo-Vandermonde matrix is defined by
|
| 1104 |
+
|
| 1105 |
+
.. math:: V[..., i] = He_i(x),
|
| 1106 |
+
|
| 1107 |
+
where `0 <= i <= deg`. The leading indices of `V` index the elements of
|
| 1108 |
+
`x` and the last index is the degree of the HermiteE polynomial.
|
| 1109 |
+
|
| 1110 |
+
If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
|
| 1111 |
+
array ``V = hermevander(x, n)``, then ``np.dot(V, c)`` and
|
| 1112 |
+
``hermeval(x, c)`` are the same up to roundoff. This equivalence is
|
| 1113 |
+
useful both for least squares fitting and for the evaluation of a large
|
| 1114 |
+
number of HermiteE series of the same degree and sample points.
|
| 1115 |
+
|
| 1116 |
+
Parameters
|
| 1117 |
+
----------
|
| 1118 |
+
x : array_like
|
| 1119 |
+
Array of points. The dtype is converted to float64 or complex128
|
| 1120 |
+
depending on whether any of the elements are complex. If `x` is
|
| 1121 |
+
scalar it is converted to a 1-D array.
|
| 1122 |
+
deg : int
|
| 1123 |
+
Degree of the resulting matrix.
|
| 1124 |
+
|
| 1125 |
+
Returns
|
| 1126 |
+
-------
|
| 1127 |
+
vander : ndarray
|
| 1128 |
+
The pseudo-Vandermonde matrix. The shape of the returned matrix is
|
| 1129 |
+
``x.shape + (deg + 1,)``, where The last index is the degree of the
|
| 1130 |
+
corresponding HermiteE polynomial. The dtype will be the same as
|
| 1131 |
+
the converted `x`.
|
| 1132 |
+
|
| 1133 |
+
Examples
|
| 1134 |
+
--------
|
| 1135 |
+
>>> from numpy.polynomial.hermite_e import hermevander
|
| 1136 |
+
>>> x = np.array([-1, 0, 1])
|
| 1137 |
+
>>> hermevander(x, 3)
|
| 1138 |
+
array([[ 1., -1., 0., 2.],
|
| 1139 |
+
[ 1., 0., -1., -0.],
|
| 1140 |
+
[ 1., 1., 0., -2.]])
|
| 1141 |
+
|
| 1142 |
+
"""
|
| 1143 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1144 |
+
if ideg < 0:
|
| 1145 |
+
raise ValueError("deg must be non-negative")
|
| 1146 |
+
|
| 1147 |
+
x = np.array(x, copy=False, ndmin=1) + 0.0
|
| 1148 |
+
dims = (ideg + 1,) + x.shape
|
| 1149 |
+
dtyp = x.dtype
|
| 1150 |
+
v = np.empty(dims, dtype=dtyp)
|
| 1151 |
+
v[0] = x*0 + 1
|
| 1152 |
+
if ideg > 0:
|
| 1153 |
+
v[1] = x
|
| 1154 |
+
for i in range(2, ideg + 1):
|
| 1155 |
+
v[i] = (v[i-1]*x - v[i-2]*(i - 1))
|
| 1156 |
+
return np.moveaxis(v, 0, -1)
|
| 1157 |
+
|
| 1158 |
+
|
| 1159 |
+
def hermevander2d(x, y, deg):
|
| 1160 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1161 |
+
|
| 1162 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1163 |
+
points `(x, y)`. The pseudo-Vandermonde matrix is defined by
|
| 1164 |
+
|
| 1165 |
+
.. math:: V[..., (deg[1] + 1)*i + j] = He_i(x) * He_j(y),
|
| 1166 |
+
|
| 1167 |
+
where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
|
| 1168 |
+
`V` index the points `(x, y)` and the last index encodes the degrees of
|
| 1169 |
+
the HermiteE polynomials.
|
| 1170 |
+
|
| 1171 |
+
If ``V = hermevander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
|
| 1172 |
+
correspond to the elements of a 2-D coefficient array `c` of shape
|
| 1173 |
+
(xdeg + 1, ydeg + 1) in the order
|
| 1174 |
+
|
| 1175 |
+
.. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
|
| 1176 |
+
|
| 1177 |
+
and ``np.dot(V, c.flat)`` and ``hermeval2d(x, y, c)`` will be the same
|
| 1178 |
+
up to roundoff. This equivalence is useful both for least squares
|
| 1179 |
+
fitting and for the evaluation of a large number of 2-D HermiteE
|
| 1180 |
+
series of the same degrees and sample points.
|
| 1181 |
+
|
| 1182 |
+
Parameters
|
| 1183 |
+
----------
|
| 1184 |
+
x, y : array_like
|
| 1185 |
+
Arrays of point coordinates, all of the same shape. The dtypes
|
| 1186 |
+
will be converted to either float64 or complex128 depending on
|
| 1187 |
+
whether any of the elements are complex. Scalars are converted to
|
| 1188 |
+
1-D arrays.
|
| 1189 |
+
deg : list of ints
|
| 1190 |
+
List of maximum degrees of the form [x_deg, y_deg].
|
| 1191 |
+
|
| 1192 |
+
Returns
|
| 1193 |
+
-------
|
| 1194 |
+
vander2d : ndarray
|
| 1195 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1196 |
+
:math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same
|
| 1197 |
+
as the converted `x` and `y`.
|
| 1198 |
+
|
| 1199 |
+
See Also
|
| 1200 |
+
--------
|
| 1201 |
+
hermevander, hermevander3d, hermeval2d, hermeval3d
|
| 1202 |
+
|
| 1203 |
+
Notes
|
| 1204 |
+
-----
|
| 1205 |
+
|
| 1206 |
+
.. versionadded:: 1.7.0
|
| 1207 |
+
|
| 1208 |
+
"""
|
| 1209 |
+
return pu._vander_nd_flat((hermevander, hermevander), (x, y), deg)
|
| 1210 |
+
|
| 1211 |
+
|
| 1212 |
+
def hermevander3d(x, y, z, deg):
|
| 1213 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1214 |
+
|
| 1215 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1216 |
+
points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
|
| 1217 |
+
then Hehe pseudo-Vandermonde matrix is defined by
|
| 1218 |
+
|
| 1219 |
+
.. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = He_i(x)*He_j(y)*He_k(z),
|
| 1220 |
+
|
| 1221 |
+
where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading
|
| 1222 |
+
indices of `V` index the points `(x, y, z)` and the last index encodes
|
| 1223 |
+
the degrees of the HermiteE polynomials.
|
| 1224 |
+
|
| 1225 |
+
If ``V = hermevander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
|
| 1226 |
+
of `V` correspond to the elements of a 3-D coefficient array `c` of
|
| 1227 |
+
shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
|
| 1228 |
+
|
| 1229 |
+
.. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
|
| 1230 |
+
|
| 1231 |
+
and ``np.dot(V, c.flat)`` and ``hermeval3d(x, y, z, c)`` will be the
|
| 1232 |
+
same up to roundoff. This equivalence is useful both for least squares
|
| 1233 |
+
fitting and for the evaluation of a large number of 3-D HermiteE
|
| 1234 |
+
series of the same degrees and sample points.
|
| 1235 |
+
|
| 1236 |
+
Parameters
|
| 1237 |
+
----------
|
| 1238 |
+
x, y, z : array_like
|
| 1239 |
+
Arrays of point coordinates, all of the same shape. The dtypes will
|
| 1240 |
+
be converted to either float64 or complex128 depending on whether
|
| 1241 |
+
any of the elements are complex. Scalars are converted to 1-D
|
| 1242 |
+
arrays.
|
| 1243 |
+
deg : list of ints
|
| 1244 |
+
List of maximum degrees of the form [x_deg, y_deg, z_deg].
|
| 1245 |
+
|
| 1246 |
+
Returns
|
| 1247 |
+
-------
|
| 1248 |
+
vander3d : ndarray
|
| 1249 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1250 |
+
:math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will
|
| 1251 |
+
be the same as the converted `x`, `y`, and `z`.
|
| 1252 |
+
|
| 1253 |
+
See Also
|
| 1254 |
+
--------
|
| 1255 |
+
hermevander, hermevander3d, hermeval2d, hermeval3d
|
| 1256 |
+
|
| 1257 |
+
Notes
|
| 1258 |
+
-----
|
| 1259 |
+
|
| 1260 |
+
.. versionadded:: 1.7.0
|
| 1261 |
+
|
| 1262 |
+
"""
|
| 1263 |
+
return pu._vander_nd_flat((hermevander, hermevander, hermevander), (x, y, z), deg)
|
| 1264 |
+
|
| 1265 |
+
|
| 1266 |
+
def hermefit(x, y, deg, rcond=None, full=False, w=None):
|
| 1267 |
+
"""
|
| 1268 |
+
Least squares fit of Hermite series to data.
|
| 1269 |
+
|
| 1270 |
+
Return the coefficients of a HermiteE series of degree `deg` that is
|
| 1271 |
+
the least squares fit to the data values `y` given at points `x`. If
|
| 1272 |
+
`y` is 1-D the returned coefficients will also be 1-D. If `y` is 2-D
|
| 1273 |
+
multiple fits are done, one for each column of `y`, and the resulting
|
| 1274 |
+
coefficients are stored in the corresponding columns of a 2-D return.
|
| 1275 |
+
The fitted polynomial(s) are in the form
|
| 1276 |
+
|
| 1277 |
+
.. math:: p(x) = c_0 + c_1 * He_1(x) + ... + c_n * He_n(x),
|
| 1278 |
+
|
| 1279 |
+
where `n` is `deg`.
|
| 1280 |
+
|
| 1281 |
+
Parameters
|
| 1282 |
+
----------
|
| 1283 |
+
x : array_like, shape (M,)
|
| 1284 |
+
x-coordinates of the M sample points ``(x[i], y[i])``.
|
| 1285 |
+
y : array_like, shape (M,) or (M, K)
|
| 1286 |
+
y-coordinates of the sample points. Several data sets of sample
|
| 1287 |
+
points sharing the same x-coordinates can be fitted at once by
|
| 1288 |
+
passing in a 2D-array that contains one dataset per column.
|
| 1289 |
+
deg : int or 1-D array_like
|
| 1290 |
+
Degree(s) of the fitting polynomials. If `deg` is a single integer
|
| 1291 |
+
all terms up to and including the `deg`'th term are included in the
|
| 1292 |
+
fit. For NumPy versions >= 1.11.0 a list of integers specifying the
|
| 1293 |
+
degrees of the terms to include may be used instead.
|
| 1294 |
+
rcond : float, optional
|
| 1295 |
+
Relative condition number of the fit. Singular values smaller than
|
| 1296 |
+
this relative to the largest singular value will be ignored. The
|
| 1297 |
+
default value is len(x)*eps, where eps is the relative precision of
|
| 1298 |
+
the float type, about 2e-16 in most cases.
|
| 1299 |
+
full : bool, optional
|
| 1300 |
+
Switch determining nature of return value. When it is False (the
|
| 1301 |
+
default) just the coefficients are returned, when True diagnostic
|
| 1302 |
+
information from the singular value decomposition is also returned.
|
| 1303 |
+
w : array_like, shape (`M`,), optional
|
| 1304 |
+
Weights. If not None, the weight ``w[i]`` applies to the unsquared
|
| 1305 |
+
residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
|
| 1306 |
+
chosen so that the errors of the products ``w[i]*y[i]`` all have the
|
| 1307 |
+
same variance. When using inverse-variance weighting, use
|
| 1308 |
+
``w[i] = 1/sigma(y[i])``. The default value is None.
|
| 1309 |
+
|
| 1310 |
+
Returns
|
| 1311 |
+
-------
|
| 1312 |
+
coef : ndarray, shape (M,) or (M, K)
|
| 1313 |
+
Hermite coefficients ordered from low to high. If `y` was 2-D,
|
| 1314 |
+
the coefficients for the data in column k of `y` are in column
|
| 1315 |
+
`k`.
|
| 1316 |
+
|
| 1317 |
+
[residuals, rank, singular_values, rcond] : list
|
| 1318 |
+
These values are only returned if ``full == True``
|
| 1319 |
+
|
| 1320 |
+
- residuals -- sum of squared residuals of the least squares fit
|
| 1321 |
+
- rank -- the numerical rank of the scaled Vandermonde matrix
|
| 1322 |
+
- singular_values -- singular values of the scaled Vandermonde matrix
|
| 1323 |
+
- rcond -- value of `rcond`.
|
| 1324 |
+
|
| 1325 |
+
For more details, see `numpy.linalg.lstsq`.
|
| 1326 |
+
|
| 1327 |
+
Warns
|
| 1328 |
+
-----
|
| 1329 |
+
RankWarning
|
| 1330 |
+
The rank of the coefficient matrix in the least-squares fit is
|
| 1331 |
+
deficient. The warning is only raised if ``full = False``. The
|
| 1332 |
+
warnings can be turned off by
|
| 1333 |
+
|
| 1334 |
+
>>> import warnings
|
| 1335 |
+
>>> warnings.simplefilter('ignore', np.RankWarning)
|
| 1336 |
+
|
| 1337 |
+
See Also
|
| 1338 |
+
--------
|
| 1339 |
+
numpy.polynomial.chebyshev.chebfit
|
| 1340 |
+
numpy.polynomial.legendre.legfit
|
| 1341 |
+
numpy.polynomial.polynomial.polyfit
|
| 1342 |
+
numpy.polynomial.hermite.hermfit
|
| 1343 |
+
numpy.polynomial.laguerre.lagfit
|
| 1344 |
+
hermeval : Evaluates a Hermite series.
|
| 1345 |
+
hermevander : pseudo Vandermonde matrix of Hermite series.
|
| 1346 |
+
hermeweight : HermiteE weight function.
|
| 1347 |
+
numpy.linalg.lstsq : Computes a least-squares fit from the matrix.
|
| 1348 |
+
scipy.interpolate.UnivariateSpline : Computes spline fits.
|
| 1349 |
+
|
| 1350 |
+
Notes
|
| 1351 |
+
-----
|
| 1352 |
+
The solution is the coefficients of the HermiteE series `p` that
|
| 1353 |
+
minimizes the sum of the weighted squared errors
|
| 1354 |
+
|
| 1355 |
+
.. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
|
| 1356 |
+
|
| 1357 |
+
where the :math:`w_j` are the weights. This problem is solved by
|
| 1358 |
+
setting up the (typically) overdetermined matrix equation
|
| 1359 |
+
|
| 1360 |
+
.. math:: V(x) * c = w * y,
|
| 1361 |
+
|
| 1362 |
+
where `V` is the pseudo Vandermonde matrix of `x`, the elements of `c`
|
| 1363 |
+
are the coefficients to be solved for, and the elements of `y` are the
|
| 1364 |
+
observed values. This equation is then solved using the singular value
|
| 1365 |
+
decomposition of `V`.
|
| 1366 |
+
|
| 1367 |
+
If some of the singular values of `V` are so small that they are
|
| 1368 |
+
neglected, then a `RankWarning` will be issued. This means that the
|
| 1369 |
+
coefficient values may be poorly determined. Using a lower order fit
|
| 1370 |
+
will usually get rid of the warning. The `rcond` parameter can also be
|
| 1371 |
+
set to a value smaller than its default, but the resulting fit may be
|
| 1372 |
+
spurious and have large contributions from roundoff error.
|
| 1373 |
+
|
| 1374 |
+
Fits using HermiteE series are probably most useful when the data can
|
| 1375 |
+
be approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the HermiteE
|
| 1376 |
+
weight. In that case the weight ``sqrt(w(x[i]))`` should be used
|
| 1377 |
+
together with data values ``y[i]/sqrt(w(x[i]))``. The weight function is
|
| 1378 |
+
available as `hermeweight`.
|
| 1379 |
+
|
| 1380 |
+
References
|
| 1381 |
+
----------
|
| 1382 |
+
.. [1] Wikipedia, "Curve fitting",
|
| 1383 |
+
https://en.wikipedia.org/wiki/Curve_fitting
|
| 1384 |
+
|
| 1385 |
+
Examples
|
| 1386 |
+
--------
|
| 1387 |
+
>>> from numpy.polynomial.hermite_e import hermefit, hermeval
|
| 1388 |
+
>>> x = np.linspace(-10, 10)
|
| 1389 |
+
>>> np.random.seed(123)
|
| 1390 |
+
>>> err = np.random.randn(len(x))/10
|
| 1391 |
+
>>> y = hermeval(x, [1, 2, 3]) + err
|
| 1392 |
+
>>> hermefit(x, y, 2)
|
| 1393 |
+
array([ 1.01690445, 1.99951418, 2.99948696]) # may vary
|
| 1394 |
+
|
| 1395 |
+
"""
|
| 1396 |
+
return pu._fit(hermevander, x, y, deg, rcond, full, w)
|
| 1397 |
+
|
| 1398 |
+
|
| 1399 |
+
def hermecompanion(c):
|
| 1400 |
+
"""
|
| 1401 |
+
Return the scaled companion matrix of c.
|
| 1402 |
+
|
| 1403 |
+
The basis polynomials are scaled so that the companion matrix is
|
| 1404 |
+
symmetric when `c` is an HermiteE basis polynomial. This provides
|
| 1405 |
+
better eigenvalue estimates than the unscaled case and for basis
|
| 1406 |
+
polynomials the eigenvalues are guaranteed to be real if
|
| 1407 |
+
`numpy.linalg.eigvalsh` is used to obtain them.
|
| 1408 |
+
|
| 1409 |
+
Parameters
|
| 1410 |
+
----------
|
| 1411 |
+
c : array_like
|
| 1412 |
+
1-D array of HermiteE series coefficients ordered from low to high
|
| 1413 |
+
degree.
|
| 1414 |
+
|
| 1415 |
+
Returns
|
| 1416 |
+
-------
|
| 1417 |
+
mat : ndarray
|
| 1418 |
+
Scaled companion matrix of dimensions (deg, deg).
|
| 1419 |
+
|
| 1420 |
+
Notes
|
| 1421 |
+
-----
|
| 1422 |
+
|
| 1423 |
+
.. versionadded:: 1.7.0
|
| 1424 |
+
|
| 1425 |
+
"""
|
| 1426 |
+
# c is a trimmed copy
|
| 1427 |
+
[c] = pu.as_series([c])
|
| 1428 |
+
if len(c) < 2:
|
| 1429 |
+
raise ValueError('Series must have maximum degree of at least 1.')
|
| 1430 |
+
if len(c) == 2:
|
| 1431 |
+
return np.array([[-c[0]/c[1]]])
|
| 1432 |
+
|
| 1433 |
+
n = len(c) - 1
|
| 1434 |
+
mat = np.zeros((n, n), dtype=c.dtype)
|
| 1435 |
+
scl = np.hstack((1., 1./np.sqrt(np.arange(n - 1, 0, -1))))
|
| 1436 |
+
scl = np.multiply.accumulate(scl)[::-1]
|
| 1437 |
+
top = mat.reshape(-1)[1::n+1]
|
| 1438 |
+
bot = mat.reshape(-1)[n::n+1]
|
| 1439 |
+
top[...] = np.sqrt(np.arange(1, n))
|
| 1440 |
+
bot[...] = top
|
| 1441 |
+
mat[:, -1] -= scl*c[:-1]/c[-1]
|
| 1442 |
+
return mat
|
| 1443 |
+
|
| 1444 |
+
|
| 1445 |
+
def hermeroots(c):
|
| 1446 |
+
"""
|
| 1447 |
+
Compute the roots of a HermiteE series.
|
| 1448 |
+
|
| 1449 |
+
Return the roots (a.k.a. "zeros") of the polynomial
|
| 1450 |
+
|
| 1451 |
+
.. math:: p(x) = \\sum_i c[i] * He_i(x).
|
| 1452 |
+
|
| 1453 |
+
Parameters
|
| 1454 |
+
----------
|
| 1455 |
+
c : 1-D array_like
|
| 1456 |
+
1-D array of coefficients.
|
| 1457 |
+
|
| 1458 |
+
Returns
|
| 1459 |
+
-------
|
| 1460 |
+
out : ndarray
|
| 1461 |
+
Array of the roots of the series. If all the roots are real,
|
| 1462 |
+
then `out` is also real, otherwise it is complex.
|
| 1463 |
+
|
| 1464 |
+
See Also
|
| 1465 |
+
--------
|
| 1466 |
+
numpy.polynomial.polynomial.polyroots
|
| 1467 |
+
numpy.polynomial.legendre.legroots
|
| 1468 |
+
numpy.polynomial.laguerre.lagroots
|
| 1469 |
+
numpy.polynomial.hermite.hermroots
|
| 1470 |
+
numpy.polynomial.chebyshev.chebroots
|
| 1471 |
+
|
| 1472 |
+
Notes
|
| 1473 |
+
-----
|
| 1474 |
+
The root estimates are obtained as the eigenvalues of the companion
|
| 1475 |
+
matrix, Roots far from the origin of the complex plane may have large
|
| 1476 |
+
errors due to the numerical instability of the series for such
|
| 1477 |
+
values. Roots with multiplicity greater than 1 will also show larger
|
| 1478 |
+
errors as the value of the series near such points is relatively
|
| 1479 |
+
insensitive to errors in the roots. Isolated roots near the origin can
|
| 1480 |
+
be improved by a few iterations of Newton's method.
|
| 1481 |
+
|
| 1482 |
+
The HermiteE series basis polynomials aren't powers of `x` so the
|
| 1483 |
+
results of this function may seem unintuitive.
|
| 1484 |
+
|
| 1485 |
+
Examples
|
| 1486 |
+
--------
|
| 1487 |
+
>>> from numpy.polynomial.hermite_e import hermeroots, hermefromroots
|
| 1488 |
+
>>> coef = hermefromroots([-1, 0, 1])
|
| 1489 |
+
>>> coef
|
| 1490 |
+
array([0., 2., 0., 1.])
|
| 1491 |
+
>>> hermeroots(coef)
|
| 1492 |
+
array([-1., 0., 1.]) # may vary
|
| 1493 |
+
|
| 1494 |
+
"""
|
| 1495 |
+
# c is a trimmed copy
|
| 1496 |
+
[c] = pu.as_series([c])
|
| 1497 |
+
if len(c) <= 1:
|
| 1498 |
+
return np.array([], dtype=c.dtype)
|
| 1499 |
+
if len(c) == 2:
|
| 1500 |
+
return np.array([-c[0]/c[1]])
|
| 1501 |
+
|
| 1502 |
+
# rotated companion matrix reduces error
|
| 1503 |
+
m = hermecompanion(c)[::-1,::-1]
|
| 1504 |
+
r = la.eigvals(m)
|
| 1505 |
+
r.sort()
|
| 1506 |
+
return r
|
| 1507 |
+
|
| 1508 |
+
|
| 1509 |
+
def _normed_hermite_e_n(x, n):
|
| 1510 |
+
"""
|
| 1511 |
+
Evaluate a normalized HermiteE polynomial.
|
| 1512 |
+
|
| 1513 |
+
Compute the value of the normalized HermiteE polynomial of degree ``n``
|
| 1514 |
+
at the points ``x``.
|
| 1515 |
+
|
| 1516 |
+
|
| 1517 |
+
Parameters
|
| 1518 |
+
----------
|
| 1519 |
+
x : ndarray of double.
|
| 1520 |
+
Points at which to evaluate the function
|
| 1521 |
+
n : int
|
| 1522 |
+
Degree of the normalized HermiteE function to be evaluated.
|
| 1523 |
+
|
| 1524 |
+
Returns
|
| 1525 |
+
-------
|
| 1526 |
+
values : ndarray
|
| 1527 |
+
The shape of the return value is described above.
|
| 1528 |
+
|
| 1529 |
+
Notes
|
| 1530 |
+
-----
|
| 1531 |
+
.. versionadded:: 1.10.0
|
| 1532 |
+
|
| 1533 |
+
This function is needed for finding the Gauss points and integration
|
| 1534 |
+
weights for high degrees. The values of the standard HermiteE functions
|
| 1535 |
+
overflow when n >= 207.
|
| 1536 |
+
|
| 1537 |
+
"""
|
| 1538 |
+
if n == 0:
|
| 1539 |
+
return np.full(x.shape, 1/np.sqrt(np.sqrt(2*np.pi)))
|
| 1540 |
+
|
| 1541 |
+
c0 = 0.
|
| 1542 |
+
c1 = 1./np.sqrt(np.sqrt(2*np.pi))
|
| 1543 |
+
nd = float(n)
|
| 1544 |
+
for i in range(n - 1):
|
| 1545 |
+
tmp = c0
|
| 1546 |
+
c0 = -c1*np.sqrt((nd - 1.)/nd)
|
| 1547 |
+
c1 = tmp + c1*x*np.sqrt(1./nd)
|
| 1548 |
+
nd = nd - 1.0
|
| 1549 |
+
return c0 + c1*x
|
| 1550 |
+
|
| 1551 |
+
|
| 1552 |
+
def hermegauss(deg):
|
| 1553 |
+
"""
|
| 1554 |
+
Gauss-HermiteE quadrature.
|
| 1555 |
+
|
| 1556 |
+
Computes the sample points and weights for Gauss-HermiteE quadrature.
|
| 1557 |
+
These sample points and weights will correctly integrate polynomials of
|
| 1558 |
+
degree :math:`2*deg - 1` or less over the interval :math:`[-\\inf, \\inf]`
|
| 1559 |
+
with the weight function :math:`f(x) = \\exp(-x^2/2)`.
|
| 1560 |
+
|
| 1561 |
+
Parameters
|
| 1562 |
+
----------
|
| 1563 |
+
deg : int
|
| 1564 |
+
Number of sample points and weights. It must be >= 1.
|
| 1565 |
+
|
| 1566 |
+
Returns
|
| 1567 |
+
-------
|
| 1568 |
+
x : ndarray
|
| 1569 |
+
1-D ndarray containing the sample points.
|
| 1570 |
+
y : ndarray
|
| 1571 |
+
1-D ndarray containing the weights.
|
| 1572 |
+
|
| 1573 |
+
Notes
|
| 1574 |
+
-----
|
| 1575 |
+
|
| 1576 |
+
.. versionadded:: 1.7.0
|
| 1577 |
+
|
| 1578 |
+
The results have only been tested up to degree 100, higher degrees may
|
| 1579 |
+
be problematic. The weights are determined by using the fact that
|
| 1580 |
+
|
| 1581 |
+
.. math:: w_k = c / (He'_n(x_k) * He_{n-1}(x_k))
|
| 1582 |
+
|
| 1583 |
+
where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
|
| 1584 |
+
is the k'th root of :math:`He_n`, and then scaling the results to get
|
| 1585 |
+
the right value when integrating 1.
|
| 1586 |
+
|
| 1587 |
+
"""
|
| 1588 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1589 |
+
if ideg <= 0:
|
| 1590 |
+
raise ValueError("deg must be a positive integer")
|
| 1591 |
+
|
| 1592 |
+
# first approximation of roots. We use the fact that the companion
|
| 1593 |
+
# matrix is symmetric in this case in order to obtain better zeros.
|
| 1594 |
+
c = np.array([0]*deg + [1])
|
| 1595 |
+
m = hermecompanion(c)
|
| 1596 |
+
x = la.eigvalsh(m)
|
| 1597 |
+
|
| 1598 |
+
# improve roots by one application of Newton
|
| 1599 |
+
dy = _normed_hermite_e_n(x, ideg)
|
| 1600 |
+
df = _normed_hermite_e_n(x, ideg - 1) * np.sqrt(ideg)
|
| 1601 |
+
x -= dy/df
|
| 1602 |
+
|
| 1603 |
+
# compute the weights. We scale the factor to avoid possible numerical
|
| 1604 |
+
# overflow.
|
| 1605 |
+
fm = _normed_hermite_e_n(x, ideg - 1)
|
| 1606 |
+
fm /= np.abs(fm).max()
|
| 1607 |
+
w = 1/(fm * fm)
|
| 1608 |
+
|
| 1609 |
+
# for Hermite_e we can also symmetrize
|
| 1610 |
+
w = (w + w[::-1])/2
|
| 1611 |
+
x = (x - x[::-1])/2
|
| 1612 |
+
|
| 1613 |
+
# scale w to get the right value
|
| 1614 |
+
w *= np.sqrt(2*np.pi) / w.sum()
|
| 1615 |
+
|
| 1616 |
+
return x, w
|
| 1617 |
+
|
| 1618 |
+
|
| 1619 |
+
def hermeweight(x):
|
| 1620 |
+
"""Weight function of the Hermite_e polynomials.
|
| 1621 |
+
|
| 1622 |
+
The weight function is :math:`\\exp(-x^2/2)` and the interval of
|
| 1623 |
+
integration is :math:`[-\\inf, \\inf]`. the HermiteE polynomials are
|
| 1624 |
+
orthogonal, but not normalized, with respect to this weight function.
|
| 1625 |
+
|
| 1626 |
+
Parameters
|
| 1627 |
+
----------
|
| 1628 |
+
x : array_like
|
| 1629 |
+
Values at which the weight function will be computed.
|
| 1630 |
+
|
| 1631 |
+
Returns
|
| 1632 |
+
-------
|
| 1633 |
+
w : ndarray
|
| 1634 |
+
The weight function at `x`.
|
| 1635 |
+
|
| 1636 |
+
Notes
|
| 1637 |
+
-----
|
| 1638 |
+
|
| 1639 |
+
.. versionadded:: 1.7.0
|
| 1640 |
+
|
| 1641 |
+
"""
|
| 1642 |
+
w = np.exp(-.5*x**2)
|
| 1643 |
+
return w
|
| 1644 |
+
|
| 1645 |
+
|
| 1646 |
+
#
|
| 1647 |
+
# HermiteE series class
|
| 1648 |
+
#
|
| 1649 |
+
|
| 1650 |
+
class HermiteE(ABCPolyBase):
|
| 1651 |
+
"""An HermiteE series class.
|
| 1652 |
+
|
| 1653 |
+
The HermiteE class provides the standard Python numerical methods
|
| 1654 |
+
'+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
|
| 1655 |
+
attributes and methods listed in the `ABCPolyBase` documentation.
|
| 1656 |
+
|
| 1657 |
+
Parameters
|
| 1658 |
+
----------
|
| 1659 |
+
coef : array_like
|
| 1660 |
+
HermiteE coefficients in order of increasing degree, i.e,
|
| 1661 |
+
``(1, 2, 3)`` gives ``1*He_0(x) + 2*He_1(X) + 3*He_2(x)``.
|
| 1662 |
+
domain : (2,) array_like, optional
|
| 1663 |
+
Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
|
| 1664 |
+
to the interval ``[window[0], window[1]]`` by shifting and scaling.
|
| 1665 |
+
The default value is [-1, 1].
|
| 1666 |
+
window : (2,) array_like, optional
|
| 1667 |
+
Window, see `domain` for its use. The default value is [-1, 1].
|
| 1668 |
+
|
| 1669 |
+
.. versionadded:: 1.6.0
|
| 1670 |
+
symbol : str, optional
|
| 1671 |
+
Symbol used to represent the independent variable in string
|
| 1672 |
+
representations of the polynomial expression, e.g. for printing.
|
| 1673 |
+
The symbol must be a valid Python identifier. Default value is 'x'.
|
| 1674 |
+
|
| 1675 |
+
.. versionadded:: 1.24
|
| 1676 |
+
|
| 1677 |
+
"""
|
| 1678 |
+
# Virtual Functions
|
| 1679 |
+
_add = staticmethod(hermeadd)
|
| 1680 |
+
_sub = staticmethod(hermesub)
|
| 1681 |
+
_mul = staticmethod(hermemul)
|
| 1682 |
+
_div = staticmethod(hermediv)
|
| 1683 |
+
_pow = staticmethod(hermepow)
|
| 1684 |
+
_val = staticmethod(hermeval)
|
| 1685 |
+
_int = staticmethod(hermeint)
|
| 1686 |
+
_der = staticmethod(hermeder)
|
| 1687 |
+
_fit = staticmethod(hermefit)
|
| 1688 |
+
_line = staticmethod(hermeline)
|
| 1689 |
+
_roots = staticmethod(hermeroots)
|
| 1690 |
+
_fromroots = staticmethod(hermefromroots)
|
| 1691 |
+
|
| 1692 |
+
# Virtual properties
|
| 1693 |
+
domain = np.array(hermedomain)
|
| 1694 |
+
window = np.array(hermedomain)
|
| 1695 |
+
basis_name = 'He'
|
lib/python3.12/site-packages/numpy/polynomial/hermite_e.pyi
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any
|
| 2 |
+
|
| 3 |
+
from numpy import ndarray, dtype, int_
|
| 4 |
+
from numpy.polynomial._polybase import ABCPolyBase
|
| 5 |
+
from numpy.polynomial.polyutils import trimcoef
|
| 6 |
+
|
| 7 |
+
__all__: list[str]
|
| 8 |
+
|
| 9 |
+
hermetrim = trimcoef
|
| 10 |
+
|
| 11 |
+
def poly2herme(pol): ...
|
| 12 |
+
def herme2poly(c): ...
|
| 13 |
+
|
| 14 |
+
hermedomain: ndarray[Any, dtype[int_]]
|
| 15 |
+
hermezero: ndarray[Any, dtype[int_]]
|
| 16 |
+
hermeone: ndarray[Any, dtype[int_]]
|
| 17 |
+
hermex: ndarray[Any, dtype[int_]]
|
| 18 |
+
|
| 19 |
+
def hermeline(off, scl): ...
|
| 20 |
+
def hermefromroots(roots): ...
|
| 21 |
+
def hermeadd(c1, c2): ...
|
| 22 |
+
def hermesub(c1, c2): ...
|
| 23 |
+
def hermemulx(c): ...
|
| 24 |
+
def hermemul(c1, c2): ...
|
| 25 |
+
def hermediv(c1, c2): ...
|
| 26 |
+
def hermepow(c, pow, maxpower=...): ...
|
| 27 |
+
def hermeder(c, m=..., scl=..., axis=...): ...
|
| 28 |
+
def hermeint(c, m=..., k = ..., lbnd=..., scl=..., axis=...): ...
|
| 29 |
+
def hermeval(x, c, tensor=...): ...
|
| 30 |
+
def hermeval2d(x, y, c): ...
|
| 31 |
+
def hermegrid2d(x, y, c): ...
|
| 32 |
+
def hermeval3d(x, y, z, c): ...
|
| 33 |
+
def hermegrid3d(x, y, z, c): ...
|
| 34 |
+
def hermevander(x, deg): ...
|
| 35 |
+
def hermevander2d(x, y, deg): ...
|
| 36 |
+
def hermevander3d(x, y, z, deg): ...
|
| 37 |
+
def hermefit(x, y, deg, rcond=..., full=..., w=...): ...
|
| 38 |
+
def hermecompanion(c): ...
|
| 39 |
+
def hermeroots(c): ...
|
| 40 |
+
def hermegauss(deg): ...
|
| 41 |
+
def hermeweight(x): ...
|
| 42 |
+
|
| 43 |
+
class HermiteE(ABCPolyBase):
|
| 44 |
+
domain: Any
|
| 45 |
+
window: Any
|
| 46 |
+
basis_name: Any
|
lib/python3.12/site-packages/numpy/polynomial/laguerre.py
ADDED
|
@@ -0,0 +1,1651 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
==================================================
|
| 3 |
+
Laguerre Series (:mod:`numpy.polynomial.laguerre`)
|
| 4 |
+
==================================================
|
| 5 |
+
|
| 6 |
+
This module provides a number of objects (mostly functions) useful for
|
| 7 |
+
dealing with Laguerre series, including a `Laguerre` class that
|
| 8 |
+
encapsulates the usual arithmetic operations. (General information
|
| 9 |
+
on how this module represents and works with such polynomials is in the
|
| 10 |
+
docstring for its "parent" sub-package, `numpy.polynomial`).
|
| 11 |
+
|
| 12 |
+
Classes
|
| 13 |
+
-------
|
| 14 |
+
.. autosummary::
|
| 15 |
+
:toctree: generated/
|
| 16 |
+
|
| 17 |
+
Laguerre
|
| 18 |
+
|
| 19 |
+
Constants
|
| 20 |
+
---------
|
| 21 |
+
.. autosummary::
|
| 22 |
+
:toctree: generated/
|
| 23 |
+
|
| 24 |
+
lagdomain
|
| 25 |
+
lagzero
|
| 26 |
+
lagone
|
| 27 |
+
lagx
|
| 28 |
+
|
| 29 |
+
Arithmetic
|
| 30 |
+
----------
|
| 31 |
+
.. autosummary::
|
| 32 |
+
:toctree: generated/
|
| 33 |
+
|
| 34 |
+
lagadd
|
| 35 |
+
lagsub
|
| 36 |
+
lagmulx
|
| 37 |
+
lagmul
|
| 38 |
+
lagdiv
|
| 39 |
+
lagpow
|
| 40 |
+
lagval
|
| 41 |
+
lagval2d
|
| 42 |
+
lagval3d
|
| 43 |
+
laggrid2d
|
| 44 |
+
laggrid3d
|
| 45 |
+
|
| 46 |
+
Calculus
|
| 47 |
+
--------
|
| 48 |
+
.. autosummary::
|
| 49 |
+
:toctree: generated/
|
| 50 |
+
|
| 51 |
+
lagder
|
| 52 |
+
lagint
|
| 53 |
+
|
| 54 |
+
Misc Functions
|
| 55 |
+
--------------
|
| 56 |
+
.. autosummary::
|
| 57 |
+
:toctree: generated/
|
| 58 |
+
|
| 59 |
+
lagfromroots
|
| 60 |
+
lagroots
|
| 61 |
+
lagvander
|
| 62 |
+
lagvander2d
|
| 63 |
+
lagvander3d
|
| 64 |
+
laggauss
|
| 65 |
+
lagweight
|
| 66 |
+
lagcompanion
|
| 67 |
+
lagfit
|
| 68 |
+
lagtrim
|
| 69 |
+
lagline
|
| 70 |
+
lag2poly
|
| 71 |
+
poly2lag
|
| 72 |
+
|
| 73 |
+
See also
|
| 74 |
+
--------
|
| 75 |
+
`numpy.polynomial`
|
| 76 |
+
|
| 77 |
+
"""
|
| 78 |
+
import numpy as np
|
| 79 |
+
import numpy.linalg as la
|
| 80 |
+
from numpy.core.multiarray import normalize_axis_index
|
| 81 |
+
|
| 82 |
+
from . import polyutils as pu
|
| 83 |
+
from ._polybase import ABCPolyBase
|
| 84 |
+
|
| 85 |
+
__all__ = [
|
| 86 |
+
'lagzero', 'lagone', 'lagx', 'lagdomain', 'lagline', 'lagadd',
|
| 87 |
+
'lagsub', 'lagmulx', 'lagmul', 'lagdiv', 'lagpow', 'lagval', 'lagder',
|
| 88 |
+
'lagint', 'lag2poly', 'poly2lag', 'lagfromroots', 'lagvander',
|
| 89 |
+
'lagfit', 'lagtrim', 'lagroots', 'Laguerre', 'lagval2d', 'lagval3d',
|
| 90 |
+
'laggrid2d', 'laggrid3d', 'lagvander2d', 'lagvander3d', 'lagcompanion',
|
| 91 |
+
'laggauss', 'lagweight']
|
| 92 |
+
|
| 93 |
+
lagtrim = pu.trimcoef
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def poly2lag(pol):
|
| 97 |
+
"""
|
| 98 |
+
poly2lag(pol)
|
| 99 |
+
|
| 100 |
+
Convert a polynomial to a Laguerre series.
|
| 101 |
+
|
| 102 |
+
Convert an array representing the coefficients of a polynomial (relative
|
| 103 |
+
to the "standard" basis) ordered from lowest degree to highest, to an
|
| 104 |
+
array of the coefficients of the equivalent Laguerre series, ordered
|
| 105 |
+
from lowest to highest degree.
|
| 106 |
+
|
| 107 |
+
Parameters
|
| 108 |
+
----------
|
| 109 |
+
pol : array_like
|
| 110 |
+
1-D array containing the polynomial coefficients
|
| 111 |
+
|
| 112 |
+
Returns
|
| 113 |
+
-------
|
| 114 |
+
c : ndarray
|
| 115 |
+
1-D array containing the coefficients of the equivalent Laguerre
|
| 116 |
+
series.
|
| 117 |
+
|
| 118 |
+
See Also
|
| 119 |
+
--------
|
| 120 |
+
lag2poly
|
| 121 |
+
|
| 122 |
+
Notes
|
| 123 |
+
-----
|
| 124 |
+
The easy way to do conversions between polynomial basis sets
|
| 125 |
+
is to use the convert method of a class instance.
|
| 126 |
+
|
| 127 |
+
Examples
|
| 128 |
+
--------
|
| 129 |
+
>>> from numpy.polynomial.laguerre import poly2lag
|
| 130 |
+
>>> poly2lag(np.arange(4))
|
| 131 |
+
array([ 23., -63., 58., -18.])
|
| 132 |
+
|
| 133 |
+
"""
|
| 134 |
+
[pol] = pu.as_series([pol])
|
| 135 |
+
res = 0
|
| 136 |
+
for p in pol[::-1]:
|
| 137 |
+
res = lagadd(lagmulx(res), p)
|
| 138 |
+
return res
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def lag2poly(c):
|
| 142 |
+
"""
|
| 143 |
+
Convert a Laguerre series to a polynomial.
|
| 144 |
+
|
| 145 |
+
Convert an array representing the coefficients of a Laguerre series,
|
| 146 |
+
ordered from lowest degree to highest, to an array of the coefficients
|
| 147 |
+
of the equivalent polynomial (relative to the "standard" basis) ordered
|
| 148 |
+
from lowest to highest degree.
|
| 149 |
+
|
| 150 |
+
Parameters
|
| 151 |
+
----------
|
| 152 |
+
c : array_like
|
| 153 |
+
1-D array containing the Laguerre series coefficients, ordered
|
| 154 |
+
from lowest order term to highest.
|
| 155 |
+
|
| 156 |
+
Returns
|
| 157 |
+
-------
|
| 158 |
+
pol : ndarray
|
| 159 |
+
1-D array containing the coefficients of the equivalent polynomial
|
| 160 |
+
(relative to the "standard" basis) ordered from lowest order term
|
| 161 |
+
to highest.
|
| 162 |
+
|
| 163 |
+
See Also
|
| 164 |
+
--------
|
| 165 |
+
poly2lag
|
| 166 |
+
|
| 167 |
+
Notes
|
| 168 |
+
-----
|
| 169 |
+
The easy way to do conversions between polynomial basis sets
|
| 170 |
+
is to use the convert method of a class instance.
|
| 171 |
+
|
| 172 |
+
Examples
|
| 173 |
+
--------
|
| 174 |
+
>>> from numpy.polynomial.laguerre import lag2poly
|
| 175 |
+
>>> lag2poly([ 23., -63., 58., -18.])
|
| 176 |
+
array([0., 1., 2., 3.])
|
| 177 |
+
|
| 178 |
+
"""
|
| 179 |
+
from .polynomial import polyadd, polysub, polymulx
|
| 180 |
+
|
| 181 |
+
[c] = pu.as_series([c])
|
| 182 |
+
n = len(c)
|
| 183 |
+
if n == 1:
|
| 184 |
+
return c
|
| 185 |
+
else:
|
| 186 |
+
c0 = c[-2]
|
| 187 |
+
c1 = c[-1]
|
| 188 |
+
# i is the current degree of c1
|
| 189 |
+
for i in range(n - 1, 1, -1):
|
| 190 |
+
tmp = c0
|
| 191 |
+
c0 = polysub(c[i - 2], (c1*(i - 1))/i)
|
| 192 |
+
c1 = polyadd(tmp, polysub((2*i - 1)*c1, polymulx(c1))/i)
|
| 193 |
+
return polyadd(c0, polysub(c1, polymulx(c1)))
|
| 194 |
+
|
| 195 |
+
#
|
| 196 |
+
# These are constant arrays are of integer type so as to be compatible
|
| 197 |
+
# with the widest range of other types, such as Decimal.
|
| 198 |
+
#
|
| 199 |
+
|
| 200 |
+
# Laguerre
|
| 201 |
+
lagdomain = np.array([0, 1])
|
| 202 |
+
|
| 203 |
+
# Laguerre coefficients representing zero.
|
| 204 |
+
lagzero = np.array([0])
|
| 205 |
+
|
| 206 |
+
# Laguerre coefficients representing one.
|
| 207 |
+
lagone = np.array([1])
|
| 208 |
+
|
| 209 |
+
# Laguerre coefficients representing the identity x.
|
| 210 |
+
lagx = np.array([1, -1])
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
def lagline(off, scl):
|
| 214 |
+
"""
|
| 215 |
+
Laguerre series whose graph is a straight line.
|
| 216 |
+
|
| 217 |
+
Parameters
|
| 218 |
+
----------
|
| 219 |
+
off, scl : scalars
|
| 220 |
+
The specified line is given by ``off + scl*x``.
|
| 221 |
+
|
| 222 |
+
Returns
|
| 223 |
+
-------
|
| 224 |
+
y : ndarray
|
| 225 |
+
This module's representation of the Laguerre series for
|
| 226 |
+
``off + scl*x``.
|
| 227 |
+
|
| 228 |
+
See Also
|
| 229 |
+
--------
|
| 230 |
+
numpy.polynomial.polynomial.polyline
|
| 231 |
+
numpy.polynomial.chebyshev.chebline
|
| 232 |
+
numpy.polynomial.legendre.legline
|
| 233 |
+
numpy.polynomial.hermite.hermline
|
| 234 |
+
numpy.polynomial.hermite_e.hermeline
|
| 235 |
+
|
| 236 |
+
Examples
|
| 237 |
+
--------
|
| 238 |
+
>>> from numpy.polynomial.laguerre import lagline, lagval
|
| 239 |
+
>>> lagval(0,lagline(3, 2))
|
| 240 |
+
3.0
|
| 241 |
+
>>> lagval(1,lagline(3, 2))
|
| 242 |
+
5.0
|
| 243 |
+
|
| 244 |
+
"""
|
| 245 |
+
if scl != 0:
|
| 246 |
+
return np.array([off + scl, -scl])
|
| 247 |
+
else:
|
| 248 |
+
return np.array([off])
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
def lagfromroots(roots):
|
| 252 |
+
"""
|
| 253 |
+
Generate a Laguerre series with given roots.
|
| 254 |
+
|
| 255 |
+
The function returns the coefficients of the polynomial
|
| 256 |
+
|
| 257 |
+
.. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
|
| 258 |
+
|
| 259 |
+
in Laguerre form, where the `r_n` are the roots specified in `roots`.
|
| 260 |
+
If a zero has multiplicity n, then it must appear in `roots` n times.
|
| 261 |
+
For instance, if 2 is a root of multiplicity three and 3 is a root of
|
| 262 |
+
multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
|
| 263 |
+
roots can appear in any order.
|
| 264 |
+
|
| 265 |
+
If the returned coefficients are `c`, then
|
| 266 |
+
|
| 267 |
+
.. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x)
|
| 268 |
+
|
| 269 |
+
The coefficient of the last term is not generally 1 for monic
|
| 270 |
+
polynomials in Laguerre form.
|
| 271 |
+
|
| 272 |
+
Parameters
|
| 273 |
+
----------
|
| 274 |
+
roots : array_like
|
| 275 |
+
Sequence containing the roots.
|
| 276 |
+
|
| 277 |
+
Returns
|
| 278 |
+
-------
|
| 279 |
+
out : ndarray
|
| 280 |
+
1-D array of coefficients. If all roots are real then `out` is a
|
| 281 |
+
real array, if some of the roots are complex, then `out` is complex
|
| 282 |
+
even if all the coefficients in the result are real (see Examples
|
| 283 |
+
below).
|
| 284 |
+
|
| 285 |
+
See Also
|
| 286 |
+
--------
|
| 287 |
+
numpy.polynomial.polynomial.polyfromroots
|
| 288 |
+
numpy.polynomial.legendre.legfromroots
|
| 289 |
+
numpy.polynomial.chebyshev.chebfromroots
|
| 290 |
+
numpy.polynomial.hermite.hermfromroots
|
| 291 |
+
numpy.polynomial.hermite_e.hermefromroots
|
| 292 |
+
|
| 293 |
+
Examples
|
| 294 |
+
--------
|
| 295 |
+
>>> from numpy.polynomial.laguerre import lagfromroots, lagval
|
| 296 |
+
>>> coef = lagfromroots((-1, 0, 1))
|
| 297 |
+
>>> lagval((-1, 0, 1), coef)
|
| 298 |
+
array([0., 0., 0.])
|
| 299 |
+
>>> coef = lagfromroots((-1j, 1j))
|
| 300 |
+
>>> lagval((-1j, 1j), coef)
|
| 301 |
+
array([0.+0.j, 0.+0.j])
|
| 302 |
+
|
| 303 |
+
"""
|
| 304 |
+
return pu._fromroots(lagline, lagmul, roots)
|
| 305 |
+
|
| 306 |
+
|
| 307 |
+
def lagadd(c1, c2):
|
| 308 |
+
"""
|
| 309 |
+
Add one Laguerre series to another.
|
| 310 |
+
|
| 311 |
+
Returns the sum of two Laguerre series `c1` + `c2`. The arguments
|
| 312 |
+
are sequences of coefficients ordered from lowest order term to
|
| 313 |
+
highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 314 |
+
|
| 315 |
+
Parameters
|
| 316 |
+
----------
|
| 317 |
+
c1, c2 : array_like
|
| 318 |
+
1-D arrays of Laguerre series coefficients ordered from low to
|
| 319 |
+
high.
|
| 320 |
+
|
| 321 |
+
Returns
|
| 322 |
+
-------
|
| 323 |
+
out : ndarray
|
| 324 |
+
Array representing the Laguerre series of their sum.
|
| 325 |
+
|
| 326 |
+
See Also
|
| 327 |
+
--------
|
| 328 |
+
lagsub, lagmulx, lagmul, lagdiv, lagpow
|
| 329 |
+
|
| 330 |
+
Notes
|
| 331 |
+
-----
|
| 332 |
+
Unlike multiplication, division, etc., the sum of two Laguerre series
|
| 333 |
+
is a Laguerre series (without having to "reproject" the result onto
|
| 334 |
+
the basis set) so addition, just like that of "standard" polynomials,
|
| 335 |
+
is simply "component-wise."
|
| 336 |
+
|
| 337 |
+
Examples
|
| 338 |
+
--------
|
| 339 |
+
>>> from numpy.polynomial.laguerre import lagadd
|
| 340 |
+
>>> lagadd([1, 2, 3], [1, 2, 3, 4])
|
| 341 |
+
array([2., 4., 6., 4.])
|
| 342 |
+
|
| 343 |
+
|
| 344 |
+
"""
|
| 345 |
+
return pu._add(c1, c2)
|
| 346 |
+
|
| 347 |
+
|
| 348 |
+
def lagsub(c1, c2):
|
| 349 |
+
"""
|
| 350 |
+
Subtract one Laguerre series from another.
|
| 351 |
+
|
| 352 |
+
Returns the difference of two Laguerre series `c1` - `c2`. The
|
| 353 |
+
sequences of coefficients are from lowest order term to highest, i.e.,
|
| 354 |
+
[1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 355 |
+
|
| 356 |
+
Parameters
|
| 357 |
+
----------
|
| 358 |
+
c1, c2 : array_like
|
| 359 |
+
1-D arrays of Laguerre series coefficients ordered from low to
|
| 360 |
+
high.
|
| 361 |
+
|
| 362 |
+
Returns
|
| 363 |
+
-------
|
| 364 |
+
out : ndarray
|
| 365 |
+
Of Laguerre series coefficients representing their difference.
|
| 366 |
+
|
| 367 |
+
See Also
|
| 368 |
+
--------
|
| 369 |
+
lagadd, lagmulx, lagmul, lagdiv, lagpow
|
| 370 |
+
|
| 371 |
+
Notes
|
| 372 |
+
-----
|
| 373 |
+
Unlike multiplication, division, etc., the difference of two Laguerre
|
| 374 |
+
series is a Laguerre series (without having to "reproject" the result
|
| 375 |
+
onto the basis set) so subtraction, just like that of "standard"
|
| 376 |
+
polynomials, is simply "component-wise."
|
| 377 |
+
|
| 378 |
+
Examples
|
| 379 |
+
--------
|
| 380 |
+
>>> from numpy.polynomial.laguerre import lagsub
|
| 381 |
+
>>> lagsub([1, 2, 3, 4], [1, 2, 3])
|
| 382 |
+
array([0., 0., 0., 4.])
|
| 383 |
+
|
| 384 |
+
"""
|
| 385 |
+
return pu._sub(c1, c2)
|
| 386 |
+
|
| 387 |
+
|
| 388 |
+
def lagmulx(c):
|
| 389 |
+
"""Multiply a Laguerre series by x.
|
| 390 |
+
|
| 391 |
+
Multiply the Laguerre series `c` by x, where x is the independent
|
| 392 |
+
variable.
|
| 393 |
+
|
| 394 |
+
|
| 395 |
+
Parameters
|
| 396 |
+
----------
|
| 397 |
+
c : array_like
|
| 398 |
+
1-D array of Laguerre series coefficients ordered from low to
|
| 399 |
+
high.
|
| 400 |
+
|
| 401 |
+
Returns
|
| 402 |
+
-------
|
| 403 |
+
out : ndarray
|
| 404 |
+
Array representing the result of the multiplication.
|
| 405 |
+
|
| 406 |
+
See Also
|
| 407 |
+
--------
|
| 408 |
+
lagadd, lagsub, lagmul, lagdiv, lagpow
|
| 409 |
+
|
| 410 |
+
Notes
|
| 411 |
+
-----
|
| 412 |
+
The multiplication uses the recursion relationship for Laguerre
|
| 413 |
+
polynomials in the form
|
| 414 |
+
|
| 415 |
+
.. math::
|
| 416 |
+
|
| 417 |
+
xP_i(x) = (-(i + 1)*P_{i + 1}(x) + (2i + 1)P_{i}(x) - iP_{i - 1}(x))
|
| 418 |
+
|
| 419 |
+
Examples
|
| 420 |
+
--------
|
| 421 |
+
>>> from numpy.polynomial.laguerre import lagmulx
|
| 422 |
+
>>> lagmulx([1, 2, 3])
|
| 423 |
+
array([-1., -1., 11., -9.])
|
| 424 |
+
|
| 425 |
+
"""
|
| 426 |
+
# c is a trimmed copy
|
| 427 |
+
[c] = pu.as_series([c])
|
| 428 |
+
# The zero series needs special treatment
|
| 429 |
+
if len(c) == 1 and c[0] == 0:
|
| 430 |
+
return c
|
| 431 |
+
|
| 432 |
+
prd = np.empty(len(c) + 1, dtype=c.dtype)
|
| 433 |
+
prd[0] = c[0]
|
| 434 |
+
prd[1] = -c[0]
|
| 435 |
+
for i in range(1, len(c)):
|
| 436 |
+
prd[i + 1] = -c[i]*(i + 1)
|
| 437 |
+
prd[i] += c[i]*(2*i + 1)
|
| 438 |
+
prd[i - 1] -= c[i]*i
|
| 439 |
+
return prd
|
| 440 |
+
|
| 441 |
+
|
| 442 |
+
def lagmul(c1, c2):
|
| 443 |
+
"""
|
| 444 |
+
Multiply one Laguerre series by another.
|
| 445 |
+
|
| 446 |
+
Returns the product of two Laguerre series `c1` * `c2`. The arguments
|
| 447 |
+
are sequences of coefficients, from lowest order "term" to highest,
|
| 448 |
+
e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 449 |
+
|
| 450 |
+
Parameters
|
| 451 |
+
----------
|
| 452 |
+
c1, c2 : array_like
|
| 453 |
+
1-D arrays of Laguerre series coefficients ordered from low to
|
| 454 |
+
high.
|
| 455 |
+
|
| 456 |
+
Returns
|
| 457 |
+
-------
|
| 458 |
+
out : ndarray
|
| 459 |
+
Of Laguerre series coefficients representing their product.
|
| 460 |
+
|
| 461 |
+
See Also
|
| 462 |
+
--------
|
| 463 |
+
lagadd, lagsub, lagmulx, lagdiv, lagpow
|
| 464 |
+
|
| 465 |
+
Notes
|
| 466 |
+
-----
|
| 467 |
+
In general, the (polynomial) product of two C-series results in terms
|
| 468 |
+
that are not in the Laguerre polynomial basis set. Thus, to express
|
| 469 |
+
the product as a Laguerre series, it is necessary to "reproject" the
|
| 470 |
+
product onto said basis set, which may produce "unintuitive" (but
|
| 471 |
+
correct) results; see Examples section below.
|
| 472 |
+
|
| 473 |
+
Examples
|
| 474 |
+
--------
|
| 475 |
+
>>> from numpy.polynomial.laguerre import lagmul
|
| 476 |
+
>>> lagmul([1, 2, 3], [0, 1, 2])
|
| 477 |
+
array([ 8., -13., 38., -51., 36.])
|
| 478 |
+
|
| 479 |
+
"""
|
| 480 |
+
# s1, s2 are trimmed copies
|
| 481 |
+
[c1, c2] = pu.as_series([c1, c2])
|
| 482 |
+
|
| 483 |
+
if len(c1) > len(c2):
|
| 484 |
+
c = c2
|
| 485 |
+
xs = c1
|
| 486 |
+
else:
|
| 487 |
+
c = c1
|
| 488 |
+
xs = c2
|
| 489 |
+
|
| 490 |
+
if len(c) == 1:
|
| 491 |
+
c0 = c[0]*xs
|
| 492 |
+
c1 = 0
|
| 493 |
+
elif len(c) == 2:
|
| 494 |
+
c0 = c[0]*xs
|
| 495 |
+
c1 = c[1]*xs
|
| 496 |
+
else:
|
| 497 |
+
nd = len(c)
|
| 498 |
+
c0 = c[-2]*xs
|
| 499 |
+
c1 = c[-1]*xs
|
| 500 |
+
for i in range(3, len(c) + 1):
|
| 501 |
+
tmp = c0
|
| 502 |
+
nd = nd - 1
|
| 503 |
+
c0 = lagsub(c[-i]*xs, (c1*(nd - 1))/nd)
|
| 504 |
+
c1 = lagadd(tmp, lagsub((2*nd - 1)*c1, lagmulx(c1))/nd)
|
| 505 |
+
return lagadd(c0, lagsub(c1, lagmulx(c1)))
|
| 506 |
+
|
| 507 |
+
|
| 508 |
+
def lagdiv(c1, c2):
|
| 509 |
+
"""
|
| 510 |
+
Divide one Laguerre series by another.
|
| 511 |
+
|
| 512 |
+
Returns the quotient-with-remainder of two Laguerre series
|
| 513 |
+
`c1` / `c2`. The arguments are sequences of coefficients from lowest
|
| 514 |
+
order "term" to highest, e.g., [1,2,3] represents the series
|
| 515 |
+
``P_0 + 2*P_1 + 3*P_2``.
|
| 516 |
+
|
| 517 |
+
Parameters
|
| 518 |
+
----------
|
| 519 |
+
c1, c2 : array_like
|
| 520 |
+
1-D arrays of Laguerre series coefficients ordered from low to
|
| 521 |
+
high.
|
| 522 |
+
|
| 523 |
+
Returns
|
| 524 |
+
-------
|
| 525 |
+
[quo, rem] : ndarrays
|
| 526 |
+
Of Laguerre series coefficients representing the quotient and
|
| 527 |
+
remainder.
|
| 528 |
+
|
| 529 |
+
See Also
|
| 530 |
+
--------
|
| 531 |
+
lagadd, lagsub, lagmulx, lagmul, lagpow
|
| 532 |
+
|
| 533 |
+
Notes
|
| 534 |
+
-----
|
| 535 |
+
In general, the (polynomial) division of one Laguerre series by another
|
| 536 |
+
results in quotient and remainder terms that are not in the Laguerre
|
| 537 |
+
polynomial basis set. Thus, to express these results as a Laguerre
|
| 538 |
+
series, it is necessary to "reproject" the results onto the Laguerre
|
| 539 |
+
basis set, which may produce "unintuitive" (but correct) results; see
|
| 540 |
+
Examples section below.
|
| 541 |
+
|
| 542 |
+
Examples
|
| 543 |
+
--------
|
| 544 |
+
>>> from numpy.polynomial.laguerre import lagdiv
|
| 545 |
+
>>> lagdiv([ 8., -13., 38., -51., 36.], [0, 1, 2])
|
| 546 |
+
(array([1., 2., 3.]), array([0.]))
|
| 547 |
+
>>> lagdiv([ 9., -12., 38., -51., 36.], [0, 1, 2])
|
| 548 |
+
(array([1., 2., 3.]), array([1., 1.]))
|
| 549 |
+
|
| 550 |
+
"""
|
| 551 |
+
return pu._div(lagmul, c1, c2)
|
| 552 |
+
|
| 553 |
+
|
| 554 |
+
def lagpow(c, pow, maxpower=16):
|
| 555 |
+
"""Raise a Laguerre series to a power.
|
| 556 |
+
|
| 557 |
+
Returns the Laguerre series `c` raised to the power `pow`. The
|
| 558 |
+
argument `c` is a sequence of coefficients ordered from low to high.
|
| 559 |
+
i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.``
|
| 560 |
+
|
| 561 |
+
Parameters
|
| 562 |
+
----------
|
| 563 |
+
c : array_like
|
| 564 |
+
1-D array of Laguerre series coefficients ordered from low to
|
| 565 |
+
high.
|
| 566 |
+
pow : integer
|
| 567 |
+
Power to which the series will be raised
|
| 568 |
+
maxpower : integer, optional
|
| 569 |
+
Maximum power allowed. This is mainly to limit growth of the series
|
| 570 |
+
to unmanageable size. Default is 16
|
| 571 |
+
|
| 572 |
+
Returns
|
| 573 |
+
-------
|
| 574 |
+
coef : ndarray
|
| 575 |
+
Laguerre series of power.
|
| 576 |
+
|
| 577 |
+
See Also
|
| 578 |
+
--------
|
| 579 |
+
lagadd, lagsub, lagmulx, lagmul, lagdiv
|
| 580 |
+
|
| 581 |
+
Examples
|
| 582 |
+
--------
|
| 583 |
+
>>> from numpy.polynomial.laguerre import lagpow
|
| 584 |
+
>>> lagpow([1, 2, 3], 2)
|
| 585 |
+
array([ 14., -16., 56., -72., 54.])
|
| 586 |
+
|
| 587 |
+
"""
|
| 588 |
+
return pu._pow(lagmul, c, pow, maxpower)
|
| 589 |
+
|
| 590 |
+
|
| 591 |
+
def lagder(c, m=1, scl=1, axis=0):
|
| 592 |
+
"""
|
| 593 |
+
Differentiate a Laguerre series.
|
| 594 |
+
|
| 595 |
+
Returns the Laguerre series coefficients `c` differentiated `m` times
|
| 596 |
+
along `axis`. At each iteration the result is multiplied by `scl` (the
|
| 597 |
+
scaling factor is for use in a linear change of variable). The argument
|
| 598 |
+
`c` is an array of coefficients from low to high degree along each
|
| 599 |
+
axis, e.g., [1,2,3] represents the series ``1*L_0 + 2*L_1 + 3*L_2``
|
| 600 |
+
while [[1,2],[1,2]] represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) +
|
| 601 |
+
2*L_0(x)*L_1(y) + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is
|
| 602 |
+
``y``.
|
| 603 |
+
|
| 604 |
+
Parameters
|
| 605 |
+
----------
|
| 606 |
+
c : array_like
|
| 607 |
+
Array of Laguerre series coefficients. If `c` is multidimensional
|
| 608 |
+
the different axis correspond to different variables with the
|
| 609 |
+
degree in each axis given by the corresponding index.
|
| 610 |
+
m : int, optional
|
| 611 |
+
Number of derivatives taken, must be non-negative. (Default: 1)
|
| 612 |
+
scl : scalar, optional
|
| 613 |
+
Each differentiation is multiplied by `scl`. The end result is
|
| 614 |
+
multiplication by ``scl**m``. This is for use in a linear change of
|
| 615 |
+
variable. (Default: 1)
|
| 616 |
+
axis : int, optional
|
| 617 |
+
Axis over which the derivative is taken. (Default: 0).
|
| 618 |
+
|
| 619 |
+
.. versionadded:: 1.7.0
|
| 620 |
+
|
| 621 |
+
Returns
|
| 622 |
+
-------
|
| 623 |
+
der : ndarray
|
| 624 |
+
Laguerre series of the derivative.
|
| 625 |
+
|
| 626 |
+
See Also
|
| 627 |
+
--------
|
| 628 |
+
lagint
|
| 629 |
+
|
| 630 |
+
Notes
|
| 631 |
+
-----
|
| 632 |
+
In general, the result of differentiating a Laguerre series does not
|
| 633 |
+
resemble the same operation on a power series. Thus the result of this
|
| 634 |
+
function may be "unintuitive," albeit correct; see Examples section
|
| 635 |
+
below.
|
| 636 |
+
|
| 637 |
+
Examples
|
| 638 |
+
--------
|
| 639 |
+
>>> from numpy.polynomial.laguerre import lagder
|
| 640 |
+
>>> lagder([ 1., 1., 1., -3.])
|
| 641 |
+
array([1., 2., 3.])
|
| 642 |
+
>>> lagder([ 1., 0., 0., -4., 3.], m=2)
|
| 643 |
+
array([1., 2., 3.])
|
| 644 |
+
|
| 645 |
+
"""
|
| 646 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 647 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 648 |
+
c = c.astype(np.double)
|
| 649 |
+
|
| 650 |
+
cnt = pu._deprecate_as_int(m, "the order of derivation")
|
| 651 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 652 |
+
if cnt < 0:
|
| 653 |
+
raise ValueError("The order of derivation must be non-negative")
|
| 654 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 655 |
+
|
| 656 |
+
if cnt == 0:
|
| 657 |
+
return c
|
| 658 |
+
|
| 659 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 660 |
+
n = len(c)
|
| 661 |
+
if cnt >= n:
|
| 662 |
+
c = c[:1]*0
|
| 663 |
+
else:
|
| 664 |
+
for i in range(cnt):
|
| 665 |
+
n = n - 1
|
| 666 |
+
c *= scl
|
| 667 |
+
der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
|
| 668 |
+
for j in range(n, 1, -1):
|
| 669 |
+
der[j - 1] = -c[j]
|
| 670 |
+
c[j - 1] += c[j]
|
| 671 |
+
der[0] = -c[1]
|
| 672 |
+
c = der
|
| 673 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 674 |
+
return c
|
| 675 |
+
|
| 676 |
+
|
| 677 |
+
def lagint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
|
| 678 |
+
"""
|
| 679 |
+
Integrate a Laguerre series.
|
| 680 |
+
|
| 681 |
+
Returns the Laguerre series coefficients `c` integrated `m` times from
|
| 682 |
+
`lbnd` along `axis`. At each iteration the resulting series is
|
| 683 |
+
**multiplied** by `scl` and an integration constant, `k`, is added.
|
| 684 |
+
The scaling factor is for use in a linear change of variable. ("Buyer
|
| 685 |
+
beware": note that, depending on what one is doing, one may want `scl`
|
| 686 |
+
to be the reciprocal of what one might expect; for more information,
|
| 687 |
+
see the Notes section below.) The argument `c` is an array of
|
| 688 |
+
coefficients from low to high degree along each axis, e.g., [1,2,3]
|
| 689 |
+
represents the series ``L_0 + 2*L_1 + 3*L_2`` while [[1,2],[1,2]]
|
| 690 |
+
represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 2*L_0(x)*L_1(y) +
|
| 691 |
+
2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
|
| 692 |
+
|
| 693 |
+
|
| 694 |
+
Parameters
|
| 695 |
+
----------
|
| 696 |
+
c : array_like
|
| 697 |
+
Array of Laguerre series coefficients. If `c` is multidimensional
|
| 698 |
+
the different axis correspond to different variables with the
|
| 699 |
+
degree in each axis given by the corresponding index.
|
| 700 |
+
m : int, optional
|
| 701 |
+
Order of integration, must be positive. (Default: 1)
|
| 702 |
+
k : {[], list, scalar}, optional
|
| 703 |
+
Integration constant(s). The value of the first integral at
|
| 704 |
+
``lbnd`` is the first value in the list, the value of the second
|
| 705 |
+
integral at ``lbnd`` is the second value, etc. If ``k == []`` (the
|
| 706 |
+
default), all constants are set to zero. If ``m == 1``, a single
|
| 707 |
+
scalar can be given instead of a list.
|
| 708 |
+
lbnd : scalar, optional
|
| 709 |
+
The lower bound of the integral. (Default: 0)
|
| 710 |
+
scl : scalar, optional
|
| 711 |
+
Following each integration the result is *multiplied* by `scl`
|
| 712 |
+
before the integration constant is added. (Default: 1)
|
| 713 |
+
axis : int, optional
|
| 714 |
+
Axis over which the integral is taken. (Default: 0).
|
| 715 |
+
|
| 716 |
+
.. versionadded:: 1.7.0
|
| 717 |
+
|
| 718 |
+
Returns
|
| 719 |
+
-------
|
| 720 |
+
S : ndarray
|
| 721 |
+
Laguerre series coefficients of the integral.
|
| 722 |
+
|
| 723 |
+
Raises
|
| 724 |
+
------
|
| 725 |
+
ValueError
|
| 726 |
+
If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or
|
| 727 |
+
``np.ndim(scl) != 0``.
|
| 728 |
+
|
| 729 |
+
See Also
|
| 730 |
+
--------
|
| 731 |
+
lagder
|
| 732 |
+
|
| 733 |
+
Notes
|
| 734 |
+
-----
|
| 735 |
+
Note that the result of each integration is *multiplied* by `scl`.
|
| 736 |
+
Why is this important to note? Say one is making a linear change of
|
| 737 |
+
variable :math:`u = ax + b` in an integral relative to `x`. Then
|
| 738 |
+
:math:`dx = du/a`, so one will need to set `scl` equal to
|
| 739 |
+
:math:`1/a` - perhaps not what one would have first thought.
|
| 740 |
+
|
| 741 |
+
Also note that, in general, the result of integrating a C-series needs
|
| 742 |
+
to be "reprojected" onto the C-series basis set. Thus, typically,
|
| 743 |
+
the result of this function is "unintuitive," albeit correct; see
|
| 744 |
+
Examples section below.
|
| 745 |
+
|
| 746 |
+
Examples
|
| 747 |
+
--------
|
| 748 |
+
>>> from numpy.polynomial.laguerre import lagint
|
| 749 |
+
>>> lagint([1,2,3])
|
| 750 |
+
array([ 1., 1., 1., -3.])
|
| 751 |
+
>>> lagint([1,2,3], m=2)
|
| 752 |
+
array([ 1., 0., 0., -4., 3.])
|
| 753 |
+
>>> lagint([1,2,3], k=1)
|
| 754 |
+
array([ 2., 1., 1., -3.])
|
| 755 |
+
>>> lagint([1,2,3], lbnd=-1)
|
| 756 |
+
array([11.5, 1. , 1. , -3. ])
|
| 757 |
+
>>> lagint([1,2], m=2, k=[1,2], lbnd=-1)
|
| 758 |
+
array([ 11.16666667, -5. , -3. , 2. ]) # may vary
|
| 759 |
+
|
| 760 |
+
"""
|
| 761 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 762 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 763 |
+
c = c.astype(np.double)
|
| 764 |
+
if not np.iterable(k):
|
| 765 |
+
k = [k]
|
| 766 |
+
cnt = pu._deprecate_as_int(m, "the order of integration")
|
| 767 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 768 |
+
if cnt < 0:
|
| 769 |
+
raise ValueError("The order of integration must be non-negative")
|
| 770 |
+
if len(k) > cnt:
|
| 771 |
+
raise ValueError("Too many integration constants")
|
| 772 |
+
if np.ndim(lbnd) != 0:
|
| 773 |
+
raise ValueError("lbnd must be a scalar.")
|
| 774 |
+
if np.ndim(scl) != 0:
|
| 775 |
+
raise ValueError("scl must be a scalar.")
|
| 776 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 777 |
+
|
| 778 |
+
if cnt == 0:
|
| 779 |
+
return c
|
| 780 |
+
|
| 781 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 782 |
+
k = list(k) + [0]*(cnt - len(k))
|
| 783 |
+
for i in range(cnt):
|
| 784 |
+
n = len(c)
|
| 785 |
+
c *= scl
|
| 786 |
+
if n == 1 and np.all(c[0] == 0):
|
| 787 |
+
c[0] += k[i]
|
| 788 |
+
else:
|
| 789 |
+
tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
|
| 790 |
+
tmp[0] = c[0]
|
| 791 |
+
tmp[1] = -c[0]
|
| 792 |
+
for j in range(1, n):
|
| 793 |
+
tmp[j] += c[j]
|
| 794 |
+
tmp[j + 1] = -c[j]
|
| 795 |
+
tmp[0] += k[i] - lagval(lbnd, tmp)
|
| 796 |
+
c = tmp
|
| 797 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 798 |
+
return c
|
| 799 |
+
|
| 800 |
+
|
| 801 |
+
def lagval(x, c, tensor=True):
|
| 802 |
+
"""
|
| 803 |
+
Evaluate a Laguerre series at points x.
|
| 804 |
+
|
| 805 |
+
If `c` is of length `n + 1`, this function returns the value:
|
| 806 |
+
|
| 807 |
+
.. math:: p(x) = c_0 * L_0(x) + c_1 * L_1(x) + ... + c_n * L_n(x)
|
| 808 |
+
|
| 809 |
+
The parameter `x` is converted to an array only if it is a tuple or a
|
| 810 |
+
list, otherwise it is treated as a scalar. In either case, either `x`
|
| 811 |
+
or its elements must support multiplication and addition both with
|
| 812 |
+
themselves and with the elements of `c`.
|
| 813 |
+
|
| 814 |
+
If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If
|
| 815 |
+
`c` is multidimensional, then the shape of the result depends on the
|
| 816 |
+
value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
|
| 817 |
+
x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
|
| 818 |
+
scalars have shape (,).
|
| 819 |
+
|
| 820 |
+
Trailing zeros in the coefficients will be used in the evaluation, so
|
| 821 |
+
they should be avoided if efficiency is a concern.
|
| 822 |
+
|
| 823 |
+
Parameters
|
| 824 |
+
----------
|
| 825 |
+
x : array_like, compatible object
|
| 826 |
+
If `x` is a list or tuple, it is converted to an ndarray, otherwise
|
| 827 |
+
it is left unchanged and treated as a scalar. In either case, `x`
|
| 828 |
+
or its elements must support addition and multiplication with
|
| 829 |
+
themselves and with the elements of `c`.
|
| 830 |
+
c : array_like
|
| 831 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 832 |
+
degree n are contained in c[n]. If `c` is multidimensional the
|
| 833 |
+
remaining indices enumerate multiple polynomials. In the two
|
| 834 |
+
dimensional case the coefficients may be thought of as stored in
|
| 835 |
+
the columns of `c`.
|
| 836 |
+
tensor : boolean, optional
|
| 837 |
+
If True, the shape of the coefficient array is extended with ones
|
| 838 |
+
on the right, one for each dimension of `x`. Scalars have dimension 0
|
| 839 |
+
for this action. The result is that every column of coefficients in
|
| 840 |
+
`c` is evaluated for every element of `x`. If False, `x` is broadcast
|
| 841 |
+
over the columns of `c` for the evaluation. This keyword is useful
|
| 842 |
+
when `c` is multidimensional. The default value is True.
|
| 843 |
+
|
| 844 |
+
.. versionadded:: 1.7.0
|
| 845 |
+
|
| 846 |
+
Returns
|
| 847 |
+
-------
|
| 848 |
+
values : ndarray, algebra_like
|
| 849 |
+
The shape of the return value is described above.
|
| 850 |
+
|
| 851 |
+
See Also
|
| 852 |
+
--------
|
| 853 |
+
lagval2d, laggrid2d, lagval3d, laggrid3d
|
| 854 |
+
|
| 855 |
+
Notes
|
| 856 |
+
-----
|
| 857 |
+
The evaluation uses Clenshaw recursion, aka synthetic division.
|
| 858 |
+
|
| 859 |
+
Examples
|
| 860 |
+
--------
|
| 861 |
+
>>> from numpy.polynomial.laguerre import lagval
|
| 862 |
+
>>> coef = [1,2,3]
|
| 863 |
+
>>> lagval(1, coef)
|
| 864 |
+
-0.5
|
| 865 |
+
>>> lagval([[1,2],[3,4]], coef)
|
| 866 |
+
array([[-0.5, -4. ],
|
| 867 |
+
[-4.5, -2. ]])
|
| 868 |
+
|
| 869 |
+
"""
|
| 870 |
+
c = np.array(c, ndmin=1, copy=False)
|
| 871 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 872 |
+
c = c.astype(np.double)
|
| 873 |
+
if isinstance(x, (tuple, list)):
|
| 874 |
+
x = np.asarray(x)
|
| 875 |
+
if isinstance(x, np.ndarray) and tensor:
|
| 876 |
+
c = c.reshape(c.shape + (1,)*x.ndim)
|
| 877 |
+
|
| 878 |
+
if len(c) == 1:
|
| 879 |
+
c0 = c[0]
|
| 880 |
+
c1 = 0
|
| 881 |
+
elif len(c) == 2:
|
| 882 |
+
c0 = c[0]
|
| 883 |
+
c1 = c[1]
|
| 884 |
+
else:
|
| 885 |
+
nd = len(c)
|
| 886 |
+
c0 = c[-2]
|
| 887 |
+
c1 = c[-1]
|
| 888 |
+
for i in range(3, len(c) + 1):
|
| 889 |
+
tmp = c0
|
| 890 |
+
nd = nd - 1
|
| 891 |
+
c0 = c[-i] - (c1*(nd - 1))/nd
|
| 892 |
+
c1 = tmp + (c1*((2*nd - 1) - x))/nd
|
| 893 |
+
return c0 + c1*(1 - x)
|
| 894 |
+
|
| 895 |
+
|
| 896 |
+
def lagval2d(x, y, c):
|
| 897 |
+
"""
|
| 898 |
+
Evaluate a 2-D Laguerre series at points (x, y).
|
| 899 |
+
|
| 900 |
+
This function returns the values:
|
| 901 |
+
|
| 902 |
+
.. math:: p(x,y) = \\sum_{i,j} c_{i,j} * L_i(x) * L_j(y)
|
| 903 |
+
|
| 904 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 905 |
+
tuples or a lists, otherwise they are treated as a scalars and they
|
| 906 |
+
must have the same shape after conversion. In either case, either `x`
|
| 907 |
+
and `y` or their elements must support multiplication and addition both
|
| 908 |
+
with themselves and with the elements of `c`.
|
| 909 |
+
|
| 910 |
+
If `c` is a 1-D array a one is implicitly appended to its shape to make
|
| 911 |
+
it 2-D. The shape of the result will be c.shape[2:] + x.shape.
|
| 912 |
+
|
| 913 |
+
Parameters
|
| 914 |
+
----------
|
| 915 |
+
x, y : array_like, compatible objects
|
| 916 |
+
The two dimensional series is evaluated at the points `(x, y)`,
|
| 917 |
+
where `x` and `y` must have the same shape. If `x` or `y` is a list
|
| 918 |
+
or tuple, it is first converted to an ndarray, otherwise it is left
|
| 919 |
+
unchanged and if it isn't an ndarray it is treated as a scalar.
|
| 920 |
+
c : array_like
|
| 921 |
+
Array of coefficients ordered so that the coefficient of the term
|
| 922 |
+
of multi-degree i,j is contained in ``c[i,j]``. If `c` has
|
| 923 |
+
dimension greater than two the remaining indices enumerate multiple
|
| 924 |
+
sets of coefficients.
|
| 925 |
+
|
| 926 |
+
Returns
|
| 927 |
+
-------
|
| 928 |
+
values : ndarray, compatible object
|
| 929 |
+
The values of the two dimensional polynomial at points formed with
|
| 930 |
+
pairs of corresponding values from `x` and `y`.
|
| 931 |
+
|
| 932 |
+
See Also
|
| 933 |
+
--------
|
| 934 |
+
lagval, laggrid2d, lagval3d, laggrid3d
|
| 935 |
+
|
| 936 |
+
Notes
|
| 937 |
+
-----
|
| 938 |
+
|
| 939 |
+
.. versionadded:: 1.7.0
|
| 940 |
+
|
| 941 |
+
"""
|
| 942 |
+
return pu._valnd(lagval, c, x, y)
|
| 943 |
+
|
| 944 |
+
|
| 945 |
+
def laggrid2d(x, y, c):
|
| 946 |
+
"""
|
| 947 |
+
Evaluate a 2-D Laguerre series on the Cartesian product of x and y.
|
| 948 |
+
|
| 949 |
+
This function returns the values:
|
| 950 |
+
|
| 951 |
+
.. math:: p(a,b) = \\sum_{i,j} c_{i,j} * L_i(a) * L_j(b)
|
| 952 |
+
|
| 953 |
+
where the points `(a, b)` consist of all pairs formed by taking
|
| 954 |
+
`a` from `x` and `b` from `y`. The resulting points form a grid with
|
| 955 |
+
`x` in the first dimension and `y` in the second.
|
| 956 |
+
|
| 957 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 958 |
+
tuples or a lists, otherwise they are treated as a scalars. In either
|
| 959 |
+
case, either `x` and `y` or their elements must support multiplication
|
| 960 |
+
and addition both with themselves and with the elements of `c`.
|
| 961 |
+
|
| 962 |
+
If `c` has fewer than two dimensions, ones are implicitly appended to
|
| 963 |
+
its shape to make it 2-D. The shape of the result will be c.shape[2:] +
|
| 964 |
+
x.shape + y.shape.
|
| 965 |
+
|
| 966 |
+
Parameters
|
| 967 |
+
----------
|
| 968 |
+
x, y : array_like, compatible objects
|
| 969 |
+
The two dimensional series is evaluated at the points in the
|
| 970 |
+
Cartesian product of `x` and `y`. If `x` or `y` is a list or
|
| 971 |
+
tuple, it is first converted to an ndarray, otherwise it is left
|
| 972 |
+
unchanged and, if it isn't an ndarray, it is treated as a scalar.
|
| 973 |
+
c : array_like
|
| 974 |
+
Array of coefficients ordered so that the coefficient of the term of
|
| 975 |
+
multi-degree i,j is contained in `c[i,j]`. If `c` has dimension
|
| 976 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 977 |
+
coefficients.
|
| 978 |
+
|
| 979 |
+
Returns
|
| 980 |
+
-------
|
| 981 |
+
values : ndarray, compatible object
|
| 982 |
+
The values of the two dimensional Chebyshev series at points in the
|
| 983 |
+
Cartesian product of `x` and `y`.
|
| 984 |
+
|
| 985 |
+
See Also
|
| 986 |
+
--------
|
| 987 |
+
lagval, lagval2d, lagval3d, laggrid3d
|
| 988 |
+
|
| 989 |
+
Notes
|
| 990 |
+
-----
|
| 991 |
+
|
| 992 |
+
.. versionadded:: 1.7.0
|
| 993 |
+
|
| 994 |
+
"""
|
| 995 |
+
return pu._gridnd(lagval, c, x, y)
|
| 996 |
+
|
| 997 |
+
|
| 998 |
+
def lagval3d(x, y, z, c):
|
| 999 |
+
"""
|
| 1000 |
+
Evaluate a 3-D Laguerre series at points (x, y, z).
|
| 1001 |
+
|
| 1002 |
+
This function returns the values:
|
| 1003 |
+
|
| 1004 |
+
.. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * L_i(x) * L_j(y) * L_k(z)
|
| 1005 |
+
|
| 1006 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if
|
| 1007 |
+
they are tuples or a lists, otherwise they are treated as a scalars and
|
| 1008 |
+
they must have the same shape after conversion. In either case, either
|
| 1009 |
+
`x`, `y`, and `z` or their elements must support multiplication and
|
| 1010 |
+
addition both with themselves and with the elements of `c`.
|
| 1011 |
+
|
| 1012 |
+
If `c` has fewer than 3 dimensions, ones are implicitly appended to its
|
| 1013 |
+
shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1014 |
+
x.shape.
|
| 1015 |
+
|
| 1016 |
+
Parameters
|
| 1017 |
+
----------
|
| 1018 |
+
x, y, z : array_like, compatible object
|
| 1019 |
+
The three dimensional series is evaluated at the points
|
| 1020 |
+
`(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If
|
| 1021 |
+
any of `x`, `y`, or `z` is a list or tuple, it is first converted
|
| 1022 |
+
to an ndarray, otherwise it is left unchanged and if it isn't an
|
| 1023 |
+
ndarray it is treated as a scalar.
|
| 1024 |
+
c : array_like
|
| 1025 |
+
Array of coefficients ordered so that the coefficient of the term of
|
| 1026 |
+
multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
|
| 1027 |
+
greater than 3 the remaining indices enumerate multiple sets of
|
| 1028 |
+
coefficients.
|
| 1029 |
+
|
| 1030 |
+
Returns
|
| 1031 |
+
-------
|
| 1032 |
+
values : ndarray, compatible object
|
| 1033 |
+
The values of the multidimensional polynomial on points formed with
|
| 1034 |
+
triples of corresponding values from `x`, `y`, and `z`.
|
| 1035 |
+
|
| 1036 |
+
See Also
|
| 1037 |
+
--------
|
| 1038 |
+
lagval, lagval2d, laggrid2d, laggrid3d
|
| 1039 |
+
|
| 1040 |
+
Notes
|
| 1041 |
+
-----
|
| 1042 |
+
|
| 1043 |
+
.. versionadded:: 1.7.0
|
| 1044 |
+
|
| 1045 |
+
"""
|
| 1046 |
+
return pu._valnd(lagval, c, x, y, z)
|
| 1047 |
+
|
| 1048 |
+
|
| 1049 |
+
def laggrid3d(x, y, z, c):
|
| 1050 |
+
"""
|
| 1051 |
+
Evaluate a 3-D Laguerre series on the Cartesian product of x, y, and z.
|
| 1052 |
+
|
| 1053 |
+
This function returns the values:
|
| 1054 |
+
|
| 1055 |
+
.. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * L_i(a) * L_j(b) * L_k(c)
|
| 1056 |
+
|
| 1057 |
+
where the points `(a, b, c)` consist of all triples formed by taking
|
| 1058 |
+
`a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
|
| 1059 |
+
a grid with `x` in the first dimension, `y` in the second, and `z` in
|
| 1060 |
+
the third.
|
| 1061 |
+
|
| 1062 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if they
|
| 1063 |
+
are tuples or a lists, otherwise they are treated as a scalars. In
|
| 1064 |
+
either case, either `x`, `y`, and `z` or their elements must support
|
| 1065 |
+
multiplication and addition both with themselves and with the elements
|
| 1066 |
+
of `c`.
|
| 1067 |
+
|
| 1068 |
+
If `c` has fewer than three dimensions, ones are implicitly appended to
|
| 1069 |
+
its shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1070 |
+
x.shape + y.shape + z.shape.
|
| 1071 |
+
|
| 1072 |
+
Parameters
|
| 1073 |
+
----------
|
| 1074 |
+
x, y, z : array_like, compatible objects
|
| 1075 |
+
The three dimensional series is evaluated at the points in the
|
| 1076 |
+
Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a
|
| 1077 |
+
list or tuple, it is first converted to an ndarray, otherwise it is
|
| 1078 |
+
left unchanged and, if it isn't an ndarray, it is treated as a
|
| 1079 |
+
scalar.
|
| 1080 |
+
c : array_like
|
| 1081 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 1082 |
+
degree i,j are contained in ``c[i,j]``. If `c` has dimension
|
| 1083 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 1084 |
+
coefficients.
|
| 1085 |
+
|
| 1086 |
+
Returns
|
| 1087 |
+
-------
|
| 1088 |
+
values : ndarray, compatible object
|
| 1089 |
+
The values of the two dimensional polynomial at points in the Cartesian
|
| 1090 |
+
product of `x` and `y`.
|
| 1091 |
+
|
| 1092 |
+
See Also
|
| 1093 |
+
--------
|
| 1094 |
+
lagval, lagval2d, laggrid2d, lagval3d
|
| 1095 |
+
|
| 1096 |
+
Notes
|
| 1097 |
+
-----
|
| 1098 |
+
|
| 1099 |
+
.. versionadded:: 1.7.0
|
| 1100 |
+
|
| 1101 |
+
"""
|
| 1102 |
+
return pu._gridnd(lagval, c, x, y, z)
|
| 1103 |
+
|
| 1104 |
+
|
| 1105 |
+
def lagvander(x, deg):
|
| 1106 |
+
"""Pseudo-Vandermonde matrix of given degree.
|
| 1107 |
+
|
| 1108 |
+
Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
|
| 1109 |
+
`x`. The pseudo-Vandermonde matrix is defined by
|
| 1110 |
+
|
| 1111 |
+
.. math:: V[..., i] = L_i(x)
|
| 1112 |
+
|
| 1113 |
+
where `0 <= i <= deg`. The leading indices of `V` index the elements of
|
| 1114 |
+
`x` and the last index is the degree of the Laguerre polynomial.
|
| 1115 |
+
|
| 1116 |
+
If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
|
| 1117 |
+
array ``V = lagvander(x, n)``, then ``np.dot(V, c)`` and
|
| 1118 |
+
``lagval(x, c)`` are the same up to roundoff. This equivalence is
|
| 1119 |
+
useful both for least squares fitting and for the evaluation of a large
|
| 1120 |
+
number of Laguerre series of the same degree and sample points.
|
| 1121 |
+
|
| 1122 |
+
Parameters
|
| 1123 |
+
----------
|
| 1124 |
+
x : array_like
|
| 1125 |
+
Array of points. The dtype is converted to float64 or complex128
|
| 1126 |
+
depending on whether any of the elements are complex. If `x` is
|
| 1127 |
+
scalar it is converted to a 1-D array.
|
| 1128 |
+
deg : int
|
| 1129 |
+
Degree of the resulting matrix.
|
| 1130 |
+
|
| 1131 |
+
Returns
|
| 1132 |
+
-------
|
| 1133 |
+
vander : ndarray
|
| 1134 |
+
The pseudo-Vandermonde matrix. The shape of the returned matrix is
|
| 1135 |
+
``x.shape + (deg + 1,)``, where The last index is the degree of the
|
| 1136 |
+
corresponding Laguerre polynomial. The dtype will be the same as
|
| 1137 |
+
the converted `x`.
|
| 1138 |
+
|
| 1139 |
+
Examples
|
| 1140 |
+
--------
|
| 1141 |
+
>>> from numpy.polynomial.laguerre import lagvander
|
| 1142 |
+
>>> x = np.array([0, 1, 2])
|
| 1143 |
+
>>> lagvander(x, 3)
|
| 1144 |
+
array([[ 1. , 1. , 1. , 1. ],
|
| 1145 |
+
[ 1. , 0. , -0.5 , -0.66666667],
|
| 1146 |
+
[ 1. , -1. , -1. , -0.33333333]])
|
| 1147 |
+
|
| 1148 |
+
"""
|
| 1149 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1150 |
+
if ideg < 0:
|
| 1151 |
+
raise ValueError("deg must be non-negative")
|
| 1152 |
+
|
| 1153 |
+
x = np.array(x, copy=False, ndmin=1) + 0.0
|
| 1154 |
+
dims = (ideg + 1,) + x.shape
|
| 1155 |
+
dtyp = x.dtype
|
| 1156 |
+
v = np.empty(dims, dtype=dtyp)
|
| 1157 |
+
v[0] = x*0 + 1
|
| 1158 |
+
if ideg > 0:
|
| 1159 |
+
v[1] = 1 - x
|
| 1160 |
+
for i in range(2, ideg + 1):
|
| 1161 |
+
v[i] = (v[i-1]*(2*i - 1 - x) - v[i-2]*(i - 1))/i
|
| 1162 |
+
return np.moveaxis(v, 0, -1)
|
| 1163 |
+
|
| 1164 |
+
|
| 1165 |
+
def lagvander2d(x, y, deg):
|
| 1166 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1167 |
+
|
| 1168 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1169 |
+
points `(x, y)`. The pseudo-Vandermonde matrix is defined by
|
| 1170 |
+
|
| 1171 |
+
.. math:: V[..., (deg[1] + 1)*i + j] = L_i(x) * L_j(y),
|
| 1172 |
+
|
| 1173 |
+
where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
|
| 1174 |
+
`V` index the points `(x, y)` and the last index encodes the degrees of
|
| 1175 |
+
the Laguerre polynomials.
|
| 1176 |
+
|
| 1177 |
+
If ``V = lagvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
|
| 1178 |
+
correspond to the elements of a 2-D coefficient array `c` of shape
|
| 1179 |
+
(xdeg + 1, ydeg + 1) in the order
|
| 1180 |
+
|
| 1181 |
+
.. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
|
| 1182 |
+
|
| 1183 |
+
and ``np.dot(V, c.flat)`` and ``lagval2d(x, y, c)`` will be the same
|
| 1184 |
+
up to roundoff. This equivalence is useful both for least squares
|
| 1185 |
+
fitting and for the evaluation of a large number of 2-D Laguerre
|
| 1186 |
+
series of the same degrees and sample points.
|
| 1187 |
+
|
| 1188 |
+
Parameters
|
| 1189 |
+
----------
|
| 1190 |
+
x, y : array_like
|
| 1191 |
+
Arrays of point coordinates, all of the same shape. The dtypes
|
| 1192 |
+
will be converted to either float64 or complex128 depending on
|
| 1193 |
+
whether any of the elements are complex. Scalars are converted to
|
| 1194 |
+
1-D arrays.
|
| 1195 |
+
deg : list of ints
|
| 1196 |
+
List of maximum degrees of the form [x_deg, y_deg].
|
| 1197 |
+
|
| 1198 |
+
Returns
|
| 1199 |
+
-------
|
| 1200 |
+
vander2d : ndarray
|
| 1201 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1202 |
+
:math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same
|
| 1203 |
+
as the converted `x` and `y`.
|
| 1204 |
+
|
| 1205 |
+
See Also
|
| 1206 |
+
--------
|
| 1207 |
+
lagvander, lagvander3d, lagval2d, lagval3d
|
| 1208 |
+
|
| 1209 |
+
Notes
|
| 1210 |
+
-----
|
| 1211 |
+
|
| 1212 |
+
.. versionadded:: 1.7.0
|
| 1213 |
+
|
| 1214 |
+
"""
|
| 1215 |
+
return pu._vander_nd_flat((lagvander, lagvander), (x, y), deg)
|
| 1216 |
+
|
| 1217 |
+
|
| 1218 |
+
def lagvander3d(x, y, z, deg):
|
| 1219 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1220 |
+
|
| 1221 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1222 |
+
points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
|
| 1223 |
+
then The pseudo-Vandermonde matrix is defined by
|
| 1224 |
+
|
| 1225 |
+
.. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = L_i(x)*L_j(y)*L_k(z),
|
| 1226 |
+
|
| 1227 |
+
where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading
|
| 1228 |
+
indices of `V` index the points `(x, y, z)` and the last index encodes
|
| 1229 |
+
the degrees of the Laguerre polynomials.
|
| 1230 |
+
|
| 1231 |
+
If ``V = lagvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
|
| 1232 |
+
of `V` correspond to the elements of a 3-D coefficient array `c` of
|
| 1233 |
+
shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
|
| 1234 |
+
|
| 1235 |
+
.. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
|
| 1236 |
+
|
| 1237 |
+
and ``np.dot(V, c.flat)`` and ``lagval3d(x, y, z, c)`` will be the
|
| 1238 |
+
same up to roundoff. This equivalence is useful both for least squares
|
| 1239 |
+
fitting and for the evaluation of a large number of 3-D Laguerre
|
| 1240 |
+
series of the same degrees and sample points.
|
| 1241 |
+
|
| 1242 |
+
Parameters
|
| 1243 |
+
----------
|
| 1244 |
+
x, y, z : array_like
|
| 1245 |
+
Arrays of point coordinates, all of the same shape. The dtypes will
|
| 1246 |
+
be converted to either float64 or complex128 depending on whether
|
| 1247 |
+
any of the elements are complex. Scalars are converted to 1-D
|
| 1248 |
+
arrays.
|
| 1249 |
+
deg : list of ints
|
| 1250 |
+
List of maximum degrees of the form [x_deg, y_deg, z_deg].
|
| 1251 |
+
|
| 1252 |
+
Returns
|
| 1253 |
+
-------
|
| 1254 |
+
vander3d : ndarray
|
| 1255 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1256 |
+
:math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will
|
| 1257 |
+
be the same as the converted `x`, `y`, and `z`.
|
| 1258 |
+
|
| 1259 |
+
See Also
|
| 1260 |
+
--------
|
| 1261 |
+
lagvander, lagvander3d, lagval2d, lagval3d
|
| 1262 |
+
|
| 1263 |
+
Notes
|
| 1264 |
+
-----
|
| 1265 |
+
|
| 1266 |
+
.. versionadded:: 1.7.0
|
| 1267 |
+
|
| 1268 |
+
"""
|
| 1269 |
+
return pu._vander_nd_flat((lagvander, lagvander, lagvander), (x, y, z), deg)
|
| 1270 |
+
|
| 1271 |
+
|
| 1272 |
+
def lagfit(x, y, deg, rcond=None, full=False, w=None):
|
| 1273 |
+
"""
|
| 1274 |
+
Least squares fit of Laguerre series to data.
|
| 1275 |
+
|
| 1276 |
+
Return the coefficients of a Laguerre series of degree `deg` that is the
|
| 1277 |
+
least squares fit to the data values `y` given at points `x`. If `y` is
|
| 1278 |
+
1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
|
| 1279 |
+
fits are done, one for each column of `y`, and the resulting
|
| 1280 |
+
coefficients are stored in the corresponding columns of a 2-D return.
|
| 1281 |
+
The fitted polynomial(s) are in the form
|
| 1282 |
+
|
| 1283 |
+
.. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x),
|
| 1284 |
+
|
| 1285 |
+
where ``n`` is `deg`.
|
| 1286 |
+
|
| 1287 |
+
Parameters
|
| 1288 |
+
----------
|
| 1289 |
+
x : array_like, shape (M,)
|
| 1290 |
+
x-coordinates of the M sample points ``(x[i], y[i])``.
|
| 1291 |
+
y : array_like, shape (M,) or (M, K)
|
| 1292 |
+
y-coordinates of the sample points. Several data sets of sample
|
| 1293 |
+
points sharing the same x-coordinates can be fitted at once by
|
| 1294 |
+
passing in a 2D-array that contains one dataset per column.
|
| 1295 |
+
deg : int or 1-D array_like
|
| 1296 |
+
Degree(s) of the fitting polynomials. If `deg` is a single integer
|
| 1297 |
+
all terms up to and including the `deg`'th term are included in the
|
| 1298 |
+
fit. For NumPy versions >= 1.11.0 a list of integers specifying the
|
| 1299 |
+
degrees of the terms to include may be used instead.
|
| 1300 |
+
rcond : float, optional
|
| 1301 |
+
Relative condition number of the fit. Singular values smaller than
|
| 1302 |
+
this relative to the largest singular value will be ignored. The
|
| 1303 |
+
default value is len(x)*eps, where eps is the relative precision of
|
| 1304 |
+
the float type, about 2e-16 in most cases.
|
| 1305 |
+
full : bool, optional
|
| 1306 |
+
Switch determining nature of return value. When it is False (the
|
| 1307 |
+
default) just the coefficients are returned, when True diagnostic
|
| 1308 |
+
information from the singular value decomposition is also returned.
|
| 1309 |
+
w : array_like, shape (`M`,), optional
|
| 1310 |
+
Weights. If not None, the weight ``w[i]`` applies to the unsquared
|
| 1311 |
+
residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
|
| 1312 |
+
chosen so that the errors of the products ``w[i]*y[i]`` all have the
|
| 1313 |
+
same variance. When using inverse-variance weighting, use
|
| 1314 |
+
``w[i] = 1/sigma(y[i])``. The default value is None.
|
| 1315 |
+
|
| 1316 |
+
Returns
|
| 1317 |
+
-------
|
| 1318 |
+
coef : ndarray, shape (M,) or (M, K)
|
| 1319 |
+
Laguerre coefficients ordered from low to high. If `y` was 2-D,
|
| 1320 |
+
the coefficients for the data in column *k* of `y` are in column
|
| 1321 |
+
*k*.
|
| 1322 |
+
|
| 1323 |
+
[residuals, rank, singular_values, rcond] : list
|
| 1324 |
+
These values are only returned if ``full == True``
|
| 1325 |
+
|
| 1326 |
+
- residuals -- sum of squared residuals of the least squares fit
|
| 1327 |
+
- rank -- the numerical rank of the scaled Vandermonde matrix
|
| 1328 |
+
- singular_values -- singular values of the scaled Vandermonde matrix
|
| 1329 |
+
- rcond -- value of `rcond`.
|
| 1330 |
+
|
| 1331 |
+
For more details, see `numpy.linalg.lstsq`.
|
| 1332 |
+
|
| 1333 |
+
Warns
|
| 1334 |
+
-----
|
| 1335 |
+
RankWarning
|
| 1336 |
+
The rank of the coefficient matrix in the least-squares fit is
|
| 1337 |
+
deficient. The warning is only raised if ``full == False``. The
|
| 1338 |
+
warnings can be turned off by
|
| 1339 |
+
|
| 1340 |
+
>>> import warnings
|
| 1341 |
+
>>> warnings.simplefilter('ignore', np.RankWarning)
|
| 1342 |
+
|
| 1343 |
+
See Also
|
| 1344 |
+
--------
|
| 1345 |
+
numpy.polynomial.polynomial.polyfit
|
| 1346 |
+
numpy.polynomial.legendre.legfit
|
| 1347 |
+
numpy.polynomial.chebyshev.chebfit
|
| 1348 |
+
numpy.polynomial.hermite.hermfit
|
| 1349 |
+
numpy.polynomial.hermite_e.hermefit
|
| 1350 |
+
lagval : Evaluates a Laguerre series.
|
| 1351 |
+
lagvander : pseudo Vandermonde matrix of Laguerre series.
|
| 1352 |
+
lagweight : Laguerre weight function.
|
| 1353 |
+
numpy.linalg.lstsq : Computes a least-squares fit from the matrix.
|
| 1354 |
+
scipy.interpolate.UnivariateSpline : Computes spline fits.
|
| 1355 |
+
|
| 1356 |
+
Notes
|
| 1357 |
+
-----
|
| 1358 |
+
The solution is the coefficients of the Laguerre series ``p`` that
|
| 1359 |
+
minimizes the sum of the weighted squared errors
|
| 1360 |
+
|
| 1361 |
+
.. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
|
| 1362 |
+
|
| 1363 |
+
where the :math:`w_j` are the weights. This problem is solved by
|
| 1364 |
+
setting up as the (typically) overdetermined matrix equation
|
| 1365 |
+
|
| 1366 |
+
.. math:: V(x) * c = w * y,
|
| 1367 |
+
|
| 1368 |
+
where ``V`` is the weighted pseudo Vandermonde matrix of `x`, ``c`` are the
|
| 1369 |
+
coefficients to be solved for, `w` are the weights, and `y` are the
|
| 1370 |
+
observed values. This equation is then solved using the singular value
|
| 1371 |
+
decomposition of ``V``.
|
| 1372 |
+
|
| 1373 |
+
If some of the singular values of `V` are so small that they are
|
| 1374 |
+
neglected, then a `RankWarning` will be issued. This means that the
|
| 1375 |
+
coefficient values may be poorly determined. Using a lower order fit
|
| 1376 |
+
will usually get rid of the warning. The `rcond` parameter can also be
|
| 1377 |
+
set to a value smaller than its default, but the resulting fit may be
|
| 1378 |
+
spurious and have large contributions from roundoff error.
|
| 1379 |
+
|
| 1380 |
+
Fits using Laguerre series are probably most useful when the data can
|
| 1381 |
+
be approximated by ``sqrt(w(x)) * p(x)``, where ``w(x)`` is the Laguerre
|
| 1382 |
+
weight. In that case the weight ``sqrt(w(x[i]))`` should be used
|
| 1383 |
+
together with data values ``y[i]/sqrt(w(x[i]))``. The weight function is
|
| 1384 |
+
available as `lagweight`.
|
| 1385 |
+
|
| 1386 |
+
References
|
| 1387 |
+
----------
|
| 1388 |
+
.. [1] Wikipedia, "Curve fitting",
|
| 1389 |
+
https://en.wikipedia.org/wiki/Curve_fitting
|
| 1390 |
+
|
| 1391 |
+
Examples
|
| 1392 |
+
--------
|
| 1393 |
+
>>> from numpy.polynomial.laguerre import lagfit, lagval
|
| 1394 |
+
>>> x = np.linspace(0, 10)
|
| 1395 |
+
>>> err = np.random.randn(len(x))/10
|
| 1396 |
+
>>> y = lagval(x, [1, 2, 3]) + err
|
| 1397 |
+
>>> lagfit(x, y, 2)
|
| 1398 |
+
array([ 0.96971004, 2.00193749, 3.00288744]) # may vary
|
| 1399 |
+
|
| 1400 |
+
"""
|
| 1401 |
+
return pu._fit(lagvander, x, y, deg, rcond, full, w)
|
| 1402 |
+
|
| 1403 |
+
|
| 1404 |
+
def lagcompanion(c):
|
| 1405 |
+
"""
|
| 1406 |
+
Return the companion matrix of c.
|
| 1407 |
+
|
| 1408 |
+
The usual companion matrix of the Laguerre polynomials is already
|
| 1409 |
+
symmetric when `c` is a basis Laguerre polynomial, so no scaling is
|
| 1410 |
+
applied.
|
| 1411 |
+
|
| 1412 |
+
Parameters
|
| 1413 |
+
----------
|
| 1414 |
+
c : array_like
|
| 1415 |
+
1-D array of Laguerre series coefficients ordered from low to high
|
| 1416 |
+
degree.
|
| 1417 |
+
|
| 1418 |
+
Returns
|
| 1419 |
+
-------
|
| 1420 |
+
mat : ndarray
|
| 1421 |
+
Companion matrix of dimensions (deg, deg).
|
| 1422 |
+
|
| 1423 |
+
Notes
|
| 1424 |
+
-----
|
| 1425 |
+
|
| 1426 |
+
.. versionadded:: 1.7.0
|
| 1427 |
+
|
| 1428 |
+
"""
|
| 1429 |
+
# c is a trimmed copy
|
| 1430 |
+
[c] = pu.as_series([c])
|
| 1431 |
+
if len(c) < 2:
|
| 1432 |
+
raise ValueError('Series must have maximum degree of at least 1.')
|
| 1433 |
+
if len(c) == 2:
|
| 1434 |
+
return np.array([[1 + c[0]/c[1]]])
|
| 1435 |
+
|
| 1436 |
+
n = len(c) - 1
|
| 1437 |
+
mat = np.zeros((n, n), dtype=c.dtype)
|
| 1438 |
+
top = mat.reshape(-1)[1::n+1]
|
| 1439 |
+
mid = mat.reshape(-1)[0::n+1]
|
| 1440 |
+
bot = mat.reshape(-1)[n::n+1]
|
| 1441 |
+
top[...] = -np.arange(1, n)
|
| 1442 |
+
mid[...] = 2.*np.arange(n) + 1.
|
| 1443 |
+
bot[...] = top
|
| 1444 |
+
mat[:, -1] += (c[:-1]/c[-1])*n
|
| 1445 |
+
return mat
|
| 1446 |
+
|
| 1447 |
+
|
| 1448 |
+
def lagroots(c):
|
| 1449 |
+
"""
|
| 1450 |
+
Compute the roots of a Laguerre series.
|
| 1451 |
+
|
| 1452 |
+
Return the roots (a.k.a. "zeros") of the polynomial
|
| 1453 |
+
|
| 1454 |
+
.. math:: p(x) = \\sum_i c[i] * L_i(x).
|
| 1455 |
+
|
| 1456 |
+
Parameters
|
| 1457 |
+
----------
|
| 1458 |
+
c : 1-D array_like
|
| 1459 |
+
1-D array of coefficients.
|
| 1460 |
+
|
| 1461 |
+
Returns
|
| 1462 |
+
-------
|
| 1463 |
+
out : ndarray
|
| 1464 |
+
Array of the roots of the series. If all the roots are real,
|
| 1465 |
+
then `out` is also real, otherwise it is complex.
|
| 1466 |
+
|
| 1467 |
+
See Also
|
| 1468 |
+
--------
|
| 1469 |
+
numpy.polynomial.polynomial.polyroots
|
| 1470 |
+
numpy.polynomial.legendre.legroots
|
| 1471 |
+
numpy.polynomial.chebyshev.chebroots
|
| 1472 |
+
numpy.polynomial.hermite.hermroots
|
| 1473 |
+
numpy.polynomial.hermite_e.hermeroots
|
| 1474 |
+
|
| 1475 |
+
Notes
|
| 1476 |
+
-----
|
| 1477 |
+
The root estimates are obtained as the eigenvalues of the companion
|
| 1478 |
+
matrix, Roots far from the origin of the complex plane may have large
|
| 1479 |
+
errors due to the numerical instability of the series for such
|
| 1480 |
+
values. Roots with multiplicity greater than 1 will also show larger
|
| 1481 |
+
errors as the value of the series near such points is relatively
|
| 1482 |
+
insensitive to errors in the roots. Isolated roots near the origin can
|
| 1483 |
+
be improved by a few iterations of Newton's method.
|
| 1484 |
+
|
| 1485 |
+
The Laguerre series basis polynomials aren't powers of `x` so the
|
| 1486 |
+
results of this function may seem unintuitive.
|
| 1487 |
+
|
| 1488 |
+
Examples
|
| 1489 |
+
--------
|
| 1490 |
+
>>> from numpy.polynomial.laguerre import lagroots, lagfromroots
|
| 1491 |
+
>>> coef = lagfromroots([0, 1, 2])
|
| 1492 |
+
>>> coef
|
| 1493 |
+
array([ 2., -8., 12., -6.])
|
| 1494 |
+
>>> lagroots(coef)
|
| 1495 |
+
array([-4.4408921e-16, 1.0000000e+00, 2.0000000e+00])
|
| 1496 |
+
|
| 1497 |
+
"""
|
| 1498 |
+
# c is a trimmed copy
|
| 1499 |
+
[c] = pu.as_series([c])
|
| 1500 |
+
if len(c) <= 1:
|
| 1501 |
+
return np.array([], dtype=c.dtype)
|
| 1502 |
+
if len(c) == 2:
|
| 1503 |
+
return np.array([1 + c[0]/c[1]])
|
| 1504 |
+
|
| 1505 |
+
# rotated companion matrix reduces error
|
| 1506 |
+
m = lagcompanion(c)[::-1,::-1]
|
| 1507 |
+
r = la.eigvals(m)
|
| 1508 |
+
r.sort()
|
| 1509 |
+
return r
|
| 1510 |
+
|
| 1511 |
+
|
| 1512 |
+
def laggauss(deg):
|
| 1513 |
+
"""
|
| 1514 |
+
Gauss-Laguerre quadrature.
|
| 1515 |
+
|
| 1516 |
+
Computes the sample points and weights for Gauss-Laguerre quadrature.
|
| 1517 |
+
These sample points and weights will correctly integrate polynomials of
|
| 1518 |
+
degree :math:`2*deg - 1` or less over the interval :math:`[0, \\inf]`
|
| 1519 |
+
with the weight function :math:`f(x) = \\exp(-x)`.
|
| 1520 |
+
|
| 1521 |
+
Parameters
|
| 1522 |
+
----------
|
| 1523 |
+
deg : int
|
| 1524 |
+
Number of sample points and weights. It must be >= 1.
|
| 1525 |
+
|
| 1526 |
+
Returns
|
| 1527 |
+
-------
|
| 1528 |
+
x : ndarray
|
| 1529 |
+
1-D ndarray containing the sample points.
|
| 1530 |
+
y : ndarray
|
| 1531 |
+
1-D ndarray containing the weights.
|
| 1532 |
+
|
| 1533 |
+
Notes
|
| 1534 |
+
-----
|
| 1535 |
+
|
| 1536 |
+
.. versionadded:: 1.7.0
|
| 1537 |
+
|
| 1538 |
+
The results have only been tested up to degree 100 higher degrees may
|
| 1539 |
+
be problematic. The weights are determined by using the fact that
|
| 1540 |
+
|
| 1541 |
+
.. math:: w_k = c / (L'_n(x_k) * L_{n-1}(x_k))
|
| 1542 |
+
|
| 1543 |
+
where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
|
| 1544 |
+
is the k'th root of :math:`L_n`, and then scaling the results to get
|
| 1545 |
+
the right value when integrating 1.
|
| 1546 |
+
|
| 1547 |
+
"""
|
| 1548 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1549 |
+
if ideg <= 0:
|
| 1550 |
+
raise ValueError("deg must be a positive integer")
|
| 1551 |
+
|
| 1552 |
+
# first approximation of roots. We use the fact that the companion
|
| 1553 |
+
# matrix is symmetric in this case in order to obtain better zeros.
|
| 1554 |
+
c = np.array([0]*deg + [1])
|
| 1555 |
+
m = lagcompanion(c)
|
| 1556 |
+
x = la.eigvalsh(m)
|
| 1557 |
+
|
| 1558 |
+
# improve roots by one application of Newton
|
| 1559 |
+
dy = lagval(x, c)
|
| 1560 |
+
df = lagval(x, lagder(c))
|
| 1561 |
+
x -= dy/df
|
| 1562 |
+
|
| 1563 |
+
# compute the weights. We scale the factor to avoid possible numerical
|
| 1564 |
+
# overflow.
|
| 1565 |
+
fm = lagval(x, c[1:])
|
| 1566 |
+
fm /= np.abs(fm).max()
|
| 1567 |
+
df /= np.abs(df).max()
|
| 1568 |
+
w = 1/(fm * df)
|
| 1569 |
+
|
| 1570 |
+
# scale w to get the right value, 1 in this case
|
| 1571 |
+
w /= w.sum()
|
| 1572 |
+
|
| 1573 |
+
return x, w
|
| 1574 |
+
|
| 1575 |
+
|
| 1576 |
+
def lagweight(x):
|
| 1577 |
+
"""Weight function of the Laguerre polynomials.
|
| 1578 |
+
|
| 1579 |
+
The weight function is :math:`exp(-x)` and the interval of integration
|
| 1580 |
+
is :math:`[0, \\inf]`. The Laguerre polynomials are orthogonal, but not
|
| 1581 |
+
normalized, with respect to this weight function.
|
| 1582 |
+
|
| 1583 |
+
Parameters
|
| 1584 |
+
----------
|
| 1585 |
+
x : array_like
|
| 1586 |
+
Values at which the weight function will be computed.
|
| 1587 |
+
|
| 1588 |
+
Returns
|
| 1589 |
+
-------
|
| 1590 |
+
w : ndarray
|
| 1591 |
+
The weight function at `x`.
|
| 1592 |
+
|
| 1593 |
+
Notes
|
| 1594 |
+
-----
|
| 1595 |
+
|
| 1596 |
+
.. versionadded:: 1.7.0
|
| 1597 |
+
|
| 1598 |
+
"""
|
| 1599 |
+
w = np.exp(-x)
|
| 1600 |
+
return w
|
| 1601 |
+
|
| 1602 |
+
#
|
| 1603 |
+
# Laguerre series class
|
| 1604 |
+
#
|
| 1605 |
+
|
| 1606 |
+
class Laguerre(ABCPolyBase):
|
| 1607 |
+
"""A Laguerre series class.
|
| 1608 |
+
|
| 1609 |
+
The Laguerre class provides the standard Python numerical methods
|
| 1610 |
+
'+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
|
| 1611 |
+
attributes and methods listed in the `ABCPolyBase` documentation.
|
| 1612 |
+
|
| 1613 |
+
Parameters
|
| 1614 |
+
----------
|
| 1615 |
+
coef : array_like
|
| 1616 |
+
Laguerre coefficients in order of increasing degree, i.e,
|
| 1617 |
+
``(1, 2, 3)`` gives ``1*L_0(x) + 2*L_1(X) + 3*L_2(x)``.
|
| 1618 |
+
domain : (2,) array_like, optional
|
| 1619 |
+
Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
|
| 1620 |
+
to the interval ``[window[0], window[1]]`` by shifting and scaling.
|
| 1621 |
+
The default value is [0, 1].
|
| 1622 |
+
window : (2,) array_like, optional
|
| 1623 |
+
Window, see `domain` for its use. The default value is [0, 1].
|
| 1624 |
+
|
| 1625 |
+
.. versionadded:: 1.6.0
|
| 1626 |
+
symbol : str, optional
|
| 1627 |
+
Symbol used to represent the independent variable in string
|
| 1628 |
+
representations of the polynomial expression, e.g. for printing.
|
| 1629 |
+
The symbol must be a valid Python identifier. Default value is 'x'.
|
| 1630 |
+
|
| 1631 |
+
.. versionadded:: 1.24
|
| 1632 |
+
|
| 1633 |
+
"""
|
| 1634 |
+
# Virtual Functions
|
| 1635 |
+
_add = staticmethod(lagadd)
|
| 1636 |
+
_sub = staticmethod(lagsub)
|
| 1637 |
+
_mul = staticmethod(lagmul)
|
| 1638 |
+
_div = staticmethod(lagdiv)
|
| 1639 |
+
_pow = staticmethod(lagpow)
|
| 1640 |
+
_val = staticmethod(lagval)
|
| 1641 |
+
_int = staticmethod(lagint)
|
| 1642 |
+
_der = staticmethod(lagder)
|
| 1643 |
+
_fit = staticmethod(lagfit)
|
| 1644 |
+
_line = staticmethod(lagline)
|
| 1645 |
+
_roots = staticmethod(lagroots)
|
| 1646 |
+
_fromroots = staticmethod(lagfromroots)
|
| 1647 |
+
|
| 1648 |
+
# Virtual properties
|
| 1649 |
+
domain = np.array(lagdomain)
|
| 1650 |
+
window = np.array(lagdomain)
|
| 1651 |
+
basis_name = 'L'
|
lib/python3.12/site-packages/numpy/polynomial/laguerre.pyi
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any
|
| 2 |
+
|
| 3 |
+
from numpy import ndarray, dtype, int_
|
| 4 |
+
from numpy.polynomial._polybase import ABCPolyBase
|
| 5 |
+
from numpy.polynomial.polyutils import trimcoef
|
| 6 |
+
|
| 7 |
+
__all__: list[str]
|
| 8 |
+
|
| 9 |
+
lagtrim = trimcoef
|
| 10 |
+
|
| 11 |
+
def poly2lag(pol): ...
|
| 12 |
+
def lag2poly(c): ...
|
| 13 |
+
|
| 14 |
+
lagdomain: ndarray[Any, dtype[int_]]
|
| 15 |
+
lagzero: ndarray[Any, dtype[int_]]
|
| 16 |
+
lagone: ndarray[Any, dtype[int_]]
|
| 17 |
+
lagx: ndarray[Any, dtype[int_]]
|
| 18 |
+
|
| 19 |
+
def lagline(off, scl): ...
|
| 20 |
+
def lagfromroots(roots): ...
|
| 21 |
+
def lagadd(c1, c2): ...
|
| 22 |
+
def lagsub(c1, c2): ...
|
| 23 |
+
def lagmulx(c): ...
|
| 24 |
+
def lagmul(c1, c2): ...
|
| 25 |
+
def lagdiv(c1, c2): ...
|
| 26 |
+
def lagpow(c, pow, maxpower=...): ...
|
| 27 |
+
def lagder(c, m=..., scl=..., axis=...): ...
|
| 28 |
+
def lagint(c, m=..., k = ..., lbnd=..., scl=..., axis=...): ...
|
| 29 |
+
def lagval(x, c, tensor=...): ...
|
| 30 |
+
def lagval2d(x, y, c): ...
|
| 31 |
+
def laggrid2d(x, y, c): ...
|
| 32 |
+
def lagval3d(x, y, z, c): ...
|
| 33 |
+
def laggrid3d(x, y, z, c): ...
|
| 34 |
+
def lagvander(x, deg): ...
|
| 35 |
+
def lagvander2d(x, y, deg): ...
|
| 36 |
+
def lagvander3d(x, y, z, deg): ...
|
| 37 |
+
def lagfit(x, y, deg, rcond=..., full=..., w=...): ...
|
| 38 |
+
def lagcompanion(c): ...
|
| 39 |
+
def lagroots(c): ...
|
| 40 |
+
def laggauss(deg): ...
|
| 41 |
+
def lagweight(x): ...
|
| 42 |
+
|
| 43 |
+
class Laguerre(ABCPolyBase):
|
| 44 |
+
domain: Any
|
| 45 |
+
window: Any
|
| 46 |
+
basis_name: Any
|
lib/python3.12/site-packages/numpy/polynomial/legendre.py
ADDED
|
@@ -0,0 +1,1664 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
==================================================
|
| 3 |
+
Legendre Series (:mod:`numpy.polynomial.legendre`)
|
| 4 |
+
==================================================
|
| 5 |
+
|
| 6 |
+
This module provides a number of objects (mostly functions) useful for
|
| 7 |
+
dealing with Legendre series, including a `Legendre` class that
|
| 8 |
+
encapsulates the usual arithmetic operations. (General information
|
| 9 |
+
on how this module represents and works with such polynomials is in the
|
| 10 |
+
docstring for its "parent" sub-package, `numpy.polynomial`).
|
| 11 |
+
|
| 12 |
+
Classes
|
| 13 |
+
-------
|
| 14 |
+
.. autosummary::
|
| 15 |
+
:toctree: generated/
|
| 16 |
+
|
| 17 |
+
Legendre
|
| 18 |
+
|
| 19 |
+
Constants
|
| 20 |
+
---------
|
| 21 |
+
|
| 22 |
+
.. autosummary::
|
| 23 |
+
:toctree: generated/
|
| 24 |
+
|
| 25 |
+
legdomain
|
| 26 |
+
legzero
|
| 27 |
+
legone
|
| 28 |
+
legx
|
| 29 |
+
|
| 30 |
+
Arithmetic
|
| 31 |
+
----------
|
| 32 |
+
|
| 33 |
+
.. autosummary::
|
| 34 |
+
:toctree: generated/
|
| 35 |
+
|
| 36 |
+
legadd
|
| 37 |
+
legsub
|
| 38 |
+
legmulx
|
| 39 |
+
legmul
|
| 40 |
+
legdiv
|
| 41 |
+
legpow
|
| 42 |
+
legval
|
| 43 |
+
legval2d
|
| 44 |
+
legval3d
|
| 45 |
+
leggrid2d
|
| 46 |
+
leggrid3d
|
| 47 |
+
|
| 48 |
+
Calculus
|
| 49 |
+
--------
|
| 50 |
+
|
| 51 |
+
.. autosummary::
|
| 52 |
+
:toctree: generated/
|
| 53 |
+
|
| 54 |
+
legder
|
| 55 |
+
legint
|
| 56 |
+
|
| 57 |
+
Misc Functions
|
| 58 |
+
--------------
|
| 59 |
+
|
| 60 |
+
.. autosummary::
|
| 61 |
+
:toctree: generated/
|
| 62 |
+
|
| 63 |
+
legfromroots
|
| 64 |
+
legroots
|
| 65 |
+
legvander
|
| 66 |
+
legvander2d
|
| 67 |
+
legvander3d
|
| 68 |
+
leggauss
|
| 69 |
+
legweight
|
| 70 |
+
legcompanion
|
| 71 |
+
legfit
|
| 72 |
+
legtrim
|
| 73 |
+
legline
|
| 74 |
+
leg2poly
|
| 75 |
+
poly2leg
|
| 76 |
+
|
| 77 |
+
See also
|
| 78 |
+
--------
|
| 79 |
+
numpy.polynomial
|
| 80 |
+
|
| 81 |
+
"""
|
| 82 |
+
import numpy as np
|
| 83 |
+
import numpy.linalg as la
|
| 84 |
+
from numpy.core.multiarray import normalize_axis_index
|
| 85 |
+
|
| 86 |
+
from . import polyutils as pu
|
| 87 |
+
from ._polybase import ABCPolyBase
|
| 88 |
+
|
| 89 |
+
__all__ = [
|
| 90 |
+
'legzero', 'legone', 'legx', 'legdomain', 'legline', 'legadd',
|
| 91 |
+
'legsub', 'legmulx', 'legmul', 'legdiv', 'legpow', 'legval', 'legder',
|
| 92 |
+
'legint', 'leg2poly', 'poly2leg', 'legfromroots', 'legvander',
|
| 93 |
+
'legfit', 'legtrim', 'legroots', 'Legendre', 'legval2d', 'legval3d',
|
| 94 |
+
'leggrid2d', 'leggrid3d', 'legvander2d', 'legvander3d', 'legcompanion',
|
| 95 |
+
'leggauss', 'legweight']
|
| 96 |
+
|
| 97 |
+
legtrim = pu.trimcoef
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def poly2leg(pol):
|
| 101 |
+
"""
|
| 102 |
+
Convert a polynomial to a Legendre series.
|
| 103 |
+
|
| 104 |
+
Convert an array representing the coefficients of a polynomial (relative
|
| 105 |
+
to the "standard" basis) ordered from lowest degree to highest, to an
|
| 106 |
+
array of the coefficients of the equivalent Legendre series, ordered
|
| 107 |
+
from lowest to highest degree.
|
| 108 |
+
|
| 109 |
+
Parameters
|
| 110 |
+
----------
|
| 111 |
+
pol : array_like
|
| 112 |
+
1-D array containing the polynomial coefficients
|
| 113 |
+
|
| 114 |
+
Returns
|
| 115 |
+
-------
|
| 116 |
+
c : ndarray
|
| 117 |
+
1-D array containing the coefficients of the equivalent Legendre
|
| 118 |
+
series.
|
| 119 |
+
|
| 120 |
+
See Also
|
| 121 |
+
--------
|
| 122 |
+
leg2poly
|
| 123 |
+
|
| 124 |
+
Notes
|
| 125 |
+
-----
|
| 126 |
+
The easy way to do conversions between polynomial basis sets
|
| 127 |
+
is to use the convert method of a class instance.
|
| 128 |
+
|
| 129 |
+
Examples
|
| 130 |
+
--------
|
| 131 |
+
>>> from numpy import polynomial as P
|
| 132 |
+
>>> p = P.Polynomial(np.arange(4))
|
| 133 |
+
>>> p
|
| 134 |
+
Polynomial([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1])
|
| 135 |
+
>>> c = P.Legendre(P.legendre.poly2leg(p.coef))
|
| 136 |
+
>>> c
|
| 137 |
+
Legendre([ 1. , 3.25, 1. , 0.75], domain=[-1, 1], window=[-1, 1]) # may vary
|
| 138 |
+
|
| 139 |
+
"""
|
| 140 |
+
[pol] = pu.as_series([pol])
|
| 141 |
+
deg = len(pol) - 1
|
| 142 |
+
res = 0
|
| 143 |
+
for i in range(deg, -1, -1):
|
| 144 |
+
res = legadd(legmulx(res), pol[i])
|
| 145 |
+
return res
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
def leg2poly(c):
|
| 149 |
+
"""
|
| 150 |
+
Convert a Legendre series to a polynomial.
|
| 151 |
+
|
| 152 |
+
Convert an array representing the coefficients of a Legendre series,
|
| 153 |
+
ordered from lowest degree to highest, to an array of the coefficients
|
| 154 |
+
of the equivalent polynomial (relative to the "standard" basis) ordered
|
| 155 |
+
from lowest to highest degree.
|
| 156 |
+
|
| 157 |
+
Parameters
|
| 158 |
+
----------
|
| 159 |
+
c : array_like
|
| 160 |
+
1-D array containing the Legendre series coefficients, ordered
|
| 161 |
+
from lowest order term to highest.
|
| 162 |
+
|
| 163 |
+
Returns
|
| 164 |
+
-------
|
| 165 |
+
pol : ndarray
|
| 166 |
+
1-D array containing the coefficients of the equivalent polynomial
|
| 167 |
+
(relative to the "standard" basis) ordered from lowest order term
|
| 168 |
+
to highest.
|
| 169 |
+
|
| 170 |
+
See Also
|
| 171 |
+
--------
|
| 172 |
+
poly2leg
|
| 173 |
+
|
| 174 |
+
Notes
|
| 175 |
+
-----
|
| 176 |
+
The easy way to do conversions between polynomial basis sets
|
| 177 |
+
is to use the convert method of a class instance.
|
| 178 |
+
|
| 179 |
+
Examples
|
| 180 |
+
--------
|
| 181 |
+
>>> from numpy import polynomial as P
|
| 182 |
+
>>> c = P.Legendre(range(4))
|
| 183 |
+
>>> c
|
| 184 |
+
Legendre([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1])
|
| 185 |
+
>>> p = c.convert(kind=P.Polynomial)
|
| 186 |
+
>>> p
|
| 187 |
+
Polynomial([-1. , -3.5, 3. , 7.5], domain=[-1., 1.], window=[-1., 1.])
|
| 188 |
+
>>> P.legendre.leg2poly(range(4))
|
| 189 |
+
array([-1. , -3.5, 3. , 7.5])
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
"""
|
| 193 |
+
from .polynomial import polyadd, polysub, polymulx
|
| 194 |
+
|
| 195 |
+
[c] = pu.as_series([c])
|
| 196 |
+
n = len(c)
|
| 197 |
+
if n < 3:
|
| 198 |
+
return c
|
| 199 |
+
else:
|
| 200 |
+
c0 = c[-2]
|
| 201 |
+
c1 = c[-1]
|
| 202 |
+
# i is the current degree of c1
|
| 203 |
+
for i in range(n - 1, 1, -1):
|
| 204 |
+
tmp = c0
|
| 205 |
+
c0 = polysub(c[i - 2], (c1*(i - 1))/i)
|
| 206 |
+
c1 = polyadd(tmp, (polymulx(c1)*(2*i - 1))/i)
|
| 207 |
+
return polyadd(c0, polymulx(c1))
|
| 208 |
+
|
| 209 |
+
#
|
| 210 |
+
# These are constant arrays are of integer type so as to be compatible
|
| 211 |
+
# with the widest range of other types, such as Decimal.
|
| 212 |
+
#
|
| 213 |
+
|
| 214 |
+
# Legendre
|
| 215 |
+
legdomain = np.array([-1, 1])
|
| 216 |
+
|
| 217 |
+
# Legendre coefficients representing zero.
|
| 218 |
+
legzero = np.array([0])
|
| 219 |
+
|
| 220 |
+
# Legendre coefficients representing one.
|
| 221 |
+
legone = np.array([1])
|
| 222 |
+
|
| 223 |
+
# Legendre coefficients representing the identity x.
|
| 224 |
+
legx = np.array([0, 1])
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
def legline(off, scl):
|
| 228 |
+
"""
|
| 229 |
+
Legendre series whose graph is a straight line.
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
|
| 233 |
+
Parameters
|
| 234 |
+
----------
|
| 235 |
+
off, scl : scalars
|
| 236 |
+
The specified line is given by ``off + scl*x``.
|
| 237 |
+
|
| 238 |
+
Returns
|
| 239 |
+
-------
|
| 240 |
+
y : ndarray
|
| 241 |
+
This module's representation of the Legendre series for
|
| 242 |
+
``off + scl*x``.
|
| 243 |
+
|
| 244 |
+
See Also
|
| 245 |
+
--------
|
| 246 |
+
numpy.polynomial.polynomial.polyline
|
| 247 |
+
numpy.polynomial.chebyshev.chebline
|
| 248 |
+
numpy.polynomial.laguerre.lagline
|
| 249 |
+
numpy.polynomial.hermite.hermline
|
| 250 |
+
numpy.polynomial.hermite_e.hermeline
|
| 251 |
+
|
| 252 |
+
Examples
|
| 253 |
+
--------
|
| 254 |
+
>>> import numpy.polynomial.legendre as L
|
| 255 |
+
>>> L.legline(3,2)
|
| 256 |
+
array([3, 2])
|
| 257 |
+
>>> L.legval(-3, L.legline(3,2)) # should be -3
|
| 258 |
+
-3.0
|
| 259 |
+
|
| 260 |
+
"""
|
| 261 |
+
if scl != 0:
|
| 262 |
+
return np.array([off, scl])
|
| 263 |
+
else:
|
| 264 |
+
return np.array([off])
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
def legfromroots(roots):
|
| 268 |
+
"""
|
| 269 |
+
Generate a Legendre series with given roots.
|
| 270 |
+
|
| 271 |
+
The function returns the coefficients of the polynomial
|
| 272 |
+
|
| 273 |
+
.. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
|
| 274 |
+
|
| 275 |
+
in Legendre form, where the `r_n` are the roots specified in `roots`.
|
| 276 |
+
If a zero has multiplicity n, then it must appear in `roots` n times.
|
| 277 |
+
For instance, if 2 is a root of multiplicity three and 3 is a root of
|
| 278 |
+
multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
|
| 279 |
+
roots can appear in any order.
|
| 280 |
+
|
| 281 |
+
If the returned coefficients are `c`, then
|
| 282 |
+
|
| 283 |
+
.. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x)
|
| 284 |
+
|
| 285 |
+
The coefficient of the last term is not generally 1 for monic
|
| 286 |
+
polynomials in Legendre form.
|
| 287 |
+
|
| 288 |
+
Parameters
|
| 289 |
+
----------
|
| 290 |
+
roots : array_like
|
| 291 |
+
Sequence containing the roots.
|
| 292 |
+
|
| 293 |
+
Returns
|
| 294 |
+
-------
|
| 295 |
+
out : ndarray
|
| 296 |
+
1-D array of coefficients. If all roots are real then `out` is a
|
| 297 |
+
real array, if some of the roots are complex, then `out` is complex
|
| 298 |
+
even if all the coefficients in the result are real (see Examples
|
| 299 |
+
below).
|
| 300 |
+
|
| 301 |
+
See Also
|
| 302 |
+
--------
|
| 303 |
+
numpy.polynomial.polynomial.polyfromroots
|
| 304 |
+
numpy.polynomial.chebyshev.chebfromroots
|
| 305 |
+
numpy.polynomial.laguerre.lagfromroots
|
| 306 |
+
numpy.polynomial.hermite.hermfromroots
|
| 307 |
+
numpy.polynomial.hermite_e.hermefromroots
|
| 308 |
+
|
| 309 |
+
Examples
|
| 310 |
+
--------
|
| 311 |
+
>>> import numpy.polynomial.legendre as L
|
| 312 |
+
>>> L.legfromroots((-1,0,1)) # x^3 - x relative to the standard basis
|
| 313 |
+
array([ 0. , -0.4, 0. , 0.4])
|
| 314 |
+
>>> j = complex(0,1)
|
| 315 |
+
>>> L.legfromroots((-j,j)) # x^2 + 1 relative to the standard basis
|
| 316 |
+
array([ 1.33333333+0.j, 0.00000000+0.j, 0.66666667+0.j]) # may vary
|
| 317 |
+
|
| 318 |
+
"""
|
| 319 |
+
return pu._fromroots(legline, legmul, roots)
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
def legadd(c1, c2):
|
| 323 |
+
"""
|
| 324 |
+
Add one Legendre series to another.
|
| 325 |
+
|
| 326 |
+
Returns the sum of two Legendre series `c1` + `c2`. The arguments
|
| 327 |
+
are sequences of coefficients ordered from lowest order term to
|
| 328 |
+
highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 329 |
+
|
| 330 |
+
Parameters
|
| 331 |
+
----------
|
| 332 |
+
c1, c2 : array_like
|
| 333 |
+
1-D arrays of Legendre series coefficients ordered from low to
|
| 334 |
+
high.
|
| 335 |
+
|
| 336 |
+
Returns
|
| 337 |
+
-------
|
| 338 |
+
out : ndarray
|
| 339 |
+
Array representing the Legendre series of their sum.
|
| 340 |
+
|
| 341 |
+
See Also
|
| 342 |
+
--------
|
| 343 |
+
legsub, legmulx, legmul, legdiv, legpow
|
| 344 |
+
|
| 345 |
+
Notes
|
| 346 |
+
-----
|
| 347 |
+
Unlike multiplication, division, etc., the sum of two Legendre series
|
| 348 |
+
is a Legendre series (without having to "reproject" the result onto
|
| 349 |
+
the basis set) so addition, just like that of "standard" polynomials,
|
| 350 |
+
is simply "component-wise."
|
| 351 |
+
|
| 352 |
+
Examples
|
| 353 |
+
--------
|
| 354 |
+
>>> from numpy.polynomial import legendre as L
|
| 355 |
+
>>> c1 = (1,2,3)
|
| 356 |
+
>>> c2 = (3,2,1)
|
| 357 |
+
>>> L.legadd(c1,c2)
|
| 358 |
+
array([4., 4., 4.])
|
| 359 |
+
|
| 360 |
+
"""
|
| 361 |
+
return pu._add(c1, c2)
|
| 362 |
+
|
| 363 |
+
|
| 364 |
+
def legsub(c1, c2):
|
| 365 |
+
"""
|
| 366 |
+
Subtract one Legendre series from another.
|
| 367 |
+
|
| 368 |
+
Returns the difference of two Legendre series `c1` - `c2`. The
|
| 369 |
+
sequences of coefficients are from lowest order term to highest, i.e.,
|
| 370 |
+
[1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 371 |
+
|
| 372 |
+
Parameters
|
| 373 |
+
----------
|
| 374 |
+
c1, c2 : array_like
|
| 375 |
+
1-D arrays of Legendre series coefficients ordered from low to
|
| 376 |
+
high.
|
| 377 |
+
|
| 378 |
+
Returns
|
| 379 |
+
-------
|
| 380 |
+
out : ndarray
|
| 381 |
+
Of Legendre series coefficients representing their difference.
|
| 382 |
+
|
| 383 |
+
See Also
|
| 384 |
+
--------
|
| 385 |
+
legadd, legmulx, legmul, legdiv, legpow
|
| 386 |
+
|
| 387 |
+
Notes
|
| 388 |
+
-----
|
| 389 |
+
Unlike multiplication, division, etc., the difference of two Legendre
|
| 390 |
+
series is a Legendre series (without having to "reproject" the result
|
| 391 |
+
onto the basis set) so subtraction, just like that of "standard"
|
| 392 |
+
polynomials, is simply "component-wise."
|
| 393 |
+
|
| 394 |
+
Examples
|
| 395 |
+
--------
|
| 396 |
+
>>> from numpy.polynomial import legendre as L
|
| 397 |
+
>>> c1 = (1,2,3)
|
| 398 |
+
>>> c2 = (3,2,1)
|
| 399 |
+
>>> L.legsub(c1,c2)
|
| 400 |
+
array([-2., 0., 2.])
|
| 401 |
+
>>> L.legsub(c2,c1) # -C.legsub(c1,c2)
|
| 402 |
+
array([ 2., 0., -2.])
|
| 403 |
+
|
| 404 |
+
"""
|
| 405 |
+
return pu._sub(c1, c2)
|
| 406 |
+
|
| 407 |
+
|
| 408 |
+
def legmulx(c):
|
| 409 |
+
"""Multiply a Legendre series by x.
|
| 410 |
+
|
| 411 |
+
Multiply the Legendre series `c` by x, where x is the independent
|
| 412 |
+
variable.
|
| 413 |
+
|
| 414 |
+
|
| 415 |
+
Parameters
|
| 416 |
+
----------
|
| 417 |
+
c : array_like
|
| 418 |
+
1-D array of Legendre series coefficients ordered from low to
|
| 419 |
+
high.
|
| 420 |
+
|
| 421 |
+
Returns
|
| 422 |
+
-------
|
| 423 |
+
out : ndarray
|
| 424 |
+
Array representing the result of the multiplication.
|
| 425 |
+
|
| 426 |
+
See Also
|
| 427 |
+
--------
|
| 428 |
+
legadd, legmul, legdiv, legpow
|
| 429 |
+
|
| 430 |
+
Notes
|
| 431 |
+
-----
|
| 432 |
+
The multiplication uses the recursion relationship for Legendre
|
| 433 |
+
polynomials in the form
|
| 434 |
+
|
| 435 |
+
.. math::
|
| 436 |
+
|
| 437 |
+
xP_i(x) = ((i + 1)*P_{i + 1}(x) + i*P_{i - 1}(x))/(2i + 1)
|
| 438 |
+
|
| 439 |
+
Examples
|
| 440 |
+
--------
|
| 441 |
+
>>> from numpy.polynomial import legendre as L
|
| 442 |
+
>>> L.legmulx([1,2,3])
|
| 443 |
+
array([ 0.66666667, 2.2, 1.33333333, 1.8]) # may vary
|
| 444 |
+
|
| 445 |
+
"""
|
| 446 |
+
# c is a trimmed copy
|
| 447 |
+
[c] = pu.as_series([c])
|
| 448 |
+
# The zero series needs special treatment
|
| 449 |
+
if len(c) == 1 and c[0] == 0:
|
| 450 |
+
return c
|
| 451 |
+
|
| 452 |
+
prd = np.empty(len(c) + 1, dtype=c.dtype)
|
| 453 |
+
prd[0] = c[0]*0
|
| 454 |
+
prd[1] = c[0]
|
| 455 |
+
for i in range(1, len(c)):
|
| 456 |
+
j = i + 1
|
| 457 |
+
k = i - 1
|
| 458 |
+
s = i + j
|
| 459 |
+
prd[j] = (c[i]*j)/s
|
| 460 |
+
prd[k] += (c[i]*i)/s
|
| 461 |
+
return prd
|
| 462 |
+
|
| 463 |
+
|
| 464 |
+
def legmul(c1, c2):
|
| 465 |
+
"""
|
| 466 |
+
Multiply one Legendre series by another.
|
| 467 |
+
|
| 468 |
+
Returns the product of two Legendre series `c1` * `c2`. The arguments
|
| 469 |
+
are sequences of coefficients, from lowest order "term" to highest,
|
| 470 |
+
e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
|
| 471 |
+
|
| 472 |
+
Parameters
|
| 473 |
+
----------
|
| 474 |
+
c1, c2 : array_like
|
| 475 |
+
1-D arrays of Legendre series coefficients ordered from low to
|
| 476 |
+
high.
|
| 477 |
+
|
| 478 |
+
Returns
|
| 479 |
+
-------
|
| 480 |
+
out : ndarray
|
| 481 |
+
Of Legendre series coefficients representing their product.
|
| 482 |
+
|
| 483 |
+
See Also
|
| 484 |
+
--------
|
| 485 |
+
legadd, legsub, legmulx, legdiv, legpow
|
| 486 |
+
|
| 487 |
+
Notes
|
| 488 |
+
-----
|
| 489 |
+
In general, the (polynomial) product of two C-series results in terms
|
| 490 |
+
that are not in the Legendre polynomial basis set. Thus, to express
|
| 491 |
+
the product as a Legendre series, it is necessary to "reproject" the
|
| 492 |
+
product onto said basis set, which may produce "unintuitive" (but
|
| 493 |
+
correct) results; see Examples section below.
|
| 494 |
+
|
| 495 |
+
Examples
|
| 496 |
+
--------
|
| 497 |
+
>>> from numpy.polynomial import legendre as L
|
| 498 |
+
>>> c1 = (1,2,3)
|
| 499 |
+
>>> c2 = (3,2)
|
| 500 |
+
>>> L.legmul(c1,c2) # multiplication requires "reprojection"
|
| 501 |
+
array([ 4.33333333, 10.4 , 11.66666667, 3.6 ]) # may vary
|
| 502 |
+
|
| 503 |
+
"""
|
| 504 |
+
# s1, s2 are trimmed copies
|
| 505 |
+
[c1, c2] = pu.as_series([c1, c2])
|
| 506 |
+
|
| 507 |
+
if len(c1) > len(c2):
|
| 508 |
+
c = c2
|
| 509 |
+
xs = c1
|
| 510 |
+
else:
|
| 511 |
+
c = c1
|
| 512 |
+
xs = c2
|
| 513 |
+
|
| 514 |
+
if len(c) == 1:
|
| 515 |
+
c0 = c[0]*xs
|
| 516 |
+
c1 = 0
|
| 517 |
+
elif len(c) == 2:
|
| 518 |
+
c0 = c[0]*xs
|
| 519 |
+
c1 = c[1]*xs
|
| 520 |
+
else:
|
| 521 |
+
nd = len(c)
|
| 522 |
+
c0 = c[-2]*xs
|
| 523 |
+
c1 = c[-1]*xs
|
| 524 |
+
for i in range(3, len(c) + 1):
|
| 525 |
+
tmp = c0
|
| 526 |
+
nd = nd - 1
|
| 527 |
+
c0 = legsub(c[-i]*xs, (c1*(nd - 1))/nd)
|
| 528 |
+
c1 = legadd(tmp, (legmulx(c1)*(2*nd - 1))/nd)
|
| 529 |
+
return legadd(c0, legmulx(c1))
|
| 530 |
+
|
| 531 |
+
|
| 532 |
+
def legdiv(c1, c2):
|
| 533 |
+
"""
|
| 534 |
+
Divide one Legendre series by another.
|
| 535 |
+
|
| 536 |
+
Returns the quotient-with-remainder of two Legendre series
|
| 537 |
+
`c1` / `c2`. The arguments are sequences of coefficients from lowest
|
| 538 |
+
order "term" to highest, e.g., [1,2,3] represents the series
|
| 539 |
+
``P_0 + 2*P_1 + 3*P_2``.
|
| 540 |
+
|
| 541 |
+
Parameters
|
| 542 |
+
----------
|
| 543 |
+
c1, c2 : array_like
|
| 544 |
+
1-D arrays of Legendre series coefficients ordered from low to
|
| 545 |
+
high.
|
| 546 |
+
|
| 547 |
+
Returns
|
| 548 |
+
-------
|
| 549 |
+
quo, rem : ndarrays
|
| 550 |
+
Of Legendre series coefficients representing the quotient and
|
| 551 |
+
remainder.
|
| 552 |
+
|
| 553 |
+
See Also
|
| 554 |
+
--------
|
| 555 |
+
legadd, legsub, legmulx, legmul, legpow
|
| 556 |
+
|
| 557 |
+
Notes
|
| 558 |
+
-----
|
| 559 |
+
In general, the (polynomial) division of one Legendre series by another
|
| 560 |
+
results in quotient and remainder terms that are not in the Legendre
|
| 561 |
+
polynomial basis set. Thus, to express these results as a Legendre
|
| 562 |
+
series, it is necessary to "reproject" the results onto the Legendre
|
| 563 |
+
basis set, which may produce "unintuitive" (but correct) results; see
|
| 564 |
+
Examples section below.
|
| 565 |
+
|
| 566 |
+
Examples
|
| 567 |
+
--------
|
| 568 |
+
>>> from numpy.polynomial import legendre as L
|
| 569 |
+
>>> c1 = (1,2,3)
|
| 570 |
+
>>> c2 = (3,2,1)
|
| 571 |
+
>>> L.legdiv(c1,c2) # quotient "intuitive," remainder not
|
| 572 |
+
(array([3.]), array([-8., -4.]))
|
| 573 |
+
>>> c2 = (0,1,2,3)
|
| 574 |
+
>>> L.legdiv(c2,c1) # neither "intuitive"
|
| 575 |
+
(array([-0.07407407, 1.66666667]), array([-1.03703704, -2.51851852])) # may vary
|
| 576 |
+
|
| 577 |
+
"""
|
| 578 |
+
return pu._div(legmul, c1, c2)
|
| 579 |
+
|
| 580 |
+
|
| 581 |
+
def legpow(c, pow, maxpower=16):
|
| 582 |
+
"""Raise a Legendre series to a power.
|
| 583 |
+
|
| 584 |
+
Returns the Legendre series `c` raised to the power `pow`. The
|
| 585 |
+
argument `c` is a sequence of coefficients ordered from low to high.
|
| 586 |
+
i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.``
|
| 587 |
+
|
| 588 |
+
Parameters
|
| 589 |
+
----------
|
| 590 |
+
c : array_like
|
| 591 |
+
1-D array of Legendre series coefficients ordered from low to
|
| 592 |
+
high.
|
| 593 |
+
pow : integer
|
| 594 |
+
Power to which the series will be raised
|
| 595 |
+
maxpower : integer, optional
|
| 596 |
+
Maximum power allowed. This is mainly to limit growth of the series
|
| 597 |
+
to unmanageable size. Default is 16
|
| 598 |
+
|
| 599 |
+
Returns
|
| 600 |
+
-------
|
| 601 |
+
coef : ndarray
|
| 602 |
+
Legendre series of power.
|
| 603 |
+
|
| 604 |
+
See Also
|
| 605 |
+
--------
|
| 606 |
+
legadd, legsub, legmulx, legmul, legdiv
|
| 607 |
+
|
| 608 |
+
"""
|
| 609 |
+
return pu._pow(legmul, c, pow, maxpower)
|
| 610 |
+
|
| 611 |
+
|
| 612 |
+
def legder(c, m=1, scl=1, axis=0):
|
| 613 |
+
"""
|
| 614 |
+
Differentiate a Legendre series.
|
| 615 |
+
|
| 616 |
+
Returns the Legendre series coefficients `c` differentiated `m` times
|
| 617 |
+
along `axis`. At each iteration the result is multiplied by `scl` (the
|
| 618 |
+
scaling factor is for use in a linear change of variable). The argument
|
| 619 |
+
`c` is an array of coefficients from low to high degree along each
|
| 620 |
+
axis, e.g., [1,2,3] represents the series ``1*L_0 + 2*L_1 + 3*L_2``
|
| 621 |
+
while [[1,2],[1,2]] represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) +
|
| 622 |
+
2*L_0(x)*L_1(y) + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is
|
| 623 |
+
``y``.
|
| 624 |
+
|
| 625 |
+
Parameters
|
| 626 |
+
----------
|
| 627 |
+
c : array_like
|
| 628 |
+
Array of Legendre series coefficients. If c is multidimensional the
|
| 629 |
+
different axis correspond to different variables with the degree in
|
| 630 |
+
each axis given by the corresponding index.
|
| 631 |
+
m : int, optional
|
| 632 |
+
Number of derivatives taken, must be non-negative. (Default: 1)
|
| 633 |
+
scl : scalar, optional
|
| 634 |
+
Each differentiation is multiplied by `scl`. The end result is
|
| 635 |
+
multiplication by ``scl**m``. This is for use in a linear change of
|
| 636 |
+
variable. (Default: 1)
|
| 637 |
+
axis : int, optional
|
| 638 |
+
Axis over which the derivative is taken. (Default: 0).
|
| 639 |
+
|
| 640 |
+
.. versionadded:: 1.7.0
|
| 641 |
+
|
| 642 |
+
Returns
|
| 643 |
+
-------
|
| 644 |
+
der : ndarray
|
| 645 |
+
Legendre series of the derivative.
|
| 646 |
+
|
| 647 |
+
See Also
|
| 648 |
+
--------
|
| 649 |
+
legint
|
| 650 |
+
|
| 651 |
+
Notes
|
| 652 |
+
-----
|
| 653 |
+
In general, the result of differentiating a Legendre series does not
|
| 654 |
+
resemble the same operation on a power series. Thus the result of this
|
| 655 |
+
function may be "unintuitive," albeit correct; see Examples section
|
| 656 |
+
below.
|
| 657 |
+
|
| 658 |
+
Examples
|
| 659 |
+
--------
|
| 660 |
+
>>> from numpy.polynomial import legendre as L
|
| 661 |
+
>>> c = (1,2,3,4)
|
| 662 |
+
>>> L.legder(c)
|
| 663 |
+
array([ 6., 9., 20.])
|
| 664 |
+
>>> L.legder(c, 3)
|
| 665 |
+
array([60.])
|
| 666 |
+
>>> L.legder(c, scl=-1)
|
| 667 |
+
array([ -6., -9., -20.])
|
| 668 |
+
>>> L.legder(c, 2,-1)
|
| 669 |
+
array([ 9., 60.])
|
| 670 |
+
|
| 671 |
+
"""
|
| 672 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 673 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 674 |
+
c = c.astype(np.double)
|
| 675 |
+
cnt = pu._deprecate_as_int(m, "the order of derivation")
|
| 676 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 677 |
+
if cnt < 0:
|
| 678 |
+
raise ValueError("The order of derivation must be non-negative")
|
| 679 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 680 |
+
|
| 681 |
+
if cnt == 0:
|
| 682 |
+
return c
|
| 683 |
+
|
| 684 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 685 |
+
n = len(c)
|
| 686 |
+
if cnt >= n:
|
| 687 |
+
c = c[:1]*0
|
| 688 |
+
else:
|
| 689 |
+
for i in range(cnt):
|
| 690 |
+
n = n - 1
|
| 691 |
+
c *= scl
|
| 692 |
+
der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
|
| 693 |
+
for j in range(n, 2, -1):
|
| 694 |
+
der[j - 1] = (2*j - 1)*c[j]
|
| 695 |
+
c[j - 2] += c[j]
|
| 696 |
+
if n > 1:
|
| 697 |
+
der[1] = 3*c[2]
|
| 698 |
+
der[0] = c[1]
|
| 699 |
+
c = der
|
| 700 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 701 |
+
return c
|
| 702 |
+
|
| 703 |
+
|
| 704 |
+
def legint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
|
| 705 |
+
"""
|
| 706 |
+
Integrate a Legendre series.
|
| 707 |
+
|
| 708 |
+
Returns the Legendre series coefficients `c` integrated `m` times from
|
| 709 |
+
`lbnd` along `axis`. At each iteration the resulting series is
|
| 710 |
+
**multiplied** by `scl` and an integration constant, `k`, is added.
|
| 711 |
+
The scaling factor is for use in a linear change of variable. ("Buyer
|
| 712 |
+
beware": note that, depending on what one is doing, one may want `scl`
|
| 713 |
+
to be the reciprocal of what one might expect; for more information,
|
| 714 |
+
see the Notes section below.) The argument `c` is an array of
|
| 715 |
+
coefficients from low to high degree along each axis, e.g., [1,2,3]
|
| 716 |
+
represents the series ``L_0 + 2*L_1 + 3*L_2`` while [[1,2],[1,2]]
|
| 717 |
+
represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 2*L_0(x)*L_1(y) +
|
| 718 |
+
2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
|
| 719 |
+
|
| 720 |
+
Parameters
|
| 721 |
+
----------
|
| 722 |
+
c : array_like
|
| 723 |
+
Array of Legendre series coefficients. If c is multidimensional the
|
| 724 |
+
different axis correspond to different variables with the degree in
|
| 725 |
+
each axis given by the corresponding index.
|
| 726 |
+
m : int, optional
|
| 727 |
+
Order of integration, must be positive. (Default: 1)
|
| 728 |
+
k : {[], list, scalar}, optional
|
| 729 |
+
Integration constant(s). The value of the first integral at
|
| 730 |
+
``lbnd`` is the first value in the list, the value of the second
|
| 731 |
+
integral at ``lbnd`` is the second value, etc. If ``k == []`` (the
|
| 732 |
+
default), all constants are set to zero. If ``m == 1``, a single
|
| 733 |
+
scalar can be given instead of a list.
|
| 734 |
+
lbnd : scalar, optional
|
| 735 |
+
The lower bound of the integral. (Default: 0)
|
| 736 |
+
scl : scalar, optional
|
| 737 |
+
Following each integration the result is *multiplied* by `scl`
|
| 738 |
+
before the integration constant is added. (Default: 1)
|
| 739 |
+
axis : int, optional
|
| 740 |
+
Axis over which the integral is taken. (Default: 0).
|
| 741 |
+
|
| 742 |
+
.. versionadded:: 1.7.0
|
| 743 |
+
|
| 744 |
+
Returns
|
| 745 |
+
-------
|
| 746 |
+
S : ndarray
|
| 747 |
+
Legendre series coefficient array of the integral.
|
| 748 |
+
|
| 749 |
+
Raises
|
| 750 |
+
------
|
| 751 |
+
ValueError
|
| 752 |
+
If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or
|
| 753 |
+
``np.ndim(scl) != 0``.
|
| 754 |
+
|
| 755 |
+
See Also
|
| 756 |
+
--------
|
| 757 |
+
legder
|
| 758 |
+
|
| 759 |
+
Notes
|
| 760 |
+
-----
|
| 761 |
+
Note that the result of each integration is *multiplied* by `scl`.
|
| 762 |
+
Why is this important to note? Say one is making a linear change of
|
| 763 |
+
variable :math:`u = ax + b` in an integral relative to `x`. Then
|
| 764 |
+
:math:`dx = du/a`, so one will need to set `scl` equal to
|
| 765 |
+
:math:`1/a` - perhaps not what one would have first thought.
|
| 766 |
+
|
| 767 |
+
Also note that, in general, the result of integrating a C-series needs
|
| 768 |
+
to be "reprojected" onto the C-series basis set. Thus, typically,
|
| 769 |
+
the result of this function is "unintuitive," albeit correct; see
|
| 770 |
+
Examples section below.
|
| 771 |
+
|
| 772 |
+
Examples
|
| 773 |
+
--------
|
| 774 |
+
>>> from numpy.polynomial import legendre as L
|
| 775 |
+
>>> c = (1,2,3)
|
| 776 |
+
>>> L.legint(c)
|
| 777 |
+
array([ 0.33333333, 0.4 , 0.66666667, 0.6 ]) # may vary
|
| 778 |
+
>>> L.legint(c, 3)
|
| 779 |
+
array([ 1.66666667e-02, -1.78571429e-02, 4.76190476e-02, # may vary
|
| 780 |
+
-1.73472348e-18, 1.90476190e-02, 9.52380952e-03])
|
| 781 |
+
>>> L.legint(c, k=3)
|
| 782 |
+
array([ 3.33333333, 0.4 , 0.66666667, 0.6 ]) # may vary
|
| 783 |
+
>>> L.legint(c, lbnd=-2)
|
| 784 |
+
array([ 7.33333333, 0.4 , 0.66666667, 0.6 ]) # may vary
|
| 785 |
+
>>> L.legint(c, scl=2)
|
| 786 |
+
array([ 0.66666667, 0.8 , 1.33333333, 1.2 ]) # may vary
|
| 787 |
+
|
| 788 |
+
"""
|
| 789 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 790 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 791 |
+
c = c.astype(np.double)
|
| 792 |
+
if not np.iterable(k):
|
| 793 |
+
k = [k]
|
| 794 |
+
cnt = pu._deprecate_as_int(m, "the order of integration")
|
| 795 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 796 |
+
if cnt < 0:
|
| 797 |
+
raise ValueError("The order of integration must be non-negative")
|
| 798 |
+
if len(k) > cnt:
|
| 799 |
+
raise ValueError("Too many integration constants")
|
| 800 |
+
if np.ndim(lbnd) != 0:
|
| 801 |
+
raise ValueError("lbnd must be a scalar.")
|
| 802 |
+
if np.ndim(scl) != 0:
|
| 803 |
+
raise ValueError("scl must be a scalar.")
|
| 804 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 805 |
+
|
| 806 |
+
if cnt == 0:
|
| 807 |
+
return c
|
| 808 |
+
|
| 809 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 810 |
+
k = list(k) + [0]*(cnt - len(k))
|
| 811 |
+
for i in range(cnt):
|
| 812 |
+
n = len(c)
|
| 813 |
+
c *= scl
|
| 814 |
+
if n == 1 and np.all(c[0] == 0):
|
| 815 |
+
c[0] += k[i]
|
| 816 |
+
else:
|
| 817 |
+
tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
|
| 818 |
+
tmp[0] = c[0]*0
|
| 819 |
+
tmp[1] = c[0]
|
| 820 |
+
if n > 1:
|
| 821 |
+
tmp[2] = c[1]/3
|
| 822 |
+
for j in range(2, n):
|
| 823 |
+
t = c[j]/(2*j + 1)
|
| 824 |
+
tmp[j + 1] = t
|
| 825 |
+
tmp[j - 1] -= t
|
| 826 |
+
tmp[0] += k[i] - legval(lbnd, tmp)
|
| 827 |
+
c = tmp
|
| 828 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 829 |
+
return c
|
| 830 |
+
|
| 831 |
+
|
| 832 |
+
def legval(x, c, tensor=True):
|
| 833 |
+
"""
|
| 834 |
+
Evaluate a Legendre series at points x.
|
| 835 |
+
|
| 836 |
+
If `c` is of length `n + 1`, this function returns the value:
|
| 837 |
+
|
| 838 |
+
.. math:: p(x) = c_0 * L_0(x) + c_1 * L_1(x) + ... + c_n * L_n(x)
|
| 839 |
+
|
| 840 |
+
The parameter `x` is converted to an array only if it is a tuple or a
|
| 841 |
+
list, otherwise it is treated as a scalar. In either case, either `x`
|
| 842 |
+
or its elements must support multiplication and addition both with
|
| 843 |
+
themselves and with the elements of `c`.
|
| 844 |
+
|
| 845 |
+
If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If
|
| 846 |
+
`c` is multidimensional, then the shape of the result depends on the
|
| 847 |
+
value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
|
| 848 |
+
x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
|
| 849 |
+
scalars have shape (,).
|
| 850 |
+
|
| 851 |
+
Trailing zeros in the coefficients will be used in the evaluation, so
|
| 852 |
+
they should be avoided if efficiency is a concern.
|
| 853 |
+
|
| 854 |
+
Parameters
|
| 855 |
+
----------
|
| 856 |
+
x : array_like, compatible object
|
| 857 |
+
If `x` is a list or tuple, it is converted to an ndarray, otherwise
|
| 858 |
+
it is left unchanged and treated as a scalar. In either case, `x`
|
| 859 |
+
or its elements must support addition and multiplication with
|
| 860 |
+
themselves and with the elements of `c`.
|
| 861 |
+
c : array_like
|
| 862 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 863 |
+
degree n are contained in c[n]. If `c` is multidimensional the
|
| 864 |
+
remaining indices enumerate multiple polynomials. In the two
|
| 865 |
+
dimensional case the coefficients may be thought of as stored in
|
| 866 |
+
the columns of `c`.
|
| 867 |
+
tensor : boolean, optional
|
| 868 |
+
If True, the shape of the coefficient array is extended with ones
|
| 869 |
+
on the right, one for each dimension of `x`. Scalars have dimension 0
|
| 870 |
+
for this action. The result is that every column of coefficients in
|
| 871 |
+
`c` is evaluated for every element of `x`. If False, `x` is broadcast
|
| 872 |
+
over the columns of `c` for the evaluation. This keyword is useful
|
| 873 |
+
when `c` is multidimensional. The default value is True.
|
| 874 |
+
|
| 875 |
+
.. versionadded:: 1.7.0
|
| 876 |
+
|
| 877 |
+
Returns
|
| 878 |
+
-------
|
| 879 |
+
values : ndarray, algebra_like
|
| 880 |
+
The shape of the return value is described above.
|
| 881 |
+
|
| 882 |
+
See Also
|
| 883 |
+
--------
|
| 884 |
+
legval2d, leggrid2d, legval3d, leggrid3d
|
| 885 |
+
|
| 886 |
+
Notes
|
| 887 |
+
-----
|
| 888 |
+
The evaluation uses Clenshaw recursion, aka synthetic division.
|
| 889 |
+
|
| 890 |
+
"""
|
| 891 |
+
c = np.array(c, ndmin=1, copy=False)
|
| 892 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 893 |
+
c = c.astype(np.double)
|
| 894 |
+
if isinstance(x, (tuple, list)):
|
| 895 |
+
x = np.asarray(x)
|
| 896 |
+
if isinstance(x, np.ndarray) and tensor:
|
| 897 |
+
c = c.reshape(c.shape + (1,)*x.ndim)
|
| 898 |
+
|
| 899 |
+
if len(c) == 1:
|
| 900 |
+
c0 = c[0]
|
| 901 |
+
c1 = 0
|
| 902 |
+
elif len(c) == 2:
|
| 903 |
+
c0 = c[0]
|
| 904 |
+
c1 = c[1]
|
| 905 |
+
else:
|
| 906 |
+
nd = len(c)
|
| 907 |
+
c0 = c[-2]
|
| 908 |
+
c1 = c[-1]
|
| 909 |
+
for i in range(3, len(c) + 1):
|
| 910 |
+
tmp = c0
|
| 911 |
+
nd = nd - 1
|
| 912 |
+
c0 = c[-i] - (c1*(nd - 1))/nd
|
| 913 |
+
c1 = tmp + (c1*x*(2*nd - 1))/nd
|
| 914 |
+
return c0 + c1*x
|
| 915 |
+
|
| 916 |
+
|
| 917 |
+
def legval2d(x, y, c):
|
| 918 |
+
"""
|
| 919 |
+
Evaluate a 2-D Legendre series at points (x, y).
|
| 920 |
+
|
| 921 |
+
This function returns the values:
|
| 922 |
+
|
| 923 |
+
.. math:: p(x,y) = \\sum_{i,j} c_{i,j} * L_i(x) * L_j(y)
|
| 924 |
+
|
| 925 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 926 |
+
tuples or a lists, otherwise they are treated as a scalars and they
|
| 927 |
+
must have the same shape after conversion. In either case, either `x`
|
| 928 |
+
and `y` or their elements must support multiplication and addition both
|
| 929 |
+
with themselves and with the elements of `c`.
|
| 930 |
+
|
| 931 |
+
If `c` is a 1-D array a one is implicitly appended to its shape to make
|
| 932 |
+
it 2-D. The shape of the result will be c.shape[2:] + x.shape.
|
| 933 |
+
|
| 934 |
+
Parameters
|
| 935 |
+
----------
|
| 936 |
+
x, y : array_like, compatible objects
|
| 937 |
+
The two dimensional series is evaluated at the points `(x, y)`,
|
| 938 |
+
where `x` and `y` must have the same shape. If `x` or `y` is a list
|
| 939 |
+
or tuple, it is first converted to an ndarray, otherwise it is left
|
| 940 |
+
unchanged and if it isn't an ndarray it is treated as a scalar.
|
| 941 |
+
c : array_like
|
| 942 |
+
Array of coefficients ordered so that the coefficient of the term
|
| 943 |
+
of multi-degree i,j is contained in ``c[i,j]``. If `c` has
|
| 944 |
+
dimension greater than two the remaining indices enumerate multiple
|
| 945 |
+
sets of coefficients.
|
| 946 |
+
|
| 947 |
+
Returns
|
| 948 |
+
-------
|
| 949 |
+
values : ndarray, compatible object
|
| 950 |
+
The values of the two dimensional Legendre series at points formed
|
| 951 |
+
from pairs of corresponding values from `x` and `y`.
|
| 952 |
+
|
| 953 |
+
See Also
|
| 954 |
+
--------
|
| 955 |
+
legval, leggrid2d, legval3d, leggrid3d
|
| 956 |
+
|
| 957 |
+
Notes
|
| 958 |
+
-----
|
| 959 |
+
|
| 960 |
+
.. versionadded:: 1.7.0
|
| 961 |
+
|
| 962 |
+
"""
|
| 963 |
+
return pu._valnd(legval, c, x, y)
|
| 964 |
+
|
| 965 |
+
|
| 966 |
+
def leggrid2d(x, y, c):
|
| 967 |
+
"""
|
| 968 |
+
Evaluate a 2-D Legendre series on the Cartesian product of x and y.
|
| 969 |
+
|
| 970 |
+
This function returns the values:
|
| 971 |
+
|
| 972 |
+
.. math:: p(a,b) = \\sum_{i,j} c_{i,j} * L_i(a) * L_j(b)
|
| 973 |
+
|
| 974 |
+
where the points `(a, b)` consist of all pairs formed by taking
|
| 975 |
+
`a` from `x` and `b` from `y`. The resulting points form a grid with
|
| 976 |
+
`x` in the first dimension and `y` in the second.
|
| 977 |
+
|
| 978 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 979 |
+
tuples or a lists, otherwise they are treated as a scalars. In either
|
| 980 |
+
case, either `x` and `y` or their elements must support multiplication
|
| 981 |
+
and addition both with themselves and with the elements of `c`.
|
| 982 |
+
|
| 983 |
+
If `c` has fewer than two dimensions, ones are implicitly appended to
|
| 984 |
+
its shape to make it 2-D. The shape of the result will be c.shape[2:] +
|
| 985 |
+
x.shape + y.shape.
|
| 986 |
+
|
| 987 |
+
Parameters
|
| 988 |
+
----------
|
| 989 |
+
x, y : array_like, compatible objects
|
| 990 |
+
The two dimensional series is evaluated at the points in the
|
| 991 |
+
Cartesian product of `x` and `y`. If `x` or `y` is a list or
|
| 992 |
+
tuple, it is first converted to an ndarray, otherwise it is left
|
| 993 |
+
unchanged and, if it isn't an ndarray, it is treated as a scalar.
|
| 994 |
+
c : array_like
|
| 995 |
+
Array of coefficients ordered so that the coefficient of the term of
|
| 996 |
+
multi-degree i,j is contained in `c[i,j]`. If `c` has dimension
|
| 997 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 998 |
+
coefficients.
|
| 999 |
+
|
| 1000 |
+
Returns
|
| 1001 |
+
-------
|
| 1002 |
+
values : ndarray, compatible object
|
| 1003 |
+
The values of the two dimensional Chebyshev series at points in the
|
| 1004 |
+
Cartesian product of `x` and `y`.
|
| 1005 |
+
|
| 1006 |
+
See Also
|
| 1007 |
+
--------
|
| 1008 |
+
legval, legval2d, legval3d, leggrid3d
|
| 1009 |
+
|
| 1010 |
+
Notes
|
| 1011 |
+
-----
|
| 1012 |
+
|
| 1013 |
+
.. versionadded:: 1.7.0
|
| 1014 |
+
|
| 1015 |
+
"""
|
| 1016 |
+
return pu._gridnd(legval, c, x, y)
|
| 1017 |
+
|
| 1018 |
+
|
| 1019 |
+
def legval3d(x, y, z, c):
|
| 1020 |
+
"""
|
| 1021 |
+
Evaluate a 3-D Legendre series at points (x, y, z).
|
| 1022 |
+
|
| 1023 |
+
This function returns the values:
|
| 1024 |
+
|
| 1025 |
+
.. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * L_i(x) * L_j(y) * L_k(z)
|
| 1026 |
+
|
| 1027 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if
|
| 1028 |
+
they are tuples or a lists, otherwise they are treated as a scalars and
|
| 1029 |
+
they must have the same shape after conversion. In either case, either
|
| 1030 |
+
`x`, `y`, and `z` or their elements must support multiplication and
|
| 1031 |
+
addition both with themselves and with the elements of `c`.
|
| 1032 |
+
|
| 1033 |
+
If `c` has fewer than 3 dimensions, ones are implicitly appended to its
|
| 1034 |
+
shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1035 |
+
x.shape.
|
| 1036 |
+
|
| 1037 |
+
Parameters
|
| 1038 |
+
----------
|
| 1039 |
+
x, y, z : array_like, compatible object
|
| 1040 |
+
The three dimensional series is evaluated at the points
|
| 1041 |
+
`(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If
|
| 1042 |
+
any of `x`, `y`, or `z` is a list or tuple, it is first converted
|
| 1043 |
+
to an ndarray, otherwise it is left unchanged and if it isn't an
|
| 1044 |
+
ndarray it is treated as a scalar.
|
| 1045 |
+
c : array_like
|
| 1046 |
+
Array of coefficients ordered so that the coefficient of the term of
|
| 1047 |
+
multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
|
| 1048 |
+
greater than 3 the remaining indices enumerate multiple sets of
|
| 1049 |
+
coefficients.
|
| 1050 |
+
|
| 1051 |
+
Returns
|
| 1052 |
+
-------
|
| 1053 |
+
values : ndarray, compatible object
|
| 1054 |
+
The values of the multidimensional polynomial on points formed with
|
| 1055 |
+
triples of corresponding values from `x`, `y`, and `z`.
|
| 1056 |
+
|
| 1057 |
+
See Also
|
| 1058 |
+
--------
|
| 1059 |
+
legval, legval2d, leggrid2d, leggrid3d
|
| 1060 |
+
|
| 1061 |
+
Notes
|
| 1062 |
+
-----
|
| 1063 |
+
|
| 1064 |
+
.. versionadded:: 1.7.0
|
| 1065 |
+
|
| 1066 |
+
"""
|
| 1067 |
+
return pu._valnd(legval, c, x, y, z)
|
| 1068 |
+
|
| 1069 |
+
|
| 1070 |
+
def leggrid3d(x, y, z, c):
|
| 1071 |
+
"""
|
| 1072 |
+
Evaluate a 3-D Legendre series on the Cartesian product of x, y, and z.
|
| 1073 |
+
|
| 1074 |
+
This function returns the values:
|
| 1075 |
+
|
| 1076 |
+
.. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * L_i(a) * L_j(b) * L_k(c)
|
| 1077 |
+
|
| 1078 |
+
where the points `(a, b, c)` consist of all triples formed by taking
|
| 1079 |
+
`a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
|
| 1080 |
+
a grid with `x` in the first dimension, `y` in the second, and `z` in
|
| 1081 |
+
the third.
|
| 1082 |
+
|
| 1083 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if they
|
| 1084 |
+
are tuples or a lists, otherwise they are treated as a scalars. In
|
| 1085 |
+
either case, either `x`, `y`, and `z` or their elements must support
|
| 1086 |
+
multiplication and addition both with themselves and with the elements
|
| 1087 |
+
of `c`.
|
| 1088 |
+
|
| 1089 |
+
If `c` has fewer than three dimensions, ones are implicitly appended to
|
| 1090 |
+
its shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1091 |
+
x.shape + y.shape + z.shape.
|
| 1092 |
+
|
| 1093 |
+
Parameters
|
| 1094 |
+
----------
|
| 1095 |
+
x, y, z : array_like, compatible objects
|
| 1096 |
+
The three dimensional series is evaluated at the points in the
|
| 1097 |
+
Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a
|
| 1098 |
+
list or tuple, it is first converted to an ndarray, otherwise it is
|
| 1099 |
+
left unchanged and, if it isn't an ndarray, it is treated as a
|
| 1100 |
+
scalar.
|
| 1101 |
+
c : array_like
|
| 1102 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 1103 |
+
degree i,j are contained in ``c[i,j]``. If `c` has dimension
|
| 1104 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 1105 |
+
coefficients.
|
| 1106 |
+
|
| 1107 |
+
Returns
|
| 1108 |
+
-------
|
| 1109 |
+
values : ndarray, compatible object
|
| 1110 |
+
The values of the two dimensional polynomial at points in the Cartesian
|
| 1111 |
+
product of `x` and `y`.
|
| 1112 |
+
|
| 1113 |
+
See Also
|
| 1114 |
+
--------
|
| 1115 |
+
legval, legval2d, leggrid2d, legval3d
|
| 1116 |
+
|
| 1117 |
+
Notes
|
| 1118 |
+
-----
|
| 1119 |
+
|
| 1120 |
+
.. versionadded:: 1.7.0
|
| 1121 |
+
|
| 1122 |
+
"""
|
| 1123 |
+
return pu._gridnd(legval, c, x, y, z)
|
| 1124 |
+
|
| 1125 |
+
|
| 1126 |
+
def legvander(x, deg):
|
| 1127 |
+
"""Pseudo-Vandermonde matrix of given degree.
|
| 1128 |
+
|
| 1129 |
+
Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
|
| 1130 |
+
`x`. The pseudo-Vandermonde matrix is defined by
|
| 1131 |
+
|
| 1132 |
+
.. math:: V[..., i] = L_i(x)
|
| 1133 |
+
|
| 1134 |
+
where `0 <= i <= deg`. The leading indices of `V` index the elements of
|
| 1135 |
+
`x` and the last index is the degree of the Legendre polynomial.
|
| 1136 |
+
|
| 1137 |
+
If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
|
| 1138 |
+
array ``V = legvander(x, n)``, then ``np.dot(V, c)`` and
|
| 1139 |
+
``legval(x, c)`` are the same up to roundoff. This equivalence is
|
| 1140 |
+
useful both for least squares fitting and for the evaluation of a large
|
| 1141 |
+
number of Legendre series of the same degree and sample points.
|
| 1142 |
+
|
| 1143 |
+
Parameters
|
| 1144 |
+
----------
|
| 1145 |
+
x : array_like
|
| 1146 |
+
Array of points. The dtype is converted to float64 or complex128
|
| 1147 |
+
depending on whether any of the elements are complex. If `x` is
|
| 1148 |
+
scalar it is converted to a 1-D array.
|
| 1149 |
+
deg : int
|
| 1150 |
+
Degree of the resulting matrix.
|
| 1151 |
+
|
| 1152 |
+
Returns
|
| 1153 |
+
-------
|
| 1154 |
+
vander : ndarray
|
| 1155 |
+
The pseudo-Vandermonde matrix. The shape of the returned matrix is
|
| 1156 |
+
``x.shape + (deg + 1,)``, where The last index is the degree of the
|
| 1157 |
+
corresponding Legendre polynomial. The dtype will be the same as
|
| 1158 |
+
the converted `x`.
|
| 1159 |
+
|
| 1160 |
+
"""
|
| 1161 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1162 |
+
if ideg < 0:
|
| 1163 |
+
raise ValueError("deg must be non-negative")
|
| 1164 |
+
|
| 1165 |
+
x = np.array(x, copy=False, ndmin=1) + 0.0
|
| 1166 |
+
dims = (ideg + 1,) + x.shape
|
| 1167 |
+
dtyp = x.dtype
|
| 1168 |
+
v = np.empty(dims, dtype=dtyp)
|
| 1169 |
+
# Use forward recursion to generate the entries. This is not as accurate
|
| 1170 |
+
# as reverse recursion in this application but it is more efficient.
|
| 1171 |
+
v[0] = x*0 + 1
|
| 1172 |
+
if ideg > 0:
|
| 1173 |
+
v[1] = x
|
| 1174 |
+
for i in range(2, ideg + 1):
|
| 1175 |
+
v[i] = (v[i-1]*x*(2*i - 1) - v[i-2]*(i - 1))/i
|
| 1176 |
+
return np.moveaxis(v, 0, -1)
|
| 1177 |
+
|
| 1178 |
+
|
| 1179 |
+
def legvander2d(x, y, deg):
|
| 1180 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1181 |
+
|
| 1182 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1183 |
+
points `(x, y)`. The pseudo-Vandermonde matrix is defined by
|
| 1184 |
+
|
| 1185 |
+
.. math:: V[..., (deg[1] + 1)*i + j] = L_i(x) * L_j(y),
|
| 1186 |
+
|
| 1187 |
+
where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
|
| 1188 |
+
`V` index the points `(x, y)` and the last index encodes the degrees of
|
| 1189 |
+
the Legendre polynomials.
|
| 1190 |
+
|
| 1191 |
+
If ``V = legvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
|
| 1192 |
+
correspond to the elements of a 2-D coefficient array `c` of shape
|
| 1193 |
+
(xdeg + 1, ydeg + 1) in the order
|
| 1194 |
+
|
| 1195 |
+
.. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
|
| 1196 |
+
|
| 1197 |
+
and ``np.dot(V, c.flat)`` and ``legval2d(x, y, c)`` will be the same
|
| 1198 |
+
up to roundoff. This equivalence is useful both for least squares
|
| 1199 |
+
fitting and for the evaluation of a large number of 2-D Legendre
|
| 1200 |
+
series of the same degrees and sample points.
|
| 1201 |
+
|
| 1202 |
+
Parameters
|
| 1203 |
+
----------
|
| 1204 |
+
x, y : array_like
|
| 1205 |
+
Arrays of point coordinates, all of the same shape. The dtypes
|
| 1206 |
+
will be converted to either float64 or complex128 depending on
|
| 1207 |
+
whether any of the elements are complex. Scalars are converted to
|
| 1208 |
+
1-D arrays.
|
| 1209 |
+
deg : list of ints
|
| 1210 |
+
List of maximum degrees of the form [x_deg, y_deg].
|
| 1211 |
+
|
| 1212 |
+
Returns
|
| 1213 |
+
-------
|
| 1214 |
+
vander2d : ndarray
|
| 1215 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1216 |
+
:math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same
|
| 1217 |
+
as the converted `x` and `y`.
|
| 1218 |
+
|
| 1219 |
+
See Also
|
| 1220 |
+
--------
|
| 1221 |
+
legvander, legvander3d, legval2d, legval3d
|
| 1222 |
+
|
| 1223 |
+
Notes
|
| 1224 |
+
-----
|
| 1225 |
+
|
| 1226 |
+
.. versionadded:: 1.7.0
|
| 1227 |
+
|
| 1228 |
+
"""
|
| 1229 |
+
return pu._vander_nd_flat((legvander, legvander), (x, y), deg)
|
| 1230 |
+
|
| 1231 |
+
|
| 1232 |
+
def legvander3d(x, y, z, deg):
|
| 1233 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1234 |
+
|
| 1235 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1236 |
+
points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
|
| 1237 |
+
then The pseudo-Vandermonde matrix is defined by
|
| 1238 |
+
|
| 1239 |
+
.. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = L_i(x)*L_j(y)*L_k(z),
|
| 1240 |
+
|
| 1241 |
+
where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading
|
| 1242 |
+
indices of `V` index the points `(x, y, z)` and the last index encodes
|
| 1243 |
+
the degrees of the Legendre polynomials.
|
| 1244 |
+
|
| 1245 |
+
If ``V = legvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
|
| 1246 |
+
of `V` correspond to the elements of a 3-D coefficient array `c` of
|
| 1247 |
+
shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
|
| 1248 |
+
|
| 1249 |
+
.. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
|
| 1250 |
+
|
| 1251 |
+
and ``np.dot(V, c.flat)`` and ``legval3d(x, y, z, c)`` will be the
|
| 1252 |
+
same up to roundoff. This equivalence is useful both for least squares
|
| 1253 |
+
fitting and for the evaluation of a large number of 3-D Legendre
|
| 1254 |
+
series of the same degrees and sample points.
|
| 1255 |
+
|
| 1256 |
+
Parameters
|
| 1257 |
+
----------
|
| 1258 |
+
x, y, z : array_like
|
| 1259 |
+
Arrays of point coordinates, all of the same shape. The dtypes will
|
| 1260 |
+
be converted to either float64 or complex128 depending on whether
|
| 1261 |
+
any of the elements are complex. Scalars are converted to 1-D
|
| 1262 |
+
arrays.
|
| 1263 |
+
deg : list of ints
|
| 1264 |
+
List of maximum degrees of the form [x_deg, y_deg, z_deg].
|
| 1265 |
+
|
| 1266 |
+
Returns
|
| 1267 |
+
-------
|
| 1268 |
+
vander3d : ndarray
|
| 1269 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1270 |
+
:math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will
|
| 1271 |
+
be the same as the converted `x`, `y`, and `z`.
|
| 1272 |
+
|
| 1273 |
+
See Also
|
| 1274 |
+
--------
|
| 1275 |
+
legvander, legvander3d, legval2d, legval3d
|
| 1276 |
+
|
| 1277 |
+
Notes
|
| 1278 |
+
-----
|
| 1279 |
+
|
| 1280 |
+
.. versionadded:: 1.7.0
|
| 1281 |
+
|
| 1282 |
+
"""
|
| 1283 |
+
return pu._vander_nd_flat((legvander, legvander, legvander), (x, y, z), deg)
|
| 1284 |
+
|
| 1285 |
+
|
| 1286 |
+
def legfit(x, y, deg, rcond=None, full=False, w=None):
|
| 1287 |
+
"""
|
| 1288 |
+
Least squares fit of Legendre series to data.
|
| 1289 |
+
|
| 1290 |
+
Return the coefficients of a Legendre series of degree `deg` that is the
|
| 1291 |
+
least squares fit to the data values `y` given at points `x`. If `y` is
|
| 1292 |
+
1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
|
| 1293 |
+
fits are done, one for each column of `y`, and the resulting
|
| 1294 |
+
coefficients are stored in the corresponding columns of a 2-D return.
|
| 1295 |
+
The fitted polynomial(s) are in the form
|
| 1296 |
+
|
| 1297 |
+
.. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x),
|
| 1298 |
+
|
| 1299 |
+
where `n` is `deg`.
|
| 1300 |
+
|
| 1301 |
+
Parameters
|
| 1302 |
+
----------
|
| 1303 |
+
x : array_like, shape (M,)
|
| 1304 |
+
x-coordinates of the M sample points ``(x[i], y[i])``.
|
| 1305 |
+
y : array_like, shape (M,) or (M, K)
|
| 1306 |
+
y-coordinates of the sample points. Several data sets of sample
|
| 1307 |
+
points sharing the same x-coordinates can be fitted at once by
|
| 1308 |
+
passing in a 2D-array that contains one dataset per column.
|
| 1309 |
+
deg : int or 1-D array_like
|
| 1310 |
+
Degree(s) of the fitting polynomials. If `deg` is a single integer
|
| 1311 |
+
all terms up to and including the `deg`'th term are included in the
|
| 1312 |
+
fit. For NumPy versions >= 1.11.0 a list of integers specifying the
|
| 1313 |
+
degrees of the terms to include may be used instead.
|
| 1314 |
+
rcond : float, optional
|
| 1315 |
+
Relative condition number of the fit. Singular values smaller than
|
| 1316 |
+
this relative to the largest singular value will be ignored. The
|
| 1317 |
+
default value is len(x)*eps, where eps is the relative precision of
|
| 1318 |
+
the float type, about 2e-16 in most cases.
|
| 1319 |
+
full : bool, optional
|
| 1320 |
+
Switch determining nature of return value. When it is False (the
|
| 1321 |
+
default) just the coefficients are returned, when True diagnostic
|
| 1322 |
+
information from the singular value decomposition is also returned.
|
| 1323 |
+
w : array_like, shape (`M`,), optional
|
| 1324 |
+
Weights. If not None, the weight ``w[i]`` applies to the unsquared
|
| 1325 |
+
residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
|
| 1326 |
+
chosen so that the errors of the products ``w[i]*y[i]`` all have the
|
| 1327 |
+
same variance. When using inverse-variance weighting, use
|
| 1328 |
+
``w[i] = 1/sigma(y[i])``. The default value is None.
|
| 1329 |
+
|
| 1330 |
+
.. versionadded:: 1.5.0
|
| 1331 |
+
|
| 1332 |
+
Returns
|
| 1333 |
+
-------
|
| 1334 |
+
coef : ndarray, shape (M,) or (M, K)
|
| 1335 |
+
Legendre coefficients ordered from low to high. If `y` was
|
| 1336 |
+
2-D, the coefficients for the data in column k of `y` are in
|
| 1337 |
+
column `k`. If `deg` is specified as a list, coefficients for
|
| 1338 |
+
terms not included in the fit are set equal to zero in the
|
| 1339 |
+
returned `coef`.
|
| 1340 |
+
|
| 1341 |
+
[residuals, rank, singular_values, rcond] : list
|
| 1342 |
+
These values are only returned if ``full == True``
|
| 1343 |
+
|
| 1344 |
+
- residuals -- sum of squared residuals of the least squares fit
|
| 1345 |
+
- rank -- the numerical rank of the scaled Vandermonde matrix
|
| 1346 |
+
- singular_values -- singular values of the scaled Vandermonde matrix
|
| 1347 |
+
- rcond -- value of `rcond`.
|
| 1348 |
+
|
| 1349 |
+
For more details, see `numpy.linalg.lstsq`.
|
| 1350 |
+
|
| 1351 |
+
Warns
|
| 1352 |
+
-----
|
| 1353 |
+
RankWarning
|
| 1354 |
+
The rank of the coefficient matrix in the least-squares fit is
|
| 1355 |
+
deficient. The warning is only raised if ``full == False``. The
|
| 1356 |
+
warnings can be turned off by
|
| 1357 |
+
|
| 1358 |
+
>>> import warnings
|
| 1359 |
+
>>> warnings.simplefilter('ignore', np.RankWarning)
|
| 1360 |
+
|
| 1361 |
+
See Also
|
| 1362 |
+
--------
|
| 1363 |
+
numpy.polynomial.polynomial.polyfit
|
| 1364 |
+
numpy.polynomial.chebyshev.chebfit
|
| 1365 |
+
numpy.polynomial.laguerre.lagfit
|
| 1366 |
+
numpy.polynomial.hermite.hermfit
|
| 1367 |
+
numpy.polynomial.hermite_e.hermefit
|
| 1368 |
+
legval : Evaluates a Legendre series.
|
| 1369 |
+
legvander : Vandermonde matrix of Legendre series.
|
| 1370 |
+
legweight : Legendre weight function (= 1).
|
| 1371 |
+
numpy.linalg.lstsq : Computes a least-squares fit from the matrix.
|
| 1372 |
+
scipy.interpolate.UnivariateSpline : Computes spline fits.
|
| 1373 |
+
|
| 1374 |
+
Notes
|
| 1375 |
+
-----
|
| 1376 |
+
The solution is the coefficients of the Legendre series `p` that
|
| 1377 |
+
minimizes the sum of the weighted squared errors
|
| 1378 |
+
|
| 1379 |
+
.. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
|
| 1380 |
+
|
| 1381 |
+
where :math:`w_j` are the weights. This problem is solved by setting up
|
| 1382 |
+
as the (typically) overdetermined matrix equation
|
| 1383 |
+
|
| 1384 |
+
.. math:: V(x) * c = w * y,
|
| 1385 |
+
|
| 1386 |
+
where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
|
| 1387 |
+
coefficients to be solved for, `w` are the weights, and `y` are the
|
| 1388 |
+
observed values. This equation is then solved using the singular value
|
| 1389 |
+
decomposition of `V`.
|
| 1390 |
+
|
| 1391 |
+
If some of the singular values of `V` are so small that they are
|
| 1392 |
+
neglected, then a `RankWarning` will be issued. This means that the
|
| 1393 |
+
coefficient values may be poorly determined. Using a lower order fit
|
| 1394 |
+
will usually get rid of the warning. The `rcond` parameter can also be
|
| 1395 |
+
set to a value smaller than its default, but the resulting fit may be
|
| 1396 |
+
spurious and have large contributions from roundoff error.
|
| 1397 |
+
|
| 1398 |
+
Fits using Legendre series are usually better conditioned than fits
|
| 1399 |
+
using power series, but much can depend on the distribution of the
|
| 1400 |
+
sample points and the smoothness of the data. If the quality of the fit
|
| 1401 |
+
is inadequate splines may be a good alternative.
|
| 1402 |
+
|
| 1403 |
+
References
|
| 1404 |
+
----------
|
| 1405 |
+
.. [1] Wikipedia, "Curve fitting",
|
| 1406 |
+
https://en.wikipedia.org/wiki/Curve_fitting
|
| 1407 |
+
|
| 1408 |
+
Examples
|
| 1409 |
+
--------
|
| 1410 |
+
|
| 1411 |
+
"""
|
| 1412 |
+
return pu._fit(legvander, x, y, deg, rcond, full, w)
|
| 1413 |
+
|
| 1414 |
+
|
| 1415 |
+
def legcompanion(c):
|
| 1416 |
+
"""Return the scaled companion matrix of c.
|
| 1417 |
+
|
| 1418 |
+
The basis polynomials are scaled so that the companion matrix is
|
| 1419 |
+
symmetric when `c` is an Legendre basis polynomial. This provides
|
| 1420 |
+
better eigenvalue estimates than the unscaled case and for basis
|
| 1421 |
+
polynomials the eigenvalues are guaranteed to be real if
|
| 1422 |
+
`numpy.linalg.eigvalsh` is used to obtain them.
|
| 1423 |
+
|
| 1424 |
+
Parameters
|
| 1425 |
+
----------
|
| 1426 |
+
c : array_like
|
| 1427 |
+
1-D array of Legendre series coefficients ordered from low to high
|
| 1428 |
+
degree.
|
| 1429 |
+
|
| 1430 |
+
Returns
|
| 1431 |
+
-------
|
| 1432 |
+
mat : ndarray
|
| 1433 |
+
Scaled companion matrix of dimensions (deg, deg).
|
| 1434 |
+
|
| 1435 |
+
Notes
|
| 1436 |
+
-----
|
| 1437 |
+
|
| 1438 |
+
.. versionadded:: 1.7.0
|
| 1439 |
+
|
| 1440 |
+
"""
|
| 1441 |
+
# c is a trimmed copy
|
| 1442 |
+
[c] = pu.as_series([c])
|
| 1443 |
+
if len(c) < 2:
|
| 1444 |
+
raise ValueError('Series must have maximum degree of at least 1.')
|
| 1445 |
+
if len(c) == 2:
|
| 1446 |
+
return np.array([[-c[0]/c[1]]])
|
| 1447 |
+
|
| 1448 |
+
n = len(c) - 1
|
| 1449 |
+
mat = np.zeros((n, n), dtype=c.dtype)
|
| 1450 |
+
scl = 1./np.sqrt(2*np.arange(n) + 1)
|
| 1451 |
+
top = mat.reshape(-1)[1::n+1]
|
| 1452 |
+
bot = mat.reshape(-1)[n::n+1]
|
| 1453 |
+
top[...] = np.arange(1, n)*scl[:n-1]*scl[1:n]
|
| 1454 |
+
bot[...] = top
|
| 1455 |
+
mat[:, -1] -= (c[:-1]/c[-1])*(scl/scl[-1])*(n/(2*n - 1))
|
| 1456 |
+
return mat
|
| 1457 |
+
|
| 1458 |
+
|
| 1459 |
+
def legroots(c):
|
| 1460 |
+
"""
|
| 1461 |
+
Compute the roots of a Legendre series.
|
| 1462 |
+
|
| 1463 |
+
Return the roots (a.k.a. "zeros") of the polynomial
|
| 1464 |
+
|
| 1465 |
+
.. math:: p(x) = \\sum_i c[i] * L_i(x).
|
| 1466 |
+
|
| 1467 |
+
Parameters
|
| 1468 |
+
----------
|
| 1469 |
+
c : 1-D array_like
|
| 1470 |
+
1-D array of coefficients.
|
| 1471 |
+
|
| 1472 |
+
Returns
|
| 1473 |
+
-------
|
| 1474 |
+
out : ndarray
|
| 1475 |
+
Array of the roots of the series. If all the roots are real,
|
| 1476 |
+
then `out` is also real, otherwise it is complex.
|
| 1477 |
+
|
| 1478 |
+
See Also
|
| 1479 |
+
--------
|
| 1480 |
+
numpy.polynomial.polynomial.polyroots
|
| 1481 |
+
numpy.polynomial.chebyshev.chebroots
|
| 1482 |
+
numpy.polynomial.laguerre.lagroots
|
| 1483 |
+
numpy.polynomial.hermite.hermroots
|
| 1484 |
+
numpy.polynomial.hermite_e.hermeroots
|
| 1485 |
+
|
| 1486 |
+
Notes
|
| 1487 |
+
-----
|
| 1488 |
+
The root estimates are obtained as the eigenvalues of the companion
|
| 1489 |
+
matrix, Roots far from the origin of the complex plane may have large
|
| 1490 |
+
errors due to the numerical instability of the series for such values.
|
| 1491 |
+
Roots with multiplicity greater than 1 will also show larger errors as
|
| 1492 |
+
the value of the series near such points is relatively insensitive to
|
| 1493 |
+
errors in the roots. Isolated roots near the origin can be improved by
|
| 1494 |
+
a few iterations of Newton's method.
|
| 1495 |
+
|
| 1496 |
+
The Legendre series basis polynomials aren't powers of ``x`` so the
|
| 1497 |
+
results of this function may seem unintuitive.
|
| 1498 |
+
|
| 1499 |
+
Examples
|
| 1500 |
+
--------
|
| 1501 |
+
>>> import numpy.polynomial.legendre as leg
|
| 1502 |
+
>>> leg.legroots((1, 2, 3, 4)) # 4L_3 + 3L_2 + 2L_1 + 1L_0, all real roots
|
| 1503 |
+
array([-0.85099543, -0.11407192, 0.51506735]) # may vary
|
| 1504 |
+
|
| 1505 |
+
"""
|
| 1506 |
+
# c is a trimmed copy
|
| 1507 |
+
[c] = pu.as_series([c])
|
| 1508 |
+
if len(c) < 2:
|
| 1509 |
+
return np.array([], dtype=c.dtype)
|
| 1510 |
+
if len(c) == 2:
|
| 1511 |
+
return np.array([-c[0]/c[1]])
|
| 1512 |
+
|
| 1513 |
+
# rotated companion matrix reduces error
|
| 1514 |
+
m = legcompanion(c)[::-1,::-1]
|
| 1515 |
+
r = la.eigvals(m)
|
| 1516 |
+
r.sort()
|
| 1517 |
+
return r
|
| 1518 |
+
|
| 1519 |
+
|
| 1520 |
+
def leggauss(deg):
|
| 1521 |
+
"""
|
| 1522 |
+
Gauss-Legendre quadrature.
|
| 1523 |
+
|
| 1524 |
+
Computes the sample points and weights for Gauss-Legendre quadrature.
|
| 1525 |
+
These sample points and weights will correctly integrate polynomials of
|
| 1526 |
+
degree :math:`2*deg - 1` or less over the interval :math:`[-1, 1]` with
|
| 1527 |
+
the weight function :math:`f(x) = 1`.
|
| 1528 |
+
|
| 1529 |
+
Parameters
|
| 1530 |
+
----------
|
| 1531 |
+
deg : int
|
| 1532 |
+
Number of sample points and weights. It must be >= 1.
|
| 1533 |
+
|
| 1534 |
+
Returns
|
| 1535 |
+
-------
|
| 1536 |
+
x : ndarray
|
| 1537 |
+
1-D ndarray containing the sample points.
|
| 1538 |
+
y : ndarray
|
| 1539 |
+
1-D ndarray containing the weights.
|
| 1540 |
+
|
| 1541 |
+
Notes
|
| 1542 |
+
-----
|
| 1543 |
+
|
| 1544 |
+
.. versionadded:: 1.7.0
|
| 1545 |
+
|
| 1546 |
+
The results have only been tested up to degree 100, higher degrees may
|
| 1547 |
+
be problematic. The weights are determined by using the fact that
|
| 1548 |
+
|
| 1549 |
+
.. math:: w_k = c / (L'_n(x_k) * L_{n-1}(x_k))
|
| 1550 |
+
|
| 1551 |
+
where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
|
| 1552 |
+
is the k'th root of :math:`L_n`, and then scaling the results to get
|
| 1553 |
+
the right value when integrating 1.
|
| 1554 |
+
|
| 1555 |
+
"""
|
| 1556 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1557 |
+
if ideg <= 0:
|
| 1558 |
+
raise ValueError("deg must be a positive integer")
|
| 1559 |
+
|
| 1560 |
+
# first approximation of roots. We use the fact that the companion
|
| 1561 |
+
# matrix is symmetric in this case in order to obtain better zeros.
|
| 1562 |
+
c = np.array([0]*deg + [1])
|
| 1563 |
+
m = legcompanion(c)
|
| 1564 |
+
x = la.eigvalsh(m)
|
| 1565 |
+
|
| 1566 |
+
# improve roots by one application of Newton
|
| 1567 |
+
dy = legval(x, c)
|
| 1568 |
+
df = legval(x, legder(c))
|
| 1569 |
+
x -= dy/df
|
| 1570 |
+
|
| 1571 |
+
# compute the weights. We scale the factor to avoid possible numerical
|
| 1572 |
+
# overflow.
|
| 1573 |
+
fm = legval(x, c[1:])
|
| 1574 |
+
fm /= np.abs(fm).max()
|
| 1575 |
+
df /= np.abs(df).max()
|
| 1576 |
+
w = 1/(fm * df)
|
| 1577 |
+
|
| 1578 |
+
# for Legendre we can also symmetrize
|
| 1579 |
+
w = (w + w[::-1])/2
|
| 1580 |
+
x = (x - x[::-1])/2
|
| 1581 |
+
|
| 1582 |
+
# scale w to get the right value
|
| 1583 |
+
w *= 2. / w.sum()
|
| 1584 |
+
|
| 1585 |
+
return x, w
|
| 1586 |
+
|
| 1587 |
+
|
| 1588 |
+
def legweight(x):
|
| 1589 |
+
"""
|
| 1590 |
+
Weight function of the Legendre polynomials.
|
| 1591 |
+
|
| 1592 |
+
The weight function is :math:`1` and the interval of integration is
|
| 1593 |
+
:math:`[-1, 1]`. The Legendre polynomials are orthogonal, but not
|
| 1594 |
+
normalized, with respect to this weight function.
|
| 1595 |
+
|
| 1596 |
+
Parameters
|
| 1597 |
+
----------
|
| 1598 |
+
x : array_like
|
| 1599 |
+
Values at which the weight function will be computed.
|
| 1600 |
+
|
| 1601 |
+
Returns
|
| 1602 |
+
-------
|
| 1603 |
+
w : ndarray
|
| 1604 |
+
The weight function at `x`.
|
| 1605 |
+
|
| 1606 |
+
Notes
|
| 1607 |
+
-----
|
| 1608 |
+
|
| 1609 |
+
.. versionadded:: 1.7.0
|
| 1610 |
+
|
| 1611 |
+
"""
|
| 1612 |
+
w = x*0.0 + 1.0
|
| 1613 |
+
return w
|
| 1614 |
+
|
| 1615 |
+
#
|
| 1616 |
+
# Legendre series class
|
| 1617 |
+
#
|
| 1618 |
+
|
| 1619 |
+
class Legendre(ABCPolyBase):
|
| 1620 |
+
"""A Legendre series class.
|
| 1621 |
+
|
| 1622 |
+
The Legendre class provides the standard Python numerical methods
|
| 1623 |
+
'+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
|
| 1624 |
+
attributes and methods listed in the `ABCPolyBase` documentation.
|
| 1625 |
+
|
| 1626 |
+
Parameters
|
| 1627 |
+
----------
|
| 1628 |
+
coef : array_like
|
| 1629 |
+
Legendre coefficients in order of increasing degree, i.e.,
|
| 1630 |
+
``(1, 2, 3)`` gives ``1*P_0(x) + 2*P_1(x) + 3*P_2(x)``.
|
| 1631 |
+
domain : (2,) array_like, optional
|
| 1632 |
+
Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
|
| 1633 |
+
to the interval ``[window[0], window[1]]`` by shifting and scaling.
|
| 1634 |
+
The default value is [-1, 1].
|
| 1635 |
+
window : (2,) array_like, optional
|
| 1636 |
+
Window, see `domain` for its use. The default value is [-1, 1].
|
| 1637 |
+
|
| 1638 |
+
.. versionadded:: 1.6.0
|
| 1639 |
+
symbol : str, optional
|
| 1640 |
+
Symbol used to represent the independent variable in string
|
| 1641 |
+
representations of the polynomial expression, e.g. for printing.
|
| 1642 |
+
The symbol must be a valid Python identifier. Default value is 'x'.
|
| 1643 |
+
|
| 1644 |
+
.. versionadded:: 1.24
|
| 1645 |
+
|
| 1646 |
+
"""
|
| 1647 |
+
# Virtual Functions
|
| 1648 |
+
_add = staticmethod(legadd)
|
| 1649 |
+
_sub = staticmethod(legsub)
|
| 1650 |
+
_mul = staticmethod(legmul)
|
| 1651 |
+
_div = staticmethod(legdiv)
|
| 1652 |
+
_pow = staticmethod(legpow)
|
| 1653 |
+
_val = staticmethod(legval)
|
| 1654 |
+
_int = staticmethod(legint)
|
| 1655 |
+
_der = staticmethod(legder)
|
| 1656 |
+
_fit = staticmethod(legfit)
|
| 1657 |
+
_line = staticmethod(legline)
|
| 1658 |
+
_roots = staticmethod(legroots)
|
| 1659 |
+
_fromroots = staticmethod(legfromroots)
|
| 1660 |
+
|
| 1661 |
+
# Virtual properties
|
| 1662 |
+
domain = np.array(legdomain)
|
| 1663 |
+
window = np.array(legdomain)
|
| 1664 |
+
basis_name = 'P'
|
lib/python3.12/site-packages/numpy/polynomial/legendre.pyi
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any
|
| 2 |
+
|
| 3 |
+
from numpy import ndarray, dtype, int_
|
| 4 |
+
from numpy.polynomial._polybase import ABCPolyBase
|
| 5 |
+
from numpy.polynomial.polyutils import trimcoef
|
| 6 |
+
|
| 7 |
+
__all__: list[str]
|
| 8 |
+
|
| 9 |
+
legtrim = trimcoef
|
| 10 |
+
|
| 11 |
+
def poly2leg(pol): ...
|
| 12 |
+
def leg2poly(c): ...
|
| 13 |
+
|
| 14 |
+
legdomain: ndarray[Any, dtype[int_]]
|
| 15 |
+
legzero: ndarray[Any, dtype[int_]]
|
| 16 |
+
legone: ndarray[Any, dtype[int_]]
|
| 17 |
+
legx: ndarray[Any, dtype[int_]]
|
| 18 |
+
|
| 19 |
+
def legline(off, scl): ...
|
| 20 |
+
def legfromroots(roots): ...
|
| 21 |
+
def legadd(c1, c2): ...
|
| 22 |
+
def legsub(c1, c2): ...
|
| 23 |
+
def legmulx(c): ...
|
| 24 |
+
def legmul(c1, c2): ...
|
| 25 |
+
def legdiv(c1, c2): ...
|
| 26 |
+
def legpow(c, pow, maxpower=...): ...
|
| 27 |
+
def legder(c, m=..., scl=..., axis=...): ...
|
| 28 |
+
def legint(c, m=..., k = ..., lbnd=..., scl=..., axis=...): ...
|
| 29 |
+
def legval(x, c, tensor=...): ...
|
| 30 |
+
def legval2d(x, y, c): ...
|
| 31 |
+
def leggrid2d(x, y, c): ...
|
| 32 |
+
def legval3d(x, y, z, c): ...
|
| 33 |
+
def leggrid3d(x, y, z, c): ...
|
| 34 |
+
def legvander(x, deg): ...
|
| 35 |
+
def legvander2d(x, y, deg): ...
|
| 36 |
+
def legvander3d(x, y, z, deg): ...
|
| 37 |
+
def legfit(x, y, deg, rcond=..., full=..., w=...): ...
|
| 38 |
+
def legcompanion(c): ...
|
| 39 |
+
def legroots(c): ...
|
| 40 |
+
def leggauss(deg): ...
|
| 41 |
+
def legweight(x): ...
|
| 42 |
+
|
| 43 |
+
class Legendre(ABCPolyBase):
|
| 44 |
+
domain: Any
|
| 45 |
+
window: Any
|
| 46 |
+
basis_name: Any
|
lib/python3.12/site-packages/numpy/polynomial/polynomial.py
ADDED
|
@@ -0,0 +1,1542 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
=================================================
|
| 3 |
+
Power Series (:mod:`numpy.polynomial.polynomial`)
|
| 4 |
+
=================================================
|
| 5 |
+
|
| 6 |
+
This module provides a number of objects (mostly functions) useful for
|
| 7 |
+
dealing with polynomials, including a `Polynomial` class that
|
| 8 |
+
encapsulates the usual arithmetic operations. (General information
|
| 9 |
+
on how this module represents and works with polynomial objects is in
|
| 10 |
+
the docstring for its "parent" sub-package, `numpy.polynomial`).
|
| 11 |
+
|
| 12 |
+
Classes
|
| 13 |
+
-------
|
| 14 |
+
.. autosummary::
|
| 15 |
+
:toctree: generated/
|
| 16 |
+
|
| 17 |
+
Polynomial
|
| 18 |
+
|
| 19 |
+
Constants
|
| 20 |
+
---------
|
| 21 |
+
.. autosummary::
|
| 22 |
+
:toctree: generated/
|
| 23 |
+
|
| 24 |
+
polydomain
|
| 25 |
+
polyzero
|
| 26 |
+
polyone
|
| 27 |
+
polyx
|
| 28 |
+
|
| 29 |
+
Arithmetic
|
| 30 |
+
----------
|
| 31 |
+
.. autosummary::
|
| 32 |
+
:toctree: generated/
|
| 33 |
+
|
| 34 |
+
polyadd
|
| 35 |
+
polysub
|
| 36 |
+
polymulx
|
| 37 |
+
polymul
|
| 38 |
+
polydiv
|
| 39 |
+
polypow
|
| 40 |
+
polyval
|
| 41 |
+
polyval2d
|
| 42 |
+
polyval3d
|
| 43 |
+
polygrid2d
|
| 44 |
+
polygrid3d
|
| 45 |
+
|
| 46 |
+
Calculus
|
| 47 |
+
--------
|
| 48 |
+
.. autosummary::
|
| 49 |
+
:toctree: generated/
|
| 50 |
+
|
| 51 |
+
polyder
|
| 52 |
+
polyint
|
| 53 |
+
|
| 54 |
+
Misc Functions
|
| 55 |
+
--------------
|
| 56 |
+
.. autosummary::
|
| 57 |
+
:toctree: generated/
|
| 58 |
+
|
| 59 |
+
polyfromroots
|
| 60 |
+
polyroots
|
| 61 |
+
polyvalfromroots
|
| 62 |
+
polyvander
|
| 63 |
+
polyvander2d
|
| 64 |
+
polyvander3d
|
| 65 |
+
polycompanion
|
| 66 |
+
polyfit
|
| 67 |
+
polytrim
|
| 68 |
+
polyline
|
| 69 |
+
|
| 70 |
+
See Also
|
| 71 |
+
--------
|
| 72 |
+
`numpy.polynomial`
|
| 73 |
+
|
| 74 |
+
"""
|
| 75 |
+
__all__ = [
|
| 76 |
+
'polyzero', 'polyone', 'polyx', 'polydomain', 'polyline', 'polyadd',
|
| 77 |
+
'polysub', 'polymulx', 'polymul', 'polydiv', 'polypow', 'polyval',
|
| 78 |
+
'polyvalfromroots', 'polyder', 'polyint', 'polyfromroots', 'polyvander',
|
| 79 |
+
'polyfit', 'polytrim', 'polyroots', 'Polynomial', 'polyval2d', 'polyval3d',
|
| 80 |
+
'polygrid2d', 'polygrid3d', 'polyvander2d', 'polyvander3d']
|
| 81 |
+
|
| 82 |
+
import numpy as np
|
| 83 |
+
import numpy.linalg as la
|
| 84 |
+
from numpy.core.multiarray import normalize_axis_index
|
| 85 |
+
|
| 86 |
+
from . import polyutils as pu
|
| 87 |
+
from ._polybase import ABCPolyBase
|
| 88 |
+
|
| 89 |
+
polytrim = pu.trimcoef
|
| 90 |
+
|
| 91 |
+
#
|
| 92 |
+
# These are constant arrays are of integer type so as to be compatible
|
| 93 |
+
# with the widest range of other types, such as Decimal.
|
| 94 |
+
#
|
| 95 |
+
|
| 96 |
+
# Polynomial default domain.
|
| 97 |
+
polydomain = np.array([-1, 1])
|
| 98 |
+
|
| 99 |
+
# Polynomial coefficients representing zero.
|
| 100 |
+
polyzero = np.array([0])
|
| 101 |
+
|
| 102 |
+
# Polynomial coefficients representing one.
|
| 103 |
+
polyone = np.array([1])
|
| 104 |
+
|
| 105 |
+
# Polynomial coefficients representing the identity x.
|
| 106 |
+
polyx = np.array([0, 1])
|
| 107 |
+
|
| 108 |
+
#
|
| 109 |
+
# Polynomial series functions
|
| 110 |
+
#
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
def polyline(off, scl):
|
| 114 |
+
"""
|
| 115 |
+
Returns an array representing a linear polynomial.
|
| 116 |
+
|
| 117 |
+
Parameters
|
| 118 |
+
----------
|
| 119 |
+
off, scl : scalars
|
| 120 |
+
The "y-intercept" and "slope" of the line, respectively.
|
| 121 |
+
|
| 122 |
+
Returns
|
| 123 |
+
-------
|
| 124 |
+
y : ndarray
|
| 125 |
+
This module's representation of the linear polynomial ``off +
|
| 126 |
+
scl*x``.
|
| 127 |
+
|
| 128 |
+
See Also
|
| 129 |
+
--------
|
| 130 |
+
numpy.polynomial.chebyshev.chebline
|
| 131 |
+
numpy.polynomial.legendre.legline
|
| 132 |
+
numpy.polynomial.laguerre.lagline
|
| 133 |
+
numpy.polynomial.hermite.hermline
|
| 134 |
+
numpy.polynomial.hermite_e.hermeline
|
| 135 |
+
|
| 136 |
+
Examples
|
| 137 |
+
--------
|
| 138 |
+
>>> from numpy.polynomial import polynomial as P
|
| 139 |
+
>>> P.polyline(1,-1)
|
| 140 |
+
array([ 1, -1])
|
| 141 |
+
>>> P.polyval(1, P.polyline(1,-1)) # should be 0
|
| 142 |
+
0.0
|
| 143 |
+
|
| 144 |
+
"""
|
| 145 |
+
if scl != 0:
|
| 146 |
+
return np.array([off, scl])
|
| 147 |
+
else:
|
| 148 |
+
return np.array([off])
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
def polyfromroots(roots):
|
| 152 |
+
"""
|
| 153 |
+
Generate a monic polynomial with given roots.
|
| 154 |
+
|
| 155 |
+
Return the coefficients of the polynomial
|
| 156 |
+
|
| 157 |
+
.. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
|
| 158 |
+
|
| 159 |
+
where the ``r_n`` are the roots specified in `roots`. If a zero has
|
| 160 |
+
multiplicity n, then it must appear in `roots` n times. For instance,
|
| 161 |
+
if 2 is a root of multiplicity three and 3 is a root of multiplicity 2,
|
| 162 |
+
then `roots` looks something like [2, 2, 2, 3, 3]. The roots can appear
|
| 163 |
+
in any order.
|
| 164 |
+
|
| 165 |
+
If the returned coefficients are `c`, then
|
| 166 |
+
|
| 167 |
+
.. math:: p(x) = c_0 + c_1 * x + ... + x^n
|
| 168 |
+
|
| 169 |
+
The coefficient of the last term is 1 for monic polynomials in this
|
| 170 |
+
form.
|
| 171 |
+
|
| 172 |
+
Parameters
|
| 173 |
+
----------
|
| 174 |
+
roots : array_like
|
| 175 |
+
Sequence containing the roots.
|
| 176 |
+
|
| 177 |
+
Returns
|
| 178 |
+
-------
|
| 179 |
+
out : ndarray
|
| 180 |
+
1-D array of the polynomial's coefficients If all the roots are
|
| 181 |
+
real, then `out` is also real, otherwise it is complex. (see
|
| 182 |
+
Examples below).
|
| 183 |
+
|
| 184 |
+
See Also
|
| 185 |
+
--------
|
| 186 |
+
numpy.polynomial.chebyshev.chebfromroots
|
| 187 |
+
numpy.polynomial.legendre.legfromroots
|
| 188 |
+
numpy.polynomial.laguerre.lagfromroots
|
| 189 |
+
numpy.polynomial.hermite.hermfromroots
|
| 190 |
+
numpy.polynomial.hermite_e.hermefromroots
|
| 191 |
+
|
| 192 |
+
Notes
|
| 193 |
+
-----
|
| 194 |
+
The coefficients are determined by multiplying together linear factors
|
| 195 |
+
of the form ``(x - r_i)``, i.e.
|
| 196 |
+
|
| 197 |
+
.. math:: p(x) = (x - r_0) (x - r_1) ... (x - r_n)
|
| 198 |
+
|
| 199 |
+
where ``n == len(roots) - 1``; note that this implies that ``1`` is always
|
| 200 |
+
returned for :math:`a_n`.
|
| 201 |
+
|
| 202 |
+
Examples
|
| 203 |
+
--------
|
| 204 |
+
>>> from numpy.polynomial import polynomial as P
|
| 205 |
+
>>> P.polyfromroots((-1,0,1)) # x(x - 1)(x + 1) = x^3 - x
|
| 206 |
+
array([ 0., -1., 0., 1.])
|
| 207 |
+
>>> j = complex(0,1)
|
| 208 |
+
>>> P.polyfromroots((-j,j)) # complex returned, though values are real
|
| 209 |
+
array([1.+0.j, 0.+0.j, 1.+0.j])
|
| 210 |
+
|
| 211 |
+
"""
|
| 212 |
+
return pu._fromroots(polyline, polymul, roots)
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
def polyadd(c1, c2):
|
| 216 |
+
"""
|
| 217 |
+
Add one polynomial to another.
|
| 218 |
+
|
| 219 |
+
Returns the sum of two polynomials `c1` + `c2`. The arguments are
|
| 220 |
+
sequences of coefficients from lowest order term to highest, i.e.,
|
| 221 |
+
[1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``.
|
| 222 |
+
|
| 223 |
+
Parameters
|
| 224 |
+
----------
|
| 225 |
+
c1, c2 : array_like
|
| 226 |
+
1-D arrays of polynomial coefficients ordered from low to high.
|
| 227 |
+
|
| 228 |
+
Returns
|
| 229 |
+
-------
|
| 230 |
+
out : ndarray
|
| 231 |
+
The coefficient array representing their sum.
|
| 232 |
+
|
| 233 |
+
See Also
|
| 234 |
+
--------
|
| 235 |
+
polysub, polymulx, polymul, polydiv, polypow
|
| 236 |
+
|
| 237 |
+
Examples
|
| 238 |
+
--------
|
| 239 |
+
>>> from numpy.polynomial import polynomial as P
|
| 240 |
+
>>> c1 = (1,2,3)
|
| 241 |
+
>>> c2 = (3,2,1)
|
| 242 |
+
>>> sum = P.polyadd(c1,c2); sum
|
| 243 |
+
array([4., 4., 4.])
|
| 244 |
+
>>> P.polyval(2, sum) # 4 + 4(2) + 4(2**2)
|
| 245 |
+
28.0
|
| 246 |
+
|
| 247 |
+
"""
|
| 248 |
+
return pu._add(c1, c2)
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
def polysub(c1, c2):
|
| 252 |
+
"""
|
| 253 |
+
Subtract one polynomial from another.
|
| 254 |
+
|
| 255 |
+
Returns the difference of two polynomials `c1` - `c2`. The arguments
|
| 256 |
+
are sequences of coefficients from lowest order term to highest, i.e.,
|
| 257 |
+
[1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``.
|
| 258 |
+
|
| 259 |
+
Parameters
|
| 260 |
+
----------
|
| 261 |
+
c1, c2 : array_like
|
| 262 |
+
1-D arrays of polynomial coefficients ordered from low to
|
| 263 |
+
high.
|
| 264 |
+
|
| 265 |
+
Returns
|
| 266 |
+
-------
|
| 267 |
+
out : ndarray
|
| 268 |
+
Of coefficients representing their difference.
|
| 269 |
+
|
| 270 |
+
See Also
|
| 271 |
+
--------
|
| 272 |
+
polyadd, polymulx, polymul, polydiv, polypow
|
| 273 |
+
|
| 274 |
+
Examples
|
| 275 |
+
--------
|
| 276 |
+
>>> from numpy.polynomial import polynomial as P
|
| 277 |
+
>>> c1 = (1,2,3)
|
| 278 |
+
>>> c2 = (3,2,1)
|
| 279 |
+
>>> P.polysub(c1,c2)
|
| 280 |
+
array([-2., 0., 2.])
|
| 281 |
+
>>> P.polysub(c2,c1) # -P.polysub(c1,c2)
|
| 282 |
+
array([ 2., 0., -2.])
|
| 283 |
+
|
| 284 |
+
"""
|
| 285 |
+
return pu._sub(c1, c2)
|
| 286 |
+
|
| 287 |
+
|
| 288 |
+
def polymulx(c):
|
| 289 |
+
"""Multiply a polynomial by x.
|
| 290 |
+
|
| 291 |
+
Multiply the polynomial `c` by x, where x is the independent
|
| 292 |
+
variable.
|
| 293 |
+
|
| 294 |
+
|
| 295 |
+
Parameters
|
| 296 |
+
----------
|
| 297 |
+
c : array_like
|
| 298 |
+
1-D array of polynomial coefficients ordered from low to
|
| 299 |
+
high.
|
| 300 |
+
|
| 301 |
+
Returns
|
| 302 |
+
-------
|
| 303 |
+
out : ndarray
|
| 304 |
+
Array representing the result of the multiplication.
|
| 305 |
+
|
| 306 |
+
See Also
|
| 307 |
+
--------
|
| 308 |
+
polyadd, polysub, polymul, polydiv, polypow
|
| 309 |
+
|
| 310 |
+
Notes
|
| 311 |
+
-----
|
| 312 |
+
|
| 313 |
+
.. versionadded:: 1.5.0
|
| 314 |
+
|
| 315 |
+
"""
|
| 316 |
+
# c is a trimmed copy
|
| 317 |
+
[c] = pu.as_series([c])
|
| 318 |
+
# The zero series needs special treatment
|
| 319 |
+
if len(c) == 1 and c[0] == 0:
|
| 320 |
+
return c
|
| 321 |
+
|
| 322 |
+
prd = np.empty(len(c) + 1, dtype=c.dtype)
|
| 323 |
+
prd[0] = c[0]*0
|
| 324 |
+
prd[1:] = c
|
| 325 |
+
return prd
|
| 326 |
+
|
| 327 |
+
|
| 328 |
+
def polymul(c1, c2):
|
| 329 |
+
"""
|
| 330 |
+
Multiply one polynomial by another.
|
| 331 |
+
|
| 332 |
+
Returns the product of two polynomials `c1` * `c2`. The arguments are
|
| 333 |
+
sequences of coefficients, from lowest order term to highest, e.g.,
|
| 334 |
+
[1,2,3] represents the polynomial ``1 + 2*x + 3*x**2.``
|
| 335 |
+
|
| 336 |
+
Parameters
|
| 337 |
+
----------
|
| 338 |
+
c1, c2 : array_like
|
| 339 |
+
1-D arrays of coefficients representing a polynomial, relative to the
|
| 340 |
+
"standard" basis, and ordered from lowest order term to highest.
|
| 341 |
+
|
| 342 |
+
Returns
|
| 343 |
+
-------
|
| 344 |
+
out : ndarray
|
| 345 |
+
Of the coefficients of their product.
|
| 346 |
+
|
| 347 |
+
See Also
|
| 348 |
+
--------
|
| 349 |
+
polyadd, polysub, polymulx, polydiv, polypow
|
| 350 |
+
|
| 351 |
+
Examples
|
| 352 |
+
--------
|
| 353 |
+
>>> from numpy.polynomial import polynomial as P
|
| 354 |
+
>>> c1 = (1,2,3)
|
| 355 |
+
>>> c2 = (3,2,1)
|
| 356 |
+
>>> P.polymul(c1,c2)
|
| 357 |
+
array([ 3., 8., 14., 8., 3.])
|
| 358 |
+
|
| 359 |
+
"""
|
| 360 |
+
# c1, c2 are trimmed copies
|
| 361 |
+
[c1, c2] = pu.as_series([c1, c2])
|
| 362 |
+
ret = np.convolve(c1, c2)
|
| 363 |
+
return pu.trimseq(ret)
|
| 364 |
+
|
| 365 |
+
|
| 366 |
+
def polydiv(c1, c2):
|
| 367 |
+
"""
|
| 368 |
+
Divide one polynomial by another.
|
| 369 |
+
|
| 370 |
+
Returns the quotient-with-remainder of two polynomials `c1` / `c2`.
|
| 371 |
+
The arguments are sequences of coefficients, from lowest order term
|
| 372 |
+
to highest, e.g., [1,2,3] represents ``1 + 2*x + 3*x**2``.
|
| 373 |
+
|
| 374 |
+
Parameters
|
| 375 |
+
----------
|
| 376 |
+
c1, c2 : array_like
|
| 377 |
+
1-D arrays of polynomial coefficients ordered from low to high.
|
| 378 |
+
|
| 379 |
+
Returns
|
| 380 |
+
-------
|
| 381 |
+
[quo, rem] : ndarrays
|
| 382 |
+
Of coefficient series representing the quotient and remainder.
|
| 383 |
+
|
| 384 |
+
See Also
|
| 385 |
+
--------
|
| 386 |
+
polyadd, polysub, polymulx, polymul, polypow
|
| 387 |
+
|
| 388 |
+
Examples
|
| 389 |
+
--------
|
| 390 |
+
>>> from numpy.polynomial import polynomial as P
|
| 391 |
+
>>> c1 = (1,2,3)
|
| 392 |
+
>>> c2 = (3,2,1)
|
| 393 |
+
>>> P.polydiv(c1,c2)
|
| 394 |
+
(array([3.]), array([-8., -4.]))
|
| 395 |
+
>>> P.polydiv(c2,c1)
|
| 396 |
+
(array([ 0.33333333]), array([ 2.66666667, 1.33333333])) # may vary
|
| 397 |
+
|
| 398 |
+
"""
|
| 399 |
+
# c1, c2 are trimmed copies
|
| 400 |
+
[c1, c2] = pu.as_series([c1, c2])
|
| 401 |
+
if c2[-1] == 0:
|
| 402 |
+
raise ZeroDivisionError()
|
| 403 |
+
|
| 404 |
+
# note: this is more efficient than `pu._div(polymul, c1, c2)`
|
| 405 |
+
lc1 = len(c1)
|
| 406 |
+
lc2 = len(c2)
|
| 407 |
+
if lc1 < lc2:
|
| 408 |
+
return c1[:1]*0, c1
|
| 409 |
+
elif lc2 == 1:
|
| 410 |
+
return c1/c2[-1], c1[:1]*0
|
| 411 |
+
else:
|
| 412 |
+
dlen = lc1 - lc2
|
| 413 |
+
scl = c2[-1]
|
| 414 |
+
c2 = c2[:-1]/scl
|
| 415 |
+
i = dlen
|
| 416 |
+
j = lc1 - 1
|
| 417 |
+
while i >= 0:
|
| 418 |
+
c1[i:j] -= c2*c1[j]
|
| 419 |
+
i -= 1
|
| 420 |
+
j -= 1
|
| 421 |
+
return c1[j+1:]/scl, pu.trimseq(c1[:j+1])
|
| 422 |
+
|
| 423 |
+
|
| 424 |
+
def polypow(c, pow, maxpower=None):
|
| 425 |
+
"""Raise a polynomial to a power.
|
| 426 |
+
|
| 427 |
+
Returns the polynomial `c` raised to the power `pow`. The argument
|
| 428 |
+
`c` is a sequence of coefficients ordered from low to high. i.e.,
|
| 429 |
+
[1,2,3] is the series ``1 + 2*x + 3*x**2.``
|
| 430 |
+
|
| 431 |
+
Parameters
|
| 432 |
+
----------
|
| 433 |
+
c : array_like
|
| 434 |
+
1-D array of array of series coefficients ordered from low to
|
| 435 |
+
high degree.
|
| 436 |
+
pow : integer
|
| 437 |
+
Power to which the series will be raised
|
| 438 |
+
maxpower : integer, optional
|
| 439 |
+
Maximum power allowed. This is mainly to limit growth of the series
|
| 440 |
+
to unmanageable size. Default is 16
|
| 441 |
+
|
| 442 |
+
Returns
|
| 443 |
+
-------
|
| 444 |
+
coef : ndarray
|
| 445 |
+
Power series of power.
|
| 446 |
+
|
| 447 |
+
See Also
|
| 448 |
+
--------
|
| 449 |
+
polyadd, polysub, polymulx, polymul, polydiv
|
| 450 |
+
|
| 451 |
+
Examples
|
| 452 |
+
--------
|
| 453 |
+
>>> from numpy.polynomial import polynomial as P
|
| 454 |
+
>>> P.polypow([1,2,3], 2)
|
| 455 |
+
array([ 1., 4., 10., 12., 9.])
|
| 456 |
+
|
| 457 |
+
"""
|
| 458 |
+
# note: this is more efficient than `pu._pow(polymul, c1, c2)`, as it
|
| 459 |
+
# avoids calling `as_series` repeatedly
|
| 460 |
+
return pu._pow(np.convolve, c, pow, maxpower)
|
| 461 |
+
|
| 462 |
+
|
| 463 |
+
def polyder(c, m=1, scl=1, axis=0):
|
| 464 |
+
"""
|
| 465 |
+
Differentiate a polynomial.
|
| 466 |
+
|
| 467 |
+
Returns the polynomial coefficients `c` differentiated `m` times along
|
| 468 |
+
`axis`. At each iteration the result is multiplied by `scl` (the
|
| 469 |
+
scaling factor is for use in a linear change of variable). The
|
| 470 |
+
argument `c` is an array of coefficients from low to high degree along
|
| 471 |
+
each axis, e.g., [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``
|
| 472 |
+
while [[1,2],[1,2]] represents ``1 + 1*x + 2*y + 2*x*y`` if axis=0 is
|
| 473 |
+
``x`` and axis=1 is ``y``.
|
| 474 |
+
|
| 475 |
+
Parameters
|
| 476 |
+
----------
|
| 477 |
+
c : array_like
|
| 478 |
+
Array of polynomial coefficients. If c is multidimensional the
|
| 479 |
+
different axis correspond to different variables with the degree
|
| 480 |
+
in each axis given by the corresponding index.
|
| 481 |
+
m : int, optional
|
| 482 |
+
Number of derivatives taken, must be non-negative. (Default: 1)
|
| 483 |
+
scl : scalar, optional
|
| 484 |
+
Each differentiation is multiplied by `scl`. The end result is
|
| 485 |
+
multiplication by ``scl**m``. This is for use in a linear change
|
| 486 |
+
of variable. (Default: 1)
|
| 487 |
+
axis : int, optional
|
| 488 |
+
Axis over which the derivative is taken. (Default: 0).
|
| 489 |
+
|
| 490 |
+
.. versionadded:: 1.7.0
|
| 491 |
+
|
| 492 |
+
Returns
|
| 493 |
+
-------
|
| 494 |
+
der : ndarray
|
| 495 |
+
Polynomial coefficients of the derivative.
|
| 496 |
+
|
| 497 |
+
See Also
|
| 498 |
+
--------
|
| 499 |
+
polyint
|
| 500 |
+
|
| 501 |
+
Examples
|
| 502 |
+
--------
|
| 503 |
+
>>> from numpy.polynomial import polynomial as P
|
| 504 |
+
>>> c = (1,2,3,4) # 1 + 2x + 3x**2 + 4x**3
|
| 505 |
+
>>> P.polyder(c) # (d/dx)(c) = 2 + 6x + 12x**2
|
| 506 |
+
array([ 2., 6., 12.])
|
| 507 |
+
>>> P.polyder(c,3) # (d**3/dx**3)(c) = 24
|
| 508 |
+
array([24.])
|
| 509 |
+
>>> P.polyder(c,scl=-1) # (d/d(-x))(c) = -2 - 6x - 12x**2
|
| 510 |
+
array([ -2., -6., -12.])
|
| 511 |
+
>>> P.polyder(c,2,-1) # (d**2/d(-x)**2)(c) = 6 + 24x
|
| 512 |
+
array([ 6., 24.])
|
| 513 |
+
|
| 514 |
+
"""
|
| 515 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 516 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 517 |
+
# astype fails with NA
|
| 518 |
+
c = c + 0.0
|
| 519 |
+
cdt = c.dtype
|
| 520 |
+
cnt = pu._deprecate_as_int(m, "the order of derivation")
|
| 521 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 522 |
+
if cnt < 0:
|
| 523 |
+
raise ValueError("The order of derivation must be non-negative")
|
| 524 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 525 |
+
|
| 526 |
+
if cnt == 0:
|
| 527 |
+
return c
|
| 528 |
+
|
| 529 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 530 |
+
n = len(c)
|
| 531 |
+
if cnt >= n:
|
| 532 |
+
c = c[:1]*0
|
| 533 |
+
else:
|
| 534 |
+
for i in range(cnt):
|
| 535 |
+
n = n - 1
|
| 536 |
+
c *= scl
|
| 537 |
+
der = np.empty((n,) + c.shape[1:], dtype=cdt)
|
| 538 |
+
for j in range(n, 0, -1):
|
| 539 |
+
der[j - 1] = j*c[j]
|
| 540 |
+
c = der
|
| 541 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 542 |
+
return c
|
| 543 |
+
|
| 544 |
+
|
| 545 |
+
def polyint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
|
| 546 |
+
"""
|
| 547 |
+
Integrate a polynomial.
|
| 548 |
+
|
| 549 |
+
Returns the polynomial coefficients `c` integrated `m` times from
|
| 550 |
+
`lbnd` along `axis`. At each iteration the resulting series is
|
| 551 |
+
**multiplied** by `scl` and an integration constant, `k`, is added.
|
| 552 |
+
The scaling factor is for use in a linear change of variable. ("Buyer
|
| 553 |
+
beware": note that, depending on what one is doing, one may want `scl`
|
| 554 |
+
to be the reciprocal of what one might expect; for more information,
|
| 555 |
+
see the Notes section below.) The argument `c` is an array of
|
| 556 |
+
coefficients, from low to high degree along each axis, e.g., [1,2,3]
|
| 557 |
+
represents the polynomial ``1 + 2*x + 3*x**2`` while [[1,2],[1,2]]
|
| 558 |
+
represents ``1 + 1*x + 2*y + 2*x*y`` if axis=0 is ``x`` and axis=1 is
|
| 559 |
+
``y``.
|
| 560 |
+
|
| 561 |
+
Parameters
|
| 562 |
+
----------
|
| 563 |
+
c : array_like
|
| 564 |
+
1-D array of polynomial coefficients, ordered from low to high.
|
| 565 |
+
m : int, optional
|
| 566 |
+
Order of integration, must be positive. (Default: 1)
|
| 567 |
+
k : {[], list, scalar}, optional
|
| 568 |
+
Integration constant(s). The value of the first integral at zero
|
| 569 |
+
is the first value in the list, the value of the second integral
|
| 570 |
+
at zero is the second value, etc. If ``k == []`` (the default),
|
| 571 |
+
all constants are set to zero. If ``m == 1``, a single scalar can
|
| 572 |
+
be given instead of a list.
|
| 573 |
+
lbnd : scalar, optional
|
| 574 |
+
The lower bound of the integral. (Default: 0)
|
| 575 |
+
scl : scalar, optional
|
| 576 |
+
Following each integration the result is *multiplied* by `scl`
|
| 577 |
+
before the integration constant is added. (Default: 1)
|
| 578 |
+
axis : int, optional
|
| 579 |
+
Axis over which the integral is taken. (Default: 0).
|
| 580 |
+
|
| 581 |
+
.. versionadded:: 1.7.0
|
| 582 |
+
|
| 583 |
+
Returns
|
| 584 |
+
-------
|
| 585 |
+
S : ndarray
|
| 586 |
+
Coefficient array of the integral.
|
| 587 |
+
|
| 588 |
+
Raises
|
| 589 |
+
------
|
| 590 |
+
ValueError
|
| 591 |
+
If ``m < 1``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or
|
| 592 |
+
``np.ndim(scl) != 0``.
|
| 593 |
+
|
| 594 |
+
See Also
|
| 595 |
+
--------
|
| 596 |
+
polyder
|
| 597 |
+
|
| 598 |
+
Notes
|
| 599 |
+
-----
|
| 600 |
+
Note that the result of each integration is *multiplied* by `scl`. Why
|
| 601 |
+
is this important to note? Say one is making a linear change of
|
| 602 |
+
variable :math:`u = ax + b` in an integral relative to `x`. Then
|
| 603 |
+
:math:`dx = du/a`, so one will need to set `scl` equal to
|
| 604 |
+
:math:`1/a` - perhaps not what one would have first thought.
|
| 605 |
+
|
| 606 |
+
Examples
|
| 607 |
+
--------
|
| 608 |
+
>>> from numpy.polynomial import polynomial as P
|
| 609 |
+
>>> c = (1,2,3)
|
| 610 |
+
>>> P.polyint(c) # should return array([0, 1, 1, 1])
|
| 611 |
+
array([0., 1., 1., 1.])
|
| 612 |
+
>>> P.polyint(c,3) # should return array([0, 0, 0, 1/6, 1/12, 1/20])
|
| 613 |
+
array([ 0. , 0. , 0. , 0.16666667, 0.08333333, # may vary
|
| 614 |
+
0.05 ])
|
| 615 |
+
>>> P.polyint(c,k=3) # should return array([3, 1, 1, 1])
|
| 616 |
+
array([3., 1., 1., 1.])
|
| 617 |
+
>>> P.polyint(c,lbnd=-2) # should return array([6, 1, 1, 1])
|
| 618 |
+
array([6., 1., 1., 1.])
|
| 619 |
+
>>> P.polyint(c,scl=-2) # should return array([0, -2, -2, -2])
|
| 620 |
+
array([ 0., -2., -2., -2.])
|
| 621 |
+
|
| 622 |
+
"""
|
| 623 |
+
c = np.array(c, ndmin=1, copy=True)
|
| 624 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 625 |
+
# astype doesn't preserve mask attribute.
|
| 626 |
+
c = c + 0.0
|
| 627 |
+
cdt = c.dtype
|
| 628 |
+
if not np.iterable(k):
|
| 629 |
+
k = [k]
|
| 630 |
+
cnt = pu._deprecate_as_int(m, "the order of integration")
|
| 631 |
+
iaxis = pu._deprecate_as_int(axis, "the axis")
|
| 632 |
+
if cnt < 0:
|
| 633 |
+
raise ValueError("The order of integration must be non-negative")
|
| 634 |
+
if len(k) > cnt:
|
| 635 |
+
raise ValueError("Too many integration constants")
|
| 636 |
+
if np.ndim(lbnd) != 0:
|
| 637 |
+
raise ValueError("lbnd must be a scalar.")
|
| 638 |
+
if np.ndim(scl) != 0:
|
| 639 |
+
raise ValueError("scl must be a scalar.")
|
| 640 |
+
iaxis = normalize_axis_index(iaxis, c.ndim)
|
| 641 |
+
|
| 642 |
+
if cnt == 0:
|
| 643 |
+
return c
|
| 644 |
+
|
| 645 |
+
k = list(k) + [0]*(cnt - len(k))
|
| 646 |
+
c = np.moveaxis(c, iaxis, 0)
|
| 647 |
+
for i in range(cnt):
|
| 648 |
+
n = len(c)
|
| 649 |
+
c *= scl
|
| 650 |
+
if n == 1 and np.all(c[0] == 0):
|
| 651 |
+
c[0] += k[i]
|
| 652 |
+
else:
|
| 653 |
+
tmp = np.empty((n + 1,) + c.shape[1:], dtype=cdt)
|
| 654 |
+
tmp[0] = c[0]*0
|
| 655 |
+
tmp[1] = c[0]
|
| 656 |
+
for j in range(1, n):
|
| 657 |
+
tmp[j + 1] = c[j]/(j + 1)
|
| 658 |
+
tmp[0] += k[i] - polyval(lbnd, tmp)
|
| 659 |
+
c = tmp
|
| 660 |
+
c = np.moveaxis(c, 0, iaxis)
|
| 661 |
+
return c
|
| 662 |
+
|
| 663 |
+
|
| 664 |
+
def polyval(x, c, tensor=True):
|
| 665 |
+
"""
|
| 666 |
+
Evaluate a polynomial at points x.
|
| 667 |
+
|
| 668 |
+
If `c` is of length `n + 1`, this function returns the value
|
| 669 |
+
|
| 670 |
+
.. math:: p(x) = c_0 + c_1 * x + ... + c_n * x^n
|
| 671 |
+
|
| 672 |
+
The parameter `x` is converted to an array only if it is a tuple or a
|
| 673 |
+
list, otherwise it is treated as a scalar. In either case, either `x`
|
| 674 |
+
or its elements must support multiplication and addition both with
|
| 675 |
+
themselves and with the elements of `c`.
|
| 676 |
+
|
| 677 |
+
If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If
|
| 678 |
+
`c` is multidimensional, then the shape of the result depends on the
|
| 679 |
+
value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
|
| 680 |
+
x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
|
| 681 |
+
scalars have shape (,).
|
| 682 |
+
|
| 683 |
+
Trailing zeros in the coefficients will be used in the evaluation, so
|
| 684 |
+
they should be avoided if efficiency is a concern.
|
| 685 |
+
|
| 686 |
+
Parameters
|
| 687 |
+
----------
|
| 688 |
+
x : array_like, compatible object
|
| 689 |
+
If `x` is a list or tuple, it is converted to an ndarray, otherwise
|
| 690 |
+
it is left unchanged and treated as a scalar. In either case, `x`
|
| 691 |
+
or its elements must support addition and multiplication with
|
| 692 |
+
with themselves and with the elements of `c`.
|
| 693 |
+
c : array_like
|
| 694 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 695 |
+
degree n are contained in c[n]. If `c` is multidimensional the
|
| 696 |
+
remaining indices enumerate multiple polynomials. In the two
|
| 697 |
+
dimensional case the coefficients may be thought of as stored in
|
| 698 |
+
the columns of `c`.
|
| 699 |
+
tensor : boolean, optional
|
| 700 |
+
If True, the shape of the coefficient array is extended with ones
|
| 701 |
+
on the right, one for each dimension of `x`. Scalars have dimension 0
|
| 702 |
+
for this action. The result is that every column of coefficients in
|
| 703 |
+
`c` is evaluated for every element of `x`. If False, `x` is broadcast
|
| 704 |
+
over the columns of `c` for the evaluation. This keyword is useful
|
| 705 |
+
when `c` is multidimensional. The default value is True.
|
| 706 |
+
|
| 707 |
+
.. versionadded:: 1.7.0
|
| 708 |
+
|
| 709 |
+
Returns
|
| 710 |
+
-------
|
| 711 |
+
values : ndarray, compatible object
|
| 712 |
+
The shape of the returned array is described above.
|
| 713 |
+
|
| 714 |
+
See Also
|
| 715 |
+
--------
|
| 716 |
+
polyval2d, polygrid2d, polyval3d, polygrid3d
|
| 717 |
+
|
| 718 |
+
Notes
|
| 719 |
+
-----
|
| 720 |
+
The evaluation uses Horner's method.
|
| 721 |
+
|
| 722 |
+
Examples
|
| 723 |
+
--------
|
| 724 |
+
>>> from numpy.polynomial.polynomial import polyval
|
| 725 |
+
>>> polyval(1, [1,2,3])
|
| 726 |
+
6.0
|
| 727 |
+
>>> a = np.arange(4).reshape(2,2)
|
| 728 |
+
>>> a
|
| 729 |
+
array([[0, 1],
|
| 730 |
+
[2, 3]])
|
| 731 |
+
>>> polyval(a, [1,2,3])
|
| 732 |
+
array([[ 1., 6.],
|
| 733 |
+
[17., 34.]])
|
| 734 |
+
>>> coef = np.arange(4).reshape(2,2) # multidimensional coefficients
|
| 735 |
+
>>> coef
|
| 736 |
+
array([[0, 1],
|
| 737 |
+
[2, 3]])
|
| 738 |
+
>>> polyval([1,2], coef, tensor=True)
|
| 739 |
+
array([[2., 4.],
|
| 740 |
+
[4., 7.]])
|
| 741 |
+
>>> polyval([1,2], coef, tensor=False)
|
| 742 |
+
array([2., 7.])
|
| 743 |
+
|
| 744 |
+
"""
|
| 745 |
+
c = np.array(c, ndmin=1, copy=False)
|
| 746 |
+
if c.dtype.char in '?bBhHiIlLqQpP':
|
| 747 |
+
# astype fails with NA
|
| 748 |
+
c = c + 0.0
|
| 749 |
+
if isinstance(x, (tuple, list)):
|
| 750 |
+
x = np.asarray(x)
|
| 751 |
+
if isinstance(x, np.ndarray) and tensor:
|
| 752 |
+
c = c.reshape(c.shape + (1,)*x.ndim)
|
| 753 |
+
|
| 754 |
+
c0 = c[-1] + x*0
|
| 755 |
+
for i in range(2, len(c) + 1):
|
| 756 |
+
c0 = c[-i] + c0*x
|
| 757 |
+
return c0
|
| 758 |
+
|
| 759 |
+
|
| 760 |
+
def polyvalfromroots(x, r, tensor=True):
|
| 761 |
+
"""
|
| 762 |
+
Evaluate a polynomial specified by its roots at points x.
|
| 763 |
+
|
| 764 |
+
If `r` is of length `N`, this function returns the value
|
| 765 |
+
|
| 766 |
+
.. math:: p(x) = \\prod_{n=1}^{N} (x - r_n)
|
| 767 |
+
|
| 768 |
+
The parameter `x` is converted to an array only if it is a tuple or a
|
| 769 |
+
list, otherwise it is treated as a scalar. In either case, either `x`
|
| 770 |
+
or its elements must support multiplication and addition both with
|
| 771 |
+
themselves and with the elements of `r`.
|
| 772 |
+
|
| 773 |
+
If `r` is a 1-D array, then `p(x)` will have the same shape as `x`. If `r`
|
| 774 |
+
is multidimensional, then the shape of the result depends on the value of
|
| 775 |
+
`tensor`. If `tensor` is ``True`` the shape will be r.shape[1:] + x.shape;
|
| 776 |
+
that is, each polynomial is evaluated at every value of `x`. If `tensor` is
|
| 777 |
+
``False``, the shape will be r.shape[1:]; that is, each polynomial is
|
| 778 |
+
evaluated only for the corresponding broadcast value of `x`. Note that
|
| 779 |
+
scalars have shape (,).
|
| 780 |
+
|
| 781 |
+
.. versionadded:: 1.12
|
| 782 |
+
|
| 783 |
+
Parameters
|
| 784 |
+
----------
|
| 785 |
+
x : array_like, compatible object
|
| 786 |
+
If `x` is a list or tuple, it is converted to an ndarray, otherwise
|
| 787 |
+
it is left unchanged and treated as a scalar. In either case, `x`
|
| 788 |
+
or its elements must support addition and multiplication with
|
| 789 |
+
with themselves and with the elements of `r`.
|
| 790 |
+
r : array_like
|
| 791 |
+
Array of roots. If `r` is multidimensional the first index is the
|
| 792 |
+
root index, while the remaining indices enumerate multiple
|
| 793 |
+
polynomials. For instance, in the two dimensional case the roots
|
| 794 |
+
of each polynomial may be thought of as stored in the columns of `r`.
|
| 795 |
+
tensor : boolean, optional
|
| 796 |
+
If True, the shape of the roots array is extended with ones on the
|
| 797 |
+
right, one for each dimension of `x`. Scalars have dimension 0 for this
|
| 798 |
+
action. The result is that every column of coefficients in `r` is
|
| 799 |
+
evaluated for every element of `x`. If False, `x` is broadcast over the
|
| 800 |
+
columns of `r` for the evaluation. This keyword is useful when `r` is
|
| 801 |
+
multidimensional. The default value is True.
|
| 802 |
+
|
| 803 |
+
Returns
|
| 804 |
+
-------
|
| 805 |
+
values : ndarray, compatible object
|
| 806 |
+
The shape of the returned array is described above.
|
| 807 |
+
|
| 808 |
+
See Also
|
| 809 |
+
--------
|
| 810 |
+
polyroots, polyfromroots, polyval
|
| 811 |
+
|
| 812 |
+
Examples
|
| 813 |
+
--------
|
| 814 |
+
>>> from numpy.polynomial.polynomial import polyvalfromroots
|
| 815 |
+
>>> polyvalfromroots(1, [1,2,3])
|
| 816 |
+
0.0
|
| 817 |
+
>>> a = np.arange(4).reshape(2,2)
|
| 818 |
+
>>> a
|
| 819 |
+
array([[0, 1],
|
| 820 |
+
[2, 3]])
|
| 821 |
+
>>> polyvalfromroots(a, [-1, 0, 1])
|
| 822 |
+
array([[-0., 0.],
|
| 823 |
+
[ 6., 24.]])
|
| 824 |
+
>>> r = np.arange(-2, 2).reshape(2,2) # multidimensional coefficients
|
| 825 |
+
>>> r # each column of r defines one polynomial
|
| 826 |
+
array([[-2, -1],
|
| 827 |
+
[ 0, 1]])
|
| 828 |
+
>>> b = [-2, 1]
|
| 829 |
+
>>> polyvalfromroots(b, r, tensor=True)
|
| 830 |
+
array([[-0., 3.],
|
| 831 |
+
[ 3., 0.]])
|
| 832 |
+
>>> polyvalfromroots(b, r, tensor=False)
|
| 833 |
+
array([-0., 0.])
|
| 834 |
+
"""
|
| 835 |
+
r = np.array(r, ndmin=1, copy=False)
|
| 836 |
+
if r.dtype.char in '?bBhHiIlLqQpP':
|
| 837 |
+
r = r.astype(np.double)
|
| 838 |
+
if isinstance(x, (tuple, list)):
|
| 839 |
+
x = np.asarray(x)
|
| 840 |
+
if isinstance(x, np.ndarray):
|
| 841 |
+
if tensor:
|
| 842 |
+
r = r.reshape(r.shape + (1,)*x.ndim)
|
| 843 |
+
elif x.ndim >= r.ndim:
|
| 844 |
+
raise ValueError("x.ndim must be < r.ndim when tensor == False")
|
| 845 |
+
return np.prod(x - r, axis=0)
|
| 846 |
+
|
| 847 |
+
|
| 848 |
+
def polyval2d(x, y, c):
|
| 849 |
+
"""
|
| 850 |
+
Evaluate a 2-D polynomial at points (x, y).
|
| 851 |
+
|
| 852 |
+
This function returns the value
|
| 853 |
+
|
| 854 |
+
.. math:: p(x,y) = \\sum_{i,j} c_{i,j} * x^i * y^j
|
| 855 |
+
|
| 856 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 857 |
+
tuples or a lists, otherwise they are treated as a scalars and they
|
| 858 |
+
must have the same shape after conversion. In either case, either `x`
|
| 859 |
+
and `y` or their elements must support multiplication and addition both
|
| 860 |
+
with themselves and with the elements of `c`.
|
| 861 |
+
|
| 862 |
+
If `c` has fewer than two dimensions, ones are implicitly appended to
|
| 863 |
+
its shape to make it 2-D. The shape of the result will be c.shape[2:] +
|
| 864 |
+
x.shape.
|
| 865 |
+
|
| 866 |
+
Parameters
|
| 867 |
+
----------
|
| 868 |
+
x, y : array_like, compatible objects
|
| 869 |
+
The two dimensional series is evaluated at the points `(x, y)`,
|
| 870 |
+
where `x` and `y` must have the same shape. If `x` or `y` is a list
|
| 871 |
+
or tuple, it is first converted to an ndarray, otherwise it is left
|
| 872 |
+
unchanged and, if it isn't an ndarray, it is treated as a scalar.
|
| 873 |
+
c : array_like
|
| 874 |
+
Array of coefficients ordered so that the coefficient of the term
|
| 875 |
+
of multi-degree i,j is contained in `c[i,j]`. If `c` has
|
| 876 |
+
dimension greater than two the remaining indices enumerate multiple
|
| 877 |
+
sets of coefficients.
|
| 878 |
+
|
| 879 |
+
Returns
|
| 880 |
+
-------
|
| 881 |
+
values : ndarray, compatible object
|
| 882 |
+
The values of the two dimensional polynomial at points formed with
|
| 883 |
+
pairs of corresponding values from `x` and `y`.
|
| 884 |
+
|
| 885 |
+
See Also
|
| 886 |
+
--------
|
| 887 |
+
polyval, polygrid2d, polyval3d, polygrid3d
|
| 888 |
+
|
| 889 |
+
Notes
|
| 890 |
+
-----
|
| 891 |
+
|
| 892 |
+
.. versionadded:: 1.7.0
|
| 893 |
+
|
| 894 |
+
"""
|
| 895 |
+
return pu._valnd(polyval, c, x, y)
|
| 896 |
+
|
| 897 |
+
|
| 898 |
+
def polygrid2d(x, y, c):
|
| 899 |
+
"""
|
| 900 |
+
Evaluate a 2-D polynomial on the Cartesian product of x and y.
|
| 901 |
+
|
| 902 |
+
This function returns the values:
|
| 903 |
+
|
| 904 |
+
.. math:: p(a,b) = \\sum_{i,j} c_{i,j} * a^i * b^j
|
| 905 |
+
|
| 906 |
+
where the points `(a, b)` consist of all pairs formed by taking
|
| 907 |
+
`a` from `x` and `b` from `y`. The resulting points form a grid with
|
| 908 |
+
`x` in the first dimension and `y` in the second.
|
| 909 |
+
|
| 910 |
+
The parameters `x` and `y` are converted to arrays only if they are
|
| 911 |
+
tuples or a lists, otherwise they are treated as a scalars. In either
|
| 912 |
+
case, either `x` and `y` or their elements must support multiplication
|
| 913 |
+
and addition both with themselves and with the elements of `c`.
|
| 914 |
+
|
| 915 |
+
If `c` has fewer than two dimensions, ones are implicitly appended to
|
| 916 |
+
its shape to make it 2-D. The shape of the result will be c.shape[2:] +
|
| 917 |
+
x.shape + y.shape.
|
| 918 |
+
|
| 919 |
+
Parameters
|
| 920 |
+
----------
|
| 921 |
+
x, y : array_like, compatible objects
|
| 922 |
+
The two dimensional series is evaluated at the points in the
|
| 923 |
+
Cartesian product of `x` and `y`. If `x` or `y` is a list or
|
| 924 |
+
tuple, it is first converted to an ndarray, otherwise it is left
|
| 925 |
+
unchanged and, if it isn't an ndarray, it is treated as a scalar.
|
| 926 |
+
c : array_like
|
| 927 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 928 |
+
degree i,j are contained in ``c[i,j]``. If `c` has dimension
|
| 929 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 930 |
+
coefficients.
|
| 931 |
+
|
| 932 |
+
Returns
|
| 933 |
+
-------
|
| 934 |
+
values : ndarray, compatible object
|
| 935 |
+
The values of the two dimensional polynomial at points in the Cartesian
|
| 936 |
+
product of `x` and `y`.
|
| 937 |
+
|
| 938 |
+
See Also
|
| 939 |
+
--------
|
| 940 |
+
polyval, polyval2d, polyval3d, polygrid3d
|
| 941 |
+
|
| 942 |
+
Notes
|
| 943 |
+
-----
|
| 944 |
+
|
| 945 |
+
.. versionadded:: 1.7.0
|
| 946 |
+
|
| 947 |
+
"""
|
| 948 |
+
return pu._gridnd(polyval, c, x, y)
|
| 949 |
+
|
| 950 |
+
|
| 951 |
+
def polyval3d(x, y, z, c):
|
| 952 |
+
"""
|
| 953 |
+
Evaluate a 3-D polynomial at points (x, y, z).
|
| 954 |
+
|
| 955 |
+
This function returns the values:
|
| 956 |
+
|
| 957 |
+
.. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * x^i * y^j * z^k
|
| 958 |
+
|
| 959 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if
|
| 960 |
+
they are tuples or a lists, otherwise they are treated as a scalars and
|
| 961 |
+
they must have the same shape after conversion. In either case, either
|
| 962 |
+
`x`, `y`, and `z` or their elements must support multiplication and
|
| 963 |
+
addition both with themselves and with the elements of `c`.
|
| 964 |
+
|
| 965 |
+
If `c` has fewer than 3 dimensions, ones are implicitly appended to its
|
| 966 |
+
shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 967 |
+
x.shape.
|
| 968 |
+
|
| 969 |
+
Parameters
|
| 970 |
+
----------
|
| 971 |
+
x, y, z : array_like, compatible object
|
| 972 |
+
The three dimensional series is evaluated at the points
|
| 973 |
+
`(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If
|
| 974 |
+
any of `x`, `y`, or `z` is a list or tuple, it is first converted
|
| 975 |
+
to an ndarray, otherwise it is left unchanged and if it isn't an
|
| 976 |
+
ndarray it is treated as a scalar.
|
| 977 |
+
c : array_like
|
| 978 |
+
Array of coefficients ordered so that the coefficient of the term of
|
| 979 |
+
multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
|
| 980 |
+
greater than 3 the remaining indices enumerate multiple sets of
|
| 981 |
+
coefficients.
|
| 982 |
+
|
| 983 |
+
Returns
|
| 984 |
+
-------
|
| 985 |
+
values : ndarray, compatible object
|
| 986 |
+
The values of the multidimensional polynomial on points formed with
|
| 987 |
+
triples of corresponding values from `x`, `y`, and `z`.
|
| 988 |
+
|
| 989 |
+
See Also
|
| 990 |
+
--------
|
| 991 |
+
polyval, polyval2d, polygrid2d, polygrid3d
|
| 992 |
+
|
| 993 |
+
Notes
|
| 994 |
+
-----
|
| 995 |
+
|
| 996 |
+
.. versionadded:: 1.7.0
|
| 997 |
+
|
| 998 |
+
"""
|
| 999 |
+
return pu._valnd(polyval, c, x, y, z)
|
| 1000 |
+
|
| 1001 |
+
|
| 1002 |
+
def polygrid3d(x, y, z, c):
|
| 1003 |
+
"""
|
| 1004 |
+
Evaluate a 3-D polynomial on the Cartesian product of x, y and z.
|
| 1005 |
+
|
| 1006 |
+
This function returns the values:
|
| 1007 |
+
|
| 1008 |
+
.. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * a^i * b^j * c^k
|
| 1009 |
+
|
| 1010 |
+
where the points `(a, b, c)` consist of all triples formed by taking
|
| 1011 |
+
`a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
|
| 1012 |
+
a grid with `x` in the first dimension, `y` in the second, and `z` in
|
| 1013 |
+
the third.
|
| 1014 |
+
|
| 1015 |
+
The parameters `x`, `y`, and `z` are converted to arrays only if they
|
| 1016 |
+
are tuples or a lists, otherwise they are treated as a scalars. In
|
| 1017 |
+
either case, either `x`, `y`, and `z` or their elements must support
|
| 1018 |
+
multiplication and addition both with themselves and with the elements
|
| 1019 |
+
of `c`.
|
| 1020 |
+
|
| 1021 |
+
If `c` has fewer than three dimensions, ones are implicitly appended to
|
| 1022 |
+
its shape to make it 3-D. The shape of the result will be c.shape[3:] +
|
| 1023 |
+
x.shape + y.shape + z.shape.
|
| 1024 |
+
|
| 1025 |
+
Parameters
|
| 1026 |
+
----------
|
| 1027 |
+
x, y, z : array_like, compatible objects
|
| 1028 |
+
The three dimensional series is evaluated at the points in the
|
| 1029 |
+
Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a
|
| 1030 |
+
list or tuple, it is first converted to an ndarray, otherwise it is
|
| 1031 |
+
left unchanged and, if it isn't an ndarray, it is treated as a
|
| 1032 |
+
scalar.
|
| 1033 |
+
c : array_like
|
| 1034 |
+
Array of coefficients ordered so that the coefficients for terms of
|
| 1035 |
+
degree i,j are contained in ``c[i,j]``. If `c` has dimension
|
| 1036 |
+
greater than two the remaining indices enumerate multiple sets of
|
| 1037 |
+
coefficients.
|
| 1038 |
+
|
| 1039 |
+
Returns
|
| 1040 |
+
-------
|
| 1041 |
+
values : ndarray, compatible object
|
| 1042 |
+
The values of the two dimensional polynomial at points in the Cartesian
|
| 1043 |
+
product of `x` and `y`.
|
| 1044 |
+
|
| 1045 |
+
See Also
|
| 1046 |
+
--------
|
| 1047 |
+
polyval, polyval2d, polygrid2d, polyval3d
|
| 1048 |
+
|
| 1049 |
+
Notes
|
| 1050 |
+
-----
|
| 1051 |
+
|
| 1052 |
+
.. versionadded:: 1.7.0
|
| 1053 |
+
|
| 1054 |
+
"""
|
| 1055 |
+
return pu._gridnd(polyval, c, x, y, z)
|
| 1056 |
+
|
| 1057 |
+
|
| 1058 |
+
def polyvander(x, deg):
|
| 1059 |
+
"""Vandermonde matrix of given degree.
|
| 1060 |
+
|
| 1061 |
+
Returns the Vandermonde matrix of degree `deg` and sample points
|
| 1062 |
+
`x`. The Vandermonde matrix is defined by
|
| 1063 |
+
|
| 1064 |
+
.. math:: V[..., i] = x^i,
|
| 1065 |
+
|
| 1066 |
+
where `0 <= i <= deg`. The leading indices of `V` index the elements of
|
| 1067 |
+
`x` and the last index is the power of `x`.
|
| 1068 |
+
|
| 1069 |
+
If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
|
| 1070 |
+
matrix ``V = polyvander(x, n)``, then ``np.dot(V, c)`` and
|
| 1071 |
+
``polyval(x, c)`` are the same up to roundoff. This equivalence is
|
| 1072 |
+
useful both for least squares fitting and for the evaluation of a large
|
| 1073 |
+
number of polynomials of the same degree and sample points.
|
| 1074 |
+
|
| 1075 |
+
Parameters
|
| 1076 |
+
----------
|
| 1077 |
+
x : array_like
|
| 1078 |
+
Array of points. The dtype is converted to float64 or complex128
|
| 1079 |
+
depending on whether any of the elements are complex. If `x` is
|
| 1080 |
+
scalar it is converted to a 1-D array.
|
| 1081 |
+
deg : int
|
| 1082 |
+
Degree of the resulting matrix.
|
| 1083 |
+
|
| 1084 |
+
Returns
|
| 1085 |
+
-------
|
| 1086 |
+
vander : ndarray.
|
| 1087 |
+
The Vandermonde matrix. The shape of the returned matrix is
|
| 1088 |
+
``x.shape + (deg + 1,)``, where the last index is the power of `x`.
|
| 1089 |
+
The dtype will be the same as the converted `x`.
|
| 1090 |
+
|
| 1091 |
+
See Also
|
| 1092 |
+
--------
|
| 1093 |
+
polyvander2d, polyvander3d
|
| 1094 |
+
|
| 1095 |
+
"""
|
| 1096 |
+
ideg = pu._deprecate_as_int(deg, "deg")
|
| 1097 |
+
if ideg < 0:
|
| 1098 |
+
raise ValueError("deg must be non-negative")
|
| 1099 |
+
|
| 1100 |
+
x = np.array(x, copy=False, ndmin=1) + 0.0
|
| 1101 |
+
dims = (ideg + 1,) + x.shape
|
| 1102 |
+
dtyp = x.dtype
|
| 1103 |
+
v = np.empty(dims, dtype=dtyp)
|
| 1104 |
+
v[0] = x*0 + 1
|
| 1105 |
+
if ideg > 0:
|
| 1106 |
+
v[1] = x
|
| 1107 |
+
for i in range(2, ideg + 1):
|
| 1108 |
+
v[i] = v[i-1]*x
|
| 1109 |
+
return np.moveaxis(v, 0, -1)
|
| 1110 |
+
|
| 1111 |
+
|
| 1112 |
+
def polyvander2d(x, y, deg):
|
| 1113 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1114 |
+
|
| 1115 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1116 |
+
points `(x, y)`. The pseudo-Vandermonde matrix is defined by
|
| 1117 |
+
|
| 1118 |
+
.. math:: V[..., (deg[1] + 1)*i + j] = x^i * y^j,
|
| 1119 |
+
|
| 1120 |
+
where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
|
| 1121 |
+
`V` index the points `(x, y)` and the last index encodes the powers of
|
| 1122 |
+
`x` and `y`.
|
| 1123 |
+
|
| 1124 |
+
If ``V = polyvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
|
| 1125 |
+
correspond to the elements of a 2-D coefficient array `c` of shape
|
| 1126 |
+
(xdeg + 1, ydeg + 1) in the order
|
| 1127 |
+
|
| 1128 |
+
.. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
|
| 1129 |
+
|
| 1130 |
+
and ``np.dot(V, c.flat)`` and ``polyval2d(x, y, c)`` will be the same
|
| 1131 |
+
up to roundoff. This equivalence is useful both for least squares
|
| 1132 |
+
fitting and for the evaluation of a large number of 2-D polynomials
|
| 1133 |
+
of the same degrees and sample points.
|
| 1134 |
+
|
| 1135 |
+
Parameters
|
| 1136 |
+
----------
|
| 1137 |
+
x, y : array_like
|
| 1138 |
+
Arrays of point coordinates, all of the same shape. The dtypes
|
| 1139 |
+
will be converted to either float64 or complex128 depending on
|
| 1140 |
+
whether any of the elements are complex. Scalars are converted to
|
| 1141 |
+
1-D arrays.
|
| 1142 |
+
deg : list of ints
|
| 1143 |
+
List of maximum degrees of the form [x_deg, y_deg].
|
| 1144 |
+
|
| 1145 |
+
Returns
|
| 1146 |
+
-------
|
| 1147 |
+
vander2d : ndarray
|
| 1148 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1149 |
+
:math:`order = (deg[0]+1)*(deg([1]+1)`. The dtype will be the same
|
| 1150 |
+
as the converted `x` and `y`.
|
| 1151 |
+
|
| 1152 |
+
See Also
|
| 1153 |
+
--------
|
| 1154 |
+
polyvander, polyvander3d, polyval2d, polyval3d
|
| 1155 |
+
|
| 1156 |
+
"""
|
| 1157 |
+
return pu._vander_nd_flat((polyvander, polyvander), (x, y), deg)
|
| 1158 |
+
|
| 1159 |
+
|
| 1160 |
+
def polyvander3d(x, y, z, deg):
|
| 1161 |
+
"""Pseudo-Vandermonde matrix of given degrees.
|
| 1162 |
+
|
| 1163 |
+
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
|
| 1164 |
+
points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
|
| 1165 |
+
then The pseudo-Vandermonde matrix is defined by
|
| 1166 |
+
|
| 1167 |
+
.. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = x^i * y^j * z^k,
|
| 1168 |
+
|
| 1169 |
+
where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading
|
| 1170 |
+
indices of `V` index the points `(x, y, z)` and the last index encodes
|
| 1171 |
+
the powers of `x`, `y`, and `z`.
|
| 1172 |
+
|
| 1173 |
+
If ``V = polyvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
|
| 1174 |
+
of `V` correspond to the elements of a 3-D coefficient array `c` of
|
| 1175 |
+
shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
|
| 1176 |
+
|
| 1177 |
+
.. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
|
| 1178 |
+
|
| 1179 |
+
and ``np.dot(V, c.flat)`` and ``polyval3d(x, y, z, c)`` will be the
|
| 1180 |
+
same up to roundoff. This equivalence is useful both for least squares
|
| 1181 |
+
fitting and for the evaluation of a large number of 3-D polynomials
|
| 1182 |
+
of the same degrees and sample points.
|
| 1183 |
+
|
| 1184 |
+
Parameters
|
| 1185 |
+
----------
|
| 1186 |
+
x, y, z : array_like
|
| 1187 |
+
Arrays of point coordinates, all of the same shape. The dtypes will
|
| 1188 |
+
be converted to either float64 or complex128 depending on whether
|
| 1189 |
+
any of the elements are complex. Scalars are converted to 1-D
|
| 1190 |
+
arrays.
|
| 1191 |
+
deg : list of ints
|
| 1192 |
+
List of maximum degrees of the form [x_deg, y_deg, z_deg].
|
| 1193 |
+
|
| 1194 |
+
Returns
|
| 1195 |
+
-------
|
| 1196 |
+
vander3d : ndarray
|
| 1197 |
+
The shape of the returned matrix is ``x.shape + (order,)``, where
|
| 1198 |
+
:math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`. The dtype will
|
| 1199 |
+
be the same as the converted `x`, `y`, and `z`.
|
| 1200 |
+
|
| 1201 |
+
See Also
|
| 1202 |
+
--------
|
| 1203 |
+
polyvander, polyvander3d, polyval2d, polyval3d
|
| 1204 |
+
|
| 1205 |
+
Notes
|
| 1206 |
+
-----
|
| 1207 |
+
|
| 1208 |
+
.. versionadded:: 1.7.0
|
| 1209 |
+
|
| 1210 |
+
"""
|
| 1211 |
+
return pu._vander_nd_flat((polyvander, polyvander, polyvander), (x, y, z), deg)
|
| 1212 |
+
|
| 1213 |
+
|
| 1214 |
+
def polyfit(x, y, deg, rcond=None, full=False, w=None):
|
| 1215 |
+
"""
|
| 1216 |
+
Least-squares fit of a polynomial to data.
|
| 1217 |
+
|
| 1218 |
+
Return the coefficients of a polynomial of degree `deg` that is the
|
| 1219 |
+
least squares fit to the data values `y` given at points `x`. If `y` is
|
| 1220 |
+
1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
|
| 1221 |
+
fits are done, one for each column of `y`, and the resulting
|
| 1222 |
+
coefficients are stored in the corresponding columns of a 2-D return.
|
| 1223 |
+
The fitted polynomial(s) are in the form
|
| 1224 |
+
|
| 1225 |
+
.. math:: p(x) = c_0 + c_1 * x + ... + c_n * x^n,
|
| 1226 |
+
|
| 1227 |
+
where `n` is `deg`.
|
| 1228 |
+
|
| 1229 |
+
Parameters
|
| 1230 |
+
----------
|
| 1231 |
+
x : array_like, shape (`M`,)
|
| 1232 |
+
x-coordinates of the `M` sample (data) points ``(x[i], y[i])``.
|
| 1233 |
+
y : array_like, shape (`M`,) or (`M`, `K`)
|
| 1234 |
+
y-coordinates of the sample points. Several sets of sample points
|
| 1235 |
+
sharing the same x-coordinates can be (independently) fit with one
|
| 1236 |
+
call to `polyfit` by passing in for `y` a 2-D array that contains
|
| 1237 |
+
one data set per column.
|
| 1238 |
+
deg : int or 1-D array_like
|
| 1239 |
+
Degree(s) of the fitting polynomials. If `deg` is a single integer
|
| 1240 |
+
all terms up to and including the `deg`'th term are included in the
|
| 1241 |
+
fit. For NumPy versions >= 1.11.0 a list of integers specifying the
|
| 1242 |
+
degrees of the terms to include may be used instead.
|
| 1243 |
+
rcond : float, optional
|
| 1244 |
+
Relative condition number of the fit. Singular values smaller
|
| 1245 |
+
than `rcond`, relative to the largest singular value, will be
|
| 1246 |
+
ignored. The default value is ``len(x)*eps``, where `eps` is the
|
| 1247 |
+
relative precision of the platform's float type, about 2e-16 in
|
| 1248 |
+
most cases.
|
| 1249 |
+
full : bool, optional
|
| 1250 |
+
Switch determining the nature of the return value. When ``False``
|
| 1251 |
+
(the default) just the coefficients are returned; when ``True``,
|
| 1252 |
+
diagnostic information from the singular value decomposition (used
|
| 1253 |
+
to solve the fit's matrix equation) is also returned.
|
| 1254 |
+
w : array_like, shape (`M`,), optional
|
| 1255 |
+
Weights. If not None, the weight ``w[i]`` applies to the unsquared
|
| 1256 |
+
residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
|
| 1257 |
+
chosen so that the errors of the products ``w[i]*y[i]`` all have the
|
| 1258 |
+
same variance. When using inverse-variance weighting, use
|
| 1259 |
+
``w[i] = 1/sigma(y[i])``. The default value is None.
|
| 1260 |
+
|
| 1261 |
+
.. versionadded:: 1.5.0
|
| 1262 |
+
|
| 1263 |
+
Returns
|
| 1264 |
+
-------
|
| 1265 |
+
coef : ndarray, shape (`deg` + 1,) or (`deg` + 1, `K`)
|
| 1266 |
+
Polynomial coefficients ordered from low to high. If `y` was 2-D,
|
| 1267 |
+
the coefficients in column `k` of `coef` represent the polynomial
|
| 1268 |
+
fit to the data in `y`'s `k`-th column.
|
| 1269 |
+
|
| 1270 |
+
[residuals, rank, singular_values, rcond] : list
|
| 1271 |
+
These values are only returned if ``full == True``
|
| 1272 |
+
|
| 1273 |
+
- residuals -- sum of squared residuals of the least squares fit
|
| 1274 |
+
- rank -- the numerical rank of the scaled Vandermonde matrix
|
| 1275 |
+
- singular_values -- singular values of the scaled Vandermonde matrix
|
| 1276 |
+
- rcond -- value of `rcond`.
|
| 1277 |
+
|
| 1278 |
+
For more details, see `numpy.linalg.lstsq`.
|
| 1279 |
+
|
| 1280 |
+
Raises
|
| 1281 |
+
------
|
| 1282 |
+
RankWarning
|
| 1283 |
+
Raised if the matrix in the least-squares fit is rank deficient.
|
| 1284 |
+
The warning is only raised if ``full == False``. The warnings can
|
| 1285 |
+
be turned off by:
|
| 1286 |
+
|
| 1287 |
+
>>> import warnings
|
| 1288 |
+
>>> warnings.simplefilter('ignore', np.RankWarning)
|
| 1289 |
+
|
| 1290 |
+
See Also
|
| 1291 |
+
--------
|
| 1292 |
+
numpy.polynomial.chebyshev.chebfit
|
| 1293 |
+
numpy.polynomial.legendre.legfit
|
| 1294 |
+
numpy.polynomial.laguerre.lagfit
|
| 1295 |
+
numpy.polynomial.hermite.hermfit
|
| 1296 |
+
numpy.polynomial.hermite_e.hermefit
|
| 1297 |
+
polyval : Evaluates a polynomial.
|
| 1298 |
+
polyvander : Vandermonde matrix for powers.
|
| 1299 |
+
numpy.linalg.lstsq : Computes a least-squares fit from the matrix.
|
| 1300 |
+
scipy.interpolate.UnivariateSpline : Computes spline fits.
|
| 1301 |
+
|
| 1302 |
+
Notes
|
| 1303 |
+
-----
|
| 1304 |
+
The solution is the coefficients of the polynomial `p` that minimizes
|
| 1305 |
+
the sum of the weighted squared errors
|
| 1306 |
+
|
| 1307 |
+
.. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
|
| 1308 |
+
|
| 1309 |
+
where the :math:`w_j` are the weights. This problem is solved by
|
| 1310 |
+
setting up the (typically) over-determined matrix equation:
|
| 1311 |
+
|
| 1312 |
+
.. math:: V(x) * c = w * y,
|
| 1313 |
+
|
| 1314 |
+
where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
|
| 1315 |
+
coefficients to be solved for, `w` are the weights, and `y` are the
|
| 1316 |
+
observed values. This equation is then solved using the singular value
|
| 1317 |
+
decomposition of `V`.
|
| 1318 |
+
|
| 1319 |
+
If some of the singular values of `V` are so small that they are
|
| 1320 |
+
neglected (and `full` == ``False``), a `RankWarning` will be raised.
|
| 1321 |
+
This means that the coefficient values may be poorly determined.
|
| 1322 |
+
Fitting to a lower order polynomial will usually get rid of the warning
|
| 1323 |
+
(but may not be what you want, of course; if you have independent
|
| 1324 |
+
reason(s) for choosing the degree which isn't working, you may have to:
|
| 1325 |
+
a) reconsider those reasons, and/or b) reconsider the quality of your
|
| 1326 |
+
data). The `rcond` parameter can also be set to a value smaller than
|
| 1327 |
+
its default, but the resulting fit may be spurious and have large
|
| 1328 |
+
contributions from roundoff error.
|
| 1329 |
+
|
| 1330 |
+
Polynomial fits using double precision tend to "fail" at about
|
| 1331 |
+
(polynomial) degree 20. Fits using Chebyshev or Legendre series are
|
| 1332 |
+
generally better conditioned, but much can still depend on the
|
| 1333 |
+
distribution of the sample points and the smoothness of the data. If
|
| 1334 |
+
the quality of the fit is inadequate, splines may be a good
|
| 1335 |
+
alternative.
|
| 1336 |
+
|
| 1337 |
+
Examples
|
| 1338 |
+
--------
|
| 1339 |
+
>>> np.random.seed(123)
|
| 1340 |
+
>>> from numpy.polynomial import polynomial as P
|
| 1341 |
+
>>> x = np.linspace(-1,1,51) # x "data": [-1, -0.96, ..., 0.96, 1]
|
| 1342 |
+
>>> y = x**3 - x + np.random.randn(len(x)) # x^3 - x + Gaussian noise
|
| 1343 |
+
>>> c, stats = P.polyfit(x,y,3,full=True)
|
| 1344 |
+
>>> np.random.seed(123)
|
| 1345 |
+
>>> c # c[0], c[2] should be approx. 0, c[1] approx. -1, c[3] approx. 1
|
| 1346 |
+
array([ 0.01909725, -1.30598256, -0.00577963, 1.02644286]) # may vary
|
| 1347 |
+
>>> stats # note the large SSR, explaining the rather poor results
|
| 1348 |
+
[array([ 38.06116253]), 4, array([ 1.38446749, 1.32119158, 0.50443316, # may vary
|
| 1349 |
+
0.28853036]), 1.1324274851176597e-014]
|
| 1350 |
+
|
| 1351 |
+
Same thing without the added noise
|
| 1352 |
+
|
| 1353 |
+
>>> y = x**3 - x
|
| 1354 |
+
>>> c, stats = P.polyfit(x,y,3,full=True)
|
| 1355 |
+
>>> c # c[0], c[2] should be "very close to 0", c[1] ~= -1, c[3] ~= 1
|
| 1356 |
+
array([-6.36925336e-18, -1.00000000e+00, -4.08053781e-16, 1.00000000e+00])
|
| 1357 |
+
>>> stats # note the minuscule SSR
|
| 1358 |
+
[array([ 7.46346754e-31]), 4, array([ 1.38446749, 1.32119158, # may vary
|
| 1359 |
+
0.50443316, 0.28853036]), 1.1324274851176597e-014]
|
| 1360 |
+
|
| 1361 |
+
"""
|
| 1362 |
+
return pu._fit(polyvander, x, y, deg, rcond, full, w)
|
| 1363 |
+
|
| 1364 |
+
|
| 1365 |
+
def polycompanion(c):
|
| 1366 |
+
"""
|
| 1367 |
+
Return the companion matrix of c.
|
| 1368 |
+
|
| 1369 |
+
The companion matrix for power series cannot be made symmetric by
|
| 1370 |
+
scaling the basis, so this function differs from those for the
|
| 1371 |
+
orthogonal polynomials.
|
| 1372 |
+
|
| 1373 |
+
Parameters
|
| 1374 |
+
----------
|
| 1375 |
+
c : array_like
|
| 1376 |
+
1-D array of polynomial coefficients ordered from low to high
|
| 1377 |
+
degree.
|
| 1378 |
+
|
| 1379 |
+
Returns
|
| 1380 |
+
-------
|
| 1381 |
+
mat : ndarray
|
| 1382 |
+
Companion matrix of dimensions (deg, deg).
|
| 1383 |
+
|
| 1384 |
+
Notes
|
| 1385 |
+
-----
|
| 1386 |
+
|
| 1387 |
+
.. versionadded:: 1.7.0
|
| 1388 |
+
|
| 1389 |
+
"""
|
| 1390 |
+
# c is a trimmed copy
|
| 1391 |
+
[c] = pu.as_series([c])
|
| 1392 |
+
if len(c) < 2:
|
| 1393 |
+
raise ValueError('Series must have maximum degree of at least 1.')
|
| 1394 |
+
if len(c) == 2:
|
| 1395 |
+
return np.array([[-c[0]/c[1]]])
|
| 1396 |
+
|
| 1397 |
+
n = len(c) - 1
|
| 1398 |
+
mat = np.zeros((n, n), dtype=c.dtype)
|
| 1399 |
+
bot = mat.reshape(-1)[n::n+1]
|
| 1400 |
+
bot[...] = 1
|
| 1401 |
+
mat[:, -1] -= c[:-1]/c[-1]
|
| 1402 |
+
return mat
|
| 1403 |
+
|
| 1404 |
+
|
| 1405 |
+
def polyroots(c):
|
| 1406 |
+
"""
|
| 1407 |
+
Compute the roots of a polynomial.
|
| 1408 |
+
|
| 1409 |
+
Return the roots (a.k.a. "zeros") of the polynomial
|
| 1410 |
+
|
| 1411 |
+
.. math:: p(x) = \\sum_i c[i] * x^i.
|
| 1412 |
+
|
| 1413 |
+
Parameters
|
| 1414 |
+
----------
|
| 1415 |
+
c : 1-D array_like
|
| 1416 |
+
1-D array of polynomial coefficients.
|
| 1417 |
+
|
| 1418 |
+
Returns
|
| 1419 |
+
-------
|
| 1420 |
+
out : ndarray
|
| 1421 |
+
Array of the roots of the polynomial. If all the roots are real,
|
| 1422 |
+
then `out` is also real, otherwise it is complex.
|
| 1423 |
+
|
| 1424 |
+
See Also
|
| 1425 |
+
--------
|
| 1426 |
+
numpy.polynomial.chebyshev.chebroots
|
| 1427 |
+
numpy.polynomial.legendre.legroots
|
| 1428 |
+
numpy.polynomial.laguerre.lagroots
|
| 1429 |
+
numpy.polynomial.hermite.hermroots
|
| 1430 |
+
numpy.polynomial.hermite_e.hermeroots
|
| 1431 |
+
|
| 1432 |
+
Notes
|
| 1433 |
+
-----
|
| 1434 |
+
The root estimates are obtained as the eigenvalues of the companion
|
| 1435 |
+
matrix, Roots far from the origin of the complex plane may have large
|
| 1436 |
+
errors due to the numerical instability of the power series for such
|
| 1437 |
+
values. Roots with multiplicity greater than 1 will also show larger
|
| 1438 |
+
errors as the value of the series near such points is relatively
|
| 1439 |
+
insensitive to errors in the roots. Isolated roots near the origin can
|
| 1440 |
+
be improved by a few iterations of Newton's method.
|
| 1441 |
+
|
| 1442 |
+
Examples
|
| 1443 |
+
--------
|
| 1444 |
+
>>> import numpy.polynomial.polynomial as poly
|
| 1445 |
+
>>> poly.polyroots(poly.polyfromroots((-1,0,1)))
|
| 1446 |
+
array([-1., 0., 1.])
|
| 1447 |
+
>>> poly.polyroots(poly.polyfromroots((-1,0,1))).dtype
|
| 1448 |
+
dtype('float64')
|
| 1449 |
+
>>> j = complex(0,1)
|
| 1450 |
+
>>> poly.polyroots(poly.polyfromroots((-j,0,j)))
|
| 1451 |
+
array([ 0.00000000e+00+0.j, 0.00000000e+00+1.j, 2.77555756e-17-1.j]) # may vary
|
| 1452 |
+
|
| 1453 |
+
"""
|
| 1454 |
+
# c is a trimmed copy
|
| 1455 |
+
[c] = pu.as_series([c])
|
| 1456 |
+
if len(c) < 2:
|
| 1457 |
+
return np.array([], dtype=c.dtype)
|
| 1458 |
+
if len(c) == 2:
|
| 1459 |
+
return np.array([-c[0]/c[1]])
|
| 1460 |
+
|
| 1461 |
+
# rotated companion matrix reduces error
|
| 1462 |
+
m = polycompanion(c)[::-1,::-1]
|
| 1463 |
+
r = la.eigvals(m)
|
| 1464 |
+
r.sort()
|
| 1465 |
+
return r
|
| 1466 |
+
|
| 1467 |
+
|
| 1468 |
+
#
|
| 1469 |
+
# polynomial class
|
| 1470 |
+
#
|
| 1471 |
+
|
| 1472 |
+
class Polynomial(ABCPolyBase):
|
| 1473 |
+
"""A power series class.
|
| 1474 |
+
|
| 1475 |
+
The Polynomial class provides the standard Python numerical methods
|
| 1476 |
+
'+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
|
| 1477 |
+
attributes and methods listed in the `ABCPolyBase` documentation.
|
| 1478 |
+
|
| 1479 |
+
Parameters
|
| 1480 |
+
----------
|
| 1481 |
+
coef : array_like
|
| 1482 |
+
Polynomial coefficients in order of increasing degree, i.e.,
|
| 1483 |
+
``(1, 2, 3)`` give ``1 + 2*x + 3*x**2``.
|
| 1484 |
+
domain : (2,) array_like, optional
|
| 1485 |
+
Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
|
| 1486 |
+
to the interval ``[window[0], window[1]]`` by shifting and scaling.
|
| 1487 |
+
The default value is [-1, 1].
|
| 1488 |
+
window : (2,) array_like, optional
|
| 1489 |
+
Window, see `domain` for its use. The default value is [-1, 1].
|
| 1490 |
+
|
| 1491 |
+
.. versionadded:: 1.6.0
|
| 1492 |
+
symbol : str, optional
|
| 1493 |
+
Symbol used to represent the independent variable in string
|
| 1494 |
+
representations of the polynomial expression, e.g. for printing.
|
| 1495 |
+
The symbol must be a valid Python identifier. Default value is 'x'.
|
| 1496 |
+
|
| 1497 |
+
.. versionadded:: 1.24
|
| 1498 |
+
|
| 1499 |
+
"""
|
| 1500 |
+
# Virtual Functions
|
| 1501 |
+
_add = staticmethod(polyadd)
|
| 1502 |
+
_sub = staticmethod(polysub)
|
| 1503 |
+
_mul = staticmethod(polymul)
|
| 1504 |
+
_div = staticmethod(polydiv)
|
| 1505 |
+
_pow = staticmethod(polypow)
|
| 1506 |
+
_val = staticmethod(polyval)
|
| 1507 |
+
_int = staticmethod(polyint)
|
| 1508 |
+
_der = staticmethod(polyder)
|
| 1509 |
+
_fit = staticmethod(polyfit)
|
| 1510 |
+
_line = staticmethod(polyline)
|
| 1511 |
+
_roots = staticmethod(polyroots)
|
| 1512 |
+
_fromroots = staticmethod(polyfromroots)
|
| 1513 |
+
|
| 1514 |
+
# Virtual properties
|
| 1515 |
+
domain = np.array(polydomain)
|
| 1516 |
+
window = np.array(polydomain)
|
| 1517 |
+
basis_name = None
|
| 1518 |
+
|
| 1519 |
+
@classmethod
|
| 1520 |
+
def _str_term_unicode(cls, i, arg_str):
|
| 1521 |
+
if i == '1':
|
| 1522 |
+
return f"·{arg_str}"
|
| 1523 |
+
else:
|
| 1524 |
+
return f"·{arg_str}{i.translate(cls._superscript_mapping)}"
|
| 1525 |
+
|
| 1526 |
+
@staticmethod
|
| 1527 |
+
def _str_term_ascii(i, arg_str):
|
| 1528 |
+
if i == '1':
|
| 1529 |
+
return f" {arg_str}"
|
| 1530 |
+
else:
|
| 1531 |
+
return f" {arg_str}**{i}"
|
| 1532 |
+
|
| 1533 |
+
@staticmethod
|
| 1534 |
+
def _repr_latex_term(i, arg_str, needs_parens):
|
| 1535 |
+
if needs_parens:
|
| 1536 |
+
arg_str = rf"\left({arg_str}\right)"
|
| 1537 |
+
if i == 0:
|
| 1538 |
+
return '1'
|
| 1539 |
+
elif i == 1:
|
| 1540 |
+
return arg_str
|
| 1541 |
+
else:
|
| 1542 |
+
return f"{arg_str}^{{{i}}}"
|
lib/python3.12/site-packages/numpy/polynomial/polynomial.pyi
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any
|
| 2 |
+
|
| 3 |
+
from numpy import ndarray, dtype, int_
|
| 4 |
+
from numpy.polynomial._polybase import ABCPolyBase
|
| 5 |
+
from numpy.polynomial.polyutils import trimcoef
|
| 6 |
+
|
| 7 |
+
__all__: list[str]
|
| 8 |
+
|
| 9 |
+
polytrim = trimcoef
|
| 10 |
+
|
| 11 |
+
polydomain: ndarray[Any, dtype[int_]]
|
| 12 |
+
polyzero: ndarray[Any, dtype[int_]]
|
| 13 |
+
polyone: ndarray[Any, dtype[int_]]
|
| 14 |
+
polyx: ndarray[Any, dtype[int_]]
|
| 15 |
+
|
| 16 |
+
def polyline(off, scl): ...
|
| 17 |
+
def polyfromroots(roots): ...
|
| 18 |
+
def polyadd(c1, c2): ...
|
| 19 |
+
def polysub(c1, c2): ...
|
| 20 |
+
def polymulx(c): ...
|
| 21 |
+
def polymul(c1, c2): ...
|
| 22 |
+
def polydiv(c1, c2): ...
|
| 23 |
+
def polypow(c, pow, maxpower=...): ...
|
| 24 |
+
def polyder(c, m=..., scl=..., axis=...): ...
|
| 25 |
+
def polyint(c, m=..., k=..., lbnd=..., scl=..., axis=...): ...
|
| 26 |
+
def polyval(x, c, tensor=...): ...
|
| 27 |
+
def polyvalfromroots(x, r, tensor=...): ...
|
| 28 |
+
def polyval2d(x, y, c): ...
|
| 29 |
+
def polygrid2d(x, y, c): ...
|
| 30 |
+
def polyval3d(x, y, z, c): ...
|
| 31 |
+
def polygrid3d(x, y, z, c): ...
|
| 32 |
+
def polyvander(x, deg): ...
|
| 33 |
+
def polyvander2d(x, y, deg): ...
|
| 34 |
+
def polyvander3d(x, y, z, deg): ...
|
| 35 |
+
def polyfit(x, y, deg, rcond=..., full=..., w=...): ...
|
| 36 |
+
def polyroots(c): ...
|
| 37 |
+
|
| 38 |
+
class Polynomial(ABCPolyBase):
|
| 39 |
+
domain: Any
|
| 40 |
+
window: Any
|
| 41 |
+
basis_name: Any
|
lib/python3.12/site-packages/numpy/polynomial/polyutils.py
ADDED
|
@@ -0,0 +1,789 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Utility classes and functions for the polynomial modules.
|
| 3 |
+
|
| 4 |
+
This module provides: error and warning objects; a polynomial base class;
|
| 5 |
+
and some routines used in both the `polynomial` and `chebyshev` modules.
|
| 6 |
+
|
| 7 |
+
Warning objects
|
| 8 |
+
---------------
|
| 9 |
+
|
| 10 |
+
.. autosummary::
|
| 11 |
+
:toctree: generated/
|
| 12 |
+
|
| 13 |
+
RankWarning raised in least-squares fit for rank-deficient matrix.
|
| 14 |
+
|
| 15 |
+
Functions
|
| 16 |
+
---------
|
| 17 |
+
|
| 18 |
+
.. autosummary::
|
| 19 |
+
:toctree: generated/
|
| 20 |
+
|
| 21 |
+
as_series convert list of array_likes into 1-D arrays of common type.
|
| 22 |
+
trimseq remove trailing zeros.
|
| 23 |
+
trimcoef remove small trailing coefficients.
|
| 24 |
+
getdomain return the domain appropriate for a given set of abscissae.
|
| 25 |
+
mapdomain maps points between domains.
|
| 26 |
+
mapparms parameters of the linear map between domains.
|
| 27 |
+
|
| 28 |
+
"""
|
| 29 |
+
import operator
|
| 30 |
+
import functools
|
| 31 |
+
import warnings
|
| 32 |
+
|
| 33 |
+
import numpy as np
|
| 34 |
+
|
| 35 |
+
from numpy.core.multiarray import dragon4_positional, dragon4_scientific
|
| 36 |
+
from numpy.core.umath import absolute
|
| 37 |
+
|
| 38 |
+
__all__ = [
|
| 39 |
+
'RankWarning', 'as_series', 'trimseq',
|
| 40 |
+
'trimcoef', 'getdomain', 'mapdomain', 'mapparms',
|
| 41 |
+
'format_float']
|
| 42 |
+
|
| 43 |
+
#
|
| 44 |
+
# Warnings and Exceptions
|
| 45 |
+
#
|
| 46 |
+
|
| 47 |
+
class RankWarning(UserWarning):
|
| 48 |
+
"""Issued by chebfit when the design matrix is rank deficient."""
|
| 49 |
+
pass
|
| 50 |
+
|
| 51 |
+
#
|
| 52 |
+
# Helper functions to convert inputs to 1-D arrays
|
| 53 |
+
#
|
| 54 |
+
def trimseq(seq):
|
| 55 |
+
"""Remove small Poly series coefficients.
|
| 56 |
+
|
| 57 |
+
Parameters
|
| 58 |
+
----------
|
| 59 |
+
seq : sequence
|
| 60 |
+
Sequence of Poly series coefficients. This routine fails for
|
| 61 |
+
empty sequences.
|
| 62 |
+
|
| 63 |
+
Returns
|
| 64 |
+
-------
|
| 65 |
+
series : sequence
|
| 66 |
+
Subsequence with trailing zeros removed. If the resulting sequence
|
| 67 |
+
would be empty, return the first element. The returned sequence may
|
| 68 |
+
or may not be a view.
|
| 69 |
+
|
| 70 |
+
Notes
|
| 71 |
+
-----
|
| 72 |
+
Do not lose the type info if the sequence contains unknown objects.
|
| 73 |
+
|
| 74 |
+
"""
|
| 75 |
+
if len(seq) == 0:
|
| 76 |
+
return seq
|
| 77 |
+
else:
|
| 78 |
+
for i in range(len(seq) - 1, -1, -1):
|
| 79 |
+
if seq[i] != 0:
|
| 80 |
+
break
|
| 81 |
+
return seq[:i+1]
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def as_series(alist, trim=True):
|
| 85 |
+
"""
|
| 86 |
+
Return argument as a list of 1-d arrays.
|
| 87 |
+
|
| 88 |
+
The returned list contains array(s) of dtype double, complex double, or
|
| 89 |
+
object. A 1-d argument of shape ``(N,)`` is parsed into ``N`` arrays of
|
| 90 |
+
size one; a 2-d argument of shape ``(M,N)`` is parsed into ``M`` arrays
|
| 91 |
+
of size ``N`` (i.e., is "parsed by row"); and a higher dimensional array
|
| 92 |
+
raises a Value Error if it is not first reshaped into either a 1-d or 2-d
|
| 93 |
+
array.
|
| 94 |
+
|
| 95 |
+
Parameters
|
| 96 |
+
----------
|
| 97 |
+
alist : array_like
|
| 98 |
+
A 1- or 2-d array_like
|
| 99 |
+
trim : boolean, optional
|
| 100 |
+
When True, trailing zeros are removed from the inputs.
|
| 101 |
+
When False, the inputs are passed through intact.
|
| 102 |
+
|
| 103 |
+
Returns
|
| 104 |
+
-------
|
| 105 |
+
[a1, a2,...] : list of 1-D arrays
|
| 106 |
+
A copy of the input data as a list of 1-d arrays.
|
| 107 |
+
|
| 108 |
+
Raises
|
| 109 |
+
------
|
| 110 |
+
ValueError
|
| 111 |
+
Raised when `as_series` cannot convert its input to 1-d arrays, or at
|
| 112 |
+
least one of the resulting arrays is empty.
|
| 113 |
+
|
| 114 |
+
Examples
|
| 115 |
+
--------
|
| 116 |
+
>>> from numpy.polynomial import polyutils as pu
|
| 117 |
+
>>> a = np.arange(4)
|
| 118 |
+
>>> pu.as_series(a)
|
| 119 |
+
[array([0.]), array([1.]), array([2.]), array([3.])]
|
| 120 |
+
>>> b = np.arange(6).reshape((2,3))
|
| 121 |
+
>>> pu.as_series(b)
|
| 122 |
+
[array([0., 1., 2.]), array([3., 4., 5.])]
|
| 123 |
+
|
| 124 |
+
>>> pu.as_series((1, np.arange(3), np.arange(2, dtype=np.float16)))
|
| 125 |
+
[array([1.]), array([0., 1., 2.]), array([0., 1.])]
|
| 126 |
+
|
| 127 |
+
>>> pu.as_series([2, [1.1, 0.]])
|
| 128 |
+
[array([2.]), array([1.1])]
|
| 129 |
+
|
| 130 |
+
>>> pu.as_series([2, [1.1, 0.]], trim=False)
|
| 131 |
+
[array([2.]), array([1.1, 0. ])]
|
| 132 |
+
|
| 133 |
+
"""
|
| 134 |
+
arrays = [np.array(a, ndmin=1, copy=False) for a in alist]
|
| 135 |
+
if min([a.size for a in arrays]) == 0:
|
| 136 |
+
raise ValueError("Coefficient array is empty")
|
| 137 |
+
if any(a.ndim != 1 for a in arrays):
|
| 138 |
+
raise ValueError("Coefficient array is not 1-d")
|
| 139 |
+
if trim:
|
| 140 |
+
arrays = [trimseq(a) for a in arrays]
|
| 141 |
+
|
| 142 |
+
if any(a.dtype == np.dtype(object) for a in arrays):
|
| 143 |
+
ret = []
|
| 144 |
+
for a in arrays:
|
| 145 |
+
if a.dtype != np.dtype(object):
|
| 146 |
+
tmp = np.empty(len(a), dtype=np.dtype(object))
|
| 147 |
+
tmp[:] = a[:]
|
| 148 |
+
ret.append(tmp)
|
| 149 |
+
else:
|
| 150 |
+
ret.append(a.copy())
|
| 151 |
+
else:
|
| 152 |
+
try:
|
| 153 |
+
dtype = np.common_type(*arrays)
|
| 154 |
+
except Exception as e:
|
| 155 |
+
raise ValueError("Coefficient arrays have no common type") from e
|
| 156 |
+
ret = [np.array(a, copy=True, dtype=dtype) for a in arrays]
|
| 157 |
+
return ret
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
def trimcoef(c, tol=0):
|
| 161 |
+
"""
|
| 162 |
+
Remove "small" "trailing" coefficients from a polynomial.
|
| 163 |
+
|
| 164 |
+
"Small" means "small in absolute value" and is controlled by the
|
| 165 |
+
parameter `tol`; "trailing" means highest order coefficient(s), e.g., in
|
| 166 |
+
``[0, 1, 1, 0, 0]`` (which represents ``0 + x + x**2 + 0*x**3 + 0*x**4``)
|
| 167 |
+
both the 3-rd and 4-th order coefficients would be "trimmed."
|
| 168 |
+
|
| 169 |
+
Parameters
|
| 170 |
+
----------
|
| 171 |
+
c : array_like
|
| 172 |
+
1-d array of coefficients, ordered from lowest order to highest.
|
| 173 |
+
tol : number, optional
|
| 174 |
+
Trailing (i.e., highest order) elements with absolute value less
|
| 175 |
+
than or equal to `tol` (default value is zero) are removed.
|
| 176 |
+
|
| 177 |
+
Returns
|
| 178 |
+
-------
|
| 179 |
+
trimmed : ndarray
|
| 180 |
+
1-d array with trailing zeros removed. If the resulting series
|
| 181 |
+
would be empty, a series containing a single zero is returned.
|
| 182 |
+
|
| 183 |
+
Raises
|
| 184 |
+
------
|
| 185 |
+
ValueError
|
| 186 |
+
If `tol` < 0
|
| 187 |
+
|
| 188 |
+
See Also
|
| 189 |
+
--------
|
| 190 |
+
trimseq
|
| 191 |
+
|
| 192 |
+
Examples
|
| 193 |
+
--------
|
| 194 |
+
>>> from numpy.polynomial import polyutils as pu
|
| 195 |
+
>>> pu.trimcoef((0,0,3,0,5,0,0))
|
| 196 |
+
array([0., 0., 3., 0., 5.])
|
| 197 |
+
>>> pu.trimcoef((0,0,1e-3,0,1e-5,0,0),1e-3) # item == tol is trimmed
|
| 198 |
+
array([0.])
|
| 199 |
+
>>> i = complex(0,1) # works for complex
|
| 200 |
+
>>> pu.trimcoef((3e-4,1e-3*(1-i),5e-4,2e-5*(1+i)), 1e-3)
|
| 201 |
+
array([0.0003+0.j , 0.001 -0.001j])
|
| 202 |
+
|
| 203 |
+
"""
|
| 204 |
+
if tol < 0:
|
| 205 |
+
raise ValueError("tol must be non-negative")
|
| 206 |
+
|
| 207 |
+
[c] = as_series([c])
|
| 208 |
+
[ind] = np.nonzero(np.abs(c) > tol)
|
| 209 |
+
if len(ind) == 0:
|
| 210 |
+
return c[:1]*0
|
| 211 |
+
else:
|
| 212 |
+
return c[:ind[-1] + 1].copy()
|
| 213 |
+
|
| 214 |
+
def getdomain(x):
|
| 215 |
+
"""
|
| 216 |
+
Return a domain suitable for given abscissae.
|
| 217 |
+
|
| 218 |
+
Find a domain suitable for a polynomial or Chebyshev series
|
| 219 |
+
defined at the values supplied.
|
| 220 |
+
|
| 221 |
+
Parameters
|
| 222 |
+
----------
|
| 223 |
+
x : array_like
|
| 224 |
+
1-d array of abscissae whose domain will be determined.
|
| 225 |
+
|
| 226 |
+
Returns
|
| 227 |
+
-------
|
| 228 |
+
domain : ndarray
|
| 229 |
+
1-d array containing two values. If the inputs are complex, then
|
| 230 |
+
the two returned points are the lower left and upper right corners
|
| 231 |
+
of the smallest rectangle (aligned with the axes) in the complex
|
| 232 |
+
plane containing the points `x`. If the inputs are real, then the
|
| 233 |
+
two points are the ends of the smallest interval containing the
|
| 234 |
+
points `x`.
|
| 235 |
+
|
| 236 |
+
See Also
|
| 237 |
+
--------
|
| 238 |
+
mapparms, mapdomain
|
| 239 |
+
|
| 240 |
+
Examples
|
| 241 |
+
--------
|
| 242 |
+
>>> from numpy.polynomial import polyutils as pu
|
| 243 |
+
>>> points = np.arange(4)**2 - 5; points
|
| 244 |
+
array([-5, -4, -1, 4])
|
| 245 |
+
>>> pu.getdomain(points)
|
| 246 |
+
array([-5., 4.])
|
| 247 |
+
>>> c = np.exp(complex(0,1)*np.pi*np.arange(12)/6) # unit circle
|
| 248 |
+
>>> pu.getdomain(c)
|
| 249 |
+
array([-1.-1.j, 1.+1.j])
|
| 250 |
+
|
| 251 |
+
"""
|
| 252 |
+
[x] = as_series([x], trim=False)
|
| 253 |
+
if x.dtype.char in np.typecodes['Complex']:
|
| 254 |
+
rmin, rmax = x.real.min(), x.real.max()
|
| 255 |
+
imin, imax = x.imag.min(), x.imag.max()
|
| 256 |
+
return np.array((complex(rmin, imin), complex(rmax, imax)))
|
| 257 |
+
else:
|
| 258 |
+
return np.array((x.min(), x.max()))
|
| 259 |
+
|
| 260 |
+
def mapparms(old, new):
|
| 261 |
+
"""
|
| 262 |
+
Linear map parameters between domains.
|
| 263 |
+
|
| 264 |
+
Return the parameters of the linear map ``offset + scale*x`` that maps
|
| 265 |
+
`old` to `new` such that ``old[i] -> new[i]``, ``i = 0, 1``.
|
| 266 |
+
|
| 267 |
+
Parameters
|
| 268 |
+
----------
|
| 269 |
+
old, new : array_like
|
| 270 |
+
Domains. Each domain must (successfully) convert to a 1-d array
|
| 271 |
+
containing precisely two values.
|
| 272 |
+
|
| 273 |
+
Returns
|
| 274 |
+
-------
|
| 275 |
+
offset, scale : scalars
|
| 276 |
+
The map ``L(x) = offset + scale*x`` maps the first domain to the
|
| 277 |
+
second.
|
| 278 |
+
|
| 279 |
+
See Also
|
| 280 |
+
--------
|
| 281 |
+
getdomain, mapdomain
|
| 282 |
+
|
| 283 |
+
Notes
|
| 284 |
+
-----
|
| 285 |
+
Also works for complex numbers, and thus can be used to calculate the
|
| 286 |
+
parameters required to map any line in the complex plane to any other
|
| 287 |
+
line therein.
|
| 288 |
+
|
| 289 |
+
Examples
|
| 290 |
+
--------
|
| 291 |
+
>>> from numpy.polynomial import polyutils as pu
|
| 292 |
+
>>> pu.mapparms((-1,1),(-1,1))
|
| 293 |
+
(0.0, 1.0)
|
| 294 |
+
>>> pu.mapparms((1,-1),(-1,1))
|
| 295 |
+
(-0.0, -1.0)
|
| 296 |
+
>>> i = complex(0,1)
|
| 297 |
+
>>> pu.mapparms((-i,-1),(1,i))
|
| 298 |
+
((1+1j), (1-0j))
|
| 299 |
+
|
| 300 |
+
"""
|
| 301 |
+
oldlen = old[1] - old[0]
|
| 302 |
+
newlen = new[1] - new[0]
|
| 303 |
+
off = (old[1]*new[0] - old[0]*new[1])/oldlen
|
| 304 |
+
scl = newlen/oldlen
|
| 305 |
+
return off, scl
|
| 306 |
+
|
| 307 |
+
def mapdomain(x, old, new):
|
| 308 |
+
"""
|
| 309 |
+
Apply linear map to input points.
|
| 310 |
+
|
| 311 |
+
The linear map ``offset + scale*x`` that maps the domain `old` to
|
| 312 |
+
the domain `new` is applied to the points `x`.
|
| 313 |
+
|
| 314 |
+
Parameters
|
| 315 |
+
----------
|
| 316 |
+
x : array_like
|
| 317 |
+
Points to be mapped. If `x` is a subtype of ndarray the subtype
|
| 318 |
+
will be preserved.
|
| 319 |
+
old, new : array_like
|
| 320 |
+
The two domains that determine the map. Each must (successfully)
|
| 321 |
+
convert to 1-d arrays containing precisely two values.
|
| 322 |
+
|
| 323 |
+
Returns
|
| 324 |
+
-------
|
| 325 |
+
x_out : ndarray
|
| 326 |
+
Array of points of the same shape as `x`, after application of the
|
| 327 |
+
linear map between the two domains.
|
| 328 |
+
|
| 329 |
+
See Also
|
| 330 |
+
--------
|
| 331 |
+
getdomain, mapparms
|
| 332 |
+
|
| 333 |
+
Notes
|
| 334 |
+
-----
|
| 335 |
+
Effectively, this implements:
|
| 336 |
+
|
| 337 |
+
.. math::
|
| 338 |
+
x\\_out = new[0] + m(x - old[0])
|
| 339 |
+
|
| 340 |
+
where
|
| 341 |
+
|
| 342 |
+
.. math::
|
| 343 |
+
m = \\frac{new[1]-new[0]}{old[1]-old[0]}
|
| 344 |
+
|
| 345 |
+
Examples
|
| 346 |
+
--------
|
| 347 |
+
>>> from numpy.polynomial import polyutils as pu
|
| 348 |
+
>>> old_domain = (-1,1)
|
| 349 |
+
>>> new_domain = (0,2*np.pi)
|
| 350 |
+
>>> x = np.linspace(-1,1,6); x
|
| 351 |
+
array([-1. , -0.6, -0.2, 0.2, 0.6, 1. ])
|
| 352 |
+
>>> x_out = pu.mapdomain(x, old_domain, new_domain); x_out
|
| 353 |
+
array([ 0. , 1.25663706, 2.51327412, 3.76991118, 5.02654825, # may vary
|
| 354 |
+
6.28318531])
|
| 355 |
+
>>> x - pu.mapdomain(x_out, new_domain, old_domain)
|
| 356 |
+
array([0., 0., 0., 0., 0., 0.])
|
| 357 |
+
|
| 358 |
+
Also works for complex numbers (and thus can be used to map any line in
|
| 359 |
+
the complex plane to any other line therein).
|
| 360 |
+
|
| 361 |
+
>>> i = complex(0,1)
|
| 362 |
+
>>> old = (-1 - i, 1 + i)
|
| 363 |
+
>>> new = (-1 + i, 1 - i)
|
| 364 |
+
>>> z = np.linspace(old[0], old[1], 6); z
|
| 365 |
+
array([-1. -1.j , -0.6-0.6j, -0.2-0.2j, 0.2+0.2j, 0.6+0.6j, 1. +1.j ])
|
| 366 |
+
>>> new_z = pu.mapdomain(z, old, new); new_z
|
| 367 |
+
array([-1.0+1.j , -0.6+0.6j, -0.2+0.2j, 0.2-0.2j, 0.6-0.6j, 1.0-1.j ]) # may vary
|
| 368 |
+
|
| 369 |
+
"""
|
| 370 |
+
x = np.asanyarray(x)
|
| 371 |
+
off, scl = mapparms(old, new)
|
| 372 |
+
return off + scl*x
|
| 373 |
+
|
| 374 |
+
|
| 375 |
+
def _nth_slice(i, ndim):
|
| 376 |
+
sl = [np.newaxis] * ndim
|
| 377 |
+
sl[i] = slice(None)
|
| 378 |
+
return tuple(sl)
|
| 379 |
+
|
| 380 |
+
|
| 381 |
+
def _vander_nd(vander_fs, points, degrees):
|
| 382 |
+
r"""
|
| 383 |
+
A generalization of the Vandermonde matrix for N dimensions
|
| 384 |
+
|
| 385 |
+
The result is built by combining the results of 1d Vandermonde matrices,
|
| 386 |
+
|
| 387 |
+
.. math::
|
| 388 |
+
W[i_0, \ldots, i_M, j_0, \ldots, j_N] = \prod_{k=0}^N{V_k(x_k)[i_0, \ldots, i_M, j_k]}
|
| 389 |
+
|
| 390 |
+
where
|
| 391 |
+
|
| 392 |
+
.. math::
|
| 393 |
+
N &= \texttt{len(points)} = \texttt{len(degrees)} = \texttt{len(vander\_fs)} \\
|
| 394 |
+
M &= \texttt{points[k].ndim} \\
|
| 395 |
+
V_k &= \texttt{vander\_fs[k]} \\
|
| 396 |
+
x_k &= \texttt{points[k]} \\
|
| 397 |
+
0 \le j_k &\le \texttt{degrees[k]}
|
| 398 |
+
|
| 399 |
+
Expanding the one-dimensional :math:`V_k` functions gives:
|
| 400 |
+
|
| 401 |
+
.. math::
|
| 402 |
+
W[i_0, \ldots, i_M, j_0, \ldots, j_N] = \prod_{k=0}^N{B_{k, j_k}(x_k[i_0, \ldots, i_M])}
|
| 403 |
+
|
| 404 |
+
where :math:`B_{k,m}` is the m'th basis of the polynomial construction used along
|
| 405 |
+
dimension :math:`k`. For a regular polynomial, :math:`B_{k, m}(x) = P_m(x) = x^m`.
|
| 406 |
+
|
| 407 |
+
Parameters
|
| 408 |
+
----------
|
| 409 |
+
vander_fs : Sequence[function(array_like, int) -> ndarray]
|
| 410 |
+
The 1d vander function to use for each axis, such as ``polyvander``
|
| 411 |
+
points : Sequence[array_like]
|
| 412 |
+
Arrays of point coordinates, all of the same shape. The dtypes
|
| 413 |
+
will be converted to either float64 or complex128 depending on
|
| 414 |
+
whether any of the elements are complex. Scalars are converted to
|
| 415 |
+
1-D arrays.
|
| 416 |
+
This must be the same length as `vander_fs`.
|
| 417 |
+
degrees : Sequence[int]
|
| 418 |
+
The maximum degree (inclusive) to use for each axis.
|
| 419 |
+
This must be the same length as `vander_fs`.
|
| 420 |
+
|
| 421 |
+
Returns
|
| 422 |
+
-------
|
| 423 |
+
vander_nd : ndarray
|
| 424 |
+
An array of shape ``points[0].shape + tuple(d + 1 for d in degrees)``.
|
| 425 |
+
"""
|
| 426 |
+
n_dims = len(vander_fs)
|
| 427 |
+
if n_dims != len(points):
|
| 428 |
+
raise ValueError(
|
| 429 |
+
f"Expected {n_dims} dimensions of sample points, got {len(points)}")
|
| 430 |
+
if n_dims != len(degrees):
|
| 431 |
+
raise ValueError(
|
| 432 |
+
f"Expected {n_dims} dimensions of degrees, got {len(degrees)}")
|
| 433 |
+
if n_dims == 0:
|
| 434 |
+
raise ValueError("Unable to guess a dtype or shape when no points are given")
|
| 435 |
+
|
| 436 |
+
# convert to the same shape and type
|
| 437 |
+
points = tuple(np.array(tuple(points), copy=False) + 0.0)
|
| 438 |
+
|
| 439 |
+
# produce the vandermonde matrix for each dimension, placing the last
|
| 440 |
+
# axis of each in an independent trailing axis of the output
|
| 441 |
+
vander_arrays = (
|
| 442 |
+
vander_fs[i](points[i], degrees[i])[(...,) + _nth_slice(i, n_dims)]
|
| 443 |
+
for i in range(n_dims)
|
| 444 |
+
)
|
| 445 |
+
|
| 446 |
+
# we checked this wasn't empty already, so no `initial` needed
|
| 447 |
+
return functools.reduce(operator.mul, vander_arrays)
|
| 448 |
+
|
| 449 |
+
|
| 450 |
+
def _vander_nd_flat(vander_fs, points, degrees):
|
| 451 |
+
"""
|
| 452 |
+
Like `_vander_nd`, but flattens the last ``len(degrees)`` axes into a single axis
|
| 453 |
+
|
| 454 |
+
Used to implement the public ``<type>vander<n>d`` functions.
|
| 455 |
+
"""
|
| 456 |
+
v = _vander_nd(vander_fs, points, degrees)
|
| 457 |
+
return v.reshape(v.shape[:-len(degrees)] + (-1,))
|
| 458 |
+
|
| 459 |
+
|
| 460 |
+
def _fromroots(line_f, mul_f, roots):
|
| 461 |
+
"""
|
| 462 |
+
Helper function used to implement the ``<type>fromroots`` functions.
|
| 463 |
+
|
| 464 |
+
Parameters
|
| 465 |
+
----------
|
| 466 |
+
line_f : function(float, float) -> ndarray
|
| 467 |
+
The ``<type>line`` function, such as ``polyline``
|
| 468 |
+
mul_f : function(array_like, array_like) -> ndarray
|
| 469 |
+
The ``<type>mul`` function, such as ``polymul``
|
| 470 |
+
roots
|
| 471 |
+
See the ``<type>fromroots`` functions for more detail
|
| 472 |
+
"""
|
| 473 |
+
if len(roots) == 0:
|
| 474 |
+
return np.ones(1)
|
| 475 |
+
else:
|
| 476 |
+
[roots] = as_series([roots], trim=False)
|
| 477 |
+
roots.sort()
|
| 478 |
+
p = [line_f(-r, 1) for r in roots]
|
| 479 |
+
n = len(p)
|
| 480 |
+
while n > 1:
|
| 481 |
+
m, r = divmod(n, 2)
|
| 482 |
+
tmp = [mul_f(p[i], p[i+m]) for i in range(m)]
|
| 483 |
+
if r:
|
| 484 |
+
tmp[0] = mul_f(tmp[0], p[-1])
|
| 485 |
+
p = tmp
|
| 486 |
+
n = m
|
| 487 |
+
return p[0]
|
| 488 |
+
|
| 489 |
+
|
| 490 |
+
def _valnd(val_f, c, *args):
|
| 491 |
+
"""
|
| 492 |
+
Helper function used to implement the ``<type>val<n>d`` functions.
|
| 493 |
+
|
| 494 |
+
Parameters
|
| 495 |
+
----------
|
| 496 |
+
val_f : function(array_like, array_like, tensor: bool) -> array_like
|
| 497 |
+
The ``<type>val`` function, such as ``polyval``
|
| 498 |
+
c, args
|
| 499 |
+
See the ``<type>val<n>d`` functions for more detail
|
| 500 |
+
"""
|
| 501 |
+
args = [np.asanyarray(a) for a in args]
|
| 502 |
+
shape0 = args[0].shape
|
| 503 |
+
if not all((a.shape == shape0 for a in args[1:])):
|
| 504 |
+
if len(args) == 3:
|
| 505 |
+
raise ValueError('x, y, z are incompatible')
|
| 506 |
+
elif len(args) == 2:
|
| 507 |
+
raise ValueError('x, y are incompatible')
|
| 508 |
+
else:
|
| 509 |
+
raise ValueError('ordinates are incompatible')
|
| 510 |
+
it = iter(args)
|
| 511 |
+
x0 = next(it)
|
| 512 |
+
|
| 513 |
+
# use tensor on only the first
|
| 514 |
+
c = val_f(x0, c)
|
| 515 |
+
for xi in it:
|
| 516 |
+
c = val_f(xi, c, tensor=False)
|
| 517 |
+
return c
|
| 518 |
+
|
| 519 |
+
|
| 520 |
+
def _gridnd(val_f, c, *args):
|
| 521 |
+
"""
|
| 522 |
+
Helper function used to implement the ``<type>grid<n>d`` functions.
|
| 523 |
+
|
| 524 |
+
Parameters
|
| 525 |
+
----------
|
| 526 |
+
val_f : function(array_like, array_like, tensor: bool) -> array_like
|
| 527 |
+
The ``<type>val`` function, such as ``polyval``
|
| 528 |
+
c, args
|
| 529 |
+
See the ``<type>grid<n>d`` functions for more detail
|
| 530 |
+
"""
|
| 531 |
+
for xi in args:
|
| 532 |
+
c = val_f(xi, c)
|
| 533 |
+
return c
|
| 534 |
+
|
| 535 |
+
|
| 536 |
+
def _div(mul_f, c1, c2):
|
| 537 |
+
"""
|
| 538 |
+
Helper function used to implement the ``<type>div`` functions.
|
| 539 |
+
|
| 540 |
+
Implementation uses repeated subtraction of c2 multiplied by the nth basis.
|
| 541 |
+
For some polynomial types, a more efficient approach may be possible.
|
| 542 |
+
|
| 543 |
+
Parameters
|
| 544 |
+
----------
|
| 545 |
+
mul_f : function(array_like, array_like) -> array_like
|
| 546 |
+
The ``<type>mul`` function, such as ``polymul``
|
| 547 |
+
c1, c2
|
| 548 |
+
See the ``<type>div`` functions for more detail
|
| 549 |
+
"""
|
| 550 |
+
# c1, c2 are trimmed copies
|
| 551 |
+
[c1, c2] = as_series([c1, c2])
|
| 552 |
+
if c2[-1] == 0:
|
| 553 |
+
raise ZeroDivisionError()
|
| 554 |
+
|
| 555 |
+
lc1 = len(c1)
|
| 556 |
+
lc2 = len(c2)
|
| 557 |
+
if lc1 < lc2:
|
| 558 |
+
return c1[:1]*0, c1
|
| 559 |
+
elif lc2 == 1:
|
| 560 |
+
return c1/c2[-1], c1[:1]*0
|
| 561 |
+
else:
|
| 562 |
+
quo = np.empty(lc1 - lc2 + 1, dtype=c1.dtype)
|
| 563 |
+
rem = c1
|
| 564 |
+
for i in range(lc1 - lc2, - 1, -1):
|
| 565 |
+
p = mul_f([0]*i + [1], c2)
|
| 566 |
+
q = rem[-1]/p[-1]
|
| 567 |
+
rem = rem[:-1] - q*p[:-1]
|
| 568 |
+
quo[i] = q
|
| 569 |
+
return quo, trimseq(rem)
|
| 570 |
+
|
| 571 |
+
|
| 572 |
+
def _add(c1, c2):
|
| 573 |
+
""" Helper function used to implement the ``<type>add`` functions. """
|
| 574 |
+
# c1, c2 are trimmed copies
|
| 575 |
+
[c1, c2] = as_series([c1, c2])
|
| 576 |
+
if len(c1) > len(c2):
|
| 577 |
+
c1[:c2.size] += c2
|
| 578 |
+
ret = c1
|
| 579 |
+
else:
|
| 580 |
+
c2[:c1.size] += c1
|
| 581 |
+
ret = c2
|
| 582 |
+
return trimseq(ret)
|
| 583 |
+
|
| 584 |
+
|
| 585 |
+
def _sub(c1, c2):
|
| 586 |
+
""" Helper function used to implement the ``<type>sub`` functions. """
|
| 587 |
+
# c1, c2 are trimmed copies
|
| 588 |
+
[c1, c2] = as_series([c1, c2])
|
| 589 |
+
if len(c1) > len(c2):
|
| 590 |
+
c1[:c2.size] -= c2
|
| 591 |
+
ret = c1
|
| 592 |
+
else:
|
| 593 |
+
c2 = -c2
|
| 594 |
+
c2[:c1.size] += c1
|
| 595 |
+
ret = c2
|
| 596 |
+
return trimseq(ret)
|
| 597 |
+
|
| 598 |
+
|
| 599 |
+
def _fit(vander_f, x, y, deg, rcond=None, full=False, w=None):
|
| 600 |
+
"""
|
| 601 |
+
Helper function used to implement the ``<type>fit`` functions.
|
| 602 |
+
|
| 603 |
+
Parameters
|
| 604 |
+
----------
|
| 605 |
+
vander_f : function(array_like, int) -> ndarray
|
| 606 |
+
The 1d vander function, such as ``polyvander``
|
| 607 |
+
c1, c2
|
| 608 |
+
See the ``<type>fit`` functions for more detail
|
| 609 |
+
"""
|
| 610 |
+
x = np.asarray(x) + 0.0
|
| 611 |
+
y = np.asarray(y) + 0.0
|
| 612 |
+
deg = np.asarray(deg)
|
| 613 |
+
|
| 614 |
+
# check arguments.
|
| 615 |
+
if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
|
| 616 |
+
raise TypeError("deg must be an int or non-empty 1-D array of int")
|
| 617 |
+
if deg.min() < 0:
|
| 618 |
+
raise ValueError("expected deg >= 0")
|
| 619 |
+
if x.ndim != 1:
|
| 620 |
+
raise TypeError("expected 1D vector for x")
|
| 621 |
+
if x.size == 0:
|
| 622 |
+
raise TypeError("expected non-empty vector for x")
|
| 623 |
+
if y.ndim < 1 or y.ndim > 2:
|
| 624 |
+
raise TypeError("expected 1D or 2D array for y")
|
| 625 |
+
if len(x) != len(y):
|
| 626 |
+
raise TypeError("expected x and y to have same length")
|
| 627 |
+
|
| 628 |
+
if deg.ndim == 0:
|
| 629 |
+
lmax = deg
|
| 630 |
+
order = lmax + 1
|
| 631 |
+
van = vander_f(x, lmax)
|
| 632 |
+
else:
|
| 633 |
+
deg = np.sort(deg)
|
| 634 |
+
lmax = deg[-1]
|
| 635 |
+
order = len(deg)
|
| 636 |
+
van = vander_f(x, lmax)[:, deg]
|
| 637 |
+
|
| 638 |
+
# set up the least squares matrices in transposed form
|
| 639 |
+
lhs = van.T
|
| 640 |
+
rhs = y.T
|
| 641 |
+
if w is not None:
|
| 642 |
+
w = np.asarray(w) + 0.0
|
| 643 |
+
if w.ndim != 1:
|
| 644 |
+
raise TypeError("expected 1D vector for w")
|
| 645 |
+
if len(x) != len(w):
|
| 646 |
+
raise TypeError("expected x and w to have same length")
|
| 647 |
+
# apply weights. Don't use inplace operations as they
|
| 648 |
+
# can cause problems with NA.
|
| 649 |
+
lhs = lhs * w
|
| 650 |
+
rhs = rhs * w
|
| 651 |
+
|
| 652 |
+
# set rcond
|
| 653 |
+
if rcond is None:
|
| 654 |
+
rcond = len(x)*np.finfo(x.dtype).eps
|
| 655 |
+
|
| 656 |
+
# Determine the norms of the design matrix columns.
|
| 657 |
+
if issubclass(lhs.dtype.type, np.complexfloating):
|
| 658 |
+
scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
|
| 659 |
+
else:
|
| 660 |
+
scl = np.sqrt(np.square(lhs).sum(1))
|
| 661 |
+
scl[scl == 0] = 1
|
| 662 |
+
|
| 663 |
+
# Solve the least squares problem.
|
| 664 |
+
c, resids, rank, s = np.linalg.lstsq(lhs.T/scl, rhs.T, rcond)
|
| 665 |
+
c = (c.T/scl).T
|
| 666 |
+
|
| 667 |
+
# Expand c to include non-fitted coefficients which are set to zero
|
| 668 |
+
if deg.ndim > 0:
|
| 669 |
+
if c.ndim == 2:
|
| 670 |
+
cc = np.zeros((lmax+1, c.shape[1]), dtype=c.dtype)
|
| 671 |
+
else:
|
| 672 |
+
cc = np.zeros(lmax+1, dtype=c.dtype)
|
| 673 |
+
cc[deg] = c
|
| 674 |
+
c = cc
|
| 675 |
+
|
| 676 |
+
# warn on rank reduction
|
| 677 |
+
if rank != order and not full:
|
| 678 |
+
msg = "The fit may be poorly conditioned"
|
| 679 |
+
warnings.warn(msg, RankWarning, stacklevel=2)
|
| 680 |
+
|
| 681 |
+
if full:
|
| 682 |
+
return c, [resids, rank, s, rcond]
|
| 683 |
+
else:
|
| 684 |
+
return c
|
| 685 |
+
|
| 686 |
+
|
| 687 |
+
def _pow(mul_f, c, pow, maxpower):
|
| 688 |
+
"""
|
| 689 |
+
Helper function used to implement the ``<type>pow`` functions.
|
| 690 |
+
|
| 691 |
+
Parameters
|
| 692 |
+
----------
|
| 693 |
+
mul_f : function(array_like, array_like) -> ndarray
|
| 694 |
+
The ``<type>mul`` function, such as ``polymul``
|
| 695 |
+
c : array_like
|
| 696 |
+
1-D array of array of series coefficients
|
| 697 |
+
pow, maxpower
|
| 698 |
+
See the ``<type>pow`` functions for more detail
|
| 699 |
+
"""
|
| 700 |
+
# c is a trimmed copy
|
| 701 |
+
[c] = as_series([c])
|
| 702 |
+
power = int(pow)
|
| 703 |
+
if power != pow or power < 0:
|
| 704 |
+
raise ValueError("Power must be a non-negative integer.")
|
| 705 |
+
elif maxpower is not None and power > maxpower:
|
| 706 |
+
raise ValueError("Power is too large")
|
| 707 |
+
elif power == 0:
|
| 708 |
+
return np.array([1], dtype=c.dtype)
|
| 709 |
+
elif power == 1:
|
| 710 |
+
return c
|
| 711 |
+
else:
|
| 712 |
+
# This can be made more efficient by using powers of two
|
| 713 |
+
# in the usual way.
|
| 714 |
+
prd = c
|
| 715 |
+
for i in range(2, power + 1):
|
| 716 |
+
prd = mul_f(prd, c)
|
| 717 |
+
return prd
|
| 718 |
+
|
| 719 |
+
|
| 720 |
+
def _deprecate_as_int(x, desc):
|
| 721 |
+
"""
|
| 722 |
+
Like `operator.index`, but emits a deprecation warning when passed a float
|
| 723 |
+
|
| 724 |
+
Parameters
|
| 725 |
+
----------
|
| 726 |
+
x : int-like, or float with integral value
|
| 727 |
+
Value to interpret as an integer
|
| 728 |
+
desc : str
|
| 729 |
+
description to include in any error message
|
| 730 |
+
|
| 731 |
+
Raises
|
| 732 |
+
------
|
| 733 |
+
TypeError : if x is a non-integral float or non-numeric
|
| 734 |
+
DeprecationWarning : if x is an integral float
|
| 735 |
+
"""
|
| 736 |
+
try:
|
| 737 |
+
return operator.index(x)
|
| 738 |
+
except TypeError as e:
|
| 739 |
+
# Numpy 1.17.0, 2019-03-11
|
| 740 |
+
try:
|
| 741 |
+
ix = int(x)
|
| 742 |
+
except TypeError:
|
| 743 |
+
pass
|
| 744 |
+
else:
|
| 745 |
+
if ix == x:
|
| 746 |
+
warnings.warn(
|
| 747 |
+
f"In future, this will raise TypeError, as {desc} will "
|
| 748 |
+
"need to be an integer not just an integral float.",
|
| 749 |
+
DeprecationWarning,
|
| 750 |
+
stacklevel=3
|
| 751 |
+
)
|
| 752 |
+
return ix
|
| 753 |
+
|
| 754 |
+
raise TypeError(f"{desc} must be an integer") from e
|
| 755 |
+
|
| 756 |
+
|
| 757 |
+
def format_float(x, parens=False):
|
| 758 |
+
if not np.issubdtype(type(x), np.floating):
|
| 759 |
+
return str(x)
|
| 760 |
+
|
| 761 |
+
opts = np.get_printoptions()
|
| 762 |
+
|
| 763 |
+
if np.isnan(x):
|
| 764 |
+
return opts['nanstr']
|
| 765 |
+
elif np.isinf(x):
|
| 766 |
+
return opts['infstr']
|
| 767 |
+
|
| 768 |
+
exp_format = False
|
| 769 |
+
if x != 0:
|
| 770 |
+
a = absolute(x)
|
| 771 |
+
if a >= 1.e8 or a < 10**min(0, -(opts['precision']-1)//2):
|
| 772 |
+
exp_format = True
|
| 773 |
+
|
| 774 |
+
trim, unique = '0', True
|
| 775 |
+
if opts['floatmode'] == 'fixed':
|
| 776 |
+
trim, unique = 'k', False
|
| 777 |
+
|
| 778 |
+
if exp_format:
|
| 779 |
+
s = dragon4_scientific(x, precision=opts['precision'],
|
| 780 |
+
unique=unique, trim=trim,
|
| 781 |
+
sign=opts['sign'] == '+')
|
| 782 |
+
if parens:
|
| 783 |
+
s = '(' + s + ')'
|
| 784 |
+
else:
|
| 785 |
+
s = dragon4_positional(x, precision=opts['precision'],
|
| 786 |
+
fractional=True,
|
| 787 |
+
unique=unique, trim=trim,
|
| 788 |
+
sign=opts['sign'] == '+')
|
| 789 |
+
return s
|
lib/python3.12/site-packages/numpy/polynomial/polyutils.pyi
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__all__: list[str]
|
| 2 |
+
|
| 3 |
+
class RankWarning(UserWarning): ...
|
| 4 |
+
|
| 5 |
+
def trimseq(seq): ...
|
| 6 |
+
def as_series(alist, trim=...): ...
|
| 7 |
+
def trimcoef(c, tol=...): ...
|
| 8 |
+
def getdomain(x): ...
|
| 9 |
+
def mapparms(old, new): ...
|
| 10 |
+
def mapdomain(x, old, new): ...
|
| 11 |
+
def format_float(x, parens=...): ...
|
lib/python3.12/site-packages/numpy/polynomial/setup.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
def configuration(parent_package='',top_path=None):
|
| 2 |
+
from numpy.distutils.misc_util import Configuration
|
| 3 |
+
config = Configuration('polynomial', parent_package, top_path)
|
| 4 |
+
config.add_subpackage('tests')
|
| 5 |
+
config.add_data_files('*.pyi')
|
| 6 |
+
return config
|
| 7 |
+
|
| 8 |
+
if __name__ == '__main__':
|
| 9 |
+
from numpy.distutils.core import setup
|
| 10 |
+
setup(configuration=configuration)
|
lib/python3.12/site-packages/numpy/polynomial/tests/__init__.py
ADDED
|
File without changes
|
lib/python3.12/site-packages/numpy/polynomial/tests/__pycache__/test_classes.cpython-312.pyc
ADDED
|
Binary file (33.4 kB). View file
|
|
|