Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .venv/lib/python3.11/site-packages/numpy/f2py/src/fortranobject.c +1423 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/src/fortranobject.h +173 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/abstract_interface/foo.f90 +34 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/abstract_interface/gh18403_mod.f90 +6 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/block_docstring/foo.f +6 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/common/block.f +11 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/common/gh19161.f90 +10 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/isocintrin/isoCtests.f90 +34 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/mixed/foo.f +5 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90 +8 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90 +8 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/module_data/mod.mod +0 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/module_data/module_data_docstring.f90 +12 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/regression/gh25337/data.f90 +8 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/regression/gh25337/use_data.f90 +6 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/regression/inout.f90 +9 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_complex/foo77.f +45 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_complex/foo90.f90 +48 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_logical/foo77.f +56 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_logical/foo90.f90 +59 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_real/foo77.f +45 -0
- .venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_real/foo90.f90 +48 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/__init__.py +11 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/__init__.pyi +15 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/__pycache__/defmatrix.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/__pycache__/setup.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/defmatrix.py +1114 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/defmatrix.pyi +16 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/setup.py +12 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__init__.py +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_defmatrix.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_interaction.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_masked_matrix.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_matrix_linalg.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_multiarray.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_numeric.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_regression.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_defmatrix.py +453 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_interaction.py +354 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_masked_matrix.py +231 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_matrix_linalg.py +93 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_multiarray.py +16 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_numeric.py +17 -0
- .venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_regression.py +31 -0
- .venv/lib/python3.11/site-packages/numpy/polynomial/__init__.pyi +22 -0
- .venv/lib/python3.11/site-packages/numpy/polynomial/chebyshev.pyi +51 -0
- .venv/lib/python3.11/site-packages/numpy/polynomial/hermite.py +1703 -0
- .venv/lib/python3.11/site-packages/numpy/polynomial/hermite_e.py +1695 -0
.venv/lib/python3.11/site-packages/numpy/f2py/src/fortranobject.c
ADDED
@@ -0,0 +1,1423 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#define FORTRANOBJECT_C
|
2 |
+
#include "fortranobject.h"
|
3 |
+
|
4 |
+
#ifdef __cplusplus
|
5 |
+
extern "C" {
|
6 |
+
#endif
|
7 |
+
|
8 |
+
#include <stdarg.h>
|
9 |
+
#include <stdlib.h>
|
10 |
+
#include <string.h>
|
11 |
+
|
12 |
+
/*
|
13 |
+
This file implements: FortranObject, array_from_pyobj, copy_ND_array
|
14 |
+
|
15 |
+
Author: Pearu Peterson <[email protected]>
|
16 |
+
$Revision: 1.52 $
|
17 |
+
$Date: 2005/07/11 07:44:20 $
|
18 |
+
*/
|
19 |
+
|
20 |
+
int
|
21 |
+
F2PyDict_SetItemString(PyObject *dict, char *name, PyObject *obj)
|
22 |
+
{
|
23 |
+
if (obj == NULL) {
|
24 |
+
fprintf(stderr, "Error loading %s\n", name);
|
25 |
+
if (PyErr_Occurred()) {
|
26 |
+
PyErr_Print();
|
27 |
+
PyErr_Clear();
|
28 |
+
}
|
29 |
+
return -1;
|
30 |
+
}
|
31 |
+
return PyDict_SetItemString(dict, name, obj);
|
32 |
+
}
|
33 |
+
|
34 |
+
/*
|
35 |
+
* Python-only fallback for thread-local callback pointers
|
36 |
+
*/
|
37 |
+
void *
|
38 |
+
F2PySwapThreadLocalCallbackPtr(char *key, void *ptr)
|
39 |
+
{
|
40 |
+
PyObject *local_dict, *value;
|
41 |
+
void *prev;
|
42 |
+
|
43 |
+
local_dict = PyThreadState_GetDict();
|
44 |
+
if (local_dict == NULL) {
|
45 |
+
Py_FatalError(
|
46 |
+
"F2PySwapThreadLocalCallbackPtr: PyThreadState_GetDict "
|
47 |
+
"failed");
|
48 |
+
}
|
49 |
+
|
50 |
+
value = PyDict_GetItemString(local_dict, key);
|
51 |
+
if (value != NULL) {
|
52 |
+
prev = PyLong_AsVoidPtr(value);
|
53 |
+
if (PyErr_Occurred()) {
|
54 |
+
Py_FatalError(
|
55 |
+
"F2PySwapThreadLocalCallbackPtr: PyLong_AsVoidPtr failed");
|
56 |
+
}
|
57 |
+
}
|
58 |
+
else {
|
59 |
+
prev = NULL;
|
60 |
+
}
|
61 |
+
|
62 |
+
value = PyLong_FromVoidPtr((void *)ptr);
|
63 |
+
if (value == NULL) {
|
64 |
+
Py_FatalError(
|
65 |
+
"F2PySwapThreadLocalCallbackPtr: PyLong_FromVoidPtr failed");
|
66 |
+
}
|
67 |
+
|
68 |
+
if (PyDict_SetItemString(local_dict, key, value) != 0) {
|
69 |
+
Py_FatalError(
|
70 |
+
"F2PySwapThreadLocalCallbackPtr: PyDict_SetItemString failed");
|
71 |
+
}
|
72 |
+
|
73 |
+
Py_DECREF(value);
|
74 |
+
|
75 |
+
return prev;
|
76 |
+
}
|
77 |
+
|
78 |
+
void *
|
79 |
+
F2PyGetThreadLocalCallbackPtr(char *key)
|
80 |
+
{
|
81 |
+
PyObject *local_dict, *value;
|
82 |
+
void *prev;
|
83 |
+
|
84 |
+
local_dict = PyThreadState_GetDict();
|
85 |
+
if (local_dict == NULL) {
|
86 |
+
Py_FatalError(
|
87 |
+
"F2PyGetThreadLocalCallbackPtr: PyThreadState_GetDict failed");
|
88 |
+
}
|
89 |
+
|
90 |
+
value = PyDict_GetItemString(local_dict, key);
|
91 |
+
if (value != NULL) {
|
92 |
+
prev = PyLong_AsVoidPtr(value);
|
93 |
+
if (PyErr_Occurred()) {
|
94 |
+
Py_FatalError(
|
95 |
+
"F2PyGetThreadLocalCallbackPtr: PyLong_AsVoidPtr failed");
|
96 |
+
}
|
97 |
+
}
|
98 |
+
else {
|
99 |
+
prev = NULL;
|
100 |
+
}
|
101 |
+
|
102 |
+
return prev;
|
103 |
+
}
|
104 |
+
|
105 |
+
static PyArray_Descr *
|
106 |
+
get_descr_from_type_and_elsize(const int type_num, const int elsize) {
|
107 |
+
PyArray_Descr * descr = PyArray_DescrFromType(type_num);
|
108 |
+
if (type_num == NPY_STRING) {
|
109 |
+
// PyArray_DescrFromType returns descr with elsize = 0.
|
110 |
+
PyArray_DESCR_REPLACE(descr);
|
111 |
+
if (descr == NULL) {
|
112 |
+
return NULL;
|
113 |
+
}
|
114 |
+
descr->elsize = elsize;
|
115 |
+
}
|
116 |
+
return descr;
|
117 |
+
}
|
118 |
+
|
119 |
+
/************************* FortranObject *******************************/
|
120 |
+
|
121 |
+
typedef PyObject *(*fortranfunc)(PyObject *, PyObject *, PyObject *, void *);
|
122 |
+
|
123 |
+
PyObject *
|
124 |
+
PyFortranObject_New(FortranDataDef *defs, f2py_void_func init)
|
125 |
+
{
|
126 |
+
int i;
|
127 |
+
PyFortranObject *fp = NULL;
|
128 |
+
PyObject *v = NULL;
|
129 |
+
if (init != NULL) { /* Initialize F90 module objects */
|
130 |
+
(*(init))();
|
131 |
+
}
|
132 |
+
fp = PyObject_New(PyFortranObject, &PyFortran_Type);
|
133 |
+
if (fp == NULL) {
|
134 |
+
return NULL;
|
135 |
+
}
|
136 |
+
if ((fp->dict = PyDict_New()) == NULL) {
|
137 |
+
Py_DECREF(fp);
|
138 |
+
return NULL;
|
139 |
+
}
|
140 |
+
fp->len = 0;
|
141 |
+
while (defs[fp->len].name != NULL) {
|
142 |
+
fp->len++;
|
143 |
+
}
|
144 |
+
if (fp->len == 0) {
|
145 |
+
goto fail;
|
146 |
+
}
|
147 |
+
fp->defs = defs;
|
148 |
+
for (i = 0; i < fp->len; i++) {
|
149 |
+
if (fp->defs[i].rank == -1) { /* Is Fortran routine */
|
150 |
+
v = PyFortranObject_NewAsAttr(&(fp->defs[i]));
|
151 |
+
if (v == NULL) {
|
152 |
+
goto fail;
|
153 |
+
}
|
154 |
+
PyDict_SetItemString(fp->dict, fp->defs[i].name, v);
|
155 |
+
Py_XDECREF(v);
|
156 |
+
}
|
157 |
+
else if ((fp->defs[i].data) !=
|
158 |
+
NULL) { /* Is Fortran variable or array (not allocatable) */
|
159 |
+
PyArray_Descr *
|
160 |
+
descr = get_descr_from_type_and_elsize(fp->defs[i].type,
|
161 |
+
fp->defs[i].elsize);
|
162 |
+
if (descr == NULL) {
|
163 |
+
goto fail;
|
164 |
+
}
|
165 |
+
v = PyArray_NewFromDescr(&PyArray_Type, descr, fp->defs[i].rank,
|
166 |
+
fp->defs[i].dims.d, NULL, fp->defs[i].data,
|
167 |
+
NPY_ARRAY_FARRAY, NULL);
|
168 |
+
if (v == NULL) {
|
169 |
+
Py_DECREF(descr);
|
170 |
+
goto fail;
|
171 |
+
}
|
172 |
+
PyDict_SetItemString(fp->dict, fp->defs[i].name, v);
|
173 |
+
Py_XDECREF(v);
|
174 |
+
}
|
175 |
+
}
|
176 |
+
return (PyObject *)fp;
|
177 |
+
fail:
|
178 |
+
Py_XDECREF(fp);
|
179 |
+
return NULL;
|
180 |
+
}
|
181 |
+
|
182 |
+
PyObject *
|
183 |
+
PyFortranObject_NewAsAttr(FortranDataDef *defs)
|
184 |
+
{ /* used for calling F90 module routines */
|
185 |
+
PyFortranObject *fp = NULL;
|
186 |
+
fp = PyObject_New(PyFortranObject, &PyFortran_Type);
|
187 |
+
if (fp == NULL)
|
188 |
+
return NULL;
|
189 |
+
if ((fp->dict = PyDict_New()) == NULL) {
|
190 |
+
PyObject_Del(fp);
|
191 |
+
return NULL;
|
192 |
+
}
|
193 |
+
fp->len = 1;
|
194 |
+
fp->defs = defs;
|
195 |
+
if (defs->rank == -1) {
|
196 |
+
PyDict_SetItemString(fp->dict, "__name__", PyUnicode_FromFormat("function %s", defs->name));
|
197 |
+
} else if (defs->rank == 0) {
|
198 |
+
PyDict_SetItemString(fp->dict, "__name__", PyUnicode_FromFormat("scalar %s", defs->name));
|
199 |
+
} else {
|
200 |
+
PyDict_SetItemString(fp->dict, "__name__", PyUnicode_FromFormat("array %s", defs->name));
|
201 |
+
}
|
202 |
+
return (PyObject *)fp;
|
203 |
+
}
|
204 |
+
|
205 |
+
/* Fortran methods */
|
206 |
+
|
207 |
+
static void
|
208 |
+
fortran_dealloc(PyFortranObject *fp)
|
209 |
+
{
|
210 |
+
Py_XDECREF(fp->dict);
|
211 |
+
PyObject_Del(fp);
|
212 |
+
}
|
213 |
+
|
214 |
+
/* Returns number of bytes consumed from buf, or -1 on error. */
|
215 |
+
static Py_ssize_t
|
216 |
+
format_def(char *buf, Py_ssize_t size, FortranDataDef def)
|
217 |
+
{
|
218 |
+
char *p = buf;
|
219 |
+
int i;
|
220 |
+
npy_intp n;
|
221 |
+
|
222 |
+
n = PyOS_snprintf(p, size, "array(%" NPY_INTP_FMT, def.dims.d[0]);
|
223 |
+
if (n < 0 || n >= size) {
|
224 |
+
return -1;
|
225 |
+
}
|
226 |
+
p += n;
|
227 |
+
size -= n;
|
228 |
+
|
229 |
+
for (i = 1; i < def.rank; i++) {
|
230 |
+
n = PyOS_snprintf(p, size, ",%" NPY_INTP_FMT, def.dims.d[i]);
|
231 |
+
if (n < 0 || n >= size) {
|
232 |
+
return -1;
|
233 |
+
}
|
234 |
+
p += n;
|
235 |
+
size -= n;
|
236 |
+
}
|
237 |
+
|
238 |
+
if (size <= 0) {
|
239 |
+
return -1;
|
240 |
+
}
|
241 |
+
|
242 |
+
*p++ = ')';
|
243 |
+
size--;
|
244 |
+
|
245 |
+
if (def.data == NULL) {
|
246 |
+
static const char notalloc[] = ", not allocated";
|
247 |
+
if ((size_t)size < sizeof(notalloc)) {
|
248 |
+
return -1;
|
249 |
+
}
|
250 |
+
memcpy(p, notalloc, sizeof(notalloc));
|
251 |
+
p += sizeof(notalloc);
|
252 |
+
size -= sizeof(notalloc);
|
253 |
+
}
|
254 |
+
|
255 |
+
return p - buf;
|
256 |
+
}
|
257 |
+
|
258 |
+
static PyObject *
|
259 |
+
fortran_doc(FortranDataDef def)
|
260 |
+
{
|
261 |
+
char *buf, *p;
|
262 |
+
PyObject *s = NULL;
|
263 |
+
Py_ssize_t n, origsize, size = 100;
|
264 |
+
|
265 |
+
if (def.doc != NULL) {
|
266 |
+
size += strlen(def.doc);
|
267 |
+
}
|
268 |
+
origsize = size;
|
269 |
+
buf = p = (char *)PyMem_Malloc(size);
|
270 |
+
if (buf == NULL) {
|
271 |
+
return PyErr_NoMemory();
|
272 |
+
}
|
273 |
+
|
274 |
+
if (def.rank == -1) {
|
275 |
+
if (def.doc) {
|
276 |
+
n = strlen(def.doc);
|
277 |
+
if (n > size) {
|
278 |
+
goto fail;
|
279 |
+
}
|
280 |
+
memcpy(p, def.doc, n);
|
281 |
+
p += n;
|
282 |
+
size -= n;
|
283 |
+
}
|
284 |
+
else {
|
285 |
+
n = PyOS_snprintf(p, size, "%s - no docs available", def.name);
|
286 |
+
if (n < 0 || n >= size) {
|
287 |
+
goto fail;
|
288 |
+
}
|
289 |
+
p += n;
|
290 |
+
size -= n;
|
291 |
+
}
|
292 |
+
}
|
293 |
+
else {
|
294 |
+
PyArray_Descr *d = PyArray_DescrFromType(def.type);
|
295 |
+
n = PyOS_snprintf(p, size, "%s : '%c'-", def.name, d->type);
|
296 |
+
Py_DECREF(d);
|
297 |
+
if (n < 0 || n >= size) {
|
298 |
+
goto fail;
|
299 |
+
}
|
300 |
+
p += n;
|
301 |
+
size -= n;
|
302 |
+
|
303 |
+
if (def.data == NULL) {
|
304 |
+
n = format_def(p, size, def);
|
305 |
+
if (n < 0) {
|
306 |
+
goto fail;
|
307 |
+
}
|
308 |
+
p += n;
|
309 |
+
size -= n;
|
310 |
+
}
|
311 |
+
else if (def.rank > 0) {
|
312 |
+
n = format_def(p, size, def);
|
313 |
+
if (n < 0) {
|
314 |
+
goto fail;
|
315 |
+
}
|
316 |
+
p += n;
|
317 |
+
size -= n;
|
318 |
+
}
|
319 |
+
else {
|
320 |
+
n = strlen("scalar");
|
321 |
+
if (size < n) {
|
322 |
+
goto fail;
|
323 |
+
}
|
324 |
+
memcpy(p, "scalar", n);
|
325 |
+
p += n;
|
326 |
+
size -= n;
|
327 |
+
}
|
328 |
+
}
|
329 |
+
if (size <= 1) {
|
330 |
+
goto fail;
|
331 |
+
}
|
332 |
+
*p++ = '\n';
|
333 |
+
size--;
|
334 |
+
|
335 |
+
/* p now points one beyond the last character of the string in buf */
|
336 |
+
s = PyUnicode_FromStringAndSize(buf, p - buf);
|
337 |
+
|
338 |
+
PyMem_Free(buf);
|
339 |
+
return s;
|
340 |
+
|
341 |
+
fail:
|
342 |
+
fprintf(stderr,
|
343 |
+
"fortranobject.c: fortran_doc: len(p)=%zd>%zd=size:"
|
344 |
+
" too long docstring required, increase size\n",
|
345 |
+
p - buf, origsize);
|
346 |
+
PyMem_Free(buf);
|
347 |
+
return NULL;
|
348 |
+
}
|
349 |
+
|
350 |
+
static FortranDataDef *save_def; /* save pointer of an allocatable array */
|
351 |
+
static void
|
352 |
+
set_data(char *d, npy_intp *f)
|
353 |
+
{ /* callback from Fortran */
|
354 |
+
if (*f) /* In fortran f=allocated(d) */
|
355 |
+
save_def->data = d;
|
356 |
+
else
|
357 |
+
save_def->data = NULL;
|
358 |
+
/* printf("set_data: d=%p,f=%d\n",d,*f); */
|
359 |
+
}
|
360 |
+
|
361 |
+
static PyObject *
|
362 |
+
fortran_getattr(PyFortranObject *fp, char *name)
|
363 |
+
{
|
364 |
+
int i, j, k, flag;
|
365 |
+
if (fp->dict != NULL) {
|
366 |
+
PyObject *v = _PyDict_GetItemStringWithError(fp->dict, name);
|
367 |
+
if (v == NULL && PyErr_Occurred()) {
|
368 |
+
return NULL;
|
369 |
+
}
|
370 |
+
else if (v != NULL) {
|
371 |
+
Py_INCREF(v);
|
372 |
+
return v;
|
373 |
+
}
|
374 |
+
}
|
375 |
+
for (i = 0, j = 1; i < fp->len && (j = strcmp(name, fp->defs[i].name));
|
376 |
+
i++)
|
377 |
+
;
|
378 |
+
if (j == 0)
|
379 |
+
if (fp->defs[i].rank != -1) { /* F90 allocatable array */
|
380 |
+
if (fp->defs[i].func == NULL)
|
381 |
+
return NULL;
|
382 |
+
for (k = 0; k < fp->defs[i].rank; ++k) fp->defs[i].dims.d[k] = -1;
|
383 |
+
save_def = &fp->defs[i];
|
384 |
+
(*(fp->defs[i].func))(&fp->defs[i].rank, fp->defs[i].dims.d,
|
385 |
+
set_data, &flag);
|
386 |
+
if (flag == 2)
|
387 |
+
k = fp->defs[i].rank + 1;
|
388 |
+
else
|
389 |
+
k = fp->defs[i].rank;
|
390 |
+
if (fp->defs[i].data != NULL) { /* array is allocated */
|
391 |
+
PyObject *v = PyArray_New(
|
392 |
+
&PyArray_Type, k, fp->defs[i].dims.d, fp->defs[i].type,
|
393 |
+
NULL, fp->defs[i].data, 0, NPY_ARRAY_FARRAY, NULL);
|
394 |
+
if (v == NULL)
|
395 |
+
return NULL;
|
396 |
+
/* Py_INCREF(v); */
|
397 |
+
return v;
|
398 |
+
}
|
399 |
+
else { /* array is not allocated */
|
400 |
+
Py_RETURN_NONE;
|
401 |
+
}
|
402 |
+
}
|
403 |
+
if (strcmp(name, "__dict__") == 0) {
|
404 |
+
Py_INCREF(fp->dict);
|
405 |
+
return fp->dict;
|
406 |
+
}
|
407 |
+
if (strcmp(name, "__doc__") == 0) {
|
408 |
+
PyObject *s = PyUnicode_FromString(""), *s2, *s3;
|
409 |
+
for (i = 0; i < fp->len; i++) {
|
410 |
+
s2 = fortran_doc(fp->defs[i]);
|
411 |
+
s3 = PyUnicode_Concat(s, s2);
|
412 |
+
Py_DECREF(s2);
|
413 |
+
Py_DECREF(s);
|
414 |
+
s = s3;
|
415 |
+
}
|
416 |
+
if (PyDict_SetItemString(fp->dict, name, s))
|
417 |
+
return NULL;
|
418 |
+
return s;
|
419 |
+
}
|
420 |
+
if ((strcmp(name, "_cpointer") == 0) && (fp->len == 1)) {
|
421 |
+
PyObject *cobj =
|
422 |
+
F2PyCapsule_FromVoidPtr((void *)(fp->defs[0].data), NULL);
|
423 |
+
if (PyDict_SetItemString(fp->dict, name, cobj))
|
424 |
+
return NULL;
|
425 |
+
return cobj;
|
426 |
+
}
|
427 |
+
PyObject *str, *ret;
|
428 |
+
str = PyUnicode_FromString(name);
|
429 |
+
ret = PyObject_GenericGetAttr((PyObject *)fp, str);
|
430 |
+
Py_DECREF(str);
|
431 |
+
return ret;
|
432 |
+
}
|
433 |
+
|
434 |
+
static int
|
435 |
+
fortran_setattr(PyFortranObject *fp, char *name, PyObject *v)
|
436 |
+
{
|
437 |
+
int i, j, flag;
|
438 |
+
PyArrayObject *arr = NULL;
|
439 |
+
for (i = 0, j = 1; i < fp->len && (j = strcmp(name, fp->defs[i].name));
|
440 |
+
i++)
|
441 |
+
;
|
442 |
+
if (j == 0) {
|
443 |
+
if (fp->defs[i].rank == -1) {
|
444 |
+
PyErr_SetString(PyExc_AttributeError,
|
445 |
+
"over-writing fortran routine");
|
446 |
+
return -1;
|
447 |
+
}
|
448 |
+
if (fp->defs[i].func != NULL) { /* is allocatable array */
|
449 |
+
npy_intp dims[F2PY_MAX_DIMS];
|
450 |
+
int k;
|
451 |
+
save_def = &fp->defs[i];
|
452 |
+
if (v != Py_None) { /* set new value (reallocate if needed --
|
453 |
+
see f2py generated code for more
|
454 |
+
details ) */
|
455 |
+
for (k = 0; k < fp->defs[i].rank; k++) dims[k] = -1;
|
456 |
+
if ((arr = array_from_pyobj(fp->defs[i].type, dims,
|
457 |
+
fp->defs[i].rank, F2PY_INTENT_IN,
|
458 |
+
v)) == NULL)
|
459 |
+
return -1;
|
460 |
+
(*(fp->defs[i].func))(&fp->defs[i].rank, PyArray_DIMS(arr),
|
461 |
+
set_data, &flag);
|
462 |
+
}
|
463 |
+
else { /* deallocate */
|
464 |
+
for (k = 0; k < fp->defs[i].rank; k++) dims[k] = 0;
|
465 |
+
(*(fp->defs[i].func))(&fp->defs[i].rank, dims, set_data,
|
466 |
+
&flag);
|
467 |
+
for (k = 0; k < fp->defs[i].rank; k++) dims[k] = -1;
|
468 |
+
}
|
469 |
+
memcpy(fp->defs[i].dims.d, dims,
|
470 |
+
fp->defs[i].rank * sizeof(npy_intp));
|
471 |
+
}
|
472 |
+
else { /* not allocatable array */
|
473 |
+
if ((arr = array_from_pyobj(fp->defs[i].type, fp->defs[i].dims.d,
|
474 |
+
fp->defs[i].rank, F2PY_INTENT_IN,
|
475 |
+
v)) == NULL)
|
476 |
+
return -1;
|
477 |
+
}
|
478 |
+
if (fp->defs[i].data !=
|
479 |
+
NULL) { /* copy Python object to Fortran array */
|
480 |
+
npy_intp s = PyArray_MultiplyList(fp->defs[i].dims.d,
|
481 |
+
PyArray_NDIM(arr));
|
482 |
+
if (s == -1)
|
483 |
+
s = PyArray_MultiplyList(PyArray_DIMS(arr), PyArray_NDIM(arr));
|
484 |
+
if (s < 0 || (memcpy(fp->defs[i].data, PyArray_DATA(arr),
|
485 |
+
s * PyArray_ITEMSIZE(arr))) == NULL) {
|
486 |
+
if ((PyObject *)arr != v) {
|
487 |
+
Py_DECREF(arr);
|
488 |
+
}
|
489 |
+
return -1;
|
490 |
+
}
|
491 |
+
if ((PyObject *)arr != v) {
|
492 |
+
Py_DECREF(arr);
|
493 |
+
}
|
494 |
+
}
|
495 |
+
else
|
496 |
+
return (fp->defs[i].func == NULL ? -1 : 0);
|
497 |
+
return 0; /* successful */
|
498 |
+
}
|
499 |
+
if (fp->dict == NULL) {
|
500 |
+
fp->dict = PyDict_New();
|
501 |
+
if (fp->dict == NULL)
|
502 |
+
return -1;
|
503 |
+
}
|
504 |
+
if (v == NULL) {
|
505 |
+
int rv = PyDict_DelItemString(fp->dict, name);
|
506 |
+
if (rv < 0)
|
507 |
+
PyErr_SetString(PyExc_AttributeError,
|
508 |
+
"delete non-existing fortran attribute");
|
509 |
+
return rv;
|
510 |
+
}
|
511 |
+
else
|
512 |
+
return PyDict_SetItemString(fp->dict, name, v);
|
513 |
+
}
|
514 |
+
|
515 |
+
static PyObject *
|
516 |
+
fortran_call(PyFortranObject *fp, PyObject *arg, PyObject *kw)
|
517 |
+
{
|
518 |
+
int i = 0;
|
519 |
+
/* printf("fortran call
|
520 |
+
name=%s,func=%p,data=%p,%p\n",fp->defs[i].name,
|
521 |
+
fp->defs[i].func,fp->defs[i].data,&fp->defs[i].data); */
|
522 |
+
if (fp->defs[i].rank == -1) { /* is Fortran routine */
|
523 |
+
if (fp->defs[i].func == NULL) {
|
524 |
+
PyErr_Format(PyExc_RuntimeError, "no function to call");
|
525 |
+
return NULL;
|
526 |
+
}
|
527 |
+
else if (fp->defs[i].data == NULL)
|
528 |
+
/* dummy routine */
|
529 |
+
return (*((fortranfunc)(fp->defs[i].func)))((PyObject *)fp, arg,
|
530 |
+
kw, NULL);
|
531 |
+
else
|
532 |
+
return (*((fortranfunc)(fp->defs[i].func)))(
|
533 |
+
(PyObject *)fp, arg, kw, (void *)fp->defs[i].data);
|
534 |
+
}
|
535 |
+
PyErr_Format(PyExc_TypeError, "this fortran object is not callable");
|
536 |
+
return NULL;
|
537 |
+
}
|
538 |
+
|
539 |
+
static PyObject *
|
540 |
+
fortran_repr(PyFortranObject *fp)
|
541 |
+
{
|
542 |
+
PyObject *name = NULL, *repr = NULL;
|
543 |
+
name = PyObject_GetAttrString((PyObject *)fp, "__name__");
|
544 |
+
PyErr_Clear();
|
545 |
+
if (name != NULL && PyUnicode_Check(name)) {
|
546 |
+
repr = PyUnicode_FromFormat("<fortran %U>", name);
|
547 |
+
}
|
548 |
+
else {
|
549 |
+
repr = PyUnicode_FromString("<fortran object>");
|
550 |
+
}
|
551 |
+
Py_XDECREF(name);
|
552 |
+
return repr;
|
553 |
+
}
|
554 |
+
|
555 |
+
PyTypeObject PyFortran_Type = {
|
556 |
+
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "fortran",
|
557 |
+
.tp_basicsize = sizeof(PyFortranObject),
|
558 |
+
.tp_dealloc = (destructor)fortran_dealloc,
|
559 |
+
.tp_getattr = (getattrfunc)fortran_getattr,
|
560 |
+
.tp_setattr = (setattrfunc)fortran_setattr,
|
561 |
+
.tp_repr = (reprfunc)fortran_repr,
|
562 |
+
.tp_call = (ternaryfunc)fortran_call,
|
563 |
+
};
|
564 |
+
|
565 |
+
/************************* f2py_report_atexit *******************************/
|
566 |
+
|
567 |
+
#ifdef F2PY_REPORT_ATEXIT
|
568 |
+
static int passed_time = 0;
|
569 |
+
static int passed_counter = 0;
|
570 |
+
static int passed_call_time = 0;
|
571 |
+
static struct timeb start_time;
|
572 |
+
static struct timeb stop_time;
|
573 |
+
static struct timeb start_call_time;
|
574 |
+
static struct timeb stop_call_time;
|
575 |
+
static int cb_passed_time = 0;
|
576 |
+
static int cb_passed_counter = 0;
|
577 |
+
static int cb_passed_call_time = 0;
|
578 |
+
static struct timeb cb_start_time;
|
579 |
+
static struct timeb cb_stop_time;
|
580 |
+
static struct timeb cb_start_call_time;
|
581 |
+
static struct timeb cb_stop_call_time;
|
582 |
+
|
583 |
+
extern void
|
584 |
+
f2py_start_clock(void)
|
585 |
+
{
|
586 |
+
ftime(&start_time);
|
587 |
+
}
|
588 |
+
extern void
|
589 |
+
f2py_start_call_clock(void)
|
590 |
+
{
|
591 |
+
f2py_stop_clock();
|
592 |
+
ftime(&start_call_time);
|
593 |
+
}
|
594 |
+
extern void
|
595 |
+
f2py_stop_clock(void)
|
596 |
+
{
|
597 |
+
ftime(&stop_time);
|
598 |
+
passed_time += 1000 * (stop_time.time - start_time.time);
|
599 |
+
passed_time += stop_time.millitm - start_time.millitm;
|
600 |
+
}
|
601 |
+
extern void
|
602 |
+
f2py_stop_call_clock(void)
|
603 |
+
{
|
604 |
+
ftime(&stop_call_time);
|
605 |
+
passed_call_time += 1000 * (stop_call_time.time - start_call_time.time);
|
606 |
+
passed_call_time += stop_call_time.millitm - start_call_time.millitm;
|
607 |
+
passed_counter += 1;
|
608 |
+
f2py_start_clock();
|
609 |
+
}
|
610 |
+
|
611 |
+
extern void
|
612 |
+
f2py_cb_start_clock(void)
|
613 |
+
{
|
614 |
+
ftime(&cb_start_time);
|
615 |
+
}
|
616 |
+
extern void
|
617 |
+
f2py_cb_start_call_clock(void)
|
618 |
+
{
|
619 |
+
f2py_cb_stop_clock();
|
620 |
+
ftime(&cb_start_call_time);
|
621 |
+
}
|
622 |
+
extern void
|
623 |
+
f2py_cb_stop_clock(void)
|
624 |
+
{
|
625 |
+
ftime(&cb_stop_time);
|
626 |
+
cb_passed_time += 1000 * (cb_stop_time.time - cb_start_time.time);
|
627 |
+
cb_passed_time += cb_stop_time.millitm - cb_start_time.millitm;
|
628 |
+
}
|
629 |
+
extern void
|
630 |
+
f2py_cb_stop_call_clock(void)
|
631 |
+
{
|
632 |
+
ftime(&cb_stop_call_time);
|
633 |
+
cb_passed_call_time +=
|
634 |
+
1000 * (cb_stop_call_time.time - cb_start_call_time.time);
|
635 |
+
cb_passed_call_time +=
|
636 |
+
cb_stop_call_time.millitm - cb_start_call_time.millitm;
|
637 |
+
cb_passed_counter += 1;
|
638 |
+
f2py_cb_start_clock();
|
639 |
+
}
|
640 |
+
|
641 |
+
static int f2py_report_on_exit_been_here = 0;
|
642 |
+
extern void
|
643 |
+
f2py_report_on_exit(int exit_flag, void *name)
|
644 |
+
{
|
645 |
+
if (f2py_report_on_exit_been_here) {
|
646 |
+
fprintf(stderr, " %s\n", (char *)name);
|
647 |
+
return;
|
648 |
+
}
|
649 |
+
f2py_report_on_exit_been_here = 1;
|
650 |
+
fprintf(stderr, " /-----------------------\\\n");
|
651 |
+
fprintf(stderr, " < F2PY performance report >\n");
|
652 |
+
fprintf(stderr, " \\-----------------------/\n");
|
653 |
+
fprintf(stderr, "Overall time spent in ...\n");
|
654 |
+
fprintf(stderr, "(a) wrapped (Fortran/C) functions : %8d msec\n",
|
655 |
+
passed_call_time);
|
656 |
+
fprintf(stderr, "(b) f2py interface, %6d calls : %8d msec\n",
|
657 |
+
passed_counter, passed_time);
|
658 |
+
fprintf(stderr, "(c) call-back (Python) functions : %8d msec\n",
|
659 |
+
cb_passed_call_time);
|
660 |
+
fprintf(stderr, "(d) f2py call-back interface, %6d calls : %8d msec\n",
|
661 |
+
cb_passed_counter, cb_passed_time);
|
662 |
+
|
663 |
+
fprintf(stderr,
|
664 |
+
"(e) wrapped (Fortran/C) functions (actual) : %8d msec\n\n",
|
665 |
+
passed_call_time - cb_passed_call_time - cb_passed_time);
|
666 |
+
fprintf(stderr,
|
667 |
+
"Use -DF2PY_REPORT_ATEXIT_DISABLE to disable this message.\n");
|
668 |
+
fprintf(stderr, "Exit status: %d\n", exit_flag);
|
669 |
+
fprintf(stderr, "Modules : %s\n", (char *)name);
|
670 |
+
}
|
671 |
+
#endif
|
672 |
+
|
673 |
+
/********************** report on array copy ****************************/
|
674 |
+
|
675 |
+
#ifdef F2PY_REPORT_ON_ARRAY_COPY
|
676 |
+
static void
|
677 |
+
f2py_report_on_array_copy(PyArrayObject *arr)
|
678 |
+
{
|
679 |
+
const npy_intp arr_size = PyArray_Size((PyObject *)arr);
|
680 |
+
if (arr_size > F2PY_REPORT_ON_ARRAY_COPY) {
|
681 |
+
fprintf(stderr,
|
682 |
+
"copied an array: size=%ld, elsize=%" NPY_INTP_FMT "\n",
|
683 |
+
arr_size, (npy_intp)PyArray_ITEMSIZE(arr));
|
684 |
+
}
|
685 |
+
}
|
686 |
+
static void
|
687 |
+
f2py_report_on_array_copy_fromany(void)
|
688 |
+
{
|
689 |
+
fprintf(stderr, "created an array from object\n");
|
690 |
+
}
|
691 |
+
|
692 |
+
#define F2PY_REPORT_ON_ARRAY_COPY_FROMARR \
|
693 |
+
f2py_report_on_array_copy((PyArrayObject *)arr)
|
694 |
+
#define F2PY_REPORT_ON_ARRAY_COPY_FROMANY f2py_report_on_array_copy_fromany()
|
695 |
+
#else
|
696 |
+
#define F2PY_REPORT_ON_ARRAY_COPY_FROMARR
|
697 |
+
#define F2PY_REPORT_ON_ARRAY_COPY_FROMANY
|
698 |
+
#endif
|
699 |
+
|
700 |
+
/************************* array_from_obj *******************************/
|
701 |
+
|
702 |
+
/*
|
703 |
+
* File: array_from_pyobj.c
|
704 |
+
*
|
705 |
+
* Description:
|
706 |
+
* ------------
|
707 |
+
* Provides array_from_pyobj function that returns a contiguous array
|
708 |
+
* object with the given dimensions and required storage order, either
|
709 |
+
* in row-major (C) or column-major (Fortran) order. The function
|
710 |
+
* array_from_pyobj is very flexible about its Python object argument
|
711 |
+
* that can be any number, list, tuple, or array.
|
712 |
+
*
|
713 |
+
* array_from_pyobj is used in f2py generated Python extension
|
714 |
+
* modules.
|
715 |
+
*
|
716 |
+
* Author: Pearu Peterson <[email protected]>
|
717 |
+
* Created: 13-16 January 2002
|
718 |
+
* $Id: fortranobject.c,v 1.52 2005/07/11 07:44:20 pearu Exp $
|
719 |
+
*/
|
720 |
+
|
721 |
+
static int check_and_fix_dimensions(const PyArrayObject* arr,
|
722 |
+
const int rank,
|
723 |
+
npy_intp *dims,
|
724 |
+
const char *errmess);
|
725 |
+
|
726 |
+
static int
|
727 |
+
find_first_negative_dimension(const int rank, const npy_intp *dims)
|
728 |
+
{
|
729 |
+
int i;
|
730 |
+
for (i = 0; i < rank; ++i) {
|
731 |
+
if (dims[i] < 0) {
|
732 |
+
return i;
|
733 |
+
}
|
734 |
+
}
|
735 |
+
return -1;
|
736 |
+
}
|
737 |
+
|
738 |
+
#ifdef DEBUG_COPY_ND_ARRAY
|
739 |
+
void
|
740 |
+
dump_dims(int rank, npy_intp const *dims)
|
741 |
+
{
|
742 |
+
int i;
|
743 |
+
printf("[");
|
744 |
+
for (i = 0; i < rank; ++i) {
|
745 |
+
printf("%3" NPY_INTP_FMT, dims[i]);
|
746 |
+
}
|
747 |
+
printf("]\n");
|
748 |
+
}
|
749 |
+
void
|
750 |
+
dump_attrs(const PyArrayObject *obj)
|
751 |
+
{
|
752 |
+
const PyArrayObject_fields *arr = (const PyArrayObject_fields *)obj;
|
753 |
+
int rank = PyArray_NDIM(arr);
|
754 |
+
npy_intp size = PyArray_Size((PyObject *)arr);
|
755 |
+
printf("\trank = %d, flags = %d, size = %" NPY_INTP_FMT "\n", rank,
|
756 |
+
arr->flags, size);
|
757 |
+
printf("\tstrides = ");
|
758 |
+
dump_dims(rank, arr->strides);
|
759 |
+
printf("\tdimensions = ");
|
760 |
+
dump_dims(rank, arr->dimensions);
|
761 |
+
}
|
762 |
+
#endif
|
763 |
+
|
764 |
+
#define SWAPTYPE(a, b, t) \
|
765 |
+
{ \
|
766 |
+
t c; \
|
767 |
+
c = (a); \
|
768 |
+
(a) = (b); \
|
769 |
+
(b) = c; \
|
770 |
+
}
|
771 |
+
|
772 |
+
static int
|
773 |
+
swap_arrays(PyArrayObject *obj1, PyArrayObject *obj2)
|
774 |
+
{
|
775 |
+
PyArrayObject_fields *arr1 = (PyArrayObject_fields *)obj1,
|
776 |
+
*arr2 = (PyArrayObject_fields *)obj2;
|
777 |
+
SWAPTYPE(arr1->data, arr2->data, char *);
|
778 |
+
SWAPTYPE(arr1->nd, arr2->nd, int);
|
779 |
+
SWAPTYPE(arr1->dimensions, arr2->dimensions, npy_intp *);
|
780 |
+
SWAPTYPE(arr1->strides, arr2->strides, npy_intp *);
|
781 |
+
SWAPTYPE(arr1->base, arr2->base, PyObject *);
|
782 |
+
SWAPTYPE(arr1->descr, arr2->descr, PyArray_Descr *);
|
783 |
+
SWAPTYPE(arr1->flags, arr2->flags, int);
|
784 |
+
/* SWAPTYPE(arr1->weakreflist,arr2->weakreflist,PyObject*); */
|
785 |
+
return 0;
|
786 |
+
}
|
787 |
+
|
788 |
+
#define ARRAY_ISCOMPATIBLE(arr,type_num) \
|
789 |
+
((PyArray_ISINTEGER(arr) && PyTypeNum_ISINTEGER(type_num)) || \
|
790 |
+
(PyArray_ISFLOAT(arr) && PyTypeNum_ISFLOAT(type_num)) || \
|
791 |
+
(PyArray_ISCOMPLEX(arr) && PyTypeNum_ISCOMPLEX(type_num)) || \
|
792 |
+
(PyArray_ISBOOL(arr) && PyTypeNum_ISBOOL(type_num)) || \
|
793 |
+
(PyArray_ISSTRING(arr) && PyTypeNum_ISSTRING(type_num)))
|
794 |
+
|
795 |
+
static int
|
796 |
+
get_elsize(PyObject *obj) {
|
797 |
+
/*
|
798 |
+
get_elsize determines array itemsize from a Python object. Returns
|
799 |
+
elsize if successful, -1 otherwise.
|
800 |
+
|
801 |
+
Supported types of the input are: numpy.ndarray, bytes, str, tuple,
|
802 |
+
list.
|
803 |
+
*/
|
804 |
+
|
805 |
+
if (PyArray_Check(obj)) {
|
806 |
+
return PyArray_DESCR((PyArrayObject *)obj)->elsize;
|
807 |
+
} else if (PyBytes_Check(obj)) {
|
808 |
+
return PyBytes_GET_SIZE(obj);
|
809 |
+
} else if (PyUnicode_Check(obj)) {
|
810 |
+
return PyUnicode_GET_LENGTH(obj);
|
811 |
+
} else if (PySequence_Check(obj)) {
|
812 |
+
PyObject* fast = PySequence_Fast(obj, "f2py:fortranobject.c:get_elsize");
|
813 |
+
if (fast != NULL) {
|
814 |
+
Py_ssize_t i, n = PySequence_Fast_GET_SIZE(fast);
|
815 |
+
int sz, elsize = 0;
|
816 |
+
for (i=0; i<n; i++) {
|
817 |
+
sz = get_elsize(PySequence_Fast_GET_ITEM(fast, i) /* borrowed */);
|
818 |
+
if (sz > elsize) {
|
819 |
+
elsize = sz;
|
820 |
+
}
|
821 |
+
}
|
822 |
+
Py_DECREF(fast);
|
823 |
+
return elsize;
|
824 |
+
}
|
825 |
+
}
|
826 |
+
return -1;
|
827 |
+
}
|
828 |
+
|
829 |
+
extern PyArrayObject *
|
830 |
+
ndarray_from_pyobj(const int type_num,
|
831 |
+
const int elsize_,
|
832 |
+
npy_intp *dims,
|
833 |
+
const int rank,
|
834 |
+
const int intent,
|
835 |
+
PyObject *obj,
|
836 |
+
const char *errmess) {
|
837 |
+
/*
|
838 |
+
* Return an array with given element type and shape from a Python
|
839 |
+
* object while taking into account the usage intent of the array.
|
840 |
+
*
|
841 |
+
* - element type is defined by type_num and elsize
|
842 |
+
* - shape is defined by dims and rank
|
843 |
+
*
|
844 |
+
* ndarray_from_pyobj is used to convert Python object arguments
|
845 |
+
* to numpy ndarrays with given type and shape that data is passed
|
846 |
+
* to interfaced Fortran or C functions.
|
847 |
+
*
|
848 |
+
* errmess (if not NULL), contains a prefix of an error message
|
849 |
+
* for an exception to be triggered within this function.
|
850 |
+
*
|
851 |
+
* Negative elsize value means that elsize is to be determined
|
852 |
+
* from the Python object in runtime.
|
853 |
+
*
|
854 |
+
* Note on strings
|
855 |
+
* ---------------
|
856 |
+
*
|
857 |
+
* String type (type_num == NPY_STRING) does not have fixed
|
858 |
+
* element size and, by default, the type object sets it to
|
859 |
+
* 0. Therefore, for string types, one has to use elsize
|
860 |
+
* argument. For other types, elsize value is ignored.
|
861 |
+
*
|
862 |
+
* NumPy defines the type of a fixed-width string as
|
863 |
+
* dtype('S<width>'). In addition, there is also dtype('c'), that
|
864 |
+
* appears as dtype('S1') (these have the same type_num value),
|
865 |
+
* but is actually different (.char attribute is either 'S' or
|
866 |
+
* 'c', respecitely).
|
867 |
+
*
|
868 |
+
* In Fortran, character arrays and strings are different
|
869 |
+
* concepts. The relation between Fortran types, NumPy dtypes,
|
870 |
+
* and type_num-elsize pairs, is defined as follows:
|
871 |
+
*
|
872 |
+
* character*5 foo | dtype('S5') | elsize=5, shape=()
|
873 |
+
* character(5) foo | dtype('S1') | elsize=1, shape=(5)
|
874 |
+
* character*5 foo(n) | dtype('S5') | elsize=5, shape=(n,)
|
875 |
+
* character(5) foo(n) | dtype('S1') | elsize=1, shape=(5, n)
|
876 |
+
* character*(*) foo | dtype('S') | elsize=-1, shape=()
|
877 |
+
*
|
878 |
+
* Note about reference counting
|
879 |
+
* -----------------------------
|
880 |
+
*
|
881 |
+
* If the caller returns the array to Python, it must be done with
|
882 |
+
* Py_BuildValue("N",arr). Otherwise, if obj!=arr then the caller
|
883 |
+
* must call Py_DECREF(arr).
|
884 |
+
*
|
885 |
+
* Note on intent(cache,out,..)
|
886 |
+
* ----------------------------
|
887 |
+
* Don't expect correct data when returning intent(cache) array.
|
888 |
+
*
|
889 |
+
*/
|
890 |
+
char mess[F2PY_MESSAGE_BUFFER_SIZE];
|
891 |
+
PyArrayObject *arr = NULL;
|
892 |
+
int elsize = (elsize_ < 0 ? get_elsize(obj) : elsize_);
|
893 |
+
if (elsize < 0) {
|
894 |
+
if (errmess != NULL) {
|
895 |
+
strcpy(mess, errmess);
|
896 |
+
}
|
897 |
+
sprintf(mess + strlen(mess),
|
898 |
+
" -- failed to determine element size from %s",
|
899 |
+
Py_TYPE(obj)->tp_name);
|
900 |
+
PyErr_SetString(PyExc_SystemError, mess);
|
901 |
+
return NULL;
|
902 |
+
}
|
903 |
+
PyArray_Descr * descr = get_descr_from_type_and_elsize(type_num, elsize); // new reference
|
904 |
+
if (descr == NULL) {
|
905 |
+
return NULL;
|
906 |
+
}
|
907 |
+
elsize = descr->elsize;
|
908 |
+
if ((intent & F2PY_INTENT_HIDE)
|
909 |
+
|| ((intent & F2PY_INTENT_CACHE) && (obj == Py_None))
|
910 |
+
|| ((intent & F2PY_OPTIONAL) && (obj == Py_None))
|
911 |
+
) {
|
912 |
+
/* intent(cache), optional, intent(hide) */
|
913 |
+
int ineg = find_first_negative_dimension(rank, dims);
|
914 |
+
if (ineg >= 0) {
|
915 |
+
int i;
|
916 |
+
strcpy(mess, "failed to create intent(cache|hide)|optional array"
|
917 |
+
"-- must have defined dimensions but got (");
|
918 |
+
for(i = 0; i < rank; ++i)
|
919 |
+
sprintf(mess + strlen(mess), "%" NPY_INTP_FMT ",", dims[i]);
|
920 |
+
strcat(mess, ")");
|
921 |
+
PyErr_SetString(PyExc_ValueError, mess);
|
922 |
+
Py_DECREF(descr);
|
923 |
+
return NULL;
|
924 |
+
}
|
925 |
+
arr = (PyArrayObject *) \
|
926 |
+
PyArray_NewFromDescr(&PyArray_Type, descr, rank, dims,
|
927 |
+
NULL, NULL, !(intent & F2PY_INTENT_C), NULL);
|
928 |
+
if (arr == NULL) {
|
929 |
+
Py_DECREF(descr);
|
930 |
+
return NULL;
|
931 |
+
}
|
932 |
+
if (PyArray_ITEMSIZE(arr) != elsize) {
|
933 |
+
strcpy(mess, "failed to create intent(cache|hide)|optional array");
|
934 |
+
sprintf(mess+strlen(mess)," -- expected elsize=%d got %" NPY_INTP_FMT, elsize, (npy_intp)PyArray_ITEMSIZE(arr));
|
935 |
+
PyErr_SetString(PyExc_ValueError,mess);
|
936 |
+
Py_DECREF(arr);
|
937 |
+
return NULL;
|
938 |
+
}
|
939 |
+
if (!(intent & F2PY_INTENT_CACHE)) {
|
940 |
+
PyArray_FILLWBYTE(arr, 0);
|
941 |
+
}
|
942 |
+
return arr;
|
943 |
+
}
|
944 |
+
|
945 |
+
if (PyArray_Check(obj)) {
|
946 |
+
arr = (PyArrayObject *)obj;
|
947 |
+
if (intent & F2PY_INTENT_CACHE) {
|
948 |
+
/* intent(cache) */
|
949 |
+
if (PyArray_ISONESEGMENT(arr)
|
950 |
+
&& PyArray_ITEMSIZE(arr) >= elsize) {
|
951 |
+
if (check_and_fix_dimensions(arr, rank, dims, errmess)) {
|
952 |
+
Py_DECREF(descr);
|
953 |
+
return NULL;
|
954 |
+
}
|
955 |
+
if (intent & F2PY_INTENT_OUT)
|
956 |
+
Py_INCREF(arr);
|
957 |
+
Py_DECREF(descr);
|
958 |
+
return arr;
|
959 |
+
}
|
960 |
+
strcpy(mess, "failed to initialize intent(cache) array");
|
961 |
+
if (!PyArray_ISONESEGMENT(arr))
|
962 |
+
strcat(mess, " -- input must be in one segment");
|
963 |
+
if (PyArray_ITEMSIZE(arr) < elsize)
|
964 |
+
sprintf(mess + strlen(mess),
|
965 |
+
" -- expected at least elsize=%d but got "
|
966 |
+
"%" NPY_INTP_FMT,
|
967 |
+
elsize, (npy_intp)PyArray_ITEMSIZE(arr));
|
968 |
+
PyErr_SetString(PyExc_ValueError, mess);
|
969 |
+
Py_DECREF(descr);
|
970 |
+
return NULL;
|
971 |
+
}
|
972 |
+
|
973 |
+
/* here we have always intent(in) or intent(inout) or intent(inplace)
|
974 |
+
*/
|
975 |
+
|
976 |
+
if (check_and_fix_dimensions(arr, rank, dims, errmess)) {
|
977 |
+
Py_DECREF(descr);
|
978 |
+
return NULL;
|
979 |
+
}
|
980 |
+
/*
|
981 |
+
printf("intent alignment=%d\n", F2PY_GET_ALIGNMENT(intent));
|
982 |
+
printf("alignment check=%d\n", F2PY_CHECK_ALIGNMENT(arr, intent));
|
983 |
+
int i;
|
984 |
+
for (i=1;i<=16;i++)
|
985 |
+
printf("i=%d isaligned=%d\n", i, ARRAY_ISALIGNED(arr, i));
|
986 |
+
*/
|
987 |
+
if ((! (intent & F2PY_INTENT_COPY)) &&
|
988 |
+
PyArray_ITEMSIZE(arr) == elsize &&
|
989 |
+
ARRAY_ISCOMPATIBLE(arr,type_num) &&
|
990 |
+
F2PY_CHECK_ALIGNMENT(arr, intent)) {
|
991 |
+
if ((intent & F2PY_INTENT_INOUT || intent & F2PY_INTENT_INPLACE)
|
992 |
+
? ((intent & F2PY_INTENT_C) ? PyArray_ISCARRAY(arr) : PyArray_ISFARRAY(arr))
|
993 |
+
: ((intent & F2PY_INTENT_C) ? PyArray_ISCARRAY_RO(arr) : PyArray_ISFARRAY_RO(arr))) {
|
994 |
+
if ((intent & F2PY_INTENT_OUT)) {
|
995 |
+
Py_INCREF(arr);
|
996 |
+
}
|
997 |
+
/* Returning input array */
|
998 |
+
Py_DECREF(descr);
|
999 |
+
return arr;
|
1000 |
+
}
|
1001 |
+
}
|
1002 |
+
if (intent & F2PY_INTENT_INOUT) {
|
1003 |
+
strcpy(mess, "failed to initialize intent(inout) array");
|
1004 |
+
/* Must use PyArray_IS*ARRAY because intent(inout) requires
|
1005 |
+
* writable input */
|
1006 |
+
if ((intent & F2PY_INTENT_C) && !PyArray_ISCARRAY(arr))
|
1007 |
+
strcat(mess, " -- input not contiguous");
|
1008 |
+
if (!(intent & F2PY_INTENT_C) && !PyArray_ISFARRAY(arr))
|
1009 |
+
strcat(mess, " -- input not fortran contiguous");
|
1010 |
+
if (PyArray_ITEMSIZE(arr) != elsize)
|
1011 |
+
sprintf(mess + strlen(mess),
|
1012 |
+
" -- expected elsize=%d but got %" NPY_INTP_FMT,
|
1013 |
+
elsize,
|
1014 |
+
(npy_intp)PyArray_ITEMSIZE(arr)
|
1015 |
+
);
|
1016 |
+
if (!(ARRAY_ISCOMPATIBLE(arr, type_num))) {
|
1017 |
+
sprintf(mess + strlen(mess),
|
1018 |
+
" -- input '%c' not compatible to '%c'",
|
1019 |
+
PyArray_DESCR(arr)->type, descr->type);
|
1020 |
+
}
|
1021 |
+
if (!(F2PY_CHECK_ALIGNMENT(arr, intent)))
|
1022 |
+
sprintf(mess + strlen(mess), " -- input not %d-aligned",
|
1023 |
+
F2PY_GET_ALIGNMENT(intent));
|
1024 |
+
PyErr_SetString(PyExc_ValueError, mess);
|
1025 |
+
Py_DECREF(descr);
|
1026 |
+
return NULL;
|
1027 |
+
}
|
1028 |
+
|
1029 |
+
/* here we have always intent(in) or intent(inplace) */
|
1030 |
+
|
1031 |
+
{
|
1032 |
+
PyArrayObject * retarr = (PyArrayObject *) \
|
1033 |
+
PyArray_NewFromDescr(&PyArray_Type, descr, PyArray_NDIM(arr), PyArray_DIMS(arr),
|
1034 |
+
NULL, NULL, !(intent & F2PY_INTENT_C), NULL);
|
1035 |
+
if (retarr==NULL) {
|
1036 |
+
Py_DECREF(descr);
|
1037 |
+
return NULL;
|
1038 |
+
}
|
1039 |
+
F2PY_REPORT_ON_ARRAY_COPY_FROMARR;
|
1040 |
+
if (PyArray_CopyInto(retarr, arr)) {
|
1041 |
+
Py_DECREF(retarr);
|
1042 |
+
return NULL;
|
1043 |
+
}
|
1044 |
+
if (intent & F2PY_INTENT_INPLACE) {
|
1045 |
+
if (swap_arrays(arr,retarr)) {
|
1046 |
+
Py_DECREF(retarr);
|
1047 |
+
return NULL; /* XXX: set exception */
|
1048 |
+
}
|
1049 |
+
Py_XDECREF(retarr);
|
1050 |
+
if (intent & F2PY_INTENT_OUT)
|
1051 |
+
Py_INCREF(arr);
|
1052 |
+
} else {
|
1053 |
+
arr = retarr;
|
1054 |
+
}
|
1055 |
+
}
|
1056 |
+
return arr;
|
1057 |
+
}
|
1058 |
+
|
1059 |
+
if ((intent & F2PY_INTENT_INOUT) || (intent & F2PY_INTENT_INPLACE) ||
|
1060 |
+
(intent & F2PY_INTENT_CACHE)) {
|
1061 |
+
PyErr_Format(PyExc_TypeError,
|
1062 |
+
"failed to initialize intent(inout|inplace|cache) "
|
1063 |
+
"array, input '%s' object is not an array",
|
1064 |
+
Py_TYPE(obj)->tp_name);
|
1065 |
+
Py_DECREF(descr);
|
1066 |
+
return NULL;
|
1067 |
+
}
|
1068 |
+
|
1069 |
+
{
|
1070 |
+
F2PY_REPORT_ON_ARRAY_COPY_FROMANY;
|
1071 |
+
arr = (PyArrayObject *)PyArray_FromAny(
|
1072 |
+
obj, descr, 0, 0,
|
1073 |
+
((intent & F2PY_INTENT_C) ? NPY_ARRAY_CARRAY
|
1074 |
+
: NPY_ARRAY_FARRAY) |
|
1075 |
+
NPY_ARRAY_FORCECAST,
|
1076 |
+
NULL);
|
1077 |
+
// Warning: in the case of NPY_STRING, PyArray_FromAny may
|
1078 |
+
// reset descr->elsize, e.g. dtype('S0') becomes dtype('S1').
|
1079 |
+
if (arr == NULL) {
|
1080 |
+
Py_DECREF(descr);
|
1081 |
+
return NULL;
|
1082 |
+
}
|
1083 |
+
if (type_num != NPY_STRING && PyArray_ITEMSIZE(arr) != elsize) {
|
1084 |
+
// This is internal sanity tests: elsize has been set to
|
1085 |
+
// descr->elsize in the beginning of this function.
|
1086 |
+
strcpy(mess, "failed to initialize intent(in) array");
|
1087 |
+
sprintf(mess + strlen(mess),
|
1088 |
+
" -- expected elsize=%d got %" NPY_INTP_FMT, elsize,
|
1089 |
+
(npy_intp)PyArray_ITEMSIZE(arr));
|
1090 |
+
PyErr_SetString(PyExc_ValueError, mess);
|
1091 |
+
Py_DECREF(arr);
|
1092 |
+
return NULL;
|
1093 |
+
}
|
1094 |
+
if (check_and_fix_dimensions(arr, rank, dims, errmess)) {
|
1095 |
+
Py_DECREF(arr);
|
1096 |
+
return NULL;
|
1097 |
+
}
|
1098 |
+
return arr;
|
1099 |
+
}
|
1100 |
+
}
|
1101 |
+
|
1102 |
+
extern PyArrayObject *
|
1103 |
+
array_from_pyobj(const int type_num,
|
1104 |
+
npy_intp *dims,
|
1105 |
+
const int rank,
|
1106 |
+
const int intent,
|
1107 |
+
PyObject *obj) {
|
1108 |
+
/*
|
1109 |
+
Same as ndarray_from_pyobj but with elsize determined from type,
|
1110 |
+
if possible. Provided for backward compatibility.
|
1111 |
+
*/
|
1112 |
+
PyArray_Descr* descr = PyArray_DescrFromType(type_num);
|
1113 |
+
int elsize = descr->elsize;
|
1114 |
+
Py_DECREF(descr);
|
1115 |
+
return ndarray_from_pyobj(type_num, elsize, dims, rank, intent, obj, NULL);
|
1116 |
+
}
|
1117 |
+
|
1118 |
+
/*****************************************/
|
1119 |
+
/* Helper functions for array_from_pyobj */
|
1120 |
+
/*****************************************/
|
1121 |
+
|
1122 |
+
static int
|
1123 |
+
check_and_fix_dimensions(const PyArrayObject* arr, const int rank,
|
1124 |
+
npy_intp *dims, const char *errmess)
|
1125 |
+
{
|
1126 |
+
/*
|
1127 |
+
* This function fills in blanks (that are -1's) in dims list using
|
1128 |
+
* the dimensions from arr. It also checks that non-blank dims will
|
1129 |
+
* match with the corresponding values in arr dimensions.
|
1130 |
+
*
|
1131 |
+
* Returns 0 if the function is successful.
|
1132 |
+
*
|
1133 |
+
* If an error condition is detected, an exception is set and 1 is
|
1134 |
+
* returned.
|
1135 |
+
*/
|
1136 |
+
char mess[F2PY_MESSAGE_BUFFER_SIZE];
|
1137 |
+
const npy_intp arr_size =
|
1138 |
+
(PyArray_NDIM(arr)) ? PyArray_Size((PyObject *)arr) : 1;
|
1139 |
+
#ifdef DEBUG_COPY_ND_ARRAY
|
1140 |
+
dump_attrs(arr);
|
1141 |
+
printf("check_and_fix_dimensions:init: dims=");
|
1142 |
+
dump_dims(rank, dims);
|
1143 |
+
#endif
|
1144 |
+
if (rank > PyArray_NDIM(arr)) { /* [1,2] -> [[1],[2]]; 1 -> [[1]] */
|
1145 |
+
npy_intp new_size = 1;
|
1146 |
+
int free_axe = -1;
|
1147 |
+
int i;
|
1148 |
+
npy_intp d;
|
1149 |
+
/* Fill dims where -1 or 0; check dimensions; calc new_size; */
|
1150 |
+
for (i = 0; i < PyArray_NDIM(arr); ++i) {
|
1151 |
+
d = PyArray_DIM(arr, i);
|
1152 |
+
if (dims[i] >= 0) {
|
1153 |
+
if (d > 1 && dims[i] != d) {
|
1154 |
+
PyErr_Format(
|
1155 |
+
PyExc_ValueError,
|
1156 |
+
"%d-th dimension must be fixed to %" NPY_INTP_FMT
|
1157 |
+
" but got %" NPY_INTP_FMT "\n",
|
1158 |
+
i, dims[i], d);
|
1159 |
+
return 1;
|
1160 |
+
}
|
1161 |
+
if (!dims[i])
|
1162 |
+
dims[i] = 1;
|
1163 |
+
}
|
1164 |
+
else {
|
1165 |
+
dims[i] = d ? d : 1;
|
1166 |
+
}
|
1167 |
+
new_size *= dims[i];
|
1168 |
+
}
|
1169 |
+
for (i = PyArray_NDIM(arr); i < rank; ++i)
|
1170 |
+
if (dims[i] > 1) {
|
1171 |
+
PyErr_Format(PyExc_ValueError,
|
1172 |
+
"%d-th dimension must be %" NPY_INTP_FMT
|
1173 |
+
" but got 0 (not defined).\n",
|
1174 |
+
i, dims[i]);
|
1175 |
+
return 1;
|
1176 |
+
}
|
1177 |
+
else if (free_axe < 0)
|
1178 |
+
free_axe = i;
|
1179 |
+
else
|
1180 |
+
dims[i] = 1;
|
1181 |
+
if (free_axe >= 0) {
|
1182 |
+
dims[free_axe] = arr_size / new_size;
|
1183 |
+
new_size *= dims[free_axe];
|
1184 |
+
}
|
1185 |
+
if (new_size != arr_size) {
|
1186 |
+
PyErr_Format(PyExc_ValueError,
|
1187 |
+
"unexpected array size: new_size=%" NPY_INTP_FMT
|
1188 |
+
", got array with arr_size=%" NPY_INTP_FMT
|
1189 |
+
" (maybe too many free indices)\n",
|
1190 |
+
new_size, arr_size);
|
1191 |
+
return 1;
|
1192 |
+
}
|
1193 |
+
}
|
1194 |
+
else if (rank == PyArray_NDIM(arr)) {
|
1195 |
+
npy_intp new_size = 1;
|
1196 |
+
int i;
|
1197 |
+
npy_intp d;
|
1198 |
+
for (i = 0; i < rank; ++i) {
|
1199 |
+
d = PyArray_DIM(arr, i);
|
1200 |
+
if (dims[i] >= 0) {
|
1201 |
+
if (d > 1 && d != dims[i]) {
|
1202 |
+
if (errmess != NULL) {
|
1203 |
+
strcpy(mess, errmess);
|
1204 |
+
}
|
1205 |
+
sprintf(mess + strlen(mess),
|
1206 |
+
" -- %d-th dimension must be fixed to %"
|
1207 |
+
NPY_INTP_FMT " but got %" NPY_INTP_FMT,
|
1208 |
+
i, dims[i], d);
|
1209 |
+
PyErr_SetString(PyExc_ValueError, mess);
|
1210 |
+
return 1;
|
1211 |
+
}
|
1212 |
+
if (!dims[i])
|
1213 |
+
dims[i] = 1;
|
1214 |
+
}
|
1215 |
+
else
|
1216 |
+
dims[i] = d;
|
1217 |
+
new_size *= dims[i];
|
1218 |
+
}
|
1219 |
+
if (new_size != arr_size) {
|
1220 |
+
PyErr_Format(PyExc_ValueError,
|
1221 |
+
"unexpected array size: new_size=%" NPY_INTP_FMT
|
1222 |
+
", got array with arr_size=%" NPY_INTP_FMT "\n",
|
1223 |
+
new_size, arr_size);
|
1224 |
+
return 1;
|
1225 |
+
}
|
1226 |
+
}
|
1227 |
+
else { /* [[1,2]] -> [[1],[2]] */
|
1228 |
+
int i, j;
|
1229 |
+
npy_intp d;
|
1230 |
+
int effrank;
|
1231 |
+
npy_intp size;
|
1232 |
+
for (i = 0, effrank = 0; i < PyArray_NDIM(arr); ++i)
|
1233 |
+
if (PyArray_DIM(arr, i) > 1)
|
1234 |
+
++effrank;
|
1235 |
+
if (dims[rank - 1] >= 0)
|
1236 |
+
if (effrank > rank) {
|
1237 |
+
PyErr_Format(PyExc_ValueError,
|
1238 |
+
"too many axes: %d (effrank=%d), "
|
1239 |
+
"expected rank=%d\n",
|
1240 |
+
PyArray_NDIM(arr), effrank, rank);
|
1241 |
+
return 1;
|
1242 |
+
}
|
1243 |
+
|
1244 |
+
for (i = 0, j = 0; i < rank; ++i) {
|
1245 |
+
while (j < PyArray_NDIM(arr) && PyArray_DIM(arr, j) < 2) ++j;
|
1246 |
+
if (j >= PyArray_NDIM(arr))
|
1247 |
+
d = 1;
|
1248 |
+
else
|
1249 |
+
d = PyArray_DIM(arr, j++);
|
1250 |
+
if (dims[i] >= 0) {
|
1251 |
+
if (d > 1 && d != dims[i]) {
|
1252 |
+
if (errmess != NULL) {
|
1253 |
+
strcpy(mess, errmess);
|
1254 |
+
}
|
1255 |
+
sprintf(mess + strlen(mess),
|
1256 |
+
" -- %d-th dimension must be fixed to %"
|
1257 |
+
NPY_INTP_FMT " but got %" NPY_INTP_FMT
|
1258 |
+
" (real index=%d)\n",
|
1259 |
+
i, dims[i], d, j-1);
|
1260 |
+
PyErr_SetString(PyExc_ValueError, mess);
|
1261 |
+
return 1;
|
1262 |
+
}
|
1263 |
+
if (!dims[i])
|
1264 |
+
dims[i] = 1;
|
1265 |
+
}
|
1266 |
+
else
|
1267 |
+
dims[i] = d;
|
1268 |
+
}
|
1269 |
+
|
1270 |
+
for (i = rank; i < PyArray_NDIM(arr);
|
1271 |
+
++i) { /* [[1,2],[3,4]] -> [1,2,3,4] */
|
1272 |
+
while (j < PyArray_NDIM(arr) && PyArray_DIM(arr, j) < 2) ++j;
|
1273 |
+
if (j >= PyArray_NDIM(arr))
|
1274 |
+
d = 1;
|
1275 |
+
else
|
1276 |
+
d = PyArray_DIM(arr, j++);
|
1277 |
+
dims[rank - 1] *= d;
|
1278 |
+
}
|
1279 |
+
for (i = 0, size = 1; i < rank; ++i) size *= dims[i];
|
1280 |
+
if (size != arr_size) {
|
1281 |
+
char msg[200];
|
1282 |
+
int len;
|
1283 |
+
snprintf(msg, sizeof(msg),
|
1284 |
+
"unexpected array size: size=%" NPY_INTP_FMT
|
1285 |
+
", arr_size=%" NPY_INTP_FMT
|
1286 |
+
", rank=%d, effrank=%d, arr.nd=%d, dims=[",
|
1287 |
+
size, arr_size, rank, effrank, PyArray_NDIM(arr));
|
1288 |
+
for (i = 0; i < rank; ++i) {
|
1289 |
+
len = strlen(msg);
|
1290 |
+
snprintf(msg + len, sizeof(msg) - len, " %" NPY_INTP_FMT,
|
1291 |
+
dims[i]);
|
1292 |
+
}
|
1293 |
+
len = strlen(msg);
|
1294 |
+
snprintf(msg + len, sizeof(msg) - len, " ], arr.dims=[");
|
1295 |
+
for (i = 0; i < PyArray_NDIM(arr); ++i) {
|
1296 |
+
len = strlen(msg);
|
1297 |
+
snprintf(msg + len, sizeof(msg) - len, " %" NPY_INTP_FMT,
|
1298 |
+
PyArray_DIM(arr, i));
|
1299 |
+
}
|
1300 |
+
len = strlen(msg);
|
1301 |
+
snprintf(msg + len, sizeof(msg) - len, " ]\n");
|
1302 |
+
PyErr_SetString(PyExc_ValueError, msg);
|
1303 |
+
return 1;
|
1304 |
+
}
|
1305 |
+
}
|
1306 |
+
#ifdef DEBUG_COPY_ND_ARRAY
|
1307 |
+
printf("check_and_fix_dimensions:end: dims=");
|
1308 |
+
dump_dims(rank, dims);
|
1309 |
+
#endif
|
1310 |
+
return 0;
|
1311 |
+
}
|
1312 |
+
|
1313 |
+
/* End of file: array_from_pyobj.c */
|
1314 |
+
|
1315 |
+
/************************* copy_ND_array *******************************/
|
1316 |
+
|
1317 |
+
extern int
|
1318 |
+
copy_ND_array(const PyArrayObject *arr, PyArrayObject *out)
|
1319 |
+
{
|
1320 |
+
F2PY_REPORT_ON_ARRAY_COPY_FROMARR;
|
1321 |
+
return PyArray_CopyInto(out, (PyArrayObject *)arr);
|
1322 |
+
}
|
1323 |
+
|
1324 |
+
/********************* Various utility functions ***********************/
|
1325 |
+
|
1326 |
+
extern int
|
1327 |
+
f2py_describe(PyObject *obj, char *buf) {
|
1328 |
+
/*
|
1329 |
+
Write the description of a Python object to buf. The caller must
|
1330 |
+
provide buffer with size sufficient to write the description.
|
1331 |
+
|
1332 |
+
Return 1 on success.
|
1333 |
+
*/
|
1334 |
+
char localbuf[F2PY_MESSAGE_BUFFER_SIZE];
|
1335 |
+
if (PyBytes_Check(obj)) {
|
1336 |
+
sprintf(localbuf, "%d-%s", (npy_int)PyBytes_GET_SIZE(obj), Py_TYPE(obj)->tp_name);
|
1337 |
+
} else if (PyUnicode_Check(obj)) {
|
1338 |
+
sprintf(localbuf, "%d-%s", (npy_int)PyUnicode_GET_LENGTH(obj), Py_TYPE(obj)->tp_name);
|
1339 |
+
} else if (PyArray_CheckScalar(obj)) {
|
1340 |
+
PyArrayObject* arr = (PyArrayObject*)obj;
|
1341 |
+
sprintf(localbuf, "%c%" NPY_INTP_FMT "-%s-scalar", PyArray_DESCR(arr)->kind, PyArray_ITEMSIZE(arr), Py_TYPE(obj)->tp_name);
|
1342 |
+
} else if (PyArray_Check(obj)) {
|
1343 |
+
int i;
|
1344 |
+
PyArrayObject* arr = (PyArrayObject*)obj;
|
1345 |
+
strcpy(localbuf, "(");
|
1346 |
+
for (i=0; i<PyArray_NDIM(arr); i++) {
|
1347 |
+
if (i) {
|
1348 |
+
strcat(localbuf, " ");
|
1349 |
+
}
|
1350 |
+
sprintf(localbuf + strlen(localbuf), "%" NPY_INTP_FMT ",", PyArray_DIM(arr, i));
|
1351 |
+
}
|
1352 |
+
sprintf(localbuf + strlen(localbuf), ")-%c%" NPY_INTP_FMT "-%s", PyArray_DESCR(arr)->kind, PyArray_ITEMSIZE(arr), Py_TYPE(obj)->tp_name);
|
1353 |
+
} else if (PySequence_Check(obj)) {
|
1354 |
+
sprintf(localbuf, "%d-%s", (npy_int)PySequence_Length(obj), Py_TYPE(obj)->tp_name);
|
1355 |
+
} else {
|
1356 |
+
sprintf(localbuf, "%s instance", Py_TYPE(obj)->tp_name);
|
1357 |
+
}
|
1358 |
+
// TODO: detect the size of buf and make sure that size(buf) >= size(localbuf).
|
1359 |
+
strcpy(buf, localbuf);
|
1360 |
+
return 1;
|
1361 |
+
}
|
1362 |
+
|
1363 |
+
extern npy_intp
|
1364 |
+
f2py_size_impl(PyArrayObject* var, ...)
|
1365 |
+
{
|
1366 |
+
npy_intp sz = 0;
|
1367 |
+
npy_intp dim;
|
1368 |
+
npy_intp rank;
|
1369 |
+
va_list argp;
|
1370 |
+
va_start(argp, var);
|
1371 |
+
dim = va_arg(argp, npy_int);
|
1372 |
+
if (dim==-1)
|
1373 |
+
{
|
1374 |
+
sz = PyArray_SIZE(var);
|
1375 |
+
}
|
1376 |
+
else
|
1377 |
+
{
|
1378 |
+
rank = PyArray_NDIM(var);
|
1379 |
+
if (dim>=1 && dim<=rank)
|
1380 |
+
sz = PyArray_DIM(var, dim-1);
|
1381 |
+
else
|
1382 |
+
fprintf(stderr, "f2py_size: 2nd argument value=%" NPY_INTP_FMT
|
1383 |
+
" fails to satisfy 1<=value<=%" NPY_INTP_FMT
|
1384 |
+
". Result will be 0.\n", dim, rank);
|
1385 |
+
}
|
1386 |
+
va_end(argp);
|
1387 |
+
return sz;
|
1388 |
+
}
|
1389 |
+
|
1390 |
+
/*********************************************/
|
1391 |
+
/* Compatibility functions for Python >= 3.0 */
|
1392 |
+
/*********************************************/
|
1393 |
+
|
1394 |
+
PyObject *
|
1395 |
+
F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *))
|
1396 |
+
{
|
1397 |
+
PyObject *ret = PyCapsule_New(ptr, NULL, dtor);
|
1398 |
+
if (ret == NULL) {
|
1399 |
+
PyErr_Clear();
|
1400 |
+
}
|
1401 |
+
return ret;
|
1402 |
+
}
|
1403 |
+
|
1404 |
+
void *
|
1405 |
+
F2PyCapsule_AsVoidPtr(PyObject *obj)
|
1406 |
+
{
|
1407 |
+
void *ret = PyCapsule_GetPointer(obj, NULL);
|
1408 |
+
if (ret == NULL) {
|
1409 |
+
PyErr_Clear();
|
1410 |
+
}
|
1411 |
+
return ret;
|
1412 |
+
}
|
1413 |
+
|
1414 |
+
int
|
1415 |
+
F2PyCapsule_Check(PyObject *ptr)
|
1416 |
+
{
|
1417 |
+
return PyCapsule_CheckExact(ptr);
|
1418 |
+
}
|
1419 |
+
|
1420 |
+
#ifdef __cplusplus
|
1421 |
+
}
|
1422 |
+
#endif
|
1423 |
+
/************************* EOF fortranobject.c *******************************/
|
.venv/lib/python3.11/site-packages/numpy/f2py/src/fortranobject.h
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#ifndef Py_FORTRANOBJECT_H
|
2 |
+
#define Py_FORTRANOBJECT_H
|
3 |
+
#ifdef __cplusplus
|
4 |
+
extern "C" {
|
5 |
+
#endif
|
6 |
+
|
7 |
+
#include <Python.h>
|
8 |
+
|
9 |
+
#ifndef NPY_NO_DEPRECATED_API
|
10 |
+
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
|
11 |
+
#endif
|
12 |
+
#ifdef FORTRANOBJECT_C
|
13 |
+
#define NO_IMPORT_ARRAY
|
14 |
+
#endif
|
15 |
+
#define PY_ARRAY_UNIQUE_SYMBOL _npy_f2py_ARRAY_API
|
16 |
+
#include "numpy/arrayobject.h"
|
17 |
+
#include "numpy/npy_3kcompat.h"
|
18 |
+
|
19 |
+
#ifdef F2PY_REPORT_ATEXIT
|
20 |
+
#include <sys/timeb.h>
|
21 |
+
// clang-format off
|
22 |
+
extern void f2py_start_clock(void);
|
23 |
+
extern void f2py_stop_clock(void);
|
24 |
+
extern void f2py_start_call_clock(void);
|
25 |
+
extern void f2py_stop_call_clock(void);
|
26 |
+
extern void f2py_cb_start_clock(void);
|
27 |
+
extern void f2py_cb_stop_clock(void);
|
28 |
+
extern void f2py_cb_start_call_clock(void);
|
29 |
+
extern void f2py_cb_stop_call_clock(void);
|
30 |
+
extern void f2py_report_on_exit(int, void *);
|
31 |
+
// clang-format on
|
32 |
+
#endif
|
33 |
+
|
34 |
+
#ifdef DMALLOC
|
35 |
+
#include "dmalloc.h"
|
36 |
+
#endif
|
37 |
+
|
38 |
+
/* Fortran object interface */
|
39 |
+
|
40 |
+
/*
|
41 |
+
123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
|
42 |
+
|
43 |
+
PyFortranObject represents various Fortran objects:
|
44 |
+
Fortran (module) routines, COMMON blocks, module data.
|
45 |
+
|
46 |
+
Author: Pearu Peterson <[email protected]>
|
47 |
+
*/
|
48 |
+
|
49 |
+
#define F2PY_MAX_DIMS 40
|
50 |
+
#define F2PY_MESSAGE_BUFFER_SIZE 300 // Increase on "stack smashing detected"
|
51 |
+
|
52 |
+
typedef void (*f2py_set_data_func)(char *, npy_intp *);
|
53 |
+
typedef void (*f2py_void_func)(void);
|
54 |
+
typedef void (*f2py_init_func)(int *, npy_intp *, f2py_set_data_func, int *);
|
55 |
+
|
56 |
+
/*typedef void* (*f2py_c_func)(void*,...);*/
|
57 |
+
|
58 |
+
typedef void *(*f2pycfunc)(void);
|
59 |
+
|
60 |
+
typedef struct {
|
61 |
+
char *name; /* attribute (array||routine) name */
|
62 |
+
int rank; /* array rank, 0 for scalar, max is F2PY_MAX_DIMS,
|
63 |
+
|| rank=-1 for Fortran routine */
|
64 |
+
struct {
|
65 |
+
npy_intp d[F2PY_MAX_DIMS];
|
66 |
+
} dims; /* dimensions of the array, || not used */
|
67 |
+
int type; /* PyArray_<type> || not used */
|
68 |
+
int elsize; /* Element size || not used */
|
69 |
+
char *data; /* pointer to array || Fortran routine */
|
70 |
+
f2py_init_func func; /* initialization function for
|
71 |
+
allocatable arrays:
|
72 |
+
func(&rank,dims,set_ptr_func,name,len(name))
|
73 |
+
|| C/API wrapper for Fortran routine */
|
74 |
+
char *doc; /* documentation string; only recommended
|
75 |
+
for routines. */
|
76 |
+
} FortranDataDef;
|
77 |
+
|
78 |
+
typedef struct {
|
79 |
+
PyObject_HEAD
|
80 |
+
int len; /* Number of attributes */
|
81 |
+
FortranDataDef *defs; /* An array of FortranDataDef's */
|
82 |
+
PyObject *dict; /* Fortran object attribute dictionary */
|
83 |
+
} PyFortranObject;
|
84 |
+
|
85 |
+
#define PyFortran_Check(op) (Py_TYPE(op) == &PyFortran_Type)
|
86 |
+
#define PyFortran_Check1(op) (0 == strcmp(Py_TYPE(op)->tp_name, "fortran"))
|
87 |
+
|
88 |
+
extern PyTypeObject PyFortran_Type;
|
89 |
+
extern int
|
90 |
+
F2PyDict_SetItemString(PyObject *dict, char *name, PyObject *obj);
|
91 |
+
extern PyObject *
|
92 |
+
PyFortranObject_New(FortranDataDef *defs, f2py_void_func init);
|
93 |
+
extern PyObject *
|
94 |
+
PyFortranObject_NewAsAttr(FortranDataDef *defs);
|
95 |
+
|
96 |
+
PyObject *
|
97 |
+
F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *));
|
98 |
+
void *
|
99 |
+
F2PyCapsule_AsVoidPtr(PyObject *obj);
|
100 |
+
int
|
101 |
+
F2PyCapsule_Check(PyObject *ptr);
|
102 |
+
|
103 |
+
extern void *
|
104 |
+
F2PySwapThreadLocalCallbackPtr(char *key, void *ptr);
|
105 |
+
extern void *
|
106 |
+
F2PyGetThreadLocalCallbackPtr(char *key);
|
107 |
+
|
108 |
+
#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) & NPY_ARRAY_C_CONTIGUOUS)
|
109 |
+
#define F2PY_INTENT_IN 1
|
110 |
+
#define F2PY_INTENT_INOUT 2
|
111 |
+
#define F2PY_INTENT_OUT 4
|
112 |
+
#define F2PY_INTENT_HIDE 8
|
113 |
+
#define F2PY_INTENT_CACHE 16
|
114 |
+
#define F2PY_INTENT_COPY 32
|
115 |
+
#define F2PY_INTENT_C 64
|
116 |
+
#define F2PY_OPTIONAL 128
|
117 |
+
#define F2PY_INTENT_INPLACE 256
|
118 |
+
#define F2PY_INTENT_ALIGNED4 512
|
119 |
+
#define F2PY_INTENT_ALIGNED8 1024
|
120 |
+
#define F2PY_INTENT_ALIGNED16 2048
|
121 |
+
|
122 |
+
#define ARRAY_ISALIGNED(ARR, SIZE) ((size_t)(PyArray_DATA(ARR)) % (SIZE) == 0)
|
123 |
+
#define F2PY_ALIGN4(intent) (intent & F2PY_INTENT_ALIGNED4)
|
124 |
+
#define F2PY_ALIGN8(intent) (intent & F2PY_INTENT_ALIGNED8)
|
125 |
+
#define F2PY_ALIGN16(intent) (intent & F2PY_INTENT_ALIGNED16)
|
126 |
+
|
127 |
+
#define F2PY_GET_ALIGNMENT(intent) \
|
128 |
+
(F2PY_ALIGN4(intent) \
|
129 |
+
? 4 \
|
130 |
+
: (F2PY_ALIGN8(intent) ? 8 : (F2PY_ALIGN16(intent) ? 16 : 1)))
|
131 |
+
#define F2PY_CHECK_ALIGNMENT(arr, intent) \
|
132 |
+
ARRAY_ISALIGNED(arr, F2PY_GET_ALIGNMENT(intent))
|
133 |
+
#define F2PY_ARRAY_IS_CHARACTER_COMPATIBLE(arr) ((PyArray_DESCR(arr)->type_num == NPY_STRING && PyArray_DESCR(arr)->elsize >= 1) \
|
134 |
+
|| PyArray_DESCR(arr)->type_num == NPY_UINT8)
|
135 |
+
#define F2PY_IS_UNICODE_ARRAY(arr) (PyArray_DESCR(arr)->type_num == NPY_UNICODE)
|
136 |
+
|
137 |
+
extern PyArrayObject *
|
138 |
+
ndarray_from_pyobj(const int type_num, const int elsize_, npy_intp *dims,
|
139 |
+
const int rank, const int intent, PyObject *obj,
|
140 |
+
const char *errmess);
|
141 |
+
|
142 |
+
extern PyArrayObject *
|
143 |
+
array_from_pyobj(const int type_num, npy_intp *dims, const int rank,
|
144 |
+
const int intent, PyObject *obj);
|
145 |
+
extern int
|
146 |
+
copy_ND_array(const PyArrayObject *in, PyArrayObject *out);
|
147 |
+
|
148 |
+
#ifdef DEBUG_COPY_ND_ARRAY
|
149 |
+
extern void
|
150 |
+
dump_attrs(const PyArrayObject *arr);
|
151 |
+
#endif
|
152 |
+
|
153 |
+
extern int f2py_describe(PyObject *obj, char *buf);
|
154 |
+
|
155 |
+
/* Utility CPP macros and functions that can be used in signature file
|
156 |
+
expressions. See signature-file.rst for documentation.
|
157 |
+
*/
|
158 |
+
|
159 |
+
#define f2py_itemsize(var) (PyArray_DESCR((capi_ ## var ## _as_array))->elsize)
|
160 |
+
#define f2py_size(var, ...) f2py_size_impl((PyArrayObject *)(capi_ ## var ## _as_array), ## __VA_ARGS__, -1)
|
161 |
+
#define f2py_rank(var) var ## _Rank
|
162 |
+
#define f2py_shape(var,dim) var ## _Dims[dim]
|
163 |
+
#define f2py_len(var) f2py_shape(var,0)
|
164 |
+
#define f2py_fshape(var,dim) f2py_shape(var,rank(var)-dim-1)
|
165 |
+
#define f2py_flen(var) f2py_fshape(var,0)
|
166 |
+
#define f2py_slen(var) capi_ ## var ## _len
|
167 |
+
|
168 |
+
extern npy_intp f2py_size_impl(PyArrayObject* var, ...);
|
169 |
+
|
170 |
+
#ifdef __cplusplus
|
171 |
+
}
|
172 |
+
#endif
|
173 |
+
#endif /* !Py_FORTRANOBJECT_H */
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/abstract_interface/foo.f90
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module ops_module
|
2 |
+
|
3 |
+
abstract interface
|
4 |
+
subroutine op(x, y, z)
|
5 |
+
integer, intent(in) :: x, y
|
6 |
+
integer, intent(out) :: z
|
7 |
+
end subroutine
|
8 |
+
end interface
|
9 |
+
|
10 |
+
contains
|
11 |
+
|
12 |
+
subroutine foo(x, y, r1, r2)
|
13 |
+
integer, intent(in) :: x, y
|
14 |
+
integer, intent(out) :: r1, r2
|
15 |
+
procedure (op) add1, add2
|
16 |
+
procedure (op), pointer::p
|
17 |
+
p=>add1
|
18 |
+
call p(x, y, r1)
|
19 |
+
p=>add2
|
20 |
+
call p(x, y, r2)
|
21 |
+
end subroutine
|
22 |
+
end module
|
23 |
+
|
24 |
+
subroutine add1(x, y, z)
|
25 |
+
integer, intent(in) :: x, y
|
26 |
+
integer, intent(out) :: z
|
27 |
+
z = x + y
|
28 |
+
end subroutine
|
29 |
+
|
30 |
+
subroutine add2(x, y, z)
|
31 |
+
integer, intent(in) :: x, y
|
32 |
+
integer, intent(out) :: z
|
33 |
+
z = x + 2 * y
|
34 |
+
end subroutine
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/abstract_interface/gh18403_mod.f90
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module test
|
2 |
+
abstract interface
|
3 |
+
subroutine foo()
|
4 |
+
end subroutine
|
5 |
+
end interface
|
6 |
+
end module test
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/block_docstring/foo.f
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
SUBROUTINE FOO()
|
2 |
+
INTEGER BAR(2, 3)
|
3 |
+
|
4 |
+
COMMON /BLOCK/ BAR
|
5 |
+
RETURN
|
6 |
+
END
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/common/block.f
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
SUBROUTINE INITCB
|
2 |
+
DOUBLE PRECISION LONG
|
3 |
+
CHARACTER STRING
|
4 |
+
INTEGER OK
|
5 |
+
|
6 |
+
COMMON /BLOCK/ LONG, STRING, OK
|
7 |
+
LONG = 1.0
|
8 |
+
STRING = '2'
|
9 |
+
OK = 3
|
10 |
+
RETURN
|
11 |
+
END
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/common/gh19161.f90
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module typedefmod
|
2 |
+
use iso_fortran_env, only: real32
|
3 |
+
end module typedefmod
|
4 |
+
|
5 |
+
module data
|
6 |
+
use typedefmod, only: real32
|
7 |
+
implicit none
|
8 |
+
real(kind=real32) :: x
|
9 |
+
common/test/x
|
10 |
+
end module data
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/isocintrin/isoCtests.f90
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module coddity
|
2 |
+
use iso_c_binding, only: c_double, c_int, c_int64_t
|
3 |
+
implicit none
|
4 |
+
contains
|
5 |
+
subroutine c_add(a, b, c) bind(c, name="c_add")
|
6 |
+
real(c_double), intent(in) :: a, b
|
7 |
+
real(c_double), intent(out) :: c
|
8 |
+
c = a + b
|
9 |
+
end subroutine c_add
|
10 |
+
! gh-9693
|
11 |
+
function wat(x, y) result(z) bind(c)
|
12 |
+
integer(c_int), intent(in) :: x, y
|
13 |
+
integer(c_int) :: z
|
14 |
+
|
15 |
+
z = x + 7
|
16 |
+
end function wat
|
17 |
+
! gh-25207
|
18 |
+
subroutine c_add_int64(a, b, c) bind(c)
|
19 |
+
integer(c_int64_t), intent(in) :: a, b
|
20 |
+
integer(c_int64_t), intent(out) :: c
|
21 |
+
c = a + b
|
22 |
+
end subroutine c_add_int64
|
23 |
+
! gh-25207
|
24 |
+
subroutine add_arr(A, B, C)
|
25 |
+
integer(c_int64_t), intent(in) :: A(3)
|
26 |
+
integer(c_int64_t), intent(in) :: B(3)
|
27 |
+
integer(c_int64_t), intent(out) :: C(3)
|
28 |
+
integer :: j
|
29 |
+
|
30 |
+
do j = 1, 3
|
31 |
+
C(j) = A(j)+B(j)
|
32 |
+
end do
|
33 |
+
end subroutine
|
34 |
+
end module coddity
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/mixed/foo.f
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
subroutine bar11(a)
|
2 |
+
cf2py intent(out) a
|
3 |
+
integer a
|
4 |
+
a = 11
|
5 |
+
end
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module foo_fixed
|
2 |
+
contains
|
3 |
+
subroutine bar12(a)
|
4 |
+
!f2py intent(out) a
|
5 |
+
integer a
|
6 |
+
a = 12
|
7 |
+
end subroutine bar12
|
8 |
+
end module foo_fixed
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module foo_free
|
2 |
+
contains
|
3 |
+
subroutine bar13(a)
|
4 |
+
!f2py intent(out) a
|
5 |
+
integer a
|
6 |
+
a = 13
|
7 |
+
end subroutine bar13
|
8 |
+
end module foo_free
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/module_data/mod.mod
ADDED
Binary file (412 Bytes). View file
|
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/module_data/module_data_docstring.f90
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module mod
|
2 |
+
integer :: i
|
3 |
+
integer :: x(4)
|
4 |
+
real, dimension(2,3) :: a
|
5 |
+
real, allocatable, dimension(:,:) :: b
|
6 |
+
contains
|
7 |
+
subroutine foo
|
8 |
+
integer :: k
|
9 |
+
k = 1
|
10 |
+
a(1,2) = a(1,2)+3
|
11 |
+
end subroutine foo
|
12 |
+
end module mod
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/regression/gh25337/data.f90
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module data
|
2 |
+
real(8) :: shift
|
3 |
+
contains
|
4 |
+
subroutine set_shift(in_shift)
|
5 |
+
real(8), intent(in) :: in_shift
|
6 |
+
shift = in_shift
|
7 |
+
end subroutine set_shift
|
8 |
+
end module data
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/regression/gh25337/use_data.f90
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
subroutine shift_a(dim_a, a)
|
2 |
+
use data, only: shift
|
3 |
+
integer, intent(in) :: dim_a
|
4 |
+
real(8), intent(inout), dimension(dim_a) :: a
|
5 |
+
a = a + shift
|
6 |
+
end subroutine shift_a
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/regression/inout.f90
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
! Check that intent(in out) translates as intent(inout).
|
2 |
+
! The separation seems to be a common usage.
|
3 |
+
subroutine foo(x)
|
4 |
+
implicit none
|
5 |
+
real(4), intent(in out) :: x
|
6 |
+
dimension x(3)
|
7 |
+
x(1) = x(1) + x(2) + x(3)
|
8 |
+
return
|
9 |
+
end
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_complex/foo77.f
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
function t0(value)
|
2 |
+
complex value
|
3 |
+
complex t0
|
4 |
+
t0 = value
|
5 |
+
end
|
6 |
+
function t8(value)
|
7 |
+
complex*8 value
|
8 |
+
complex*8 t8
|
9 |
+
t8 = value
|
10 |
+
end
|
11 |
+
function t16(value)
|
12 |
+
complex*16 value
|
13 |
+
complex*16 t16
|
14 |
+
t16 = value
|
15 |
+
end
|
16 |
+
function td(value)
|
17 |
+
double complex value
|
18 |
+
double complex td
|
19 |
+
td = value
|
20 |
+
end
|
21 |
+
|
22 |
+
subroutine s0(t0,value)
|
23 |
+
complex value
|
24 |
+
complex t0
|
25 |
+
cf2py intent(out) t0
|
26 |
+
t0 = value
|
27 |
+
end
|
28 |
+
subroutine s8(t8,value)
|
29 |
+
complex*8 value
|
30 |
+
complex*8 t8
|
31 |
+
cf2py intent(out) t8
|
32 |
+
t8 = value
|
33 |
+
end
|
34 |
+
subroutine s16(t16,value)
|
35 |
+
complex*16 value
|
36 |
+
complex*16 t16
|
37 |
+
cf2py intent(out) t16
|
38 |
+
t16 = value
|
39 |
+
end
|
40 |
+
subroutine sd(td,value)
|
41 |
+
double complex value
|
42 |
+
double complex td
|
43 |
+
cf2py intent(out) td
|
44 |
+
td = value
|
45 |
+
end
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_complex/foo90.f90
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module f90_return_complex
|
2 |
+
contains
|
3 |
+
function t0(value)
|
4 |
+
complex :: value
|
5 |
+
complex :: t0
|
6 |
+
t0 = value
|
7 |
+
end function t0
|
8 |
+
function t8(value)
|
9 |
+
complex(kind=4) :: value
|
10 |
+
complex(kind=4) :: t8
|
11 |
+
t8 = value
|
12 |
+
end function t8
|
13 |
+
function t16(value)
|
14 |
+
complex(kind=8) :: value
|
15 |
+
complex(kind=8) :: t16
|
16 |
+
t16 = value
|
17 |
+
end function t16
|
18 |
+
function td(value)
|
19 |
+
double complex :: value
|
20 |
+
double complex :: td
|
21 |
+
td = value
|
22 |
+
end function td
|
23 |
+
|
24 |
+
subroutine s0(t0,value)
|
25 |
+
complex :: value
|
26 |
+
complex :: t0
|
27 |
+
!f2py intent(out) t0
|
28 |
+
t0 = value
|
29 |
+
end subroutine s0
|
30 |
+
subroutine s8(t8,value)
|
31 |
+
complex(kind=4) :: value
|
32 |
+
complex(kind=4) :: t8
|
33 |
+
!f2py intent(out) t8
|
34 |
+
t8 = value
|
35 |
+
end subroutine s8
|
36 |
+
subroutine s16(t16,value)
|
37 |
+
complex(kind=8) :: value
|
38 |
+
complex(kind=8) :: t16
|
39 |
+
!f2py intent(out) t16
|
40 |
+
t16 = value
|
41 |
+
end subroutine s16
|
42 |
+
subroutine sd(td,value)
|
43 |
+
double complex :: value
|
44 |
+
double complex :: td
|
45 |
+
!f2py intent(out) td
|
46 |
+
td = value
|
47 |
+
end subroutine sd
|
48 |
+
end module f90_return_complex
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_logical/foo77.f
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
function t0(value)
|
2 |
+
logical value
|
3 |
+
logical t0
|
4 |
+
t0 = value
|
5 |
+
end
|
6 |
+
function t1(value)
|
7 |
+
logical*1 value
|
8 |
+
logical*1 t1
|
9 |
+
t1 = value
|
10 |
+
end
|
11 |
+
function t2(value)
|
12 |
+
logical*2 value
|
13 |
+
logical*2 t2
|
14 |
+
t2 = value
|
15 |
+
end
|
16 |
+
function t4(value)
|
17 |
+
logical*4 value
|
18 |
+
logical*4 t4
|
19 |
+
t4 = value
|
20 |
+
end
|
21 |
+
c function t8(value)
|
22 |
+
c logical*8 value
|
23 |
+
c logical*8 t8
|
24 |
+
c t8 = value
|
25 |
+
c end
|
26 |
+
|
27 |
+
subroutine s0(t0,value)
|
28 |
+
logical value
|
29 |
+
logical t0
|
30 |
+
cf2py intent(out) t0
|
31 |
+
t0 = value
|
32 |
+
end
|
33 |
+
subroutine s1(t1,value)
|
34 |
+
logical*1 value
|
35 |
+
logical*1 t1
|
36 |
+
cf2py intent(out) t1
|
37 |
+
t1 = value
|
38 |
+
end
|
39 |
+
subroutine s2(t2,value)
|
40 |
+
logical*2 value
|
41 |
+
logical*2 t2
|
42 |
+
cf2py intent(out) t2
|
43 |
+
t2 = value
|
44 |
+
end
|
45 |
+
subroutine s4(t4,value)
|
46 |
+
logical*4 value
|
47 |
+
logical*4 t4
|
48 |
+
cf2py intent(out) t4
|
49 |
+
t4 = value
|
50 |
+
end
|
51 |
+
c subroutine s8(t8,value)
|
52 |
+
c logical*8 value
|
53 |
+
c logical*8 t8
|
54 |
+
cf2py intent(out) t8
|
55 |
+
c t8 = value
|
56 |
+
c end
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_logical/foo90.f90
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module f90_return_logical
|
2 |
+
contains
|
3 |
+
function t0(value)
|
4 |
+
logical :: value
|
5 |
+
logical :: t0
|
6 |
+
t0 = value
|
7 |
+
end function t0
|
8 |
+
function t1(value)
|
9 |
+
logical(kind=1) :: value
|
10 |
+
logical(kind=1) :: t1
|
11 |
+
t1 = value
|
12 |
+
end function t1
|
13 |
+
function t2(value)
|
14 |
+
logical(kind=2) :: value
|
15 |
+
logical(kind=2) :: t2
|
16 |
+
t2 = value
|
17 |
+
end function t2
|
18 |
+
function t4(value)
|
19 |
+
logical(kind=4) :: value
|
20 |
+
logical(kind=4) :: t4
|
21 |
+
t4 = value
|
22 |
+
end function t4
|
23 |
+
function t8(value)
|
24 |
+
logical(kind=8) :: value
|
25 |
+
logical(kind=8) :: t8
|
26 |
+
t8 = value
|
27 |
+
end function t8
|
28 |
+
|
29 |
+
subroutine s0(t0,value)
|
30 |
+
logical :: value
|
31 |
+
logical :: t0
|
32 |
+
!f2py intent(out) t0
|
33 |
+
t0 = value
|
34 |
+
end subroutine s0
|
35 |
+
subroutine s1(t1,value)
|
36 |
+
logical(kind=1) :: value
|
37 |
+
logical(kind=1) :: t1
|
38 |
+
!f2py intent(out) t1
|
39 |
+
t1 = value
|
40 |
+
end subroutine s1
|
41 |
+
subroutine s2(t2,value)
|
42 |
+
logical(kind=2) :: value
|
43 |
+
logical(kind=2) :: t2
|
44 |
+
!f2py intent(out) t2
|
45 |
+
t2 = value
|
46 |
+
end subroutine s2
|
47 |
+
subroutine s4(t4,value)
|
48 |
+
logical(kind=4) :: value
|
49 |
+
logical(kind=4) :: t4
|
50 |
+
!f2py intent(out) t4
|
51 |
+
t4 = value
|
52 |
+
end subroutine s4
|
53 |
+
subroutine s8(t8,value)
|
54 |
+
logical(kind=8) :: value
|
55 |
+
logical(kind=8) :: t8
|
56 |
+
!f2py intent(out) t8
|
57 |
+
t8 = value
|
58 |
+
end subroutine s8
|
59 |
+
end module f90_return_logical
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_real/foo77.f
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
function t0(value)
|
2 |
+
real value
|
3 |
+
real t0
|
4 |
+
t0 = value
|
5 |
+
end
|
6 |
+
function t4(value)
|
7 |
+
real*4 value
|
8 |
+
real*4 t4
|
9 |
+
t4 = value
|
10 |
+
end
|
11 |
+
function t8(value)
|
12 |
+
real*8 value
|
13 |
+
real*8 t8
|
14 |
+
t8 = value
|
15 |
+
end
|
16 |
+
function td(value)
|
17 |
+
double precision value
|
18 |
+
double precision td
|
19 |
+
td = value
|
20 |
+
end
|
21 |
+
|
22 |
+
subroutine s0(t0,value)
|
23 |
+
real value
|
24 |
+
real t0
|
25 |
+
cf2py intent(out) t0
|
26 |
+
t0 = value
|
27 |
+
end
|
28 |
+
subroutine s4(t4,value)
|
29 |
+
real*4 value
|
30 |
+
real*4 t4
|
31 |
+
cf2py intent(out) t4
|
32 |
+
t4 = value
|
33 |
+
end
|
34 |
+
subroutine s8(t8,value)
|
35 |
+
real*8 value
|
36 |
+
real*8 t8
|
37 |
+
cf2py intent(out) t8
|
38 |
+
t8 = value
|
39 |
+
end
|
40 |
+
subroutine sd(td,value)
|
41 |
+
double precision value
|
42 |
+
double precision td
|
43 |
+
cf2py intent(out) td
|
44 |
+
td = value
|
45 |
+
end
|
.venv/lib/python3.11/site-packages/numpy/f2py/tests/src/return_real/foo90.f90
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module f90_return_real
|
2 |
+
contains
|
3 |
+
function t0(value)
|
4 |
+
real :: value
|
5 |
+
real :: t0
|
6 |
+
t0 = value
|
7 |
+
end function t0
|
8 |
+
function t4(value)
|
9 |
+
real(kind=4) :: value
|
10 |
+
real(kind=4) :: t4
|
11 |
+
t4 = value
|
12 |
+
end function t4
|
13 |
+
function t8(value)
|
14 |
+
real(kind=8) :: value
|
15 |
+
real(kind=8) :: t8
|
16 |
+
t8 = value
|
17 |
+
end function t8
|
18 |
+
function td(value)
|
19 |
+
double precision :: value
|
20 |
+
double precision :: td
|
21 |
+
td = value
|
22 |
+
end function td
|
23 |
+
|
24 |
+
subroutine s0(t0,value)
|
25 |
+
real :: value
|
26 |
+
real :: t0
|
27 |
+
!f2py intent(out) t0
|
28 |
+
t0 = value
|
29 |
+
end subroutine s0
|
30 |
+
subroutine s4(t4,value)
|
31 |
+
real(kind=4) :: value
|
32 |
+
real(kind=4) :: t4
|
33 |
+
!f2py intent(out) t4
|
34 |
+
t4 = value
|
35 |
+
end subroutine s4
|
36 |
+
subroutine s8(t8,value)
|
37 |
+
real(kind=8) :: value
|
38 |
+
real(kind=8) :: t8
|
39 |
+
!f2py intent(out) t8
|
40 |
+
t8 = value
|
41 |
+
end subroutine s8
|
42 |
+
subroutine sd(td,value)
|
43 |
+
double precision :: value
|
44 |
+
double precision :: td
|
45 |
+
!f2py intent(out) td
|
46 |
+
td = value
|
47 |
+
end subroutine sd
|
48 |
+
end module f90_return_real
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/__init__.py
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""Sub-package containing the matrix class and related functions.
|
2 |
+
|
3 |
+
"""
|
4 |
+
from . import defmatrix
|
5 |
+
from .defmatrix import *
|
6 |
+
|
7 |
+
__all__ = defmatrix.__all__
|
8 |
+
|
9 |
+
from numpy._pytesttester import PytestTester
|
10 |
+
test = PytestTester(__name__)
|
11 |
+
del PytestTester
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/__init__.pyi
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from numpy._pytesttester import PytestTester
|
2 |
+
|
3 |
+
from numpy import (
|
4 |
+
matrix as matrix,
|
5 |
+
)
|
6 |
+
|
7 |
+
from numpy.matrixlib.defmatrix import (
|
8 |
+
bmat as bmat,
|
9 |
+
mat as mat,
|
10 |
+
asmatrix as asmatrix,
|
11 |
+
)
|
12 |
+
|
13 |
+
__all__: list[str]
|
14 |
+
__path__: list[str]
|
15 |
+
test: PytestTester
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/__pycache__/__init__.cpython-311.pyc
ADDED
Binary file (516 Bytes). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/__pycache__/defmatrix.cpython-311.pyc
ADDED
Binary file (37.6 kB). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/__pycache__/setup.cpython-311.pyc
ADDED
Binary file (938 Bytes). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/defmatrix.py
ADDED
@@ -0,0 +1,1114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
__all__ = ['matrix', 'bmat', 'mat', 'asmatrix']
|
2 |
+
|
3 |
+
import sys
|
4 |
+
import warnings
|
5 |
+
import ast
|
6 |
+
|
7 |
+
from .._utils import set_module
|
8 |
+
import numpy.core.numeric as N
|
9 |
+
from numpy.core.numeric import concatenate, isscalar
|
10 |
+
# While not in __all__, matrix_power used to be defined here, so we import
|
11 |
+
# it for backward compatibility.
|
12 |
+
from numpy.linalg import matrix_power
|
13 |
+
|
14 |
+
|
15 |
+
def _convert_from_string(data):
|
16 |
+
for char in '[]':
|
17 |
+
data = data.replace(char, '')
|
18 |
+
|
19 |
+
rows = data.split(';')
|
20 |
+
newdata = []
|
21 |
+
count = 0
|
22 |
+
for row in rows:
|
23 |
+
trow = row.split(',')
|
24 |
+
newrow = []
|
25 |
+
for col in trow:
|
26 |
+
temp = col.split()
|
27 |
+
newrow.extend(map(ast.literal_eval, temp))
|
28 |
+
if count == 0:
|
29 |
+
Ncols = len(newrow)
|
30 |
+
elif len(newrow) != Ncols:
|
31 |
+
raise ValueError("Rows not the same size.")
|
32 |
+
count += 1
|
33 |
+
newdata.append(newrow)
|
34 |
+
return newdata
|
35 |
+
|
36 |
+
|
37 |
+
@set_module('numpy')
|
38 |
+
def asmatrix(data, dtype=None):
|
39 |
+
"""
|
40 |
+
Interpret the input as a matrix.
|
41 |
+
|
42 |
+
Unlike `matrix`, `asmatrix` does not make a copy if the input is already
|
43 |
+
a matrix or an ndarray. Equivalent to ``matrix(data, copy=False)``.
|
44 |
+
|
45 |
+
Parameters
|
46 |
+
----------
|
47 |
+
data : array_like
|
48 |
+
Input data.
|
49 |
+
dtype : data-type
|
50 |
+
Data-type of the output matrix.
|
51 |
+
|
52 |
+
Returns
|
53 |
+
-------
|
54 |
+
mat : matrix
|
55 |
+
`data` interpreted as a matrix.
|
56 |
+
|
57 |
+
Examples
|
58 |
+
--------
|
59 |
+
>>> x = np.array([[1, 2], [3, 4]])
|
60 |
+
|
61 |
+
>>> m = np.asmatrix(x)
|
62 |
+
|
63 |
+
>>> x[0,0] = 5
|
64 |
+
|
65 |
+
>>> m
|
66 |
+
matrix([[5, 2],
|
67 |
+
[3, 4]])
|
68 |
+
|
69 |
+
"""
|
70 |
+
return matrix(data, dtype=dtype, copy=False)
|
71 |
+
|
72 |
+
|
73 |
+
@set_module('numpy')
|
74 |
+
class matrix(N.ndarray):
|
75 |
+
"""
|
76 |
+
matrix(data, dtype=None, copy=True)
|
77 |
+
|
78 |
+
.. note:: It is no longer recommended to use this class, even for linear
|
79 |
+
algebra. Instead use regular arrays. The class may be removed
|
80 |
+
in the future.
|
81 |
+
|
82 |
+
Returns a matrix from an array-like object, or from a string of data.
|
83 |
+
A matrix is a specialized 2-D array that retains its 2-D nature
|
84 |
+
through operations. It has certain special operators, such as ``*``
|
85 |
+
(matrix multiplication) and ``**`` (matrix power).
|
86 |
+
|
87 |
+
Parameters
|
88 |
+
----------
|
89 |
+
data : array_like or string
|
90 |
+
If `data` is a string, it is interpreted as a matrix with commas
|
91 |
+
or spaces separating columns, and semicolons separating rows.
|
92 |
+
dtype : data-type
|
93 |
+
Data-type of the output matrix.
|
94 |
+
copy : bool
|
95 |
+
If `data` is already an `ndarray`, then this flag determines
|
96 |
+
whether the data is copied (the default), or whether a view is
|
97 |
+
constructed.
|
98 |
+
|
99 |
+
See Also
|
100 |
+
--------
|
101 |
+
array
|
102 |
+
|
103 |
+
Examples
|
104 |
+
--------
|
105 |
+
>>> a = np.matrix('1 2; 3 4')
|
106 |
+
>>> a
|
107 |
+
matrix([[1, 2],
|
108 |
+
[3, 4]])
|
109 |
+
|
110 |
+
>>> np.matrix([[1, 2], [3, 4]])
|
111 |
+
matrix([[1, 2],
|
112 |
+
[3, 4]])
|
113 |
+
|
114 |
+
"""
|
115 |
+
__array_priority__ = 10.0
|
116 |
+
def __new__(subtype, data, dtype=None, copy=True):
|
117 |
+
warnings.warn('the matrix subclass is not the recommended way to '
|
118 |
+
'represent matrices or deal with linear algebra (see '
|
119 |
+
'https://docs.scipy.org/doc/numpy/user/'
|
120 |
+
'numpy-for-matlab-users.html). '
|
121 |
+
'Please adjust your code to use regular ndarray.',
|
122 |
+
PendingDeprecationWarning, stacklevel=2)
|
123 |
+
if isinstance(data, matrix):
|
124 |
+
dtype2 = data.dtype
|
125 |
+
if (dtype is None):
|
126 |
+
dtype = dtype2
|
127 |
+
if (dtype2 == dtype) and (not copy):
|
128 |
+
return data
|
129 |
+
return data.astype(dtype)
|
130 |
+
|
131 |
+
if isinstance(data, N.ndarray):
|
132 |
+
if dtype is None:
|
133 |
+
intype = data.dtype
|
134 |
+
else:
|
135 |
+
intype = N.dtype(dtype)
|
136 |
+
new = data.view(subtype)
|
137 |
+
if intype != data.dtype:
|
138 |
+
return new.astype(intype)
|
139 |
+
if copy: return new.copy()
|
140 |
+
else: return new
|
141 |
+
|
142 |
+
if isinstance(data, str):
|
143 |
+
data = _convert_from_string(data)
|
144 |
+
|
145 |
+
# now convert data to an array
|
146 |
+
arr = N.array(data, dtype=dtype, copy=copy)
|
147 |
+
ndim = arr.ndim
|
148 |
+
shape = arr.shape
|
149 |
+
if (ndim > 2):
|
150 |
+
raise ValueError("matrix must be 2-dimensional")
|
151 |
+
elif ndim == 0:
|
152 |
+
shape = (1, 1)
|
153 |
+
elif ndim == 1:
|
154 |
+
shape = (1, shape[0])
|
155 |
+
|
156 |
+
order = 'C'
|
157 |
+
if (ndim == 2) and arr.flags.fortran:
|
158 |
+
order = 'F'
|
159 |
+
|
160 |
+
if not (order or arr.flags.contiguous):
|
161 |
+
arr = arr.copy()
|
162 |
+
|
163 |
+
ret = N.ndarray.__new__(subtype, shape, arr.dtype,
|
164 |
+
buffer=arr,
|
165 |
+
order=order)
|
166 |
+
return ret
|
167 |
+
|
168 |
+
def __array_finalize__(self, obj):
|
169 |
+
self._getitem = False
|
170 |
+
if (isinstance(obj, matrix) and obj._getitem): return
|
171 |
+
ndim = self.ndim
|
172 |
+
if (ndim == 2):
|
173 |
+
return
|
174 |
+
if (ndim > 2):
|
175 |
+
newshape = tuple([x for x in self.shape if x > 1])
|
176 |
+
ndim = len(newshape)
|
177 |
+
if ndim == 2:
|
178 |
+
self.shape = newshape
|
179 |
+
return
|
180 |
+
elif (ndim > 2):
|
181 |
+
raise ValueError("shape too large to be a matrix.")
|
182 |
+
else:
|
183 |
+
newshape = self.shape
|
184 |
+
if ndim == 0:
|
185 |
+
self.shape = (1, 1)
|
186 |
+
elif ndim == 1:
|
187 |
+
self.shape = (1, newshape[0])
|
188 |
+
return
|
189 |
+
|
190 |
+
def __getitem__(self, index):
|
191 |
+
self._getitem = True
|
192 |
+
|
193 |
+
try:
|
194 |
+
out = N.ndarray.__getitem__(self, index)
|
195 |
+
finally:
|
196 |
+
self._getitem = False
|
197 |
+
|
198 |
+
if not isinstance(out, N.ndarray):
|
199 |
+
return out
|
200 |
+
|
201 |
+
if out.ndim == 0:
|
202 |
+
return out[()]
|
203 |
+
if out.ndim == 1:
|
204 |
+
sh = out.shape[0]
|
205 |
+
# Determine when we should have a column array
|
206 |
+
try:
|
207 |
+
n = len(index)
|
208 |
+
except Exception:
|
209 |
+
n = 0
|
210 |
+
if n > 1 and isscalar(index[1]):
|
211 |
+
out.shape = (sh, 1)
|
212 |
+
else:
|
213 |
+
out.shape = (1, sh)
|
214 |
+
return out
|
215 |
+
|
216 |
+
def __mul__(self, other):
|
217 |
+
if isinstance(other, (N.ndarray, list, tuple)) :
|
218 |
+
# This promotes 1-D vectors to row vectors
|
219 |
+
return N.dot(self, asmatrix(other))
|
220 |
+
if isscalar(other) or not hasattr(other, '__rmul__') :
|
221 |
+
return N.dot(self, other)
|
222 |
+
return NotImplemented
|
223 |
+
|
224 |
+
def __rmul__(self, other):
|
225 |
+
return N.dot(other, self)
|
226 |
+
|
227 |
+
def __imul__(self, other):
|
228 |
+
self[:] = self * other
|
229 |
+
return self
|
230 |
+
|
231 |
+
def __pow__(self, other):
|
232 |
+
return matrix_power(self, other)
|
233 |
+
|
234 |
+
def __ipow__(self, other):
|
235 |
+
self[:] = self ** other
|
236 |
+
return self
|
237 |
+
|
238 |
+
def __rpow__(self, other):
|
239 |
+
return NotImplemented
|
240 |
+
|
241 |
+
def _align(self, axis):
|
242 |
+
"""A convenience function for operations that need to preserve axis
|
243 |
+
orientation.
|
244 |
+
"""
|
245 |
+
if axis is None:
|
246 |
+
return self[0, 0]
|
247 |
+
elif axis==0:
|
248 |
+
return self
|
249 |
+
elif axis==1:
|
250 |
+
return self.transpose()
|
251 |
+
else:
|
252 |
+
raise ValueError("unsupported axis")
|
253 |
+
|
254 |
+
def _collapse(self, axis):
|
255 |
+
"""A convenience function for operations that want to collapse
|
256 |
+
to a scalar like _align, but are using keepdims=True
|
257 |
+
"""
|
258 |
+
if axis is None:
|
259 |
+
return self[0, 0]
|
260 |
+
else:
|
261 |
+
return self
|
262 |
+
|
263 |
+
# Necessary because base-class tolist expects dimension
|
264 |
+
# reduction by x[0]
|
265 |
+
def tolist(self):
|
266 |
+
"""
|
267 |
+
Return the matrix as a (possibly nested) list.
|
268 |
+
|
269 |
+
See `ndarray.tolist` for full documentation.
|
270 |
+
|
271 |
+
See Also
|
272 |
+
--------
|
273 |
+
ndarray.tolist
|
274 |
+
|
275 |
+
Examples
|
276 |
+
--------
|
277 |
+
>>> x = np.matrix(np.arange(12).reshape((3,4))); x
|
278 |
+
matrix([[ 0, 1, 2, 3],
|
279 |
+
[ 4, 5, 6, 7],
|
280 |
+
[ 8, 9, 10, 11]])
|
281 |
+
>>> x.tolist()
|
282 |
+
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
|
283 |
+
|
284 |
+
"""
|
285 |
+
return self.__array__().tolist()
|
286 |
+
|
287 |
+
# To preserve orientation of result...
|
288 |
+
def sum(self, axis=None, dtype=None, out=None):
|
289 |
+
"""
|
290 |
+
Returns the sum of the matrix elements, along the given axis.
|
291 |
+
|
292 |
+
Refer to `numpy.sum` for full documentation.
|
293 |
+
|
294 |
+
See Also
|
295 |
+
--------
|
296 |
+
numpy.sum
|
297 |
+
|
298 |
+
Notes
|
299 |
+
-----
|
300 |
+
This is the same as `ndarray.sum`, except that where an `ndarray` would
|
301 |
+
be returned, a `matrix` object is returned instead.
|
302 |
+
|
303 |
+
Examples
|
304 |
+
--------
|
305 |
+
>>> x = np.matrix([[1, 2], [4, 3]])
|
306 |
+
>>> x.sum()
|
307 |
+
10
|
308 |
+
>>> x.sum(axis=1)
|
309 |
+
matrix([[3],
|
310 |
+
[7]])
|
311 |
+
>>> x.sum(axis=1, dtype='float')
|
312 |
+
matrix([[3.],
|
313 |
+
[7.]])
|
314 |
+
>>> out = np.zeros((2, 1), dtype='float')
|
315 |
+
>>> x.sum(axis=1, dtype='float', out=np.asmatrix(out))
|
316 |
+
matrix([[3.],
|
317 |
+
[7.]])
|
318 |
+
|
319 |
+
"""
|
320 |
+
return N.ndarray.sum(self, axis, dtype, out, keepdims=True)._collapse(axis)
|
321 |
+
|
322 |
+
|
323 |
+
# To update docstring from array to matrix...
|
324 |
+
def squeeze(self, axis=None):
|
325 |
+
"""
|
326 |
+
Return a possibly reshaped matrix.
|
327 |
+
|
328 |
+
Refer to `numpy.squeeze` for more documentation.
|
329 |
+
|
330 |
+
Parameters
|
331 |
+
----------
|
332 |
+
axis : None or int or tuple of ints, optional
|
333 |
+
Selects a subset of the axes of length one in the shape.
|
334 |
+
If an axis is selected with shape entry greater than one,
|
335 |
+
an error is raised.
|
336 |
+
|
337 |
+
Returns
|
338 |
+
-------
|
339 |
+
squeezed : matrix
|
340 |
+
The matrix, but as a (1, N) matrix if it had shape (N, 1).
|
341 |
+
|
342 |
+
See Also
|
343 |
+
--------
|
344 |
+
numpy.squeeze : related function
|
345 |
+
|
346 |
+
Notes
|
347 |
+
-----
|
348 |
+
If `m` has a single column then that column is returned
|
349 |
+
as the single row of a matrix. Otherwise `m` is returned.
|
350 |
+
The returned matrix is always either `m` itself or a view into `m`.
|
351 |
+
Supplying an axis keyword argument will not affect the returned matrix
|
352 |
+
but it may cause an error to be raised.
|
353 |
+
|
354 |
+
Examples
|
355 |
+
--------
|
356 |
+
>>> c = np.matrix([[1], [2]])
|
357 |
+
>>> c
|
358 |
+
matrix([[1],
|
359 |
+
[2]])
|
360 |
+
>>> c.squeeze()
|
361 |
+
matrix([[1, 2]])
|
362 |
+
>>> r = c.T
|
363 |
+
>>> r
|
364 |
+
matrix([[1, 2]])
|
365 |
+
>>> r.squeeze()
|
366 |
+
matrix([[1, 2]])
|
367 |
+
>>> m = np.matrix([[1, 2], [3, 4]])
|
368 |
+
>>> m.squeeze()
|
369 |
+
matrix([[1, 2],
|
370 |
+
[3, 4]])
|
371 |
+
|
372 |
+
"""
|
373 |
+
return N.ndarray.squeeze(self, axis=axis)
|
374 |
+
|
375 |
+
|
376 |
+
# To update docstring from array to matrix...
|
377 |
+
def flatten(self, order='C'):
|
378 |
+
"""
|
379 |
+
Return a flattened copy of the matrix.
|
380 |
+
|
381 |
+
All `N` elements of the matrix are placed into a single row.
|
382 |
+
|
383 |
+
Parameters
|
384 |
+
----------
|
385 |
+
order : {'C', 'F', 'A', 'K'}, optional
|
386 |
+
'C' means to flatten in row-major (C-style) order. 'F' means to
|
387 |
+
flatten in column-major (Fortran-style) order. 'A' means to
|
388 |
+
flatten in column-major order if `m` is Fortran *contiguous* in
|
389 |
+
memory, row-major order otherwise. 'K' means to flatten `m` in
|
390 |
+
the order the elements occur in memory. The default is 'C'.
|
391 |
+
|
392 |
+
Returns
|
393 |
+
-------
|
394 |
+
y : matrix
|
395 |
+
A copy of the matrix, flattened to a `(1, N)` matrix where `N`
|
396 |
+
is the number of elements in the original matrix.
|
397 |
+
|
398 |
+
See Also
|
399 |
+
--------
|
400 |
+
ravel : Return a flattened array.
|
401 |
+
flat : A 1-D flat iterator over the matrix.
|
402 |
+
|
403 |
+
Examples
|
404 |
+
--------
|
405 |
+
>>> m = np.matrix([[1,2], [3,4]])
|
406 |
+
>>> m.flatten()
|
407 |
+
matrix([[1, 2, 3, 4]])
|
408 |
+
>>> m.flatten('F')
|
409 |
+
matrix([[1, 3, 2, 4]])
|
410 |
+
|
411 |
+
"""
|
412 |
+
return N.ndarray.flatten(self, order=order)
|
413 |
+
|
414 |
+
def mean(self, axis=None, dtype=None, out=None):
|
415 |
+
"""
|
416 |
+
Returns the average of the matrix elements along the given axis.
|
417 |
+
|
418 |
+
Refer to `numpy.mean` for full documentation.
|
419 |
+
|
420 |
+
See Also
|
421 |
+
--------
|
422 |
+
numpy.mean
|
423 |
+
|
424 |
+
Notes
|
425 |
+
-----
|
426 |
+
Same as `ndarray.mean` except that, where that returns an `ndarray`,
|
427 |
+
this returns a `matrix` object.
|
428 |
+
|
429 |
+
Examples
|
430 |
+
--------
|
431 |
+
>>> x = np.matrix(np.arange(12).reshape((3, 4)))
|
432 |
+
>>> x
|
433 |
+
matrix([[ 0, 1, 2, 3],
|
434 |
+
[ 4, 5, 6, 7],
|
435 |
+
[ 8, 9, 10, 11]])
|
436 |
+
>>> x.mean()
|
437 |
+
5.5
|
438 |
+
>>> x.mean(0)
|
439 |
+
matrix([[4., 5., 6., 7.]])
|
440 |
+
>>> x.mean(1)
|
441 |
+
matrix([[ 1.5],
|
442 |
+
[ 5.5],
|
443 |
+
[ 9.5]])
|
444 |
+
|
445 |
+
"""
|
446 |
+
return N.ndarray.mean(self, axis, dtype, out, keepdims=True)._collapse(axis)
|
447 |
+
|
448 |
+
def std(self, axis=None, dtype=None, out=None, ddof=0):
|
449 |
+
"""
|
450 |
+
Return the standard deviation of the array elements along the given axis.
|
451 |
+
|
452 |
+
Refer to `numpy.std` for full documentation.
|
453 |
+
|
454 |
+
See Also
|
455 |
+
--------
|
456 |
+
numpy.std
|
457 |
+
|
458 |
+
Notes
|
459 |
+
-----
|
460 |
+
This is the same as `ndarray.std`, except that where an `ndarray` would
|
461 |
+
be returned, a `matrix` object is returned instead.
|
462 |
+
|
463 |
+
Examples
|
464 |
+
--------
|
465 |
+
>>> x = np.matrix(np.arange(12).reshape((3, 4)))
|
466 |
+
>>> x
|
467 |
+
matrix([[ 0, 1, 2, 3],
|
468 |
+
[ 4, 5, 6, 7],
|
469 |
+
[ 8, 9, 10, 11]])
|
470 |
+
>>> x.std()
|
471 |
+
3.4520525295346629 # may vary
|
472 |
+
>>> x.std(0)
|
473 |
+
matrix([[ 3.26598632, 3.26598632, 3.26598632, 3.26598632]]) # may vary
|
474 |
+
>>> x.std(1)
|
475 |
+
matrix([[ 1.11803399],
|
476 |
+
[ 1.11803399],
|
477 |
+
[ 1.11803399]])
|
478 |
+
|
479 |
+
"""
|
480 |
+
return N.ndarray.std(self, axis, dtype, out, ddof, keepdims=True)._collapse(axis)
|
481 |
+
|
482 |
+
def var(self, axis=None, dtype=None, out=None, ddof=0):
|
483 |
+
"""
|
484 |
+
Returns the variance of the matrix elements, along the given axis.
|
485 |
+
|
486 |
+
Refer to `numpy.var` for full documentation.
|
487 |
+
|
488 |
+
See Also
|
489 |
+
--------
|
490 |
+
numpy.var
|
491 |
+
|
492 |
+
Notes
|
493 |
+
-----
|
494 |
+
This is the same as `ndarray.var`, except that where an `ndarray` would
|
495 |
+
be returned, a `matrix` object is returned instead.
|
496 |
+
|
497 |
+
Examples
|
498 |
+
--------
|
499 |
+
>>> x = np.matrix(np.arange(12).reshape((3, 4)))
|
500 |
+
>>> x
|
501 |
+
matrix([[ 0, 1, 2, 3],
|
502 |
+
[ 4, 5, 6, 7],
|
503 |
+
[ 8, 9, 10, 11]])
|
504 |
+
>>> x.var()
|
505 |
+
11.916666666666666
|
506 |
+
>>> x.var(0)
|
507 |
+
matrix([[ 10.66666667, 10.66666667, 10.66666667, 10.66666667]]) # may vary
|
508 |
+
>>> x.var(1)
|
509 |
+
matrix([[1.25],
|
510 |
+
[1.25],
|
511 |
+
[1.25]])
|
512 |
+
|
513 |
+
"""
|
514 |
+
return N.ndarray.var(self, axis, dtype, out, ddof, keepdims=True)._collapse(axis)
|
515 |
+
|
516 |
+
def prod(self, axis=None, dtype=None, out=None):
|
517 |
+
"""
|
518 |
+
Return the product of the array elements over the given axis.
|
519 |
+
|
520 |
+
Refer to `prod` for full documentation.
|
521 |
+
|
522 |
+
See Also
|
523 |
+
--------
|
524 |
+
prod, ndarray.prod
|
525 |
+
|
526 |
+
Notes
|
527 |
+
-----
|
528 |
+
Same as `ndarray.prod`, except, where that returns an `ndarray`, this
|
529 |
+
returns a `matrix` object instead.
|
530 |
+
|
531 |
+
Examples
|
532 |
+
--------
|
533 |
+
>>> x = np.matrix(np.arange(12).reshape((3,4))); x
|
534 |
+
matrix([[ 0, 1, 2, 3],
|
535 |
+
[ 4, 5, 6, 7],
|
536 |
+
[ 8, 9, 10, 11]])
|
537 |
+
>>> x.prod()
|
538 |
+
0
|
539 |
+
>>> x.prod(0)
|
540 |
+
matrix([[ 0, 45, 120, 231]])
|
541 |
+
>>> x.prod(1)
|
542 |
+
matrix([[ 0],
|
543 |
+
[ 840],
|
544 |
+
[7920]])
|
545 |
+
|
546 |
+
"""
|
547 |
+
return N.ndarray.prod(self, axis, dtype, out, keepdims=True)._collapse(axis)
|
548 |
+
|
549 |
+
def any(self, axis=None, out=None):
|
550 |
+
"""
|
551 |
+
Test whether any array element along a given axis evaluates to True.
|
552 |
+
|
553 |
+
Refer to `numpy.any` for full documentation.
|
554 |
+
|
555 |
+
Parameters
|
556 |
+
----------
|
557 |
+
axis : int, optional
|
558 |
+
Axis along which logical OR is performed
|
559 |
+
out : ndarray, optional
|
560 |
+
Output to existing array instead of creating new one, must have
|
561 |
+
same shape as expected output
|
562 |
+
|
563 |
+
Returns
|
564 |
+
-------
|
565 |
+
any : bool, ndarray
|
566 |
+
Returns a single bool if `axis` is ``None``; otherwise,
|
567 |
+
returns `ndarray`
|
568 |
+
|
569 |
+
"""
|
570 |
+
return N.ndarray.any(self, axis, out, keepdims=True)._collapse(axis)
|
571 |
+
|
572 |
+
def all(self, axis=None, out=None):
|
573 |
+
"""
|
574 |
+
Test whether all matrix elements along a given axis evaluate to True.
|
575 |
+
|
576 |
+
Parameters
|
577 |
+
----------
|
578 |
+
See `numpy.all` for complete descriptions
|
579 |
+
|
580 |
+
See Also
|
581 |
+
--------
|
582 |
+
numpy.all
|
583 |
+
|
584 |
+
Notes
|
585 |
+
-----
|
586 |
+
This is the same as `ndarray.all`, but it returns a `matrix` object.
|
587 |
+
|
588 |
+
Examples
|
589 |
+
--------
|
590 |
+
>>> x = np.matrix(np.arange(12).reshape((3,4))); x
|
591 |
+
matrix([[ 0, 1, 2, 3],
|
592 |
+
[ 4, 5, 6, 7],
|
593 |
+
[ 8, 9, 10, 11]])
|
594 |
+
>>> y = x[0]; y
|
595 |
+
matrix([[0, 1, 2, 3]])
|
596 |
+
>>> (x == y)
|
597 |
+
matrix([[ True, True, True, True],
|
598 |
+
[False, False, False, False],
|
599 |
+
[False, False, False, False]])
|
600 |
+
>>> (x == y).all()
|
601 |
+
False
|
602 |
+
>>> (x == y).all(0)
|
603 |
+
matrix([[False, False, False, False]])
|
604 |
+
>>> (x == y).all(1)
|
605 |
+
matrix([[ True],
|
606 |
+
[False],
|
607 |
+
[False]])
|
608 |
+
|
609 |
+
"""
|
610 |
+
return N.ndarray.all(self, axis, out, keepdims=True)._collapse(axis)
|
611 |
+
|
612 |
+
def max(self, axis=None, out=None):
|
613 |
+
"""
|
614 |
+
Return the maximum value along an axis.
|
615 |
+
|
616 |
+
Parameters
|
617 |
+
----------
|
618 |
+
See `amax` for complete descriptions
|
619 |
+
|
620 |
+
See Also
|
621 |
+
--------
|
622 |
+
amax, ndarray.max
|
623 |
+
|
624 |
+
Notes
|
625 |
+
-----
|
626 |
+
This is the same as `ndarray.max`, but returns a `matrix` object
|
627 |
+
where `ndarray.max` would return an ndarray.
|
628 |
+
|
629 |
+
Examples
|
630 |
+
--------
|
631 |
+
>>> x = np.matrix(np.arange(12).reshape((3,4))); x
|
632 |
+
matrix([[ 0, 1, 2, 3],
|
633 |
+
[ 4, 5, 6, 7],
|
634 |
+
[ 8, 9, 10, 11]])
|
635 |
+
>>> x.max()
|
636 |
+
11
|
637 |
+
>>> x.max(0)
|
638 |
+
matrix([[ 8, 9, 10, 11]])
|
639 |
+
>>> x.max(1)
|
640 |
+
matrix([[ 3],
|
641 |
+
[ 7],
|
642 |
+
[11]])
|
643 |
+
|
644 |
+
"""
|
645 |
+
return N.ndarray.max(self, axis, out, keepdims=True)._collapse(axis)
|
646 |
+
|
647 |
+
def argmax(self, axis=None, out=None):
|
648 |
+
"""
|
649 |
+
Indexes of the maximum values along an axis.
|
650 |
+
|
651 |
+
Return the indexes of the first occurrences of the maximum values
|
652 |
+
along the specified axis. If axis is None, the index is for the
|
653 |
+
flattened matrix.
|
654 |
+
|
655 |
+
Parameters
|
656 |
+
----------
|
657 |
+
See `numpy.argmax` for complete descriptions
|
658 |
+
|
659 |
+
See Also
|
660 |
+
--------
|
661 |
+
numpy.argmax
|
662 |
+
|
663 |
+
Notes
|
664 |
+
-----
|
665 |
+
This is the same as `ndarray.argmax`, but returns a `matrix` object
|
666 |
+
where `ndarray.argmax` would return an `ndarray`.
|
667 |
+
|
668 |
+
Examples
|
669 |
+
--------
|
670 |
+
>>> x = np.matrix(np.arange(12).reshape((3,4))); x
|
671 |
+
matrix([[ 0, 1, 2, 3],
|
672 |
+
[ 4, 5, 6, 7],
|
673 |
+
[ 8, 9, 10, 11]])
|
674 |
+
>>> x.argmax()
|
675 |
+
11
|
676 |
+
>>> x.argmax(0)
|
677 |
+
matrix([[2, 2, 2, 2]])
|
678 |
+
>>> x.argmax(1)
|
679 |
+
matrix([[3],
|
680 |
+
[3],
|
681 |
+
[3]])
|
682 |
+
|
683 |
+
"""
|
684 |
+
return N.ndarray.argmax(self, axis, out)._align(axis)
|
685 |
+
|
686 |
+
def min(self, axis=None, out=None):
|
687 |
+
"""
|
688 |
+
Return the minimum value along an axis.
|
689 |
+
|
690 |
+
Parameters
|
691 |
+
----------
|
692 |
+
See `amin` for complete descriptions.
|
693 |
+
|
694 |
+
See Also
|
695 |
+
--------
|
696 |
+
amin, ndarray.min
|
697 |
+
|
698 |
+
Notes
|
699 |
+
-----
|
700 |
+
This is the same as `ndarray.min`, but returns a `matrix` object
|
701 |
+
where `ndarray.min` would return an ndarray.
|
702 |
+
|
703 |
+
Examples
|
704 |
+
--------
|
705 |
+
>>> x = -np.matrix(np.arange(12).reshape((3,4))); x
|
706 |
+
matrix([[ 0, -1, -2, -3],
|
707 |
+
[ -4, -5, -6, -7],
|
708 |
+
[ -8, -9, -10, -11]])
|
709 |
+
>>> x.min()
|
710 |
+
-11
|
711 |
+
>>> x.min(0)
|
712 |
+
matrix([[ -8, -9, -10, -11]])
|
713 |
+
>>> x.min(1)
|
714 |
+
matrix([[ -3],
|
715 |
+
[ -7],
|
716 |
+
[-11]])
|
717 |
+
|
718 |
+
"""
|
719 |
+
return N.ndarray.min(self, axis, out, keepdims=True)._collapse(axis)
|
720 |
+
|
721 |
+
def argmin(self, axis=None, out=None):
|
722 |
+
"""
|
723 |
+
Indexes of the minimum values along an axis.
|
724 |
+
|
725 |
+
Return the indexes of the first occurrences of the minimum values
|
726 |
+
along the specified axis. If axis is None, the index is for the
|
727 |
+
flattened matrix.
|
728 |
+
|
729 |
+
Parameters
|
730 |
+
----------
|
731 |
+
See `numpy.argmin` for complete descriptions.
|
732 |
+
|
733 |
+
See Also
|
734 |
+
--------
|
735 |
+
numpy.argmin
|
736 |
+
|
737 |
+
Notes
|
738 |
+
-----
|
739 |
+
This is the same as `ndarray.argmin`, but returns a `matrix` object
|
740 |
+
where `ndarray.argmin` would return an `ndarray`.
|
741 |
+
|
742 |
+
Examples
|
743 |
+
--------
|
744 |
+
>>> x = -np.matrix(np.arange(12).reshape((3,4))); x
|
745 |
+
matrix([[ 0, -1, -2, -3],
|
746 |
+
[ -4, -5, -6, -7],
|
747 |
+
[ -8, -9, -10, -11]])
|
748 |
+
>>> x.argmin()
|
749 |
+
11
|
750 |
+
>>> x.argmin(0)
|
751 |
+
matrix([[2, 2, 2, 2]])
|
752 |
+
>>> x.argmin(1)
|
753 |
+
matrix([[3],
|
754 |
+
[3],
|
755 |
+
[3]])
|
756 |
+
|
757 |
+
"""
|
758 |
+
return N.ndarray.argmin(self, axis, out)._align(axis)
|
759 |
+
|
760 |
+
def ptp(self, axis=None, out=None):
|
761 |
+
"""
|
762 |
+
Peak-to-peak (maximum - minimum) value along the given axis.
|
763 |
+
|
764 |
+
Refer to `numpy.ptp` for full documentation.
|
765 |
+
|
766 |
+
See Also
|
767 |
+
--------
|
768 |
+
numpy.ptp
|
769 |
+
|
770 |
+
Notes
|
771 |
+
-----
|
772 |
+
Same as `ndarray.ptp`, except, where that would return an `ndarray` object,
|
773 |
+
this returns a `matrix` object.
|
774 |
+
|
775 |
+
Examples
|
776 |
+
--------
|
777 |
+
>>> x = np.matrix(np.arange(12).reshape((3,4))); x
|
778 |
+
matrix([[ 0, 1, 2, 3],
|
779 |
+
[ 4, 5, 6, 7],
|
780 |
+
[ 8, 9, 10, 11]])
|
781 |
+
>>> x.ptp()
|
782 |
+
11
|
783 |
+
>>> x.ptp(0)
|
784 |
+
matrix([[8, 8, 8, 8]])
|
785 |
+
>>> x.ptp(1)
|
786 |
+
matrix([[3],
|
787 |
+
[3],
|
788 |
+
[3]])
|
789 |
+
|
790 |
+
"""
|
791 |
+
return N.ndarray.ptp(self, axis, out)._align(axis)
|
792 |
+
|
793 |
+
@property
|
794 |
+
def I(self):
|
795 |
+
"""
|
796 |
+
Returns the (multiplicative) inverse of invertible `self`.
|
797 |
+
|
798 |
+
Parameters
|
799 |
+
----------
|
800 |
+
None
|
801 |
+
|
802 |
+
Returns
|
803 |
+
-------
|
804 |
+
ret : matrix object
|
805 |
+
If `self` is non-singular, `ret` is such that ``ret * self`` ==
|
806 |
+
``self * ret`` == ``np.matrix(np.eye(self[0,:].size))`` all return
|
807 |
+
``True``.
|
808 |
+
|
809 |
+
Raises
|
810 |
+
------
|
811 |
+
numpy.linalg.LinAlgError: Singular matrix
|
812 |
+
If `self` is singular.
|
813 |
+
|
814 |
+
See Also
|
815 |
+
--------
|
816 |
+
linalg.inv
|
817 |
+
|
818 |
+
Examples
|
819 |
+
--------
|
820 |
+
>>> m = np.matrix('[1, 2; 3, 4]'); m
|
821 |
+
matrix([[1, 2],
|
822 |
+
[3, 4]])
|
823 |
+
>>> m.getI()
|
824 |
+
matrix([[-2. , 1. ],
|
825 |
+
[ 1.5, -0.5]])
|
826 |
+
>>> m.getI() * m
|
827 |
+
matrix([[ 1., 0.], # may vary
|
828 |
+
[ 0., 1.]])
|
829 |
+
|
830 |
+
"""
|
831 |
+
M, N = self.shape
|
832 |
+
if M == N:
|
833 |
+
from numpy.linalg import inv as func
|
834 |
+
else:
|
835 |
+
from numpy.linalg import pinv as func
|
836 |
+
return asmatrix(func(self))
|
837 |
+
|
838 |
+
@property
|
839 |
+
def A(self):
|
840 |
+
"""
|
841 |
+
Return `self` as an `ndarray` object.
|
842 |
+
|
843 |
+
Equivalent to ``np.asarray(self)``.
|
844 |
+
|
845 |
+
Parameters
|
846 |
+
----------
|
847 |
+
None
|
848 |
+
|
849 |
+
Returns
|
850 |
+
-------
|
851 |
+
ret : ndarray
|
852 |
+
`self` as an `ndarray`
|
853 |
+
|
854 |
+
Examples
|
855 |
+
--------
|
856 |
+
>>> x = np.matrix(np.arange(12).reshape((3,4))); x
|
857 |
+
matrix([[ 0, 1, 2, 3],
|
858 |
+
[ 4, 5, 6, 7],
|
859 |
+
[ 8, 9, 10, 11]])
|
860 |
+
>>> x.getA()
|
861 |
+
array([[ 0, 1, 2, 3],
|
862 |
+
[ 4, 5, 6, 7],
|
863 |
+
[ 8, 9, 10, 11]])
|
864 |
+
|
865 |
+
"""
|
866 |
+
return self.__array__()
|
867 |
+
|
868 |
+
@property
|
869 |
+
def A1(self):
|
870 |
+
"""
|
871 |
+
Return `self` as a flattened `ndarray`.
|
872 |
+
|
873 |
+
Equivalent to ``np.asarray(x).ravel()``
|
874 |
+
|
875 |
+
Parameters
|
876 |
+
----------
|
877 |
+
None
|
878 |
+
|
879 |
+
Returns
|
880 |
+
-------
|
881 |
+
ret : ndarray
|
882 |
+
`self`, 1-D, as an `ndarray`
|
883 |
+
|
884 |
+
Examples
|
885 |
+
--------
|
886 |
+
>>> x = np.matrix(np.arange(12).reshape((3,4))); x
|
887 |
+
matrix([[ 0, 1, 2, 3],
|
888 |
+
[ 4, 5, 6, 7],
|
889 |
+
[ 8, 9, 10, 11]])
|
890 |
+
>>> x.getA1()
|
891 |
+
array([ 0, 1, 2, ..., 9, 10, 11])
|
892 |
+
|
893 |
+
|
894 |
+
"""
|
895 |
+
return self.__array__().ravel()
|
896 |
+
|
897 |
+
|
898 |
+
def ravel(self, order='C'):
|
899 |
+
"""
|
900 |
+
Return a flattened matrix.
|
901 |
+
|
902 |
+
Refer to `numpy.ravel` for more documentation.
|
903 |
+
|
904 |
+
Parameters
|
905 |
+
----------
|
906 |
+
order : {'C', 'F', 'A', 'K'}, optional
|
907 |
+
The elements of `m` are read using this index order. 'C' means to
|
908 |
+
index the elements in C-like order, with the last axis index
|
909 |
+
changing fastest, back to the first axis index changing slowest.
|
910 |
+
'F' means to index the elements in Fortran-like index order, with
|
911 |
+
the first index changing fastest, and the last index changing
|
912 |
+
slowest. Note that the 'C' and 'F' options take no account of the
|
913 |
+
memory layout of the underlying array, and only refer to the order
|
914 |
+
of axis indexing. 'A' means to read the elements in Fortran-like
|
915 |
+
index order if `m` is Fortran *contiguous* in memory, C-like order
|
916 |
+
otherwise. 'K' means to read the elements in the order they occur
|
917 |
+
in memory, except for reversing the data when strides are negative.
|
918 |
+
By default, 'C' index order is used.
|
919 |
+
|
920 |
+
Returns
|
921 |
+
-------
|
922 |
+
ret : matrix
|
923 |
+
Return the matrix flattened to shape `(1, N)` where `N`
|
924 |
+
is the number of elements in the original matrix.
|
925 |
+
A copy is made only if necessary.
|
926 |
+
|
927 |
+
See Also
|
928 |
+
--------
|
929 |
+
matrix.flatten : returns a similar output matrix but always a copy
|
930 |
+
matrix.flat : a flat iterator on the array.
|
931 |
+
numpy.ravel : related function which returns an ndarray
|
932 |
+
|
933 |
+
"""
|
934 |
+
return N.ndarray.ravel(self, order=order)
|
935 |
+
|
936 |
+
@property
|
937 |
+
def T(self):
|
938 |
+
"""
|
939 |
+
Returns the transpose of the matrix.
|
940 |
+
|
941 |
+
Does *not* conjugate! For the complex conjugate transpose, use ``.H``.
|
942 |
+
|
943 |
+
Parameters
|
944 |
+
----------
|
945 |
+
None
|
946 |
+
|
947 |
+
Returns
|
948 |
+
-------
|
949 |
+
ret : matrix object
|
950 |
+
The (non-conjugated) transpose of the matrix.
|
951 |
+
|
952 |
+
See Also
|
953 |
+
--------
|
954 |
+
transpose, getH
|
955 |
+
|
956 |
+
Examples
|
957 |
+
--------
|
958 |
+
>>> m = np.matrix('[1, 2; 3, 4]')
|
959 |
+
>>> m
|
960 |
+
matrix([[1, 2],
|
961 |
+
[3, 4]])
|
962 |
+
>>> m.getT()
|
963 |
+
matrix([[1, 3],
|
964 |
+
[2, 4]])
|
965 |
+
|
966 |
+
"""
|
967 |
+
return self.transpose()
|
968 |
+
|
969 |
+
@property
|
970 |
+
def H(self):
|
971 |
+
"""
|
972 |
+
Returns the (complex) conjugate transpose of `self`.
|
973 |
+
|
974 |
+
Equivalent to ``np.transpose(self)`` if `self` is real-valued.
|
975 |
+
|
976 |
+
Parameters
|
977 |
+
----------
|
978 |
+
None
|
979 |
+
|
980 |
+
Returns
|
981 |
+
-------
|
982 |
+
ret : matrix object
|
983 |
+
complex conjugate transpose of `self`
|
984 |
+
|
985 |
+
Examples
|
986 |
+
--------
|
987 |
+
>>> x = np.matrix(np.arange(12).reshape((3,4)))
|
988 |
+
>>> z = x - 1j*x; z
|
989 |
+
matrix([[ 0. +0.j, 1. -1.j, 2. -2.j, 3. -3.j],
|
990 |
+
[ 4. -4.j, 5. -5.j, 6. -6.j, 7. -7.j],
|
991 |
+
[ 8. -8.j, 9. -9.j, 10.-10.j, 11.-11.j]])
|
992 |
+
>>> z.getH()
|
993 |
+
matrix([[ 0. -0.j, 4. +4.j, 8. +8.j],
|
994 |
+
[ 1. +1.j, 5. +5.j, 9. +9.j],
|
995 |
+
[ 2. +2.j, 6. +6.j, 10.+10.j],
|
996 |
+
[ 3. +3.j, 7. +7.j, 11.+11.j]])
|
997 |
+
|
998 |
+
"""
|
999 |
+
if issubclass(self.dtype.type, N.complexfloating):
|
1000 |
+
return self.transpose().conjugate()
|
1001 |
+
else:
|
1002 |
+
return self.transpose()
|
1003 |
+
|
1004 |
+
# kept for compatibility
|
1005 |
+
getT = T.fget
|
1006 |
+
getA = A.fget
|
1007 |
+
getA1 = A1.fget
|
1008 |
+
getH = H.fget
|
1009 |
+
getI = I.fget
|
1010 |
+
|
1011 |
+
def _from_string(str, gdict, ldict):
|
1012 |
+
rows = str.split(';')
|
1013 |
+
rowtup = []
|
1014 |
+
for row in rows:
|
1015 |
+
trow = row.split(',')
|
1016 |
+
newrow = []
|
1017 |
+
for x in trow:
|
1018 |
+
newrow.extend(x.split())
|
1019 |
+
trow = newrow
|
1020 |
+
coltup = []
|
1021 |
+
for col in trow:
|
1022 |
+
col = col.strip()
|
1023 |
+
try:
|
1024 |
+
thismat = ldict[col]
|
1025 |
+
except KeyError:
|
1026 |
+
try:
|
1027 |
+
thismat = gdict[col]
|
1028 |
+
except KeyError as e:
|
1029 |
+
raise NameError(f"name {col!r} is not defined") from None
|
1030 |
+
|
1031 |
+
coltup.append(thismat)
|
1032 |
+
rowtup.append(concatenate(coltup, axis=-1))
|
1033 |
+
return concatenate(rowtup, axis=0)
|
1034 |
+
|
1035 |
+
|
1036 |
+
@set_module('numpy')
|
1037 |
+
def bmat(obj, ldict=None, gdict=None):
|
1038 |
+
"""
|
1039 |
+
Build a matrix object from a string, nested sequence, or array.
|
1040 |
+
|
1041 |
+
Parameters
|
1042 |
+
----------
|
1043 |
+
obj : str or array_like
|
1044 |
+
Input data. If a string, variables in the current scope may be
|
1045 |
+
referenced by name.
|
1046 |
+
ldict : dict, optional
|
1047 |
+
A dictionary that replaces local operands in current frame.
|
1048 |
+
Ignored if `obj` is not a string or `gdict` is None.
|
1049 |
+
gdict : dict, optional
|
1050 |
+
A dictionary that replaces global operands in current frame.
|
1051 |
+
Ignored if `obj` is not a string.
|
1052 |
+
|
1053 |
+
Returns
|
1054 |
+
-------
|
1055 |
+
out : matrix
|
1056 |
+
Returns a matrix object, which is a specialized 2-D array.
|
1057 |
+
|
1058 |
+
See Also
|
1059 |
+
--------
|
1060 |
+
block :
|
1061 |
+
A generalization of this function for N-d arrays, that returns normal
|
1062 |
+
ndarrays.
|
1063 |
+
|
1064 |
+
Examples
|
1065 |
+
--------
|
1066 |
+
>>> A = np.mat('1 1; 1 1')
|
1067 |
+
>>> B = np.mat('2 2; 2 2')
|
1068 |
+
>>> C = np.mat('3 4; 5 6')
|
1069 |
+
>>> D = np.mat('7 8; 9 0')
|
1070 |
+
|
1071 |
+
All the following expressions construct the same block matrix:
|
1072 |
+
|
1073 |
+
>>> np.bmat([[A, B], [C, D]])
|
1074 |
+
matrix([[1, 1, 2, 2],
|
1075 |
+
[1, 1, 2, 2],
|
1076 |
+
[3, 4, 7, 8],
|
1077 |
+
[5, 6, 9, 0]])
|
1078 |
+
>>> np.bmat(np.r_[np.c_[A, B], np.c_[C, D]])
|
1079 |
+
matrix([[1, 1, 2, 2],
|
1080 |
+
[1, 1, 2, 2],
|
1081 |
+
[3, 4, 7, 8],
|
1082 |
+
[5, 6, 9, 0]])
|
1083 |
+
>>> np.bmat('A,B; C,D')
|
1084 |
+
matrix([[1, 1, 2, 2],
|
1085 |
+
[1, 1, 2, 2],
|
1086 |
+
[3, 4, 7, 8],
|
1087 |
+
[5, 6, 9, 0]])
|
1088 |
+
|
1089 |
+
"""
|
1090 |
+
if isinstance(obj, str):
|
1091 |
+
if gdict is None:
|
1092 |
+
# get previous frame
|
1093 |
+
frame = sys._getframe().f_back
|
1094 |
+
glob_dict = frame.f_globals
|
1095 |
+
loc_dict = frame.f_locals
|
1096 |
+
else:
|
1097 |
+
glob_dict = gdict
|
1098 |
+
loc_dict = ldict
|
1099 |
+
|
1100 |
+
return matrix(_from_string(obj, glob_dict, loc_dict))
|
1101 |
+
|
1102 |
+
if isinstance(obj, (tuple, list)):
|
1103 |
+
# [[A,B],[C,D]]
|
1104 |
+
arr_rows = []
|
1105 |
+
for row in obj:
|
1106 |
+
if isinstance(row, N.ndarray): # not 2-d
|
1107 |
+
return matrix(concatenate(obj, axis=-1))
|
1108 |
+
else:
|
1109 |
+
arr_rows.append(concatenate(row, axis=-1))
|
1110 |
+
return matrix(concatenate(arr_rows, axis=0))
|
1111 |
+
if isinstance(obj, N.ndarray):
|
1112 |
+
return matrix(obj)
|
1113 |
+
|
1114 |
+
mat = asmatrix
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/defmatrix.pyi
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from collections.abc import Sequence, Mapping
|
2 |
+
from typing import Any
|
3 |
+
from numpy import matrix as matrix
|
4 |
+
from numpy._typing import ArrayLike, DTypeLike, NDArray
|
5 |
+
|
6 |
+
__all__: list[str]
|
7 |
+
|
8 |
+
def bmat(
|
9 |
+
obj: str | Sequence[ArrayLike] | NDArray[Any],
|
10 |
+
ldict: None | Mapping[str, Any] = ...,
|
11 |
+
gdict: None | Mapping[str, Any] = ...,
|
12 |
+
) -> matrix[Any, Any]: ...
|
13 |
+
|
14 |
+
def asmatrix(data: ArrayLike, dtype: DTypeLike = ...) -> matrix[Any, Any]: ...
|
15 |
+
|
16 |
+
mat = asmatrix
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/setup.py
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
def configuration(parent_package='', top_path=None):
|
3 |
+
from numpy.distutils.misc_util import Configuration
|
4 |
+
config = Configuration('matrixlib', parent_package, top_path)
|
5 |
+
config.add_subpackage('tests')
|
6 |
+
config.add_data_files('*.pyi')
|
7 |
+
return config
|
8 |
+
|
9 |
+
if __name__ == "__main__":
|
10 |
+
from numpy.distutils.core import setup
|
11 |
+
config = configuration(top_path='').todict()
|
12 |
+
setup(**config)
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__init__.py
ADDED
File without changes
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/__init__.cpython-311.pyc
ADDED
Binary file (194 Bytes). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_defmatrix.cpython-311.pyc
ADDED
Binary file (37.7 kB). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_interaction.cpython-311.pyc
ADDED
Binary file (23.4 kB). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_masked_matrix.cpython-311.pyc
ADDED
Binary file (19.8 kB). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_matrix_linalg.cpython-311.pyc
ADDED
Binary file (5.05 kB). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_multiarray.cpython-311.pyc
ADDED
Binary file (1.77 kB). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_numeric.cpython-311.pyc
ADDED
Binary file (1.6 kB). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/__pycache__/test_regression.cpython-311.pyc
ADDED
Binary file (3.12 kB). View file
|
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_defmatrix.py
ADDED
@@ -0,0 +1,453 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import collections.abc
|
2 |
+
|
3 |
+
import numpy as np
|
4 |
+
from numpy import matrix, asmatrix, bmat
|
5 |
+
from numpy.testing import (
|
6 |
+
assert_, assert_equal, assert_almost_equal, assert_array_equal,
|
7 |
+
assert_array_almost_equal, assert_raises
|
8 |
+
)
|
9 |
+
from numpy.linalg import matrix_power
|
10 |
+
from numpy.matrixlib import mat
|
11 |
+
|
12 |
+
class TestCtor:
|
13 |
+
def test_basic(self):
|
14 |
+
A = np.array([[1, 2], [3, 4]])
|
15 |
+
mA = matrix(A)
|
16 |
+
assert_(np.all(mA.A == A))
|
17 |
+
|
18 |
+
B = bmat("A,A;A,A")
|
19 |
+
C = bmat([[A, A], [A, A]])
|
20 |
+
D = np.array([[1, 2, 1, 2],
|
21 |
+
[3, 4, 3, 4],
|
22 |
+
[1, 2, 1, 2],
|
23 |
+
[3, 4, 3, 4]])
|
24 |
+
assert_(np.all(B.A == D))
|
25 |
+
assert_(np.all(C.A == D))
|
26 |
+
|
27 |
+
E = np.array([[5, 6], [7, 8]])
|
28 |
+
AEresult = matrix([[1, 2, 5, 6], [3, 4, 7, 8]])
|
29 |
+
assert_(np.all(bmat([A, E]) == AEresult))
|
30 |
+
|
31 |
+
vec = np.arange(5)
|
32 |
+
mvec = matrix(vec)
|
33 |
+
assert_(mvec.shape == (1, 5))
|
34 |
+
|
35 |
+
def test_exceptions(self):
|
36 |
+
# Check for ValueError when called with invalid string data.
|
37 |
+
assert_raises(ValueError, matrix, "invalid")
|
38 |
+
|
39 |
+
def test_bmat_nondefault_str(self):
|
40 |
+
A = np.array([[1, 2], [3, 4]])
|
41 |
+
B = np.array([[5, 6], [7, 8]])
|
42 |
+
Aresult = np.array([[1, 2, 1, 2],
|
43 |
+
[3, 4, 3, 4],
|
44 |
+
[1, 2, 1, 2],
|
45 |
+
[3, 4, 3, 4]])
|
46 |
+
mixresult = np.array([[1, 2, 5, 6],
|
47 |
+
[3, 4, 7, 8],
|
48 |
+
[5, 6, 1, 2],
|
49 |
+
[7, 8, 3, 4]])
|
50 |
+
assert_(np.all(bmat("A,A;A,A") == Aresult))
|
51 |
+
assert_(np.all(bmat("A,A;A,A", ldict={'A':B}) == Aresult))
|
52 |
+
assert_raises(TypeError, bmat, "A,A;A,A", gdict={'A':B})
|
53 |
+
assert_(
|
54 |
+
np.all(bmat("A,A;A,A", ldict={'A':A}, gdict={'A':B}) == Aresult))
|
55 |
+
b2 = bmat("A,B;C,D", ldict={'A':A,'B':B}, gdict={'C':B,'D':A})
|
56 |
+
assert_(np.all(b2 == mixresult))
|
57 |
+
|
58 |
+
|
59 |
+
class TestProperties:
|
60 |
+
def test_sum(self):
|
61 |
+
"""Test whether matrix.sum(axis=1) preserves orientation.
|
62 |
+
Fails in NumPy <= 0.9.6.2127.
|
63 |
+
"""
|
64 |
+
M = matrix([[1, 2, 0, 0],
|
65 |
+
[3, 4, 0, 0],
|
66 |
+
[1, 2, 1, 2],
|
67 |
+
[3, 4, 3, 4]])
|
68 |
+
sum0 = matrix([8, 12, 4, 6])
|
69 |
+
sum1 = matrix([3, 7, 6, 14]).T
|
70 |
+
sumall = 30
|
71 |
+
assert_array_equal(sum0, M.sum(axis=0))
|
72 |
+
assert_array_equal(sum1, M.sum(axis=1))
|
73 |
+
assert_equal(sumall, M.sum())
|
74 |
+
|
75 |
+
assert_array_equal(sum0, np.sum(M, axis=0))
|
76 |
+
assert_array_equal(sum1, np.sum(M, axis=1))
|
77 |
+
assert_equal(sumall, np.sum(M))
|
78 |
+
|
79 |
+
def test_prod(self):
|
80 |
+
x = matrix([[1, 2, 3], [4, 5, 6]])
|
81 |
+
assert_equal(x.prod(), 720)
|
82 |
+
assert_equal(x.prod(0), matrix([[4, 10, 18]]))
|
83 |
+
assert_equal(x.prod(1), matrix([[6], [120]]))
|
84 |
+
|
85 |
+
assert_equal(np.prod(x), 720)
|
86 |
+
assert_equal(np.prod(x, axis=0), matrix([[4, 10, 18]]))
|
87 |
+
assert_equal(np.prod(x, axis=1), matrix([[6], [120]]))
|
88 |
+
|
89 |
+
y = matrix([0, 1, 3])
|
90 |
+
assert_(y.prod() == 0)
|
91 |
+
|
92 |
+
def test_max(self):
|
93 |
+
x = matrix([[1, 2, 3], [4, 5, 6]])
|
94 |
+
assert_equal(x.max(), 6)
|
95 |
+
assert_equal(x.max(0), matrix([[4, 5, 6]]))
|
96 |
+
assert_equal(x.max(1), matrix([[3], [6]]))
|
97 |
+
|
98 |
+
assert_equal(np.max(x), 6)
|
99 |
+
assert_equal(np.max(x, axis=0), matrix([[4, 5, 6]]))
|
100 |
+
assert_equal(np.max(x, axis=1), matrix([[3], [6]]))
|
101 |
+
|
102 |
+
def test_min(self):
|
103 |
+
x = matrix([[1, 2, 3], [4, 5, 6]])
|
104 |
+
assert_equal(x.min(), 1)
|
105 |
+
assert_equal(x.min(0), matrix([[1, 2, 3]]))
|
106 |
+
assert_equal(x.min(1), matrix([[1], [4]]))
|
107 |
+
|
108 |
+
assert_equal(np.min(x), 1)
|
109 |
+
assert_equal(np.min(x, axis=0), matrix([[1, 2, 3]]))
|
110 |
+
assert_equal(np.min(x, axis=1), matrix([[1], [4]]))
|
111 |
+
|
112 |
+
def test_ptp(self):
|
113 |
+
x = np.arange(4).reshape((2, 2))
|
114 |
+
assert_(x.ptp() == 3)
|
115 |
+
assert_(np.all(x.ptp(0) == np.array([2, 2])))
|
116 |
+
assert_(np.all(x.ptp(1) == np.array([1, 1])))
|
117 |
+
|
118 |
+
def test_var(self):
|
119 |
+
x = np.arange(9).reshape((3, 3))
|
120 |
+
mx = x.view(np.matrix)
|
121 |
+
assert_equal(x.var(ddof=0), mx.var(ddof=0))
|
122 |
+
assert_equal(x.var(ddof=1), mx.var(ddof=1))
|
123 |
+
|
124 |
+
def test_basic(self):
|
125 |
+
import numpy.linalg as linalg
|
126 |
+
|
127 |
+
A = np.array([[1., 2.],
|
128 |
+
[3., 4.]])
|
129 |
+
mA = matrix(A)
|
130 |
+
assert_(np.allclose(linalg.inv(A), mA.I))
|
131 |
+
assert_(np.all(np.array(np.transpose(A) == mA.T)))
|
132 |
+
assert_(np.all(np.array(np.transpose(A) == mA.H)))
|
133 |
+
assert_(np.all(A == mA.A))
|
134 |
+
|
135 |
+
B = A + 2j*A
|
136 |
+
mB = matrix(B)
|
137 |
+
assert_(np.allclose(linalg.inv(B), mB.I))
|
138 |
+
assert_(np.all(np.array(np.transpose(B) == mB.T)))
|
139 |
+
assert_(np.all(np.array(np.transpose(B).conj() == mB.H)))
|
140 |
+
|
141 |
+
def test_pinv(self):
|
142 |
+
x = matrix(np.arange(6).reshape(2, 3))
|
143 |
+
xpinv = matrix([[-0.77777778, 0.27777778],
|
144 |
+
[-0.11111111, 0.11111111],
|
145 |
+
[ 0.55555556, -0.05555556]])
|
146 |
+
assert_almost_equal(x.I, xpinv)
|
147 |
+
|
148 |
+
def test_comparisons(self):
|
149 |
+
A = np.arange(100).reshape(10, 10)
|
150 |
+
mA = matrix(A)
|
151 |
+
mB = matrix(A) + 0.1
|
152 |
+
assert_(np.all(mB == A+0.1))
|
153 |
+
assert_(np.all(mB == matrix(A+0.1)))
|
154 |
+
assert_(not np.any(mB == matrix(A-0.1)))
|
155 |
+
assert_(np.all(mA < mB))
|
156 |
+
assert_(np.all(mA <= mB))
|
157 |
+
assert_(np.all(mA <= mA))
|
158 |
+
assert_(not np.any(mA < mA))
|
159 |
+
|
160 |
+
assert_(not np.any(mB < mA))
|
161 |
+
assert_(np.all(mB >= mA))
|
162 |
+
assert_(np.all(mB >= mB))
|
163 |
+
assert_(not np.any(mB > mB))
|
164 |
+
|
165 |
+
assert_(np.all(mA == mA))
|
166 |
+
assert_(not np.any(mA == mB))
|
167 |
+
assert_(np.all(mB != mA))
|
168 |
+
|
169 |
+
assert_(not np.all(abs(mA) > 0))
|
170 |
+
assert_(np.all(abs(mB > 0)))
|
171 |
+
|
172 |
+
def test_asmatrix(self):
|
173 |
+
A = np.arange(100).reshape(10, 10)
|
174 |
+
mA = asmatrix(A)
|
175 |
+
A[0, 0] = -10
|
176 |
+
assert_(A[0, 0] == mA[0, 0])
|
177 |
+
|
178 |
+
def test_noaxis(self):
|
179 |
+
A = matrix([[1, 0], [0, 1]])
|
180 |
+
assert_(A.sum() == matrix(2))
|
181 |
+
assert_(A.mean() == matrix(0.5))
|
182 |
+
|
183 |
+
def test_repr(self):
|
184 |
+
A = matrix([[1, 0], [0, 1]])
|
185 |
+
assert_(repr(A) == "matrix([[1, 0],\n [0, 1]])")
|
186 |
+
|
187 |
+
def test_make_bool_matrix_from_str(self):
|
188 |
+
A = matrix('True; True; False')
|
189 |
+
B = matrix([[True], [True], [False]])
|
190 |
+
assert_array_equal(A, B)
|
191 |
+
|
192 |
+
class TestCasting:
|
193 |
+
def test_basic(self):
|
194 |
+
A = np.arange(100).reshape(10, 10)
|
195 |
+
mA = matrix(A)
|
196 |
+
|
197 |
+
mB = mA.copy()
|
198 |
+
O = np.ones((10, 10), np.float64) * 0.1
|
199 |
+
mB = mB + O
|
200 |
+
assert_(mB.dtype.type == np.float64)
|
201 |
+
assert_(np.all(mA != mB))
|
202 |
+
assert_(np.all(mB == mA+0.1))
|
203 |
+
|
204 |
+
mC = mA.copy()
|
205 |
+
O = np.ones((10, 10), np.complex128)
|
206 |
+
mC = mC * O
|
207 |
+
assert_(mC.dtype.type == np.complex128)
|
208 |
+
assert_(np.all(mA != mB))
|
209 |
+
|
210 |
+
|
211 |
+
class TestAlgebra:
|
212 |
+
def test_basic(self):
|
213 |
+
import numpy.linalg as linalg
|
214 |
+
|
215 |
+
A = np.array([[1., 2.], [3., 4.]])
|
216 |
+
mA = matrix(A)
|
217 |
+
|
218 |
+
B = np.identity(2)
|
219 |
+
for i in range(6):
|
220 |
+
assert_(np.allclose((mA ** i).A, B))
|
221 |
+
B = np.dot(B, A)
|
222 |
+
|
223 |
+
Ainv = linalg.inv(A)
|
224 |
+
B = np.identity(2)
|
225 |
+
for i in range(6):
|
226 |
+
assert_(np.allclose((mA ** -i).A, B))
|
227 |
+
B = np.dot(B, Ainv)
|
228 |
+
|
229 |
+
assert_(np.allclose((mA * mA).A, np.dot(A, A)))
|
230 |
+
assert_(np.allclose((mA + mA).A, (A + A)))
|
231 |
+
assert_(np.allclose((3*mA).A, (3*A)))
|
232 |
+
|
233 |
+
mA2 = matrix(A)
|
234 |
+
mA2 *= 3
|
235 |
+
assert_(np.allclose(mA2.A, 3*A))
|
236 |
+
|
237 |
+
def test_pow(self):
|
238 |
+
"""Test raising a matrix to an integer power works as expected."""
|
239 |
+
m = matrix("1. 2.; 3. 4.")
|
240 |
+
m2 = m.copy()
|
241 |
+
m2 **= 2
|
242 |
+
mi = m.copy()
|
243 |
+
mi **= -1
|
244 |
+
m4 = m2.copy()
|
245 |
+
m4 **= 2
|
246 |
+
assert_array_almost_equal(m2, m**2)
|
247 |
+
assert_array_almost_equal(m4, np.dot(m2, m2))
|
248 |
+
assert_array_almost_equal(np.dot(mi, m), np.eye(2))
|
249 |
+
|
250 |
+
def test_scalar_type_pow(self):
|
251 |
+
m = matrix([[1, 2], [3, 4]])
|
252 |
+
for scalar_t in [np.int8, np.uint8]:
|
253 |
+
two = scalar_t(2)
|
254 |
+
assert_array_almost_equal(m ** 2, m ** two)
|
255 |
+
|
256 |
+
def test_notimplemented(self):
|
257 |
+
'''Check that 'not implemented' operations produce a failure.'''
|
258 |
+
A = matrix([[1., 2.],
|
259 |
+
[3., 4.]])
|
260 |
+
|
261 |
+
# __rpow__
|
262 |
+
with assert_raises(TypeError):
|
263 |
+
1.0**A
|
264 |
+
|
265 |
+
# __mul__ with something not a list, ndarray, tuple, or scalar
|
266 |
+
with assert_raises(TypeError):
|
267 |
+
A*object()
|
268 |
+
|
269 |
+
|
270 |
+
class TestMatrixReturn:
|
271 |
+
def test_instance_methods(self):
|
272 |
+
a = matrix([1.0], dtype='f8')
|
273 |
+
methodargs = {
|
274 |
+
'astype': ('intc',),
|
275 |
+
'clip': (0.0, 1.0),
|
276 |
+
'compress': ([1],),
|
277 |
+
'repeat': (1,),
|
278 |
+
'reshape': (1,),
|
279 |
+
'swapaxes': (0, 0),
|
280 |
+
'dot': np.array([1.0]),
|
281 |
+
}
|
282 |
+
excluded_methods = [
|
283 |
+
'argmin', 'choose', 'dump', 'dumps', 'fill', 'getfield',
|
284 |
+
'getA', 'getA1', 'item', 'nonzero', 'put', 'putmask', 'resize',
|
285 |
+
'searchsorted', 'setflags', 'setfield', 'sort',
|
286 |
+
'partition', 'argpartition',
|
287 |
+
'take', 'tofile', 'tolist', 'tostring', 'tobytes', 'all', 'any',
|
288 |
+
'sum', 'argmax', 'argmin', 'min', 'max', 'mean', 'var', 'ptp',
|
289 |
+
'prod', 'std', 'ctypes', 'itemset',
|
290 |
+
]
|
291 |
+
for attrib in dir(a):
|
292 |
+
if attrib.startswith('_') or attrib in excluded_methods:
|
293 |
+
continue
|
294 |
+
f = getattr(a, attrib)
|
295 |
+
if isinstance(f, collections.abc.Callable):
|
296 |
+
# reset contents of a
|
297 |
+
a.astype('f8')
|
298 |
+
a.fill(1.0)
|
299 |
+
if attrib in methodargs:
|
300 |
+
args = methodargs[attrib]
|
301 |
+
else:
|
302 |
+
args = ()
|
303 |
+
b = f(*args)
|
304 |
+
assert_(type(b) is matrix, "%s" % attrib)
|
305 |
+
assert_(type(a.real) is matrix)
|
306 |
+
assert_(type(a.imag) is matrix)
|
307 |
+
c, d = matrix([0.0]).nonzero()
|
308 |
+
assert_(type(c) is np.ndarray)
|
309 |
+
assert_(type(d) is np.ndarray)
|
310 |
+
|
311 |
+
|
312 |
+
class TestIndexing:
|
313 |
+
def test_basic(self):
|
314 |
+
x = asmatrix(np.zeros((3, 2), float))
|
315 |
+
y = np.zeros((3, 1), float)
|
316 |
+
y[:, 0] = [0.8, 0.2, 0.3]
|
317 |
+
x[:, 1] = y > 0.5
|
318 |
+
assert_equal(x, [[0, 1], [0, 0], [0, 0]])
|
319 |
+
|
320 |
+
|
321 |
+
class TestNewScalarIndexing:
|
322 |
+
a = matrix([[1, 2], [3, 4]])
|
323 |
+
|
324 |
+
def test_dimesions(self):
|
325 |
+
a = self.a
|
326 |
+
x = a[0]
|
327 |
+
assert_equal(x.ndim, 2)
|
328 |
+
|
329 |
+
def test_array_from_matrix_list(self):
|
330 |
+
a = self.a
|
331 |
+
x = np.array([a, a])
|
332 |
+
assert_equal(x.shape, [2, 2, 2])
|
333 |
+
|
334 |
+
def test_array_to_list(self):
|
335 |
+
a = self.a
|
336 |
+
assert_equal(a.tolist(), [[1, 2], [3, 4]])
|
337 |
+
|
338 |
+
def test_fancy_indexing(self):
|
339 |
+
a = self.a
|
340 |
+
x = a[1, [0, 1, 0]]
|
341 |
+
assert_(isinstance(x, matrix))
|
342 |
+
assert_equal(x, matrix([[3, 4, 3]]))
|
343 |
+
x = a[[1, 0]]
|
344 |
+
assert_(isinstance(x, matrix))
|
345 |
+
assert_equal(x, matrix([[3, 4], [1, 2]]))
|
346 |
+
x = a[[[1], [0]], [[1, 0], [0, 1]]]
|
347 |
+
assert_(isinstance(x, matrix))
|
348 |
+
assert_equal(x, matrix([[4, 3], [1, 2]]))
|
349 |
+
|
350 |
+
def test_matrix_element(self):
|
351 |
+
x = matrix([[1, 2, 3], [4, 5, 6]])
|
352 |
+
assert_equal(x[0][0], matrix([[1, 2, 3]]))
|
353 |
+
assert_equal(x[0][0].shape, (1, 3))
|
354 |
+
assert_equal(x[0].shape, (1, 3))
|
355 |
+
assert_equal(x[:, 0].shape, (2, 1))
|
356 |
+
|
357 |
+
x = matrix(0)
|
358 |
+
assert_equal(x[0, 0], 0)
|
359 |
+
assert_equal(x[0], 0)
|
360 |
+
assert_equal(x[:, 0].shape, x.shape)
|
361 |
+
|
362 |
+
def test_scalar_indexing(self):
|
363 |
+
x = asmatrix(np.zeros((3, 2), float))
|
364 |
+
assert_equal(x[0, 0], x[0][0])
|
365 |
+
|
366 |
+
def test_row_column_indexing(self):
|
367 |
+
x = asmatrix(np.eye(2))
|
368 |
+
assert_array_equal(x[0,:], [[1, 0]])
|
369 |
+
assert_array_equal(x[1,:], [[0, 1]])
|
370 |
+
assert_array_equal(x[:, 0], [[1], [0]])
|
371 |
+
assert_array_equal(x[:, 1], [[0], [1]])
|
372 |
+
|
373 |
+
def test_boolean_indexing(self):
|
374 |
+
A = np.arange(6)
|
375 |
+
A.shape = (3, 2)
|
376 |
+
x = asmatrix(A)
|
377 |
+
assert_array_equal(x[:, np.array([True, False])], x[:, 0])
|
378 |
+
assert_array_equal(x[np.array([True, False, False]),:], x[0,:])
|
379 |
+
|
380 |
+
def test_list_indexing(self):
|
381 |
+
A = np.arange(6)
|
382 |
+
A.shape = (3, 2)
|
383 |
+
x = asmatrix(A)
|
384 |
+
assert_array_equal(x[:, [1, 0]], x[:, ::-1])
|
385 |
+
assert_array_equal(x[[2, 1, 0],:], x[::-1,:])
|
386 |
+
|
387 |
+
|
388 |
+
class TestPower:
|
389 |
+
def test_returntype(self):
|
390 |
+
a = np.array([[0, 1], [0, 0]])
|
391 |
+
assert_(type(matrix_power(a, 2)) is np.ndarray)
|
392 |
+
a = mat(a)
|
393 |
+
assert_(type(matrix_power(a, 2)) is matrix)
|
394 |
+
|
395 |
+
def test_list(self):
|
396 |
+
assert_array_equal(matrix_power([[0, 1], [0, 0]], 2), [[0, 0], [0, 0]])
|
397 |
+
|
398 |
+
|
399 |
+
class TestShape:
|
400 |
+
|
401 |
+
a = np.array([[1], [2]])
|
402 |
+
m = matrix([[1], [2]])
|
403 |
+
|
404 |
+
def test_shape(self):
|
405 |
+
assert_equal(self.a.shape, (2, 1))
|
406 |
+
assert_equal(self.m.shape, (2, 1))
|
407 |
+
|
408 |
+
def test_numpy_ravel(self):
|
409 |
+
assert_equal(np.ravel(self.a).shape, (2,))
|
410 |
+
assert_equal(np.ravel(self.m).shape, (2,))
|
411 |
+
|
412 |
+
def test_member_ravel(self):
|
413 |
+
assert_equal(self.a.ravel().shape, (2,))
|
414 |
+
assert_equal(self.m.ravel().shape, (1, 2))
|
415 |
+
|
416 |
+
def test_member_flatten(self):
|
417 |
+
assert_equal(self.a.flatten().shape, (2,))
|
418 |
+
assert_equal(self.m.flatten().shape, (1, 2))
|
419 |
+
|
420 |
+
def test_numpy_ravel_order(self):
|
421 |
+
x = np.array([[1, 2, 3], [4, 5, 6]])
|
422 |
+
assert_equal(np.ravel(x), [1, 2, 3, 4, 5, 6])
|
423 |
+
assert_equal(np.ravel(x, order='F'), [1, 4, 2, 5, 3, 6])
|
424 |
+
assert_equal(np.ravel(x.T), [1, 4, 2, 5, 3, 6])
|
425 |
+
assert_equal(np.ravel(x.T, order='A'), [1, 2, 3, 4, 5, 6])
|
426 |
+
x = matrix([[1, 2, 3], [4, 5, 6]])
|
427 |
+
assert_equal(np.ravel(x), [1, 2, 3, 4, 5, 6])
|
428 |
+
assert_equal(np.ravel(x, order='F'), [1, 4, 2, 5, 3, 6])
|
429 |
+
assert_equal(np.ravel(x.T), [1, 4, 2, 5, 3, 6])
|
430 |
+
assert_equal(np.ravel(x.T, order='A'), [1, 2, 3, 4, 5, 6])
|
431 |
+
|
432 |
+
def test_matrix_ravel_order(self):
|
433 |
+
x = matrix([[1, 2, 3], [4, 5, 6]])
|
434 |
+
assert_equal(x.ravel(), [[1, 2, 3, 4, 5, 6]])
|
435 |
+
assert_equal(x.ravel(order='F'), [[1, 4, 2, 5, 3, 6]])
|
436 |
+
assert_equal(x.T.ravel(), [[1, 4, 2, 5, 3, 6]])
|
437 |
+
assert_equal(x.T.ravel(order='A'), [[1, 2, 3, 4, 5, 6]])
|
438 |
+
|
439 |
+
def test_array_memory_sharing(self):
|
440 |
+
assert_(np.may_share_memory(self.a, self.a.ravel()))
|
441 |
+
assert_(not np.may_share_memory(self.a, self.a.flatten()))
|
442 |
+
|
443 |
+
def test_matrix_memory_sharing(self):
|
444 |
+
assert_(np.may_share_memory(self.m, self.m.ravel()))
|
445 |
+
assert_(not np.may_share_memory(self.m, self.m.flatten()))
|
446 |
+
|
447 |
+
def test_expand_dims_matrix(self):
|
448 |
+
# matrices are always 2d - so expand_dims only makes sense when the
|
449 |
+
# type is changed away from matrix.
|
450 |
+
a = np.arange(10).reshape((2, 5)).view(np.matrix)
|
451 |
+
expanded = np.expand_dims(a, axis=1)
|
452 |
+
assert_equal(expanded.ndim, 3)
|
453 |
+
assert_(not isinstance(expanded, np.matrix))
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_interaction.py
ADDED
@@ -0,0 +1,354 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""Tests of interaction of matrix with other parts of numpy.
|
2 |
+
|
3 |
+
Note that tests with MaskedArray and linalg are done in separate files.
|
4 |
+
"""
|
5 |
+
import pytest
|
6 |
+
|
7 |
+
import textwrap
|
8 |
+
import warnings
|
9 |
+
|
10 |
+
import numpy as np
|
11 |
+
from numpy.testing import (assert_, assert_equal, assert_raises,
|
12 |
+
assert_raises_regex, assert_array_equal,
|
13 |
+
assert_almost_equal, assert_array_almost_equal)
|
14 |
+
|
15 |
+
|
16 |
+
def test_fancy_indexing():
|
17 |
+
# The matrix class messes with the shape. While this is always
|
18 |
+
# weird (getitem is not used, it does not have setitem nor knows
|
19 |
+
# about fancy indexing), this tests gh-3110
|
20 |
+
# 2018-04-29: moved here from core.tests.test_index.
|
21 |
+
m = np.matrix([[1, 2], [3, 4]])
|
22 |
+
|
23 |
+
assert_(isinstance(m[[0, 1, 0], :], np.matrix))
|
24 |
+
|
25 |
+
# gh-3110. Note the transpose currently because matrices do *not*
|
26 |
+
# support dimension fixing for fancy indexing correctly.
|
27 |
+
x = np.asmatrix(np.arange(50).reshape(5, 10))
|
28 |
+
assert_equal(x[:2, np.array(-1)], x[:2, -1].T)
|
29 |
+
|
30 |
+
|
31 |
+
def test_polynomial_mapdomain():
|
32 |
+
# test that polynomial preserved matrix subtype.
|
33 |
+
# 2018-04-29: moved here from polynomial.tests.polyutils.
|
34 |
+
dom1 = [0, 4]
|
35 |
+
dom2 = [1, 3]
|
36 |
+
x = np.matrix([dom1, dom1])
|
37 |
+
res = np.polynomial.polyutils.mapdomain(x, dom1, dom2)
|
38 |
+
assert_(isinstance(res, np.matrix))
|
39 |
+
|
40 |
+
|
41 |
+
def test_sort_matrix_none():
|
42 |
+
# 2018-04-29: moved here from core.tests.test_multiarray
|
43 |
+
a = np.matrix([[2, 1, 0]])
|
44 |
+
actual = np.sort(a, axis=None)
|
45 |
+
expected = np.matrix([[0, 1, 2]])
|
46 |
+
assert_equal(actual, expected)
|
47 |
+
assert_(type(expected) is np.matrix)
|
48 |
+
|
49 |
+
|
50 |
+
def test_partition_matrix_none():
|
51 |
+
# gh-4301
|
52 |
+
# 2018-04-29: moved here from core.tests.test_multiarray
|
53 |
+
a = np.matrix([[2, 1, 0]])
|
54 |
+
actual = np.partition(a, 1, axis=None)
|
55 |
+
expected = np.matrix([[0, 1, 2]])
|
56 |
+
assert_equal(actual, expected)
|
57 |
+
assert_(type(expected) is np.matrix)
|
58 |
+
|
59 |
+
|
60 |
+
def test_dot_scalar_and_matrix_of_objects():
|
61 |
+
# Ticket #2469
|
62 |
+
# 2018-04-29: moved here from core.tests.test_multiarray
|
63 |
+
arr = np.matrix([1, 2], dtype=object)
|
64 |
+
desired = np.matrix([[3, 6]], dtype=object)
|
65 |
+
assert_equal(np.dot(arr, 3), desired)
|
66 |
+
assert_equal(np.dot(3, arr), desired)
|
67 |
+
|
68 |
+
|
69 |
+
def test_inner_scalar_and_matrix():
|
70 |
+
# 2018-04-29: moved here from core.tests.test_multiarray
|
71 |
+
for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
|
72 |
+
sca = np.array(3, dtype=dt)[()]
|
73 |
+
arr = np.matrix([[1, 2], [3, 4]], dtype=dt)
|
74 |
+
desired = np.matrix([[3, 6], [9, 12]], dtype=dt)
|
75 |
+
assert_equal(np.inner(arr, sca), desired)
|
76 |
+
assert_equal(np.inner(sca, arr), desired)
|
77 |
+
|
78 |
+
|
79 |
+
def test_inner_scalar_and_matrix_of_objects():
|
80 |
+
# Ticket #4482
|
81 |
+
# 2018-04-29: moved here from core.tests.test_multiarray
|
82 |
+
arr = np.matrix([1, 2], dtype=object)
|
83 |
+
desired = np.matrix([[3, 6]], dtype=object)
|
84 |
+
assert_equal(np.inner(arr, 3), desired)
|
85 |
+
assert_equal(np.inner(3, arr), desired)
|
86 |
+
|
87 |
+
|
88 |
+
def test_iter_allocate_output_subtype():
|
89 |
+
# Make sure that the subtype with priority wins
|
90 |
+
# 2018-04-29: moved here from core.tests.test_nditer, given the
|
91 |
+
# matrix specific shape test.
|
92 |
+
|
93 |
+
# matrix vs ndarray
|
94 |
+
a = np.matrix([[1, 2], [3, 4]])
|
95 |
+
b = np.arange(4).reshape(2, 2).T
|
96 |
+
i = np.nditer([a, b, None], [],
|
97 |
+
[['readonly'], ['readonly'], ['writeonly', 'allocate']])
|
98 |
+
assert_(type(i.operands[2]) is np.matrix)
|
99 |
+
assert_(type(i.operands[2]) is not np.ndarray)
|
100 |
+
assert_equal(i.operands[2].shape, (2, 2))
|
101 |
+
|
102 |
+
# matrix always wants things to be 2D
|
103 |
+
b = np.arange(4).reshape(1, 2, 2)
|
104 |
+
assert_raises(RuntimeError, np.nditer, [a, b, None], [],
|
105 |
+
[['readonly'], ['readonly'], ['writeonly', 'allocate']])
|
106 |
+
# but if subtypes are disabled, the result can still work
|
107 |
+
i = np.nditer([a, b, None], [],
|
108 |
+
[['readonly'], ['readonly'],
|
109 |
+
['writeonly', 'allocate', 'no_subtype']])
|
110 |
+
assert_(type(i.operands[2]) is np.ndarray)
|
111 |
+
assert_(type(i.operands[2]) is not np.matrix)
|
112 |
+
assert_equal(i.operands[2].shape, (1, 2, 2))
|
113 |
+
|
114 |
+
|
115 |
+
def like_function():
|
116 |
+
# 2018-04-29: moved here from core.tests.test_numeric
|
117 |
+
a = np.matrix([[1, 2], [3, 4]])
|
118 |
+
for like_function in np.zeros_like, np.ones_like, np.empty_like:
|
119 |
+
b = like_function(a)
|
120 |
+
assert_(type(b) is np.matrix)
|
121 |
+
|
122 |
+
c = like_function(a, subok=False)
|
123 |
+
assert_(type(c) is not np.matrix)
|
124 |
+
|
125 |
+
|
126 |
+
def test_array_astype():
|
127 |
+
# 2018-04-29: copied here from core.tests.test_api
|
128 |
+
# subok=True passes through a matrix
|
129 |
+
a = np.matrix([[0, 1, 2], [3, 4, 5]], dtype='f4')
|
130 |
+
b = a.astype('f4', subok=True, copy=False)
|
131 |
+
assert_(a is b)
|
132 |
+
|
133 |
+
# subok=True is default, and creates a subtype on a cast
|
134 |
+
b = a.astype('i4', copy=False)
|
135 |
+
assert_equal(a, b)
|
136 |
+
assert_equal(type(b), np.matrix)
|
137 |
+
|
138 |
+
# subok=False never returns a matrix
|
139 |
+
b = a.astype('f4', subok=False, copy=False)
|
140 |
+
assert_equal(a, b)
|
141 |
+
assert_(not (a is b))
|
142 |
+
assert_(type(b) is not np.matrix)
|
143 |
+
|
144 |
+
|
145 |
+
def test_stack():
|
146 |
+
# 2018-04-29: copied here from core.tests.test_shape_base
|
147 |
+
# check np.matrix cannot be stacked
|
148 |
+
m = np.matrix([[1, 2], [3, 4]])
|
149 |
+
assert_raises_regex(ValueError, 'shape too large to be a matrix',
|
150 |
+
np.stack, [m, m])
|
151 |
+
|
152 |
+
|
153 |
+
def test_object_scalar_multiply():
|
154 |
+
# Tickets #2469 and #4482
|
155 |
+
# 2018-04-29: moved here from core.tests.test_ufunc
|
156 |
+
arr = np.matrix([1, 2], dtype=object)
|
157 |
+
desired = np.matrix([[3, 6]], dtype=object)
|
158 |
+
assert_equal(np.multiply(arr, 3), desired)
|
159 |
+
assert_equal(np.multiply(3, arr), desired)
|
160 |
+
|
161 |
+
|
162 |
+
def test_nanfunctions_matrices():
|
163 |
+
# Check that it works and that type and
|
164 |
+
# shape are preserved
|
165 |
+
# 2018-04-29: moved here from core.tests.test_nanfunctions
|
166 |
+
mat = np.matrix(np.eye(3))
|
167 |
+
for f in [np.nanmin, np.nanmax]:
|
168 |
+
res = f(mat, axis=0)
|
169 |
+
assert_(isinstance(res, np.matrix))
|
170 |
+
assert_(res.shape == (1, 3))
|
171 |
+
res = f(mat, axis=1)
|
172 |
+
assert_(isinstance(res, np.matrix))
|
173 |
+
assert_(res.shape == (3, 1))
|
174 |
+
res = f(mat)
|
175 |
+
assert_(np.isscalar(res))
|
176 |
+
# check that rows of nan are dealt with for subclasses (#4628)
|
177 |
+
mat[1] = np.nan
|
178 |
+
for f in [np.nanmin, np.nanmax]:
|
179 |
+
with warnings.catch_warnings(record=True) as w:
|
180 |
+
warnings.simplefilter('always')
|
181 |
+
res = f(mat, axis=0)
|
182 |
+
assert_(isinstance(res, np.matrix))
|
183 |
+
assert_(not np.any(np.isnan(res)))
|
184 |
+
assert_(len(w) == 0)
|
185 |
+
|
186 |
+
with warnings.catch_warnings(record=True) as w:
|
187 |
+
warnings.simplefilter('always')
|
188 |
+
res = f(mat, axis=1)
|
189 |
+
assert_(isinstance(res, np.matrix))
|
190 |
+
assert_(np.isnan(res[1, 0]) and not np.isnan(res[0, 0])
|
191 |
+
and not np.isnan(res[2, 0]))
|
192 |
+
assert_(len(w) == 1, 'no warning raised')
|
193 |
+
assert_(issubclass(w[0].category, RuntimeWarning))
|
194 |
+
|
195 |
+
with warnings.catch_warnings(record=True) as w:
|
196 |
+
warnings.simplefilter('always')
|
197 |
+
res = f(mat)
|
198 |
+
assert_(np.isscalar(res))
|
199 |
+
assert_(res != np.nan)
|
200 |
+
assert_(len(w) == 0)
|
201 |
+
|
202 |
+
|
203 |
+
def test_nanfunctions_matrices_general():
|
204 |
+
# Check that it works and that type and
|
205 |
+
# shape are preserved
|
206 |
+
# 2018-04-29: moved here from core.tests.test_nanfunctions
|
207 |
+
mat = np.matrix(np.eye(3))
|
208 |
+
for f in (np.nanargmin, np.nanargmax, np.nansum, np.nanprod,
|
209 |
+
np.nanmean, np.nanvar, np.nanstd):
|
210 |
+
res = f(mat, axis=0)
|
211 |
+
assert_(isinstance(res, np.matrix))
|
212 |
+
assert_(res.shape == (1, 3))
|
213 |
+
res = f(mat, axis=1)
|
214 |
+
assert_(isinstance(res, np.matrix))
|
215 |
+
assert_(res.shape == (3, 1))
|
216 |
+
res = f(mat)
|
217 |
+
assert_(np.isscalar(res))
|
218 |
+
|
219 |
+
for f in np.nancumsum, np.nancumprod:
|
220 |
+
res = f(mat, axis=0)
|
221 |
+
assert_(isinstance(res, np.matrix))
|
222 |
+
assert_(res.shape == (3, 3))
|
223 |
+
res = f(mat, axis=1)
|
224 |
+
assert_(isinstance(res, np.matrix))
|
225 |
+
assert_(res.shape == (3, 3))
|
226 |
+
res = f(mat)
|
227 |
+
assert_(isinstance(res, np.matrix))
|
228 |
+
assert_(res.shape == (1, 3*3))
|
229 |
+
|
230 |
+
|
231 |
+
def test_average_matrix():
|
232 |
+
# 2018-04-29: moved here from core.tests.test_function_base.
|
233 |
+
y = np.matrix(np.random.rand(5, 5))
|
234 |
+
assert_array_equal(y.mean(0), np.average(y, 0))
|
235 |
+
|
236 |
+
a = np.matrix([[1, 2], [3, 4]])
|
237 |
+
w = np.matrix([[1, 2], [3, 4]])
|
238 |
+
|
239 |
+
r = np.average(a, axis=0, weights=w)
|
240 |
+
assert_equal(type(r), np.matrix)
|
241 |
+
assert_equal(r, [[2.5, 10.0/3]])
|
242 |
+
|
243 |
+
|
244 |
+
def test_trapz_matrix():
|
245 |
+
# Test to make sure matrices give the same answer as ndarrays
|
246 |
+
# 2018-04-29: moved here from core.tests.test_function_base.
|
247 |
+
x = np.linspace(0, 5)
|
248 |
+
y = x * x
|
249 |
+
r = np.trapz(y, x)
|
250 |
+
mx = np.matrix(x)
|
251 |
+
my = np.matrix(y)
|
252 |
+
mr = np.trapz(my, mx)
|
253 |
+
assert_almost_equal(mr, r)
|
254 |
+
|
255 |
+
|
256 |
+
def test_ediff1d_matrix():
|
257 |
+
# 2018-04-29: moved here from core.tests.test_arraysetops.
|
258 |
+
assert(isinstance(np.ediff1d(np.matrix(1)), np.matrix))
|
259 |
+
assert(isinstance(np.ediff1d(np.matrix(1), to_begin=1), np.matrix))
|
260 |
+
|
261 |
+
|
262 |
+
def test_apply_along_axis_matrix():
|
263 |
+
# this test is particularly malicious because matrix
|
264 |
+
# refuses to become 1d
|
265 |
+
# 2018-04-29: moved here from core.tests.test_shape_base.
|
266 |
+
def double(row):
|
267 |
+
return row * 2
|
268 |
+
|
269 |
+
m = np.matrix([[0, 1], [2, 3]])
|
270 |
+
expected = np.matrix([[0, 2], [4, 6]])
|
271 |
+
|
272 |
+
result = np.apply_along_axis(double, 0, m)
|
273 |
+
assert_(isinstance(result, np.matrix))
|
274 |
+
assert_array_equal(result, expected)
|
275 |
+
|
276 |
+
result = np.apply_along_axis(double, 1, m)
|
277 |
+
assert_(isinstance(result, np.matrix))
|
278 |
+
assert_array_equal(result, expected)
|
279 |
+
|
280 |
+
|
281 |
+
def test_kron_matrix():
|
282 |
+
# 2018-04-29: moved here from core.tests.test_shape_base.
|
283 |
+
a = np.ones([2, 2])
|
284 |
+
m = np.asmatrix(a)
|
285 |
+
assert_equal(type(np.kron(a, a)), np.ndarray)
|
286 |
+
assert_equal(type(np.kron(m, m)), np.matrix)
|
287 |
+
assert_equal(type(np.kron(a, m)), np.matrix)
|
288 |
+
assert_equal(type(np.kron(m, a)), np.matrix)
|
289 |
+
|
290 |
+
|
291 |
+
class TestConcatenatorMatrix:
|
292 |
+
# 2018-04-29: moved here from core.tests.test_index_tricks.
|
293 |
+
def test_matrix(self):
|
294 |
+
a = [1, 2]
|
295 |
+
b = [3, 4]
|
296 |
+
|
297 |
+
ab_r = np.r_['r', a, b]
|
298 |
+
ab_c = np.r_['c', a, b]
|
299 |
+
|
300 |
+
assert_equal(type(ab_r), np.matrix)
|
301 |
+
assert_equal(type(ab_c), np.matrix)
|
302 |
+
|
303 |
+
assert_equal(np.array(ab_r), [[1, 2, 3, 4]])
|
304 |
+
assert_equal(np.array(ab_c), [[1], [2], [3], [4]])
|
305 |
+
|
306 |
+
assert_raises(ValueError, lambda: np.r_['rc', a, b])
|
307 |
+
|
308 |
+
def test_matrix_scalar(self):
|
309 |
+
r = np.r_['r', [1, 2], 3]
|
310 |
+
assert_equal(type(r), np.matrix)
|
311 |
+
assert_equal(np.array(r), [[1, 2, 3]])
|
312 |
+
|
313 |
+
def test_matrix_builder(self):
|
314 |
+
a = np.array([1])
|
315 |
+
b = np.array([2])
|
316 |
+
c = np.array([3])
|
317 |
+
d = np.array([4])
|
318 |
+
actual = np.r_['a, b; c, d']
|
319 |
+
expected = np.bmat([[a, b], [c, d]])
|
320 |
+
|
321 |
+
assert_equal(actual, expected)
|
322 |
+
assert_equal(type(actual), type(expected))
|
323 |
+
|
324 |
+
|
325 |
+
def test_array_equal_error_message_matrix():
|
326 |
+
# 2018-04-29: moved here from testing.tests.test_utils.
|
327 |
+
with pytest.raises(AssertionError) as exc_info:
|
328 |
+
assert_equal(np.array([1, 2]), np.matrix([1, 2]))
|
329 |
+
msg = str(exc_info.value)
|
330 |
+
msg_reference = textwrap.dedent("""\
|
331 |
+
|
332 |
+
Arrays are not equal
|
333 |
+
|
334 |
+
(shapes (2,), (1, 2) mismatch)
|
335 |
+
x: array([1, 2])
|
336 |
+
y: matrix([[1, 2]])""")
|
337 |
+
assert_equal(msg, msg_reference)
|
338 |
+
|
339 |
+
|
340 |
+
def test_array_almost_equal_matrix():
|
341 |
+
# Matrix slicing keeps things 2-D, while array does not necessarily.
|
342 |
+
# See gh-8452.
|
343 |
+
# 2018-04-29: moved here from testing.tests.test_utils.
|
344 |
+
m1 = np.matrix([[1., 2.]])
|
345 |
+
m2 = np.matrix([[1., np.nan]])
|
346 |
+
m3 = np.matrix([[1., -np.inf]])
|
347 |
+
m4 = np.matrix([[np.nan, np.inf]])
|
348 |
+
m5 = np.matrix([[1., 2.], [np.nan, np.inf]])
|
349 |
+
for assert_func in assert_array_almost_equal, assert_almost_equal:
|
350 |
+
for m in m1, m2, m3, m4, m5:
|
351 |
+
assert_func(m, m)
|
352 |
+
a = np.array(m)
|
353 |
+
assert_func(a, m)
|
354 |
+
assert_func(m, a)
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_masked_matrix.py
ADDED
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
from numpy.testing import assert_warns
|
3 |
+
from numpy.ma.testutils import (assert_, assert_equal, assert_raises,
|
4 |
+
assert_array_equal)
|
5 |
+
from numpy.ma.core import (masked_array, masked_values, masked, allequal,
|
6 |
+
MaskType, getmask, MaskedArray, nomask,
|
7 |
+
log, add, hypot, divide)
|
8 |
+
from numpy.ma.extras import mr_
|
9 |
+
from numpy.compat import pickle
|
10 |
+
|
11 |
+
|
12 |
+
class MMatrix(MaskedArray, np.matrix,):
|
13 |
+
|
14 |
+
def __new__(cls, data, mask=nomask):
|
15 |
+
mat = np.matrix(data)
|
16 |
+
_data = MaskedArray.__new__(cls, data=mat, mask=mask)
|
17 |
+
return _data
|
18 |
+
|
19 |
+
def __array_finalize__(self, obj):
|
20 |
+
np.matrix.__array_finalize__(self, obj)
|
21 |
+
MaskedArray.__array_finalize__(self, obj)
|
22 |
+
return
|
23 |
+
|
24 |
+
@property
|
25 |
+
def _series(self):
|
26 |
+
_view = self.view(MaskedArray)
|
27 |
+
_view._sharedmask = False
|
28 |
+
return _view
|
29 |
+
|
30 |
+
|
31 |
+
class TestMaskedMatrix:
|
32 |
+
def test_matrix_indexing(self):
|
33 |
+
# Tests conversions and indexing
|
34 |
+
x1 = np.matrix([[1, 2, 3], [4, 3, 2]])
|
35 |
+
x2 = masked_array(x1, mask=[[1, 0, 0], [0, 1, 0]])
|
36 |
+
x3 = masked_array(x1, mask=[[0, 1, 0], [1, 0, 0]])
|
37 |
+
x4 = masked_array(x1)
|
38 |
+
# test conversion to strings
|
39 |
+
str(x2) # raises?
|
40 |
+
repr(x2) # raises?
|
41 |
+
# tests of indexing
|
42 |
+
assert_(type(x2[1, 0]) is type(x1[1, 0]))
|
43 |
+
assert_(x1[1, 0] == x2[1, 0])
|
44 |
+
assert_(x2[1, 1] is masked)
|
45 |
+
assert_equal(x1[0, 2], x2[0, 2])
|
46 |
+
assert_equal(x1[0, 1:], x2[0, 1:])
|
47 |
+
assert_equal(x1[:, 2], x2[:, 2])
|
48 |
+
assert_equal(x1[:], x2[:])
|
49 |
+
assert_equal(x1[1:], x3[1:])
|
50 |
+
x1[0, 2] = 9
|
51 |
+
x2[0, 2] = 9
|
52 |
+
assert_equal(x1, x2)
|
53 |
+
x1[0, 1:] = 99
|
54 |
+
x2[0, 1:] = 99
|
55 |
+
assert_equal(x1, x2)
|
56 |
+
x2[0, 1] = masked
|
57 |
+
assert_equal(x1, x2)
|
58 |
+
x2[0, 1:] = masked
|
59 |
+
assert_equal(x1, x2)
|
60 |
+
x2[0, :] = x1[0, :]
|
61 |
+
x2[0, 1] = masked
|
62 |
+
assert_(allequal(getmask(x2), np.array([[0, 1, 0], [0, 1, 0]])))
|
63 |
+
x3[1, :] = masked_array([1, 2, 3], [1, 1, 0])
|
64 |
+
assert_(allequal(getmask(x3)[1], masked_array([1, 1, 0])))
|
65 |
+
assert_(allequal(getmask(x3[1]), masked_array([1, 1, 0])))
|
66 |
+
x4[1, :] = masked_array([1, 2, 3], [1, 1, 0])
|
67 |
+
assert_(allequal(getmask(x4[1]), masked_array([1, 1, 0])))
|
68 |
+
assert_(allequal(x4[1], masked_array([1, 2, 3])))
|
69 |
+
x1 = np.matrix(np.arange(5) * 1.0)
|
70 |
+
x2 = masked_values(x1, 3.0)
|
71 |
+
assert_equal(x1, x2)
|
72 |
+
assert_(allequal(masked_array([0, 0, 0, 1, 0], dtype=MaskType),
|
73 |
+
x2.mask))
|
74 |
+
assert_equal(3.0, x2.fill_value)
|
75 |
+
|
76 |
+
def test_pickling_subbaseclass(self):
|
77 |
+
# Test pickling w/ a subclass of ndarray
|
78 |
+
a = masked_array(np.matrix(list(range(10))), mask=[1, 0, 1, 0, 0] * 2)
|
79 |
+
for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
|
80 |
+
a_pickled = pickle.loads(pickle.dumps(a, protocol=proto))
|
81 |
+
assert_equal(a_pickled._mask, a._mask)
|
82 |
+
assert_equal(a_pickled, a)
|
83 |
+
assert_(isinstance(a_pickled._data, np.matrix))
|
84 |
+
|
85 |
+
def test_count_mean_with_matrix(self):
|
86 |
+
m = masked_array(np.matrix([[1, 2], [3, 4]]), mask=np.zeros((2, 2)))
|
87 |
+
|
88 |
+
assert_equal(m.count(axis=0).shape, (1, 2))
|
89 |
+
assert_equal(m.count(axis=1).shape, (2, 1))
|
90 |
+
|
91 |
+
# Make sure broadcasting inside mean and var work
|
92 |
+
assert_equal(m.mean(axis=0), [[2., 3.]])
|
93 |
+
assert_equal(m.mean(axis=1), [[1.5], [3.5]])
|
94 |
+
|
95 |
+
def test_flat(self):
|
96 |
+
# Test that flat can return items even for matrices [#4585, #4615]
|
97 |
+
# test simple access
|
98 |
+
test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1])
|
99 |
+
assert_equal(test.flat[1], 2)
|
100 |
+
assert_equal(test.flat[2], masked)
|
101 |
+
assert_(np.all(test.flat[0:2] == test[0, 0:2]))
|
102 |
+
# Test flat on masked_matrices
|
103 |
+
test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1])
|
104 |
+
test.flat = masked_array([3, 2, 1], mask=[1, 0, 0])
|
105 |
+
control = masked_array(np.matrix([[3, 2, 1]]), mask=[1, 0, 0])
|
106 |
+
assert_equal(test, control)
|
107 |
+
# Test setting
|
108 |
+
test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1])
|
109 |
+
testflat = test.flat
|
110 |
+
testflat[:] = testflat[[2, 1, 0]]
|
111 |
+
assert_equal(test, control)
|
112 |
+
testflat[0] = 9
|
113 |
+
# test that matrices keep the correct shape (#4615)
|
114 |
+
a = masked_array(np.matrix(np.eye(2)), mask=0)
|
115 |
+
b = a.flat
|
116 |
+
b01 = b[:2]
|
117 |
+
assert_equal(b01.data, np.array([[1., 0.]]))
|
118 |
+
assert_equal(b01.mask, np.array([[False, False]]))
|
119 |
+
|
120 |
+
def test_allany_onmatrices(self):
|
121 |
+
x = np.array([[0.13, 0.26, 0.90],
|
122 |
+
[0.28, 0.33, 0.63],
|
123 |
+
[0.31, 0.87, 0.70]])
|
124 |
+
X = np.matrix(x)
|
125 |
+
m = np.array([[True, False, False],
|
126 |
+
[False, False, False],
|
127 |
+
[True, True, False]], dtype=np.bool_)
|
128 |
+
mX = masked_array(X, mask=m)
|
129 |
+
mXbig = (mX > 0.5)
|
130 |
+
mXsmall = (mX < 0.5)
|
131 |
+
|
132 |
+
assert_(not mXbig.all())
|
133 |
+
assert_(mXbig.any())
|
134 |
+
assert_equal(mXbig.all(0), np.matrix([False, False, True]))
|
135 |
+
assert_equal(mXbig.all(1), np.matrix([False, False, True]).T)
|
136 |
+
assert_equal(mXbig.any(0), np.matrix([False, False, True]))
|
137 |
+
assert_equal(mXbig.any(1), np.matrix([True, True, True]).T)
|
138 |
+
|
139 |
+
assert_(not mXsmall.all())
|
140 |
+
assert_(mXsmall.any())
|
141 |
+
assert_equal(mXsmall.all(0), np.matrix([True, True, False]))
|
142 |
+
assert_equal(mXsmall.all(1), np.matrix([False, False, False]).T)
|
143 |
+
assert_equal(mXsmall.any(0), np.matrix([True, True, False]))
|
144 |
+
assert_equal(mXsmall.any(1), np.matrix([True, True, False]).T)
|
145 |
+
|
146 |
+
def test_compressed(self):
|
147 |
+
a = masked_array(np.matrix([1, 2, 3, 4]), mask=[0, 0, 0, 0])
|
148 |
+
b = a.compressed()
|
149 |
+
assert_equal(b, a)
|
150 |
+
assert_(isinstance(b, np.matrix))
|
151 |
+
a[0, 0] = masked
|
152 |
+
b = a.compressed()
|
153 |
+
assert_equal(b, [[2, 3, 4]])
|
154 |
+
|
155 |
+
def test_ravel(self):
|
156 |
+
a = masked_array(np.matrix([1, 2, 3, 4, 5]), mask=[[0, 1, 0, 0, 0]])
|
157 |
+
aravel = a.ravel()
|
158 |
+
assert_equal(aravel.shape, (1, 5))
|
159 |
+
assert_equal(aravel._mask.shape, a.shape)
|
160 |
+
|
161 |
+
def test_view(self):
|
162 |
+
# Test view w/ flexible dtype
|
163 |
+
iterator = list(zip(np.arange(10), np.random.rand(10)))
|
164 |
+
data = np.array(iterator)
|
165 |
+
a = masked_array(iterator, dtype=[('a', float), ('b', float)])
|
166 |
+
a.mask[0] = (1, 0)
|
167 |
+
test = a.view((float, 2), np.matrix)
|
168 |
+
assert_equal(test, data)
|
169 |
+
assert_(isinstance(test, np.matrix))
|
170 |
+
assert_(not isinstance(test, MaskedArray))
|
171 |
+
|
172 |
+
|
173 |
+
class TestSubclassing:
|
174 |
+
# Test suite for masked subclasses of ndarray.
|
175 |
+
|
176 |
+
def setup_method(self):
|
177 |
+
x = np.arange(5, dtype='float')
|
178 |
+
mx = MMatrix(x, mask=[0, 1, 0, 0, 0])
|
179 |
+
self.data = (x, mx)
|
180 |
+
|
181 |
+
def test_maskedarray_subclassing(self):
|
182 |
+
# Tests subclassing MaskedArray
|
183 |
+
(x, mx) = self.data
|
184 |
+
assert_(isinstance(mx._data, np.matrix))
|
185 |
+
|
186 |
+
def test_masked_unary_operations(self):
|
187 |
+
# Tests masked_unary_operation
|
188 |
+
(x, mx) = self.data
|
189 |
+
with np.errstate(divide='ignore'):
|
190 |
+
assert_(isinstance(log(mx), MMatrix))
|
191 |
+
assert_equal(log(x), np.log(x))
|
192 |
+
|
193 |
+
def test_masked_binary_operations(self):
|
194 |
+
# Tests masked_binary_operation
|
195 |
+
(x, mx) = self.data
|
196 |
+
# Result should be a MMatrix
|
197 |
+
assert_(isinstance(add(mx, mx), MMatrix))
|
198 |
+
assert_(isinstance(add(mx, x), MMatrix))
|
199 |
+
# Result should work
|
200 |
+
assert_equal(add(mx, x), mx+x)
|
201 |
+
assert_(isinstance(add(mx, mx)._data, np.matrix))
|
202 |
+
with assert_warns(DeprecationWarning):
|
203 |
+
assert_(isinstance(add.outer(mx, mx), MMatrix))
|
204 |
+
assert_(isinstance(hypot(mx, mx), MMatrix))
|
205 |
+
assert_(isinstance(hypot(mx, x), MMatrix))
|
206 |
+
|
207 |
+
def test_masked_binary_operations2(self):
|
208 |
+
# Tests domained_masked_binary_operation
|
209 |
+
(x, mx) = self.data
|
210 |
+
xmx = masked_array(mx.data.__array__(), mask=mx.mask)
|
211 |
+
assert_(isinstance(divide(mx, mx), MMatrix))
|
212 |
+
assert_(isinstance(divide(mx, x), MMatrix))
|
213 |
+
assert_equal(divide(mx, mx), divide(xmx, xmx))
|
214 |
+
|
215 |
+
class TestConcatenator:
|
216 |
+
# Tests for mr_, the equivalent of r_ for masked arrays.
|
217 |
+
|
218 |
+
def test_matrix_builder(self):
|
219 |
+
assert_raises(np.ma.MAError, lambda: mr_['1, 2; 3, 4'])
|
220 |
+
|
221 |
+
def test_matrix(self):
|
222 |
+
# Test consistency with unmasked version. If we ever deprecate
|
223 |
+
# matrix, this test should either still pass, or both actual and
|
224 |
+
# expected should fail to be build.
|
225 |
+
actual = mr_['r', 1, 2, 3]
|
226 |
+
expected = np.ma.array(np.r_['r', 1, 2, 3])
|
227 |
+
assert_array_equal(actual, expected)
|
228 |
+
|
229 |
+
# outer type is masked array, inner type is matrix
|
230 |
+
assert_equal(type(actual), type(expected))
|
231 |
+
assert_equal(type(actual.data), type(expected.data))
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_matrix_linalg.py
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
""" Test functions for linalg module using the matrix class."""
|
2 |
+
import numpy as np
|
3 |
+
|
4 |
+
from numpy.linalg.tests.test_linalg import (
|
5 |
+
LinalgCase, apply_tag, TestQR as _TestQR, LinalgTestCase,
|
6 |
+
_TestNorm2D, _TestNormDoubleBase, _TestNormSingleBase, _TestNormInt64Base,
|
7 |
+
SolveCases, InvCases, EigvalsCases, EigCases, SVDCases, CondCases,
|
8 |
+
PinvCases, DetCases, LstsqCases)
|
9 |
+
|
10 |
+
|
11 |
+
CASES = []
|
12 |
+
|
13 |
+
# square test cases
|
14 |
+
CASES += apply_tag('square', [
|
15 |
+
LinalgCase("0x0_matrix",
|
16 |
+
np.empty((0, 0), dtype=np.double).view(np.matrix),
|
17 |
+
np.empty((0, 1), dtype=np.double).view(np.matrix),
|
18 |
+
tags={'size-0'}),
|
19 |
+
LinalgCase("matrix_b_only",
|
20 |
+
np.array([[1., 2.], [3., 4.]]),
|
21 |
+
np.matrix([2., 1.]).T),
|
22 |
+
LinalgCase("matrix_a_and_b",
|
23 |
+
np.matrix([[1., 2.], [3., 4.]]),
|
24 |
+
np.matrix([2., 1.]).T),
|
25 |
+
])
|
26 |
+
|
27 |
+
# hermitian test-cases
|
28 |
+
CASES += apply_tag('hermitian', [
|
29 |
+
LinalgCase("hmatrix_a_and_b",
|
30 |
+
np.matrix([[1., 2.], [2., 1.]]),
|
31 |
+
None),
|
32 |
+
])
|
33 |
+
# No need to make generalized or strided cases for matrices.
|
34 |
+
|
35 |
+
|
36 |
+
class MatrixTestCase(LinalgTestCase):
|
37 |
+
TEST_CASES = CASES
|
38 |
+
|
39 |
+
|
40 |
+
class TestSolveMatrix(SolveCases, MatrixTestCase):
|
41 |
+
pass
|
42 |
+
|
43 |
+
|
44 |
+
class TestInvMatrix(InvCases, MatrixTestCase):
|
45 |
+
pass
|
46 |
+
|
47 |
+
|
48 |
+
class TestEigvalsMatrix(EigvalsCases, MatrixTestCase):
|
49 |
+
pass
|
50 |
+
|
51 |
+
|
52 |
+
class TestEigMatrix(EigCases, MatrixTestCase):
|
53 |
+
pass
|
54 |
+
|
55 |
+
|
56 |
+
class TestSVDMatrix(SVDCases, MatrixTestCase):
|
57 |
+
pass
|
58 |
+
|
59 |
+
|
60 |
+
class TestCondMatrix(CondCases, MatrixTestCase):
|
61 |
+
pass
|
62 |
+
|
63 |
+
|
64 |
+
class TestPinvMatrix(PinvCases, MatrixTestCase):
|
65 |
+
pass
|
66 |
+
|
67 |
+
|
68 |
+
class TestDetMatrix(DetCases, MatrixTestCase):
|
69 |
+
pass
|
70 |
+
|
71 |
+
|
72 |
+
class TestLstsqMatrix(LstsqCases, MatrixTestCase):
|
73 |
+
pass
|
74 |
+
|
75 |
+
|
76 |
+
class _TestNorm2DMatrix(_TestNorm2D):
|
77 |
+
array = np.matrix
|
78 |
+
|
79 |
+
|
80 |
+
class TestNormDoubleMatrix(_TestNorm2DMatrix, _TestNormDoubleBase):
|
81 |
+
pass
|
82 |
+
|
83 |
+
|
84 |
+
class TestNormSingleMatrix(_TestNorm2DMatrix, _TestNormSingleBase):
|
85 |
+
pass
|
86 |
+
|
87 |
+
|
88 |
+
class TestNormInt64Matrix(_TestNorm2DMatrix, _TestNormInt64Base):
|
89 |
+
pass
|
90 |
+
|
91 |
+
|
92 |
+
class TestQRMatrix(_TestQR):
|
93 |
+
array = np.matrix
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_multiarray.py
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
from numpy.testing import assert_, assert_equal, assert_array_equal
|
3 |
+
|
4 |
+
class TestView:
|
5 |
+
def test_type(self):
|
6 |
+
x = np.array([1, 2, 3])
|
7 |
+
assert_(isinstance(x.view(np.matrix), np.matrix))
|
8 |
+
|
9 |
+
def test_keywords(self):
|
10 |
+
x = np.array([(1, 2)], dtype=[('a', np.int8), ('b', np.int8)])
|
11 |
+
# We must be specific about the endianness here:
|
12 |
+
y = x.view(dtype='<i2', type=np.matrix)
|
13 |
+
assert_array_equal(y, [[513]])
|
14 |
+
|
15 |
+
assert_(isinstance(y, np.matrix))
|
16 |
+
assert_equal(y.dtype, np.dtype('<i2'))
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_numeric.py
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
from numpy.testing import assert_equal
|
3 |
+
|
4 |
+
class TestDot:
|
5 |
+
def test_matscalar(self):
|
6 |
+
b1 = np.matrix(np.ones((3, 3), dtype=complex))
|
7 |
+
assert_equal(b1*1.0, b1)
|
8 |
+
|
9 |
+
|
10 |
+
def test_diagonal():
|
11 |
+
b1 = np.matrix([[1,2],[3,4]])
|
12 |
+
diag_b1 = np.matrix([[1, 4]])
|
13 |
+
array_b1 = np.array([1, 4])
|
14 |
+
|
15 |
+
assert_equal(b1.diagonal(), diag_b1)
|
16 |
+
assert_equal(np.diagonal(b1), array_b1)
|
17 |
+
assert_equal(np.diag(b1), array_b1)
|
.venv/lib/python3.11/site-packages/numpy/matrixlib/tests/test_regression.py
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
from numpy.testing import assert_, assert_equal, assert_raises
|
3 |
+
|
4 |
+
|
5 |
+
class TestRegression:
|
6 |
+
def test_kron_matrix(self):
|
7 |
+
# Ticket #71
|
8 |
+
x = np.matrix('[1 0; 1 0]')
|
9 |
+
assert_equal(type(np.kron(x, x)), type(x))
|
10 |
+
|
11 |
+
def test_matrix_properties(self):
|
12 |
+
# Ticket #125
|
13 |
+
a = np.matrix([1.0], dtype=float)
|
14 |
+
assert_(type(a.real) is np.matrix)
|
15 |
+
assert_(type(a.imag) is np.matrix)
|
16 |
+
c, d = np.matrix([0.0]).nonzero()
|
17 |
+
assert_(type(c) is np.ndarray)
|
18 |
+
assert_(type(d) is np.ndarray)
|
19 |
+
|
20 |
+
def test_matrix_multiply_by_1d_vector(self):
|
21 |
+
# Ticket #473
|
22 |
+
def mul():
|
23 |
+
np.mat(np.eye(2))*np.ones(2)
|
24 |
+
|
25 |
+
assert_raises(ValueError, mul)
|
26 |
+
|
27 |
+
def test_matrix_std_argmax(self):
|
28 |
+
# Ticket #83
|
29 |
+
x = np.asmatrix(np.random.uniform(0, 1, (3, 3)))
|
30 |
+
assert_equal(x.std().shape, ())
|
31 |
+
assert_equal(x.argmax().shape, ())
|
.venv/lib/python3.11/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): ...
|
.venv/lib/python3.11/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
|
.venv/lib/python3.11/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'
|
.venv/lib/python3.11/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'
|